forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/arch/s390/kernel/ptrace.c
....@@ -24,10 +24,7 @@
2424 #include <linux/seccomp.h>
2525 #include <linux/compat.h>
2626 #include <trace/syscall.h>
27
-#include <asm/segment.h>
2827 #include <asm/page.h>
29
-#include <asm/pgtable.h>
30
-#include <asm/pgalloc.h>
3128 #include <linux/uaccess.h>
3229 #include <asm/unistd.h>
3330 #include <asm/switch_to.h>
....@@ -868,40 +865,66 @@
868865 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
869866 {
870867 unsigned long mask = -1UL;
868
+ long ret = -1;
869
+
870
+ if (is_compat_task())
871
+ mask = 0xffffffff;
871872
872873 /*
873874 * The sysc_tracesys code in entry.S stored the system
874875 * call number to gprs[2].
875876 */
876877 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
877
- (tracehook_report_syscall_entry(regs) ||
878
- regs->gprs[2] >= NR_syscalls)) {
878
+ tracehook_report_syscall_entry(regs)) {
879879 /*
880
- * Tracing decided this syscall should not happen or the
881
- * debugger stored an invalid system call number. Skip
880
+ * Tracing decided this syscall should not happen. Skip
882881 * the system call and the system call restart handling.
883882 */
884
- clear_pt_regs_flag(regs, PIF_SYSCALL);
885
- return -1;
883
+ goto skip;
886884 }
887885
886
+#ifdef CONFIG_SECCOMP
888887 /* Do the secure computing check after ptrace. */
889
- if (secure_computing(NULL)) {
890
- /* seccomp failures shouldn't expose any additional code. */
891
- return -1;
888
+ if (unlikely(test_thread_flag(TIF_SECCOMP))) {
889
+ struct seccomp_data sd;
890
+
891
+ if (is_compat_task()) {
892
+ sd.instruction_pointer = regs->psw.addr & 0x7fffffff;
893
+ sd.arch = AUDIT_ARCH_S390;
894
+ } else {
895
+ sd.instruction_pointer = regs->psw.addr;
896
+ sd.arch = AUDIT_ARCH_S390X;
897
+ }
898
+
899
+ sd.nr = regs->int_code & 0xffff;
900
+ sd.args[0] = regs->orig_gpr2 & mask;
901
+ sd.args[1] = regs->gprs[3] & mask;
902
+ sd.args[2] = regs->gprs[4] & mask;
903
+ sd.args[3] = regs->gprs[5] & mask;
904
+ sd.args[4] = regs->gprs[6] & mask;
905
+ sd.args[5] = regs->gprs[7] & mask;
906
+
907
+ if (__secure_computing(&sd) == -1)
908
+ goto skip;
892909 }
910
+#endif /* CONFIG_SECCOMP */
893911
894912 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
895
- trace_sys_enter(regs, regs->gprs[2]);
913
+ trace_sys_enter(regs, regs->int_code & 0xffff);
896914
897
- if (is_compat_task())
898
- mask = 0xffffffff;
899915
900
- audit_syscall_entry(regs->gprs[2], regs->orig_gpr2 & mask,
916
+ audit_syscall_entry(regs->int_code & 0xffff, regs->orig_gpr2 & mask,
901917 regs->gprs[3] &mask, regs->gprs[4] &mask,
902918 regs->gprs[5] &mask);
903919
920
+ if ((signed long)regs->gprs[2] >= NR_syscalls) {
921
+ regs->gprs[2] = -ENOSYS;
922
+ ret = -ENOSYS;
923
+ }
904924 return regs->gprs[2];
925
+skip:
926
+ clear_pt_regs_flag(regs, PIF_SYSCALL);
927
+ return ret;
905928 }
906929
907930 asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
....@@ -921,28 +944,14 @@
921944
922945 static int s390_regs_get(struct task_struct *target,
923946 const struct user_regset *regset,
924
- unsigned int pos, unsigned int count,
925
- void *kbuf, void __user *ubuf)
947
+ struct membuf to)
926948 {
949
+ unsigned pos;
927950 if (target == current)
928951 save_access_regs(target->thread.acrs);
929952
930
- if (kbuf) {
931
- unsigned long *k = kbuf;
932
- while (count > 0) {
933
- *k++ = __peek_user(target, pos);
934
- count -= sizeof(*k);
935
- pos += sizeof(*k);
936
- }
937
- } else {
938
- unsigned long __user *u = ubuf;
939
- while (count > 0) {
940
- if (__put_user(__peek_user(target, pos), u++))
941
- return -EFAULT;
942
- count -= sizeof(*u);
943
- pos += sizeof(*u);
944
- }
945
- }
953
+ for (pos = 0; pos < sizeof(s390_regs); pos += sizeof(long))
954
+ membuf_store(&to, __peek_user(target, pos));
946955 return 0;
947956 }
948957
....@@ -983,8 +992,8 @@
983992 }
984993
985994 static int s390_fpregs_get(struct task_struct *target,
986
- const struct user_regset *regset, unsigned int pos,
987
- unsigned int count, void *kbuf, void __user *ubuf)
995
+ const struct user_regset *regset,
996
+ struct membuf to)
988997 {
989998 _s390_fp_regs fp_regs;
990999
....@@ -994,8 +1003,7 @@
9941003 fp_regs.fpc = target->thread.fpu.fpc;
9951004 fpregs_store(&fp_regs, &target->thread.fpu);
9961005
997
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
998
- &fp_regs, 0, -1);
1006
+ return membuf_write(&to, &fp_regs, sizeof(fp_regs));
9991007 }
10001008
10011009 static int s390_fpregs_set(struct task_struct *target,
....@@ -1042,20 +1050,9 @@
10421050
10431051 static int s390_last_break_get(struct task_struct *target,
10441052 const struct user_regset *regset,
1045
- unsigned int pos, unsigned int count,
1046
- void *kbuf, void __user *ubuf)
1053
+ struct membuf to)
10471054 {
1048
- if (count > 0) {
1049
- if (kbuf) {
1050
- unsigned long *k = kbuf;
1051
- *k = target->thread.last_break;
1052
- } else {
1053
- unsigned long __user *u = ubuf;
1054
- if (__put_user(target->thread.last_break, u))
1055
- return -EFAULT;
1056
- }
1057
- }
1058
- return 0;
1055
+ return membuf_store(&to, target->thread.last_break);
10591056 }
10601057
10611058 static int s390_last_break_set(struct task_struct *target,
....@@ -1068,16 +1065,13 @@
10681065
10691066 static int s390_tdb_get(struct task_struct *target,
10701067 const struct user_regset *regset,
1071
- unsigned int pos, unsigned int count,
1072
- void *kbuf, void __user *ubuf)
1068
+ struct membuf to)
10731069 {
10741070 struct pt_regs *regs = task_pt_regs(target);
1075
- unsigned char *data;
10761071
10771072 if (!(regs->int_code & 0x200))
10781073 return -ENODATA;
1079
- data = target->thread.trap_tdb;
1080
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, data, 0, 256);
1074
+ return membuf_write(&to, target->thread.trap_tdb, 256);
10811075 }
10821076
10831077 static int s390_tdb_set(struct task_struct *target,
....@@ -1090,8 +1084,7 @@
10901084
10911085 static int s390_vxrs_low_get(struct task_struct *target,
10921086 const struct user_regset *regset,
1093
- unsigned int pos, unsigned int count,
1094
- void *kbuf, void __user *ubuf)
1087
+ struct membuf to)
10951088 {
10961089 __u64 vxrs[__NUM_VXRS_LOW];
10971090 int i;
....@@ -1102,7 +1095,7 @@
11021095 save_fpu_regs();
11031096 for (i = 0; i < __NUM_VXRS_LOW; i++)
11041097 vxrs[i] = *((__u64 *)(target->thread.fpu.vxrs + i) + 1);
1105
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, vxrs, 0, -1);
1098
+ return membuf_write(&to, vxrs, sizeof(vxrs));
11061099 }
11071100
11081101 static int s390_vxrs_low_set(struct task_struct *target,
....@@ -1131,18 +1124,14 @@
11311124
11321125 static int s390_vxrs_high_get(struct task_struct *target,
11331126 const struct user_regset *regset,
1134
- unsigned int pos, unsigned int count,
1135
- void *kbuf, void __user *ubuf)
1127
+ struct membuf to)
11361128 {
1137
- __vector128 vxrs[__NUM_VXRS_HIGH];
1138
-
11391129 if (!MACHINE_HAS_VX)
11401130 return -ENODEV;
11411131 if (target == current)
11421132 save_fpu_regs();
1143
- memcpy(vxrs, target->thread.fpu.vxrs + __NUM_VXRS_LOW, sizeof(vxrs));
1144
-
1145
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf, vxrs, 0, -1);
1133
+ return membuf_write(&to, target->thread.fpu.vxrs + __NUM_VXRS_LOW,
1134
+ __NUM_VXRS_HIGH * sizeof(__vector128));
11461135 }
11471136
11481137 static int s390_vxrs_high_set(struct task_struct *target,
....@@ -1164,12 +1153,9 @@
11641153
11651154 static int s390_system_call_get(struct task_struct *target,
11661155 const struct user_regset *regset,
1167
- unsigned int pos, unsigned int count,
1168
- void *kbuf, void __user *ubuf)
1156
+ struct membuf to)
11691157 {
1170
- unsigned int *data = &target->thread.system_call;
1171
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
1172
- data, 0, sizeof(unsigned int));
1158
+ return membuf_store(&to, target->thread.system_call);
11731159 }
11741160
11751161 static int s390_system_call_set(struct task_struct *target,
....@@ -1184,8 +1170,7 @@
11841170
11851171 static int s390_gs_cb_get(struct task_struct *target,
11861172 const struct user_regset *regset,
1187
- unsigned int pos, unsigned int count,
1188
- void *kbuf, void __user *ubuf)
1173
+ struct membuf to)
11891174 {
11901175 struct gs_cb *data = target->thread.gs_cb;
11911176
....@@ -1195,8 +1180,7 @@
11951180 return -ENODATA;
11961181 if (target == current)
11971182 save_gs_cb(data);
1198
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
1199
- data, 0, sizeof(struct gs_cb));
1183
+ return membuf_write(&to, data, sizeof(struct gs_cb));
12001184 }
12011185
12021186 static int s390_gs_cb_set(struct task_struct *target,
....@@ -1240,8 +1224,7 @@
12401224
12411225 static int s390_gs_bc_get(struct task_struct *target,
12421226 const struct user_regset *regset,
1243
- unsigned int pos, unsigned int count,
1244
- void *kbuf, void __user *ubuf)
1227
+ struct membuf to)
12451228 {
12461229 struct gs_cb *data = target->thread.gs_bc_cb;
12471230
....@@ -1249,8 +1232,7 @@
12491232 return -ENODEV;
12501233 if (!data)
12511234 return -ENODATA;
1252
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
1253
- data, 0, sizeof(struct gs_cb));
1235
+ return membuf_write(&to, data, sizeof(struct gs_cb));
12541236 }
12551237
12561238 static int s390_gs_bc_set(struct task_struct *target,
....@@ -1300,8 +1282,7 @@
13001282
13011283 static int s390_runtime_instr_get(struct task_struct *target,
13021284 const struct user_regset *regset,
1303
- unsigned int pos, unsigned int count,
1304
- void *kbuf, void __user *ubuf)
1285
+ struct membuf to)
13051286 {
13061287 struct runtime_instr_cb *data = target->thread.ri_cb;
13071288
....@@ -1310,8 +1291,7 @@
13101291 if (!data)
13111292 return -ENODATA;
13121293
1313
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
1314
- data, 0, sizeof(struct runtime_instr_cb));
1294
+ return membuf_write(&to, data, sizeof(struct runtime_instr_cb));
13151295 }
13161296
13171297 static int s390_runtime_instr_set(struct task_struct *target,
....@@ -1371,7 +1351,7 @@
13711351 .n = sizeof(s390_regs) / sizeof(long),
13721352 .size = sizeof(long),
13731353 .align = sizeof(long),
1374
- .get = s390_regs_get,
1354
+ .regset_get = s390_regs_get,
13751355 .set = s390_regs_set,
13761356 },
13771357 {
....@@ -1379,7 +1359,7 @@
13791359 .n = sizeof(s390_fp_regs) / sizeof(long),
13801360 .size = sizeof(long),
13811361 .align = sizeof(long),
1382
- .get = s390_fpregs_get,
1362
+ .regset_get = s390_fpregs_get,
13831363 .set = s390_fpregs_set,
13841364 },
13851365 {
....@@ -1387,7 +1367,7 @@
13871367 .n = 1,
13881368 .size = sizeof(unsigned int),
13891369 .align = sizeof(unsigned int),
1390
- .get = s390_system_call_get,
1370
+ .regset_get = s390_system_call_get,
13911371 .set = s390_system_call_set,
13921372 },
13931373 {
....@@ -1395,7 +1375,7 @@
13951375 .n = 1,
13961376 .size = sizeof(long),
13971377 .align = sizeof(long),
1398
- .get = s390_last_break_get,
1378
+ .regset_get = s390_last_break_get,
13991379 .set = s390_last_break_set,
14001380 },
14011381 {
....@@ -1403,7 +1383,7 @@
14031383 .n = 1,
14041384 .size = 256,
14051385 .align = 1,
1406
- .get = s390_tdb_get,
1386
+ .regset_get = s390_tdb_get,
14071387 .set = s390_tdb_set,
14081388 },
14091389 {
....@@ -1411,7 +1391,7 @@
14111391 .n = __NUM_VXRS_LOW,
14121392 .size = sizeof(__u64),
14131393 .align = sizeof(__u64),
1414
- .get = s390_vxrs_low_get,
1394
+ .regset_get = s390_vxrs_low_get,
14151395 .set = s390_vxrs_low_set,
14161396 },
14171397 {
....@@ -1419,7 +1399,7 @@
14191399 .n = __NUM_VXRS_HIGH,
14201400 .size = sizeof(__vector128),
14211401 .align = sizeof(__vector128),
1422
- .get = s390_vxrs_high_get,
1402
+ .regset_get = s390_vxrs_high_get,
14231403 .set = s390_vxrs_high_set,
14241404 },
14251405 {
....@@ -1427,7 +1407,7 @@
14271407 .n = sizeof(struct gs_cb) / sizeof(__u64),
14281408 .size = sizeof(__u64),
14291409 .align = sizeof(__u64),
1430
- .get = s390_gs_cb_get,
1410
+ .regset_get = s390_gs_cb_get,
14311411 .set = s390_gs_cb_set,
14321412 },
14331413 {
....@@ -1435,7 +1415,7 @@
14351415 .n = sizeof(struct gs_cb) / sizeof(__u64),
14361416 .size = sizeof(__u64),
14371417 .align = sizeof(__u64),
1438
- .get = s390_gs_bc_get,
1418
+ .regset_get = s390_gs_bc_get,
14391419 .set = s390_gs_bc_set,
14401420 },
14411421 {
....@@ -1443,13 +1423,13 @@
14431423 .n = sizeof(struct runtime_instr_cb) / sizeof(__u64),
14441424 .size = sizeof(__u64),
14451425 .align = sizeof(__u64),
1446
- .get = s390_runtime_instr_get,
1426
+ .regset_get = s390_runtime_instr_get,
14471427 .set = s390_runtime_instr_set,
14481428 },
14491429 };
14501430
14511431 static const struct user_regset_view user_s390_view = {
1452
- .name = UTS_MACHINE,
1432
+ .name = "s390x",
14531433 .e_machine = EM_S390,
14541434 .regsets = s390_regsets,
14551435 .n = ARRAY_SIZE(s390_regsets)
....@@ -1458,28 +1438,15 @@
14581438 #ifdef CONFIG_COMPAT
14591439 static int s390_compat_regs_get(struct task_struct *target,
14601440 const struct user_regset *regset,
1461
- unsigned int pos, unsigned int count,
1462
- void *kbuf, void __user *ubuf)
1441
+ struct membuf to)
14631442 {
1443
+ unsigned n;
1444
+
14641445 if (target == current)
14651446 save_access_regs(target->thread.acrs);
14661447
1467
- if (kbuf) {
1468
- compat_ulong_t *k = kbuf;
1469
- while (count > 0) {
1470
- *k++ = __peek_user_compat(target, pos);
1471
- count -= sizeof(*k);
1472
- pos += sizeof(*k);
1473
- }
1474
- } else {
1475
- compat_ulong_t __user *u = ubuf;
1476
- while (count > 0) {
1477
- if (__put_user(__peek_user_compat(target, pos), u++))
1478
- return -EFAULT;
1479
- count -= sizeof(*u);
1480
- pos += sizeof(*u);
1481
- }
1482
- }
1448
+ for (n = 0; n < sizeof(s390_compat_regs); n += sizeof(compat_ulong_t))
1449
+ membuf_store(&to, __peek_user_compat(target, n));
14831450 return 0;
14841451 }
14851452
....@@ -1521,29 +1488,14 @@
15211488
15221489 static int s390_compat_regs_high_get(struct task_struct *target,
15231490 const struct user_regset *regset,
1524
- unsigned int pos, unsigned int count,
1525
- void *kbuf, void __user *ubuf)
1491
+ struct membuf to)
15261492 {
15271493 compat_ulong_t *gprs_high;
1494
+ int i;
15281495
1529
- gprs_high = (compat_ulong_t *)
1530
- &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)];
1531
- if (kbuf) {
1532
- compat_ulong_t *k = kbuf;
1533
- while (count > 0) {
1534
- *k++ = *gprs_high;
1535
- gprs_high += 2;
1536
- count -= sizeof(*k);
1537
- }
1538
- } else {
1539
- compat_ulong_t __user *u = ubuf;
1540
- while (count > 0) {
1541
- if (__put_user(*gprs_high, u++))
1542
- return -EFAULT;
1543
- gprs_high += 2;
1544
- count -= sizeof(*u);
1545
- }
1546
- }
1496
+ gprs_high = (compat_ulong_t *)task_pt_regs(target)->gprs;
1497
+ for (i = 0; i < NUM_GPRS; i++, gprs_high += 2)
1498
+ membuf_store(&to, *gprs_high);
15471499 return 0;
15481500 }
15491501
....@@ -1582,23 +1534,11 @@
15821534
15831535 static int s390_compat_last_break_get(struct task_struct *target,
15841536 const struct user_regset *regset,
1585
- unsigned int pos, unsigned int count,
1586
- void *kbuf, void __user *ubuf)
1537
+ struct membuf to)
15871538 {
1588
- compat_ulong_t last_break;
1539
+ compat_ulong_t last_break = target->thread.last_break;
15891540
1590
- if (count > 0) {
1591
- last_break = target->thread.last_break;
1592
- if (kbuf) {
1593
- unsigned long *k = kbuf;
1594
- *k = last_break;
1595
- } else {
1596
- unsigned long __user *u = ubuf;
1597
- if (__put_user(last_break, u))
1598
- return -EFAULT;
1599
- }
1600
- }
1601
- return 0;
1541
+ return membuf_store(&to, (unsigned long)last_break);
16021542 }
16031543
16041544 static int s390_compat_last_break_set(struct task_struct *target,
....@@ -1615,7 +1555,7 @@
16151555 .n = sizeof(s390_compat_regs) / sizeof(compat_long_t),
16161556 .size = sizeof(compat_long_t),
16171557 .align = sizeof(compat_long_t),
1618
- .get = s390_compat_regs_get,
1558
+ .regset_get = s390_compat_regs_get,
16191559 .set = s390_compat_regs_set,
16201560 },
16211561 {
....@@ -1623,7 +1563,7 @@
16231563 .n = sizeof(s390_fp_regs) / sizeof(compat_long_t),
16241564 .size = sizeof(compat_long_t),
16251565 .align = sizeof(compat_long_t),
1626
- .get = s390_fpregs_get,
1566
+ .regset_get = s390_fpregs_get,
16271567 .set = s390_fpregs_set,
16281568 },
16291569 {
....@@ -1631,7 +1571,7 @@
16311571 .n = 1,
16321572 .size = sizeof(compat_uint_t),
16331573 .align = sizeof(compat_uint_t),
1634
- .get = s390_system_call_get,
1574
+ .regset_get = s390_system_call_get,
16351575 .set = s390_system_call_set,
16361576 },
16371577 {
....@@ -1639,7 +1579,7 @@
16391579 .n = 1,
16401580 .size = sizeof(long),
16411581 .align = sizeof(long),
1642
- .get = s390_compat_last_break_get,
1582
+ .regset_get = s390_compat_last_break_get,
16431583 .set = s390_compat_last_break_set,
16441584 },
16451585 {
....@@ -1647,7 +1587,7 @@
16471587 .n = 1,
16481588 .size = 256,
16491589 .align = 1,
1650
- .get = s390_tdb_get,
1590
+ .regset_get = s390_tdb_get,
16511591 .set = s390_tdb_set,
16521592 },
16531593 {
....@@ -1655,7 +1595,7 @@
16551595 .n = __NUM_VXRS_LOW,
16561596 .size = sizeof(__u64),
16571597 .align = sizeof(__u64),
1658
- .get = s390_vxrs_low_get,
1598
+ .regset_get = s390_vxrs_low_get,
16591599 .set = s390_vxrs_low_set,
16601600 },
16611601 {
....@@ -1663,7 +1603,7 @@
16631603 .n = __NUM_VXRS_HIGH,
16641604 .size = sizeof(__vector128),
16651605 .align = sizeof(__vector128),
1666
- .get = s390_vxrs_high_get,
1606
+ .regset_get = s390_vxrs_high_get,
16671607 .set = s390_vxrs_high_set,
16681608 },
16691609 {
....@@ -1671,7 +1611,7 @@
16711611 .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
16721612 .size = sizeof(compat_long_t),
16731613 .align = sizeof(compat_long_t),
1674
- .get = s390_compat_regs_high_get,
1614
+ .regset_get = s390_compat_regs_high_get,
16751615 .set = s390_compat_regs_high_set,
16761616 },
16771617 {
....@@ -1679,7 +1619,7 @@
16791619 .n = sizeof(struct gs_cb) / sizeof(__u64),
16801620 .size = sizeof(__u64),
16811621 .align = sizeof(__u64),
1682
- .get = s390_gs_cb_get,
1622
+ .regset_get = s390_gs_cb_get,
16831623 .set = s390_gs_cb_set,
16841624 },
16851625 {
....@@ -1687,7 +1627,7 @@
16871627 .n = sizeof(struct gs_cb) / sizeof(__u64),
16881628 .size = sizeof(__u64),
16891629 .align = sizeof(__u64),
1690
- .get = s390_gs_bc_get,
1630
+ .regset_get = s390_gs_bc_get,
16911631 .set = s390_gs_bc_set,
16921632 },
16931633 {
....@@ -1695,7 +1635,7 @@
16951635 .n = sizeof(struct runtime_instr_cb) / sizeof(__u64),
16961636 .size = sizeof(__u64),
16971637 .align = sizeof(__u64),
1698
- .get = s390_runtime_instr_get,
1638
+ .regset_get = s390_runtime_instr_get,
16991639 .set = s390_runtime_instr_set,
17001640 },
17011641 };