diff options
Diffstat (limited to 'src/android.c')
| -rw-r--r-- | src/android.c | 83 |
1 files changed, 83 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 | |||
| 6527 | enum | ||
| 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 | |||
| 6541 | int | ||
| 6542 | android_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. */ |