aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-05-01 09:31:58 +0800
committerPo Lu2023-05-01 09:31:58 +0800
commit5550816f5962943abd81fbf68901dad575f18c06 (patch)
tree9fcb1305b7a3e80a349a9fba6f192d8b348cf7a5 /src
parent9a7c645dd4ef38b72787e932d444a61ed4e04c63 (diff)
downloademacs-5550816f5962943abd81fbf68901dad575f18c06.tar.gz
emacs-5550816f5962943abd81fbf68901dad575f18c06.zip
Work around system restrictions regarding exec
* doc/emacs/android.texi (Android Environment): Document `android-use-exec-loader'. * exec/exec1.c (main): Set program group of child process. * src/android.c (android_rewrite_spawn_argv): New function. * src/android.h: Update prototypes. * src/androidfns.c (syms_of_androidfns): New variable `android_use_exec_loader'. * src/callproc.c (emacs_spawn): Rewrite the argument vector to use exec1 if necessary.
Diffstat (limited to 'src')
-rw-r--r--src/android.c83
-rw-r--r--src/android.h5
-rw-r--r--src/androidfns.c14
-rw-r--r--src/callproc.c16
4 files changed, 118 insertions, 0 deletions
diff --git a/src/android.c b/src/android.c
index 3798758ff16..ce8f277e120 100644
--- a/src/android.c
+++ b/src/android.c
@@ -6514,6 +6514,89 @@ android_free_cursor (android_cursor cursor)
6514 android_destroy_handle (cursor); 6514 android_destroy_handle (cursor);
6515} 6515}
6516 6516
6517
6518
6519/* Process execution.
6520
6521 Newer Android systems use SELinux to restrict user programs from
6522 executing programs installed in the application data directory for
6523 security reasons. Emacs uses a `loader' binary installed in the
6524 application data directory to manually load executables and replace
6525 the `execve' system call. */
6526
6527enum
6528 {
6529 /* Maximum number of arguments available. */
6530 MAXARGS = 1024,
6531 };
6532
6533/* Rewrite the command line given in *ARGV to utilize the `exec1'
6534 bootstrap binary if necessary.
6535
6536 Value is 0 upon success, else 1. Set errno upon failure.
6537
6538 ARGV holds a pointer to a NULL-terminated array of arguments given
6539 to `emacs_spawn'. */
6540
6541int
6542android_rewrite_spawn_argv (const char ***argv)
6543{
6544 static const char *new_args[MAXARGS];
6545 static char exec1_name[PATH_MAX], loader_name[PATH_MAX];
6546 size_t i, nargs;
6547
6548 /* This isn't required on Android 9 or earlier. */
6549
6550 if (android_api_level < 29 || !android_use_exec_loader)
6551 return 0;
6552
6553 /* Get argv[0]; this should never be NULL.
6554 Then, verify that it exists and is executable. */
6555
6556 eassert (**argv);
6557 if (access (**argv, R_OK | X_OK))
6558 return 1;
6559
6560 /* Count the number of arguments in *argv. */
6561
6562 nargs = 0;
6563 while ((*argv)[nargs])
6564 ++nargs;
6565
6566 /* nargs now holds the number of arguments in argv. If it's larger
6567 than MAXARGS, return failure. */
6568
6569 if (nargs + 2 > MAXARGS)
6570 {
6571 errno = E2BIG;
6572 return 1;
6573 }
6574
6575 /* Fill in the name of `libexec1.so'. */
6576 snprintf (exec1_name, PATH_MAX, "%s/libexec1.so",
6577 android_lib_dir);
6578
6579 /* And libloader.so. */
6580 snprintf (loader_name, PATH_MAX, "%s/libloader.so",
6581 android_lib_dir);
6582
6583 /* Now fill in the first two arguments. */
6584 new_args[0] = exec1_name;
6585 new_args[1] = loader_name;
6586
6587 /* And insert the rest. */
6588 for (i = 0; i < nargs; ++i)
6589 new_args[i + 2] = (*argv)[i];
6590
6591 /* Replace argv. */
6592 *argv = new_args;
6593
6594 /* Return success. */
6595 return 0;
6596}
6597
6598
6599
6517#else /* ANDROID_STUBIFY */ 6600#else /* ANDROID_STUBIFY */
6518 6601
6519/* X emulation functions for Android. */ 6602/* X emulation functions for Android. */
diff --git a/src/android.h b/src/android.h
index 24666aaf989..62d420d4cce 100644
--- a/src/android.h
+++ b/src/android.h
@@ -190,6 +190,11 @@ extern void android_write_event (union android_event *);
190 190
191extern unsigned int event_serial; 191extern unsigned int event_serial;
192 192
193
194
195/* Process related functions. */
196extern int android_rewrite_spawn_argv (const char ***);
197
193#endif 198#endif
194 199
195/* JNI functions should not be built when Emacs is stubbed out for the 200/* JNI functions should not be built when Emacs is stubbed out for the
diff --git a/src/androidfns.c b/src/androidfns.c
index 3367ebdf755..3bd34edd5b9 100644
--- a/src/androidfns.c
+++ b/src/androidfns.c
@@ -3112,6 +3112,20 @@ Note that if you set this, you will no longer be able to quit Emacs
3112using the volume down button. */); 3112using the volume down button. */);
3113 android_pass_multimedia_buttons_to_system = false; 3113 android_pass_multimedia_buttons_to_system = false;
3114 3114
3115 DEFVAR_BOOL ("android-use-exec-loader", android_use_exec_loader,
3116 doc: /* Whether or not to bypass system restrictions on program execution.
3117
3118Android 10 and later prevent programs from executing files installed
3119in writable directories, such as the application data directory.
3120
3121When non-nil, Emacs will bypass this restriction by running such
3122executables under system call tracing, and replacing the `execve'
3123system call with a version which ignores the system's security
3124restrictions.
3125
3126This option has no effect on Android 9 and earlier. */);
3127 android_use_exec_loader = true;
3128
3115 /* Functions defined. */ 3129 /* Functions defined. */
3116 defsubr (&Sx_create_frame); 3130 defsubr (&Sx_create_frame);
3117 defsubr (&Sxw_color_defined_p); 3131 defsubr (&Sxw_color_defined_p);
diff --git a/src/callproc.c b/src/callproc.c
index a1811a3bb23..015b52bc9bc 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -92,6 +92,10 @@ extern char **environ;
92#include "pgtkterm.h" 92#include "pgtkterm.h"
93#endif 93#endif
94 94
95#ifdef HAVE_ANDROID
96#include "android.h"
97#endif /* HAVE_ANDROID */
98
95/* Pattern used by call-process-region to make temp files. */ 99/* Pattern used by call-process-region to make temp files. */
96static Lisp_Object Vtemp_file_name_pattern; 100static Lisp_Object Vtemp_file_name_pattern;
97 101
@@ -1437,6 +1441,18 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
1437 const char *pty_name, bool pty_in, bool pty_out, 1441 const char *pty_name, bool pty_in, bool pty_out,
1438 const sigset_t *oldset) 1442 const sigset_t *oldset)
1439{ 1443{
1444#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
1445 /* Android 10 and later don't allow directly executing programs
1446 installed in the application data directory. Emacs provides a
1447 loader binary which replaces the `execve' system call for it and
1448 all its children. On these systems, rewrite the command line to
1449 call that loader binary instead. */
1450
1451 if (android_rewrite_spawn_argv ((const char ***) &argv))
1452 return 1;
1453#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
1454
1455
1440#if USABLE_POSIX_SPAWN 1456#if USABLE_POSIX_SPAWN
1441 /* Prefer the simpler `posix_spawn' if available. `posix_spawn' 1457 /* Prefer the simpler `posix_spawn' if available. `posix_spawn'
1442 doesn't yet support setting up pseudoterminals, so we fall back 1458 doesn't yet support setting up pseudoterminals, so we fall back