diff options
| author | Po Lu | 2023-04-30 21:37:19 +0800 |
|---|---|---|
| committer | Po Lu | 2023-04-30 21:37:19 +0800 |
| commit | 368f6f3942a1f8b9483763a6ac24b3b3021e92bf (patch) | |
| tree | 284ff92e18076ed7a8be3d2775ee450922b3166d /exec/exec1.c | |
| parent | 4289ed6cffdb5ea758a78037fe385fd7c4e23677 (diff) | |
| download | emacs-368f6f3942a1f8b9483763a6ac24b3b3021e92bf.tar.gz emacs-368f6f3942a1f8b9483763a6ac24b3b3021e92bf.zip | |
Add helper binary `exec1'
* .gitignore: New files.
* Makefile.in (mostlyclean_dirs): Add libexec, if its Makefile
exists.
* autogen.sh (do_git): Autoreconf in exec as well.
* configure.ac: Configure libexec on Android.
* exec/Makefile.in:
* exec/README:
* exec/config-mips.m4.in:
* exec/config.guess:
* exec/config.h.in:
* exec/config.sub:
* exec/configure:
* exec/configure.ac:
* exec/deps.mk:
* exec/exec.c (MIN, struct exec_open_command)
(struct exec_map_command, struct exec_jump_command)
(write_open_command, write_load_command, process_interpreter_1)
(process_interpreter, process_program_header, insert_args)
(exec_0):
* exec/exec.h (_EXEC_H_, struct elf_header_32)
(struct program_header_32, struct dt_entry_32)
(struct elf_header_64, struct program_header_64)
(struct dt_entry_64, struct exec_tracee):
* exec/exec1.c (main):
* exec/install-sh (scriptversion):
* exec/loader-aarch64.s (_start):
* exec/loader-armeabi.s (_start):
* exec/loader-mips64el.s (__start):
* exec/loader-mipsel.s (__start):
* exec/loader-x86.s (_start):
* exec/loader-x86_64.s (_start):
* exec/mipsel-user.h (_MIPSEL_USER_H_):
* exec/mipsfpu.c (MIPS_ABI_FP_ANY, fpu_reqs, valid_abi_p)
(fp_mode_for_abi, cpu_supports_fr0_p, determine_fpu_mode):
* exec/mipsfpu.h (_MIPSFPU_H_, FP_FR0):
* exec/test.c (print_usage, main):
* exec/trace.c (MAX_TRACEES, aarch64_set_regs, read_memory)
(user_alloca, user_copy, remove_tracee, handle_clone)
(syscall_trap_p, handle_exec, process_system_call, tracing_execve)
(after_fork, find_tracee, exec_waitpid, exec_init): New files.
* java/Makefile.in (CROSS_EXEC_BINS): Add exec1 and
loader.
($(CROSS_EXEC_BINS) &): New target.
Diffstat (limited to 'exec/exec1.c')
| -rw-r--r-- | exec/exec1.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/exec/exec1.c b/exec/exec1.c new file mode 100644 index 00000000000..835bf8e72b9 --- /dev/null +++ b/exec/exec1.c | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | /* Program execution for Emacs. | ||
| 2 | |||
| 3 | Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #include <config.h> | ||
| 21 | #include <unistd.h> | ||
| 22 | #include <stdlib.h> | ||
| 23 | #include <sys/wait.h> | ||
| 24 | |||
| 25 | #include "exec.h" | ||
| 26 | |||
| 27 | /* exec1 is a program which takes another program and its arguments, | ||
| 28 | forks, and executes that program, all while tracing it and its | ||
| 29 | children to use the program execution mechanism defined in exec.c. | ||
| 30 | |||
| 31 | This is necessary to bypass security restrictions which prohibit | ||
| 32 | Emacs from loading executables from certain directories, by, in | ||
| 33 | effect, replacing the executable loader in the Linux kernel. */ | ||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | int | ||
| 38 | main (int argc, char **argv) | ||
| 39 | { | ||
| 40 | pid_t pid, pid1; | ||
| 41 | extern char **environ; | ||
| 42 | int wstatus; | ||
| 43 | |||
| 44 | pid = fork (); | ||
| 45 | |||
| 46 | if (!pid) | ||
| 47 | { | ||
| 48 | tracing_execve (argv[2], argv + 2, environ); | ||
| 49 | |||
| 50 | /* An error occured. Exit with failure. */ | ||
| 51 | exit (127); | ||
| 52 | } | ||
| 53 | else | ||
| 54 | { | ||
| 55 | /* Provide the file name of the loader. */ | ||
| 56 | exec_init (argv[1]); | ||
| 57 | |||
| 58 | if (after_fork (pid)) | ||
| 59 | exit (127); | ||
| 60 | |||
| 61 | /* Start waiting for the process to exit. */ | ||
| 62 | |||
| 63 | while (true) | ||
| 64 | { | ||
| 65 | pid1 = exec_waitpid (-1, &wstatus, 0); | ||
| 66 | |||
| 67 | /* If the child process exits normally, exit with its status | ||
| 68 | code. If not, raise the signal that caused it to | ||
| 69 | exit. */ | ||
| 70 | |||
| 71 | if (pid == pid1) | ||
| 72 | { | ||
| 73 | if (WIFEXITED (wstatus)) | ||
| 74 | exit (WEXITSTATUS (wstatus)); | ||
| 75 | else /* if WIFSIGNALED (wstatus) */ | ||
| 76 | { | ||
| 77 | raise (WTERMSIG (wstatus)); | ||
| 78 | |||
| 79 | /* Just in case the signal raised doesn't cause an | ||
| 80 | exit. */ | ||
| 81 | exit (127); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | /* Otherwise, continue looping. */ | ||
| 86 | } | ||
| 87 | } | ||
| 88 | } | ||