aboutsummaryrefslogtreecommitdiffstats
path: root/exec
diff options
context:
space:
mode:
authorPo Lu2024-07-02 12:10:43 +0800
committerPo Lu2024-07-02 12:12:14 +0800
commit6b5accdc05d007ab4d1804865c1b043260006673 (patch)
tree0c7909756b47cd524a397becb766ef8452cd85fa /exec
parente087d3009bf564446367a1465957d9ea7b699f01 (diff)
downloademacs-6b5accdc05d007ab4d1804865c1b043260006673.tar.gz
emacs-6b5accdc05d007ab4d1804865c1b043260006673.zip
Port seccomp acceleration to Linux 3.5.0
* etc/NEWS: Update correspondingly. * exec/Makefile.in (config-mips.m4): Don't define rule or predicate $(LOADOBJS) on it elsewhere than on MIPS. * exec/README: Direct developers to GDB. * exec/trace.c (finish_exec): Resume the tracee after reporting an error in `exec'. (after_fork): If seccomp is enabled on Android, and the kernel is 4.7 or earlier, detect whether revisions to the sequencing of seccomp events have been backported from 4.8. (exec_waitpid): Resume the process with PTRACE_CONT after receiving an unknown signal. (exec_init): Cease disabling seccomp on Android kernels earlier than 4.8.
Diffstat (limited to 'exec')
-rw-r--r--exec/Makefile.in8
-rw-r--r--exec/README3
-rw-r--r--exec/trace.c113
3 files changed, 98 insertions, 26 deletions
diff --git a/exec/Makefile.in b/exec/Makefile.in
index 6969039b0a4..7e681c0c3d8 100644
--- a/exec/Makefile.in
+++ b/exec/Makefile.in
@@ -90,16 +90,16 @@ ifeq ($(is_mips),yes)
90.s.o: 90.s.o:
91 $(M4) $< > $(notdir $<).s 91 $(M4) $< > $(notdir $<).s
92 $(AS) $(ASFLAGS) $(notdir $<).s -o $@ 92 $(AS) $(ASFLAGS) $(notdir $<).s -o $@
93else
94.s.o:
95 $(AS) $(ASFLAGS) $< -o $@
96endif
97 93
98# Set up dependencies for config-mips.m4. 94# Set up dependencies for config-mips.m4.
99 95
100config-mips.m4: config-mips.m4.in 96config-mips.m4: config-mips.m4.in
101 cd $(srcdir) && ./config.status $@ 97 cd $(srcdir) && ./config.status $@
102$(LOADOBJS): config-mips.m4 98$(LOADOBJS): config-mips.m4
99else
100.s.o:
101 $(AS) $(ASFLAGS) $< -o $@
102endif
103 103
104# Set up rules to build libexec.a. 104# Set up rules to build libexec.a.
105 105
diff --git a/exec/README b/exec/README
index f7eb21cfc84..a1534503247 100644
--- a/exec/README
+++ b/exec/README
@@ -1,3 +1,6 @@
1This directory holds the source code to a library used to replace the 1This directory holds the source code to a library used to replace the
2`execve' and `execveat' system calls, used by the Android port of 2`execve' and `execveat' system calls, used by the Android port of
3Emacs to start executables without intervention from the system. 3Emacs to start executables without intervention from the system.
4
5The most edifying resource for developers will be GDB, or to be precise,
6the Linux target implementations for architectures of interest.
diff --git a/exec/trace.c b/exec/trace.c
index dfbc255a894..2af6d867efe 100644
--- a/exec/trace.c
+++ b/exec/trace.c
@@ -845,7 +845,12 @@ finish_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
845#else /* !__aarch64__ */ 845#else /* !__aarch64__ */
846 ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs); 846 ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs);
847#endif /* __aarch64__ */ 847#endif /* __aarch64__ */
848 return; 848
849 /* Continue; not much in the way of remediation is available if
850 either of PTRACE_SETREGS and this resumption fails. */
851 ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
852 tracee->pid, 0, 0);
853 goto error;
849 } 854 }
850 855
851 /* Write the loader area to the stack, followed by its size and the 856 /* Write the loader area to the stack, followed by its size and the
@@ -1858,6 +1863,10 @@ after_fork (pid_t pid)
1858{ 1863{
1859 int wstatus, rc, flags; 1864 int wstatus, rc, flags;
1860 struct exec_tracee *tracee; 1865 struct exec_tracee *tracee;
1866#if defined HAVE_SECCOMP && __ANDROID__
1867 int statusarg;
1868 USER_REGS_STRUCT regs;
1869#endif /* defined HAVE_SECCOMP && __ANDROID__ */
1861 1870
1862 /* First, wait for something to happen to PID. */ 1871 /* First, wait for something to happen to PID. */
1863 again: 1872 again:
@@ -1897,14 +1906,86 @@ after_fork (pid_t pid)
1897 return 1; 1906 return 1;
1898 } 1907 }
1899 1908
1900 /* Request that the child stop upon the next system call, or the next 1909#if defined HAVE_SECCOMP && __ANDROID__
1901 filter event. */ 1910 /* Certain Android kernels have received backports of those new
1902 rc = ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), 1911 PTRACE_EVENT_SECCOMP semantics which were introduced in kernel
1903 pid, 0, 0); 1912 version 4.8, so that it is necessary to actively establish which
1913 variant is in place. */
1914
1915 if (kernel_4_7_or_earlier && use_seccomp_p)
1916 {
1917 /* Request that the child stop upon the next `exec' system call,
1918 one of which is assumed to always be issued by the child, as
1919 below, but await the next stop, and examine its contents.
1920 Anciently, the syscall-stop preceeded events marked
1921 PTRACE_EVENT_SECCOMP, whereas this sequence is reversed in
1922 4.8+, and in releases with these changes backported. */
1923
1924 rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
1925 if (rc)
1926 return 1;
1927
1928 while (true)
1929 {
1930 rc = waitpid (pid, &wstatus, __WALL);
1931 if (rc != pid)
1932 return 1;
1933
1934 if (WIFSTOPPED (wstatus))
1935 {
1936 /* Verify that this system call is `exec', not one issued
1937 between PTRACE_TRACEME and `exec' intercepted by
1938 PTRACE_SYSCALL. */
1939#ifdef __aarch64__
1940 rc = aarch64_get_regs (pid, &regs);
1941#else /* !__aarch64__ */
1942 rc = ptrace (PTRACE_GETREGS, pid, NULL, &regs);
1943#endif /* __aarch64__ */
1944 if (rc)
1945 return 1;
1946
1947 if (regs.SYSCALL_NUM_REG == EXEC_SYSCALL)
1948 {
1949 statusarg = ((wstatus & 0xfff00) >> 8);
1950
1951 if (statusarg == (SIGTRAP | (PTRACE_EVENT_SECCOMP << 8)))
1952 {
1953 /* The first event to be delivered is a seccomp
1954 stop, indicating that this is an unmodified
1955 <4.7 kernel. Return to await the subsequent
1956 syscall-stop, which should be received and
1957 acted on by process_system_call. */
1958 rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
1959 break;
1960 }
1961 else if (statusarg == (SIGTRAP | 0x80))
1962 {
1963 /* Syscall-traps take priority. This is a
1964 doctored 4.7 kernel. */
1965 kernel_4_7_or_earlier = false;
1966 rc = ptrace (PTRACE_CONT, pid, 0, 0);
1967 break;
1968 }
1969 }
1970
1971 rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
1972 if (rc)
1973 return 1;
1974 }
1975 else
1976 return 1;
1977 }
1978 }
1979 else
1980#endif /* HAVE_SECCOMP && __ANDROID__ */
1981 /* Request that the child stop upon the next system call, or the
1982 next filter event. */
1983 rc = ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
1984 pid, 0, 0);
1904 if (rc) 1985 if (rc)
1905 return 1; 1986 return 1;
1906 1987
1907 /* Enter the child in `tracing_processes'. */ 1988 /* Enroll the child into `tracing_processes'. */
1908 1989
1909 if (free_tracees) 1990 if (free_tracees)
1910 { 1991 {
@@ -2064,8 +2145,9 @@ exec_waitpid (pid_t pid, int *wstatus, int options)
2064#endif /* SIGSYS */ 2145#endif /* SIGSYS */
2065 2146
2066 default: 2147 default:
2067 /* Continue the process until the next syscall. */ 2148 /* Resume the process as appropriate. */
2068 ptrace (PTRACE_SYSCALL, pid, 0, status); 2149 ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
2150 pid, 0, status);
2069 return -1; 2151 return -1;
2070 } 2152 }
2071 } 2153 }
@@ -2117,20 +2199,7 @@ exec_init (const char *loader)
2117 else 2199 else
2118 { 2200 {
2119 if (major < 4 || (major == 4 && minor <= 7)) 2201 if (major < 4 || (major == 4 && minor <= 7))
2120 { 2202 kernel_4_7_or_earlier = true;
2121#ifndef __ANDROID__
2122 kernel_4_7_or_earlier = true;
2123#else /* __ANDROID __ */
2124 /* Certain Android kernels have received backports of
2125 those new PTRACE_EVENT_SECCOMP semantics which were
2126 introduced in kernel version 4.8, so that it is
2127 necessary to actively establish which variant is in
2128 place. This being much too involved for code I cannot
2129 test, simply disable seccomp on kernel releases subject
2130 to these uncertainties. */
2131 use_seccomp_p = false;
2132#endif /* !__ANDROID__ */
2133 }
2134 } 2203 }
2135 } 2204 }
2136#endif /* HAVE_SECCOMP */ 2205#endif /* HAVE_SECCOMP */