History

Merge branch 'exit-cleanups-for-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull exit cleanups from Eric Biederman: "In preparation of doing something about PTRACE_EVENT_EXIT I have started cleaning up various pieces of code related to do_exit. Most of that code I did not manage to get tested and reviewed before the merge window opened but a handful of very useful cleanups are ready to be merged. The first change is simply the removal of the bdflush system call. The code has now been disabled long enough that even the oldest userspace working userspace setups anyone can find to test are fine with the bdflush system call being removed. Changing m68k fsp040_die to use force_sigsegv(SIGSEGV) instead of calling do_exit directly is interesting only in that it is nearly the most difficult of the incorrect uses of do_exit to remove. The change to the seccomp code to simply send a signal instead of calling do_coredump directly is a very nice little cleanup made possible by realizing the existing signal sending helpers were missing a little bit of functionality that is easy to provide" * 'exit-cleanups-for-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: signal/seccomp: Dump core when there is only one live thread signal/seccomp: Refactor seccomp signal and coredump generation signal/m68k: Use force_sigsegv(SIGSEGV) in fpsp040_die exit/bdflush: Remove the deprecated bdflush system call

Linus Torvalds committed 5 years ago

Commit bcfeebb2 parents 4898370 d21918e25 files · +53 −87Browse files

Showing the changes to kernel (3 of 25 files). Show all

Unified · Split

3 files
  1. kernel/seccomp.c +7 −35
  2. kernel/signal.c +26 −4
  3. kernel/sys_ni.c +0 −1
kernel/seccomp.c+7−35
@@ -922,30 +922,6 @@ void get_seccomp_filter(struct task_struct *tsk) · 921 unmodified lines
922922 refcount_inc(&orig->users);
923923 }
924924
925−static void seccomp_init_siginfo(kernel_siginfo_t *info, int syscall, int reason)
926−{
927− clear_siginfo(info);
928− info->si_signo = SIGSYS;
929− info->si_code = SYS_SECCOMP;
930− info->si_call_addr = (void __user *)KSTK_EIP(current);
931− info->si_errno = reason;
932− info->si_arch = syscall_get_arch(current);
933− info->si_syscall = syscall;
934−}
935−
936−/**
937− * seccomp_send_sigsys - signals the task to allow in-process syscall emulation
938− * @syscall: syscall number to send to userland
939− * @reason: filter-supplied reason code to send to userland (via si_errno)
940− *
941− * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info.
942− */
943−static void seccomp_send_sigsys(int syscall, int reason)
944−{
945− struct kernel_siginfo info;
946− seccomp_init_siginfo(&info, syscall, reason);
947− force_sig_info(&info);
948−}
949925 #endif /* CONFIG_SECCOMP_FILTER */
950926
951927 /* For use with seccomp_actions_logged */
@@ -1218,7 +1194,7 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, · 266 unmodified lines
12181194 /* Show the handler the original registers. */
12191195 syscall_rollback(current, current_pt_regs());
12201196 /* Let the filter pass back 16 bits of data. */
1221− seccomp_send_sigsys(this_syscall, data);
1197+ force_sig_seccomp(this_syscall, data, false);
12221198 goto skip;
12231199
12241200 case SECCOMP_RET_TRACE:
@@ -1288,19 +1264,15 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, · 63 unmodified lines
12881264 seccomp_log(this_syscall, SIGSYS, action, true);
12891265 /* Dump core only if this is the last remaining thread. */
12901266 if (action != SECCOMP_RET_KILL_THREAD ||
1291− get_nr_threads(current) == 1) {
1292− kernel_siginfo_t info;
1293−
1267+ (atomic_read(&current->signal->live) == 1)) {
12941268 /* Show the original registers in the dump. */
12951269 syscall_rollback(current, current_pt_regs());
1296− /* Trigger a manual coredump since do_exit skips it. */
1297− seccomp_init_siginfo(&info, this_syscall, data);
1298− do_coredump(&info);
1299− }
1300− if (action == SECCOMP_RET_KILL_THREAD)
1270+ /* Trigger a coredump with SIGSYS */
1271+ force_sig_seccomp(this_syscall, data, true);
1272+ } else {
13011273 do_exit(SIGSYS);
1302− else
1303− do_group_exit(SIGSYS);
1274+ }
1275+ return -1; /* skip the syscall go directly to signal handling */
13041276 }
13051277
13061278 unreachable();
kernel/signal.c+26−4
@@ -54,6 +54,7 @@ · 53 unmodified lines
5454 #include <asm/unistd.h>
5555 #include <asm/siginfo.h>
5656 #include <asm/cacheflush.h>
57+#include <asm/syscall.h> /* for syscall_get_* */
5758
5859 /*
5960 * SLAB caches for signal bits.
@@ -1322,7 +1323,7 @@ int do_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p · 1262 unmodified lines
13221323 * that is why we also clear SIGNAL_UNKILLABLE.
13231324 */
13241325 static int
1325−force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t)
1326+force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t, bool sigdfl)
13261327 {
13271328 unsigned long int flags;
13281329 int ret, blocked, ignored;
@@ -1333,7 +1334,7 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t) · 4 unmodified lines
13331334 action = &t->sighand->action[sig-1];
13341335 ignored = action->sa.sa_handler == SIG_IGN;
13351336 blocked = sigismember(&t->blocked, sig);
1336− if (blocked || ignored) {
1337+ if (blocked || ignored || sigdfl) {
13371338 action->sa.sa_handler = SIG_DFL;
13381339 if (blocked) {
13391340 sigdelset(&t->blocked, sig);
@@ -1354,7 +1355,7 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t) · 14 unmodified lines
13541355
13551356 int force_sig_info(struct kernel_siginfo *info)
13561357 {
1357− return force_sig_info_to_task(info, current);
1358+ return force_sig_info_to_task(info, current, false);
13581359 }
13591360
13601361 /*
@@ -1696,7 +1697,7 @@ int force_sig_fault_to_task(int sig, int code, void __user *addr · 335 unmodified lines
16961697 info.si_flags = flags;
16971698 info.si_isr = isr;
16981699 #endif
1699− return force_sig_info_to_task(&info, t);
1700+ return force_sig_info_to_task(&info, t, false);
17001701 }
17011702
17021703 int force_sig_fault(int sig, int code, void __user *addr
@@ -1798,6 +1799,27 @@ int force_sig_perf(void __user *addr, u32 type, u64 sig_data) · 95 unmodified lines
17981799 return force_sig_info(&info);
17991800 }
18001801
1802+/**
1803+ * force_sig_seccomp - signals the task to allow in-process syscall emulation
1804+ * @syscall: syscall number to send to userland
1805+ * @reason: filter-supplied reason code to send to userland (via si_errno)
1806+ *
1807+ * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info.
1808+ */
1809+int force_sig_seccomp(int syscall, int reason, bool force_coredump)
1810+{
1811+ struct kernel_siginfo info;
1812+
1813+ clear_siginfo(&info);
1814+ info.si_signo = SIGSYS;
1815+ info.si_code = SYS_SECCOMP;
1816+ info.si_call_addr = (void __user *)KSTK_EIP(current);
1817+ info.si_errno = reason;
1818+ info.si_arch = syscall_get_arch(current);
1819+ info.si_syscall = syscall;
1820+ return force_sig_info_to_task(&info, current, force_coredump);
1821+}
1822+
18011823 /* For the crazy architectures that include trap information in
18021824 * the errno field, instead of an actual errno value.
18031825 */
kernel/sys_ni.c+0−1
@@ -416,7 +416,6 @@ COND_SYSCALL(epoll_wait); · 415 unmodified lines
416416 COND_SYSCALL(recv);
417417 COND_SYSCALL_COMPAT(recv);
418418 COND_SYSCALL(send);
419−COND_SYSCALL(bdflush);
420419 COND_SYSCALL(uselib);
421420
422421 /* optional: time32 */