hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/kernel/ptrace.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * linux/kernel/ptrace.c
34 *
....@@ -30,6 +31,8 @@
3031 #include <linux/cn_proc.h>
3132 #include <linux/compat.h>
3233 #include <linux/sched/signal.h>
34
+
35
+#include <asm/syscall.h> /* for syscall_get_* */
3336
3437 /*
3538 * Access another process' address space via ptrace.
....@@ -115,6 +118,9 @@
115118 BUG_ON(!child->ptrace);
116119
117120 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
121
+#ifdef TIF_SYSCALL_EMU
122
+ clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
123
+#endif
118124
119125 child->parent = child->real_parent;
120126 list_del_init(&child->ptrace_entry);
....@@ -364,6 +370,26 @@
364370 return !err;
365371 }
366372
373
+static int check_ptrace_options(unsigned long data)
374
+{
375
+ if (data & ~(unsigned long)PTRACE_O_MASK)
376
+ return -EINVAL;
377
+
378
+ if (unlikely(data & PTRACE_O_SUSPEND_SECCOMP)) {
379
+ if (!IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) ||
380
+ !IS_ENABLED(CONFIG_SECCOMP))
381
+ return -EINVAL;
382
+
383
+ if (!capable(CAP_SYS_ADMIN))
384
+ return -EPERM;
385
+
386
+ if (seccomp_mode(&current->seccomp) != SECCOMP_MODE_DISABLED ||
387
+ current->ptrace & PT_SUSPEND_SECCOMP)
388
+ return -EPERM;
389
+ }
390
+ return 0;
391
+}
392
+
367393 static int ptrace_attach(struct task_struct *task, long request,
368394 unsigned long addr,
369395 unsigned long flags)
....@@ -375,8 +401,16 @@
375401 if (seize) {
376402 if (addr != 0)
377403 goto out;
404
+ /*
405
+ * This duplicates the check in check_ptrace_options() because
406
+ * ptrace_attach() and ptrace_setoptions() have historically
407
+ * used different error codes for unknown ptrace options.
408
+ */
378409 if (flags & ~(unsigned long)PTRACE_O_MASK)
379410 goto out;
411
+ retval = check_ptrace_options(flags);
412
+ if (retval)
413
+ return retval;
380414 flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT);
381415 } else {
382416 flags = PT_PTRACED;
....@@ -420,7 +454,7 @@
420454
421455 /* SEIZE doesn't trap tracee on attach */
422456 if (!seize)
423
- send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);
457
+ send_sig_info(SIGSTOP, SEND_SIG_PRIV, task);
424458
425459 spin_lock(&task->sighand->siglock);
426460
....@@ -587,7 +621,7 @@
587621
588622 list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) {
589623 if (unlikely(p->ptrace & PT_EXITKILL))
590
- send_sig_info(SIGKILL, SEND_SIG_FORCED, p);
624
+ send_sig_info(SIGKILL, SEND_SIG_PRIV, p);
591625
592626 if (__ptrace_detach(tracer, p))
593627 list_add(&p->ptrace_entry, dead);
....@@ -649,22 +683,11 @@
649683 static int ptrace_setoptions(struct task_struct *child, unsigned long data)
650684 {
651685 unsigned flags;
686
+ int ret;
652687
653
- if (data & ~(unsigned long)PTRACE_O_MASK)
654
- return -EINVAL;
655
-
656
- if (unlikely(data & PTRACE_O_SUSPEND_SECCOMP)) {
657
- if (!IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) ||
658
- !IS_ENABLED(CONFIG_SECCOMP))
659
- return -EINVAL;
660
-
661
- if (!capable(CAP_SYS_ADMIN))
662
- return -EPERM;
663
-
664
- if (seccomp_mode(&current->seccomp) != SECCOMP_MODE_DISABLED ||
665
- current->ptrace & PT_SUSPEND_SECCOMP)
666
- return -EPERM;
667
- }
688
+ ret = check_ptrace_options(data);
689
+ if (ret)
690
+ return ret;
668691
669692 /* Avoid intermediate state when all opts are cleared */
670693 flags = child->ptrace;
....@@ -675,7 +698,7 @@
675698 return 0;
676699 }
677700
678
-static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info)
701
+static int ptrace_getsiginfo(struct task_struct *child, kernel_siginfo_t *info)
679702 {
680703 unsigned long flags;
681704 int error = -ESRCH;
....@@ -691,7 +714,7 @@
691714 return error;
692715 }
693716
694
-static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info)
717
+static int ptrace_setsiginfo(struct task_struct *child, const kernel_siginfo_t *info)
695718 {
696719 unsigned long flags;
697720 int error = -ESRCH;
....@@ -737,7 +760,7 @@
737760 pending = &child->pending;
738761
739762 for (i = 0; i < arg.nr; ) {
740
- siginfo_t info;
763
+ kernel_siginfo_t info;
741764 unsigned long off = arg.off + i;
742765 bool found = false;
743766
....@@ -908,14 +931,107 @@
908931 * to ensure no machine forgets it.
909932 */
910933 EXPORT_SYMBOL_GPL(task_user_regset_view);
911
-#endif
934
+
935
+static unsigned long
936
+ptrace_get_syscall_info_entry(struct task_struct *child, struct pt_regs *regs,
937
+ struct ptrace_syscall_info *info)
938
+{
939
+ unsigned long args[ARRAY_SIZE(info->entry.args)];
940
+ int i;
941
+
942
+ info->op = PTRACE_SYSCALL_INFO_ENTRY;
943
+ info->entry.nr = syscall_get_nr(child, regs);
944
+ syscall_get_arguments(child, regs, args);
945
+ for (i = 0; i < ARRAY_SIZE(args); i++)
946
+ info->entry.args[i] = args[i];
947
+
948
+ /* args is the last field in struct ptrace_syscall_info.entry */
949
+ return offsetofend(struct ptrace_syscall_info, entry.args);
950
+}
951
+
952
+static unsigned long
953
+ptrace_get_syscall_info_seccomp(struct task_struct *child, struct pt_regs *regs,
954
+ struct ptrace_syscall_info *info)
955
+{
956
+ /*
957
+ * As struct ptrace_syscall_info.entry is currently a subset
958
+ * of struct ptrace_syscall_info.seccomp, it makes sense to
959
+ * initialize that subset using ptrace_get_syscall_info_entry().
960
+ * This can be reconsidered in the future if these structures
961
+ * diverge significantly enough.
962
+ */
963
+ ptrace_get_syscall_info_entry(child, regs, info);
964
+ info->op = PTRACE_SYSCALL_INFO_SECCOMP;
965
+ info->seccomp.ret_data = child->ptrace_message;
966
+
967
+ /* ret_data is the last field in struct ptrace_syscall_info.seccomp */
968
+ return offsetofend(struct ptrace_syscall_info, seccomp.ret_data);
969
+}
970
+
971
+static unsigned long
972
+ptrace_get_syscall_info_exit(struct task_struct *child, struct pt_regs *regs,
973
+ struct ptrace_syscall_info *info)
974
+{
975
+ info->op = PTRACE_SYSCALL_INFO_EXIT;
976
+ info->exit.rval = syscall_get_error(child, regs);
977
+ info->exit.is_error = !!info->exit.rval;
978
+ if (!info->exit.is_error)
979
+ info->exit.rval = syscall_get_return_value(child, regs);
980
+
981
+ /* is_error is the last field in struct ptrace_syscall_info.exit */
982
+ return offsetofend(struct ptrace_syscall_info, exit.is_error);
983
+}
984
+
985
+static int
986
+ptrace_get_syscall_info(struct task_struct *child, unsigned long user_size,
987
+ void __user *datavp)
988
+{
989
+ struct pt_regs *regs = task_pt_regs(child);
990
+ struct ptrace_syscall_info info = {
991
+ .op = PTRACE_SYSCALL_INFO_NONE,
992
+ .arch = syscall_get_arch(child),
993
+ .instruction_pointer = instruction_pointer(regs),
994
+ .stack_pointer = user_stack_pointer(regs),
995
+ };
996
+ unsigned long actual_size = offsetof(struct ptrace_syscall_info, entry);
997
+ unsigned long write_size;
998
+
999
+ /*
1000
+ * This does not need lock_task_sighand() to access
1001
+ * child->last_siginfo because ptrace_freeze_traced()
1002
+ * called earlier by ptrace_check_attach() ensures that
1003
+ * the tracee cannot go away and clear its last_siginfo.
1004
+ */
1005
+ switch (child->last_siginfo ? child->last_siginfo->si_code : 0) {
1006
+ case SIGTRAP | 0x80:
1007
+ switch (child->ptrace_message) {
1008
+ case PTRACE_EVENTMSG_SYSCALL_ENTRY:
1009
+ actual_size = ptrace_get_syscall_info_entry(child, regs,
1010
+ &info);
1011
+ break;
1012
+ case PTRACE_EVENTMSG_SYSCALL_EXIT:
1013
+ actual_size = ptrace_get_syscall_info_exit(child, regs,
1014
+ &info);
1015
+ break;
1016
+ }
1017
+ break;
1018
+ case SIGTRAP | (PTRACE_EVENT_SECCOMP << 8):
1019
+ actual_size = ptrace_get_syscall_info_seccomp(child, regs,
1020
+ &info);
1021
+ break;
1022
+ }
1023
+
1024
+ write_size = min(actual_size, user_size);
1025
+ return copy_to_user(datavp, &info, write_size) ? -EFAULT : actual_size;
1026
+}
1027
+#endif /* CONFIG_HAVE_ARCH_TRACEHOOK */
9121028
9131029 int ptrace_request(struct task_struct *child, long request,
9141030 unsigned long addr, unsigned long data)
9151031 {
9161032 bool seized = child->ptrace & PT_SEIZED;
9171033 int ret = -EIO;
918
- siginfo_t siginfo, *si;
1034
+ kernel_siginfo_t siginfo, *si;
9191035 void __user *datavp = (void __user *) data;
9201036 unsigned long __user *datalp = datavp;
9211037 unsigned long flags;
....@@ -949,9 +1065,8 @@
9491065 break;
9501066
9511067 case PTRACE_SETSIGINFO:
952
- if (copy_from_user(&siginfo, datavp, sizeof siginfo))
953
- ret = -EFAULT;
954
- else
1068
+ ret = copy_siginfo_from_user(&siginfo, datavp);
1069
+ if (!ret)
9551070 ret = ptrace_setsiginfo(child, &siginfo);
9561071 break;
9571072
....@@ -1104,9 +1219,8 @@
11041219 return ptrace_resume(child, request, data);
11051220
11061221 case PTRACE_KILL:
1107
- if (child->exit_state) /* already dead */
1108
- return 0;
1109
- return ptrace_resume(child, request, SIGKILL);
1222
+ send_sig_info(SIGKILL, SEND_SIG_NOINFO, child);
1223
+ return 0;
11101224
11111225 #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
11121226 case PTRACE_GETREGSET:
....@@ -1114,7 +1228,7 @@
11141228 struct iovec kiov;
11151229 struct iovec __user *uiov = datavp;
11161230
1117
- if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov)))
1231
+ if (!access_ok(uiov, sizeof(*uiov)))
11181232 return -EFAULT;
11191233
11201234 if (__get_user(kiov.iov_base, &uiov->iov_base) ||
....@@ -1126,6 +1240,10 @@
11261240 ret = __put_user(kiov.iov_len, &uiov->iov_len);
11271241 break;
11281242 }
1243
+
1244
+ case PTRACE_GET_SYSCALL_INFO:
1245
+ ret = ptrace_get_syscall_info(child, addr, datavp);
1246
+ break;
11291247 #endif
11301248
11311249 case PTRACE_SECCOMP_GET_FILTER:
....@@ -1221,7 +1339,7 @@
12211339 {
12221340 compat_ulong_t __user *datap = compat_ptr(data);
12231341 compat_ulong_t word;
1224
- siginfo_t siginfo;
1342
+ kernel_siginfo_t siginfo;
12251343 int ret;
12261344
12271345 switch (request) {
....@@ -1255,10 +1373,9 @@
12551373 break;
12561374
12571375 case PTRACE_SETSIGINFO:
1258
- if (copy_siginfo_from_user32(
1259
- &siginfo, (struct compat_siginfo __user *) datap))
1260
- ret = -EFAULT;
1261
- else
1376
+ ret = copy_siginfo_from_user32(
1377
+ &siginfo, (struct compat_siginfo __user *) datap);
1378
+ if (!ret)
12621379 ret = ptrace_setsiginfo(child, &siginfo);
12631380 break;
12641381 #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
....@@ -1271,7 +1388,7 @@
12711388 compat_uptr_t ptr;
12721389 compat_size_t len;
12731390
1274
- if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov)))
1391
+ if (!access_ok(uiov, sizeof(*uiov)))
12751392 return -EFAULT;
12761393
12771394 if (__get_user(ptr, &uiov->iov_base) ||