hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/kernel/sys.c
....@@ -49,6 +49,7 @@
4949 #include <linux/syscalls.h>
5050 #include <linux/kprobes.h>
5151 #include <linux/user_namespace.h>
52
+#include <linux/time_namespace.h>
5253 #include <linux/binfmts.h>
5354
5455 #include <linux/sched.h>
....@@ -74,6 +75,8 @@
7475 #include <asm/unistd.h>
7576
7677 #include "uid16.h"
78
+
79
+#include <trace/hooks/sys.h>
7780
7881 #ifndef SET_UNALIGN_CTL
7982 # define SET_UNALIGN_CTL(a, b) (-EINVAL)
....@@ -105,12 +108,6 @@
105108 #ifndef SET_TSC_CTL
106109 # define SET_TSC_CTL(a) (-EINVAL)
107110 #endif
108
-#ifndef MPX_ENABLE_MANAGEMENT
109
-# define MPX_ENABLE_MANAGEMENT() (-EINVAL)
110
-#endif
111
-#ifndef MPX_DISABLE_MANAGEMENT
112
-# define MPX_DISABLE_MANAGEMENT() (-EINVAL)
113
-#endif
114111 #ifndef GET_FP_MODE
115112 # define GET_FP_MODE(a) (-EINVAL)
116113 #endif
....@@ -122,6 +119,15 @@
122119 #endif
123120 #ifndef SVE_GET_VL
124121 # define SVE_GET_VL() (-EINVAL)
122
+#endif
123
+#ifndef PAC_RESET_KEYS
124
+# define PAC_RESET_KEYS(a, b) (-EINVAL)
125
+#endif
126
+#ifndef PAC_SET_ENABLED_KEYS
127
+# define PAC_SET_ENABLED_KEYS(a, b, c) (-EINVAL)
128
+#endif
129
+#ifndef PAC_GET_ENABLED_KEYS
130
+# define PAC_GET_ENABLED_KEYS(a) (-EINVAL)
125131 #endif
126132 #ifndef SET_TAGGED_ADDR_CTRL
127133 # define SET_TAGGED_ADDR_CTRL(a) (-EINVAL)
....@@ -377,7 +383,7 @@
377383 if (rgid != (gid_t) -1) {
378384 if (gid_eq(old->gid, krgid) ||
379385 gid_eq(old->egid, krgid) ||
380
- ns_capable(old->user_ns, CAP_SETGID))
386
+ ns_capable_setid(old->user_ns, CAP_SETGID))
381387 new->gid = krgid;
382388 else
383389 goto error;
....@@ -386,7 +392,7 @@
386392 if (gid_eq(old->gid, kegid) ||
387393 gid_eq(old->egid, kegid) ||
388394 gid_eq(old->sgid, kegid) ||
389
- ns_capable(old->user_ns, CAP_SETGID))
395
+ ns_capable_setid(old->user_ns, CAP_SETGID))
390396 new->egid = kegid;
391397 else
392398 goto error;
....@@ -396,6 +402,10 @@
396402 (egid != (gid_t) -1 && !gid_eq(kegid, old->gid)))
397403 new->sgid = new->egid;
398404 new->fsgid = new->egid;
405
+
406
+ retval = security_task_fix_setgid(new, old, LSM_SETID_RE);
407
+ if (retval < 0)
408
+ goto error;
399409
400410 return commit_creds(new);
401411
....@@ -432,11 +442,15 @@
432442 old = current_cred();
433443
434444 retval = -EPERM;
435
- if (ns_capable(old->user_ns, CAP_SETGID))
445
+ if (ns_capable_setid(old->user_ns, CAP_SETGID))
436446 new->gid = new->egid = new->sgid = new->fsgid = kgid;
437447 else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
438448 new->egid = new->fsgid = kgid;
439449 else
450
+ goto error;
451
+
452
+ retval = security_task_fix_setgid(new, old, LSM_SETID_ID);
453
+ if (retval < 0)
440454 goto error;
441455
442456 return commit_creds(new);
....@@ -521,7 +535,7 @@
521535 new->uid = kruid;
522536 if (!uid_eq(old->uid, kruid) &&
523537 !uid_eq(old->euid, kruid) &&
524
- !ns_capable(old->user_ns, CAP_SETUID))
538
+ !ns_capable_setid(old->user_ns, CAP_SETUID))
525539 goto error;
526540 }
527541
....@@ -530,7 +544,7 @@
530544 if (!uid_eq(old->uid, keuid) &&
531545 !uid_eq(old->euid, keuid) &&
532546 !uid_eq(old->suid, keuid) &&
533
- !ns_capable(old->user_ns, CAP_SETUID))
547
+ !ns_capable_setid(old->user_ns, CAP_SETUID))
534548 goto error;
535549 }
536550
....@@ -589,7 +603,7 @@
589603 old = current_cred();
590604
591605 retval = -EPERM;
592
- if (ns_capable(old->user_ns, CAP_SETUID)) {
606
+ if (ns_capable_setid(old->user_ns, CAP_SETUID)) {
593607 new->suid = new->uid = kuid;
594608 if (!uid_eq(kuid, old->uid)) {
595609 retval = set_user(new);
....@@ -630,6 +644,7 @@
630644 struct cred *new;
631645 int retval;
632646 kuid_t kruid, keuid, ksuid;
647
+ bool ruid_new, euid_new, suid_new;
633648
634649 kruid = make_kuid(ns, ruid);
635650 keuid = make_kuid(ns, euid);
....@@ -644,24 +659,28 @@
644659 if ((suid != (uid_t) -1) && !uid_valid(ksuid))
645660 return -EINVAL;
646661
662
+ old = current_cred();
663
+
664
+ /* check for no-op */
665
+ if ((ruid == (uid_t) -1 || uid_eq(kruid, old->uid)) &&
666
+ (euid == (uid_t) -1 || (uid_eq(keuid, old->euid) &&
667
+ uid_eq(keuid, old->fsuid))) &&
668
+ (suid == (uid_t) -1 || uid_eq(ksuid, old->suid)))
669
+ return 0;
670
+
671
+ ruid_new = ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
672
+ !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid);
673
+ euid_new = euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
674
+ !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid);
675
+ suid_new = suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
676
+ !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid);
677
+ if ((ruid_new || euid_new || suid_new) &&
678
+ !ns_capable_setid(old->user_ns, CAP_SETUID))
679
+ return -EPERM;
680
+
647681 new = prepare_creds();
648682 if (!new)
649683 return -ENOMEM;
650
-
651
- old = current_cred();
652
-
653
- retval = -EPERM;
654
- if (!ns_capable(old->user_ns, CAP_SETUID)) {
655
- if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
656
- !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
657
- goto error;
658
- if (euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
659
- !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid))
660
- goto error;
661
- if (suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
662
- !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid))
663
- goto error;
664
- }
665684
666685 if (ruid != (uid_t) -1) {
667686 new->uid = kruid;
....@@ -722,6 +741,7 @@
722741 struct cred *new;
723742 int retval;
724743 kgid_t krgid, kegid, ksgid;
744
+ bool rgid_new, egid_new, sgid_new;
725745
726746 krgid = make_kgid(ns, rgid);
727747 kegid = make_kgid(ns, egid);
....@@ -734,23 +754,28 @@
734754 if ((sgid != (gid_t) -1) && !gid_valid(ksgid))
735755 return -EINVAL;
736756
757
+ old = current_cred();
758
+
759
+ /* check for no-op */
760
+ if ((rgid == (gid_t) -1 || gid_eq(krgid, old->gid)) &&
761
+ (egid == (gid_t) -1 || (gid_eq(kegid, old->egid) &&
762
+ gid_eq(kegid, old->fsgid))) &&
763
+ (sgid == (gid_t) -1 || gid_eq(ksgid, old->sgid)))
764
+ return 0;
765
+
766
+ rgid_new = rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
767
+ !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid);
768
+ egid_new = egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
769
+ !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid);
770
+ sgid_new = sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
771
+ !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid);
772
+ if ((rgid_new || egid_new || sgid_new) &&
773
+ !ns_capable_setid(old->user_ns, CAP_SETGID))
774
+ return -EPERM;
775
+
737776 new = prepare_creds();
738777 if (!new)
739778 return -ENOMEM;
740
- old = current_cred();
741
-
742
- retval = -EPERM;
743
- if (!ns_capable(old->user_ns, CAP_SETGID)) {
744
- if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
745
- !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
746
- goto error;
747
- if (egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
748
- !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid))
749
- goto error;
750
- if (sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
751
- !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid))
752
- goto error;
753
- }
754779
755780 if (rgid != (gid_t) -1)
756781 new->gid = krgid;
....@@ -759,6 +784,10 @@
759784 if (sgid != (gid_t) -1)
760785 new->sgid = ksgid;
761786 new->fsgid = new->egid;
787
+
788
+ retval = security_task_fix_setgid(new, old, LSM_SETID_RES);
789
+ if (retval < 0)
790
+ goto error;
762791
763792 return commit_creds(new);
764793
....@@ -819,7 +848,7 @@
819848
820849 if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) ||
821850 uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) ||
822
- ns_capable(old->user_ns, CAP_SETUID)) {
851
+ ns_capable_setid(old->user_ns, CAP_SETUID)) {
823852 if (!uid_eq(kuid, old->fsuid)) {
824853 new->fsuid = kuid;
825854 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
....@@ -863,10 +892,11 @@
863892
864893 if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
865894 gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
866
- ns_capable(old->user_ns, CAP_SETGID)) {
895
+ ns_capable_setid(old->user_ns, CAP_SETGID)) {
867896 if (!gid_eq(kgid, old->fsgid)) {
868897 new->fsgid = kgid;
869
- goto change_okay;
898
+ if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0)
899
+ goto change_okay;
870900 }
871901 }
872902
....@@ -1212,7 +1242,8 @@
12121242 /*
12131243 * Work around broken programs that cannot handle "Linux 3.0".
12141244 * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40
1215
- * And we map 4.x to 2.6.60+x, so 4.0 would be 2.6.60.
1245
+ * And we map 4.x and later versions to 2.6.60+x, so 4.0/5.0/6.0/... would be
1246
+ * 2.6.60.
12161247 */
12171248 static int override_release(char __user *release, size_t len)
12181249 {
....@@ -1538,6 +1569,8 @@
15381569
15391570 if (resource >= RLIM_NLIMITS)
15401571 return -EINVAL;
1572
+ resource = array_index_nospec(resource, RLIM_NLIMITS);
1573
+
15411574 if (new_rlim) {
15421575 if (new_rlim->rlim_cur > new_rlim->rlim_max)
15431576 return -EINVAL;
....@@ -1563,15 +1596,6 @@
15631596 retval = -EPERM;
15641597 if (!retval)
15651598 retval = security_task_setrlimit(tsk, resource, new_rlim);
1566
- if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
1567
- /*
1568
- * The caller is asking for an immediate RLIMIT_CPU
1569
- * expiry. But we use the zero value to mean "it was
1570
- * never set". So let's cheat and make it one second
1571
- * instead
1572
- */
1573
- new_rlim->rlim_cur = 1;
1574
- }
15751599 }
15761600 if (!retval) {
15771601 if (old_rlim)
....@@ -1582,10 +1606,9 @@
15821606 task_unlock(tsk->group_leader);
15831607
15841608 /*
1585
- * RLIMIT_CPU handling. Note that the kernel fails to return an error
1586
- * code if it rejected the user's attempt to set RLIMIT_CPU. This is a
1587
- * very long-standing error, and fixing it now risks breakage of
1588
- * applications, so we live with it
1609
+ * RLIMIT_CPU handling. Arm the posix CPU timer if the limit is not
1610
+ * infite. In case of RLIM_INFINITY the posix CPU timer code
1611
+ * ignores the rlimit.
15891612 */
15901613 if (!retval && new_rlim && resource == RLIMIT_CPU &&
15911614 new_rlim->rlim_cur != RLIM_INFINITY &&
....@@ -1753,6 +1776,7 @@
17531776
17541777 if (who == RUSAGE_CHILDREN)
17551778 break;
1779
+ fallthrough;
17561780
17571781 case RUSAGE_SELF:
17581782 thread_group_cputime_adjusted(p, &tgutime, &tgstime);
....@@ -1778,8 +1802,8 @@
17781802 unlock_task_sighand(p, &flags);
17791803
17801804 out:
1781
- r->ru_utime = ns_to_timeval(utime);
1782
- r->ru_stime = ns_to_timeval(stime);
1805
+ r->ru_utime = ns_to_kernel_old_timeval(utime);
1806
+ r->ru_stime = ns_to_kernel_old_timeval(stime);
17831807
17841808 if (who != RUSAGE_CHILDREN) {
17851809 struct mm_struct *mm = get_task_mm(p);
....@@ -1858,7 +1882,7 @@
18581882 if (exe_file) {
18591883 struct vm_area_struct *vma;
18601884
1861
- down_read(&mm->mmap_sem);
1885
+ mmap_read_lock(mm);
18621886 for (vma = mm->mmap; vma; vma = vma->vm_next) {
18631887 if (!vma->vm_file)
18641888 continue;
....@@ -1867,7 +1891,7 @@
18671891 goto exit_err;
18681892 }
18691893
1870
- up_read(&mm->mmap_sem);
1894
+ mmap_read_unlock(mm);
18711895 fput(exe_file);
18721896 }
18731897
....@@ -1881,19 +1905,20 @@
18811905 fdput(exe);
18821906 return err;
18831907 exit_err:
1884
- up_read(&mm->mmap_sem);
1908
+ mmap_read_unlock(mm);
18851909 fput(exe_file);
18861910 goto exit;
18871911 }
18881912
18891913 /*
1914
+ * Check arithmetic relations of passed addresses.
1915
+ *
18901916 * WARNING: we don't require any capability here so be very careful
18911917 * in what is allowed for modification from userspace.
18921918 */
1893
-static int validate_prctl_map(struct prctl_mm_map *prctl_map)
1919
+static int validate_prctl_map_addr(struct prctl_mm_map *prctl_map)
18941920 {
18951921 unsigned long mmap_max_addr = TASK_SIZE;
1896
- struct mm_struct *mm = current->mm;
18971922 int error = -EINVAL, i;
18981923
18991924 static const unsigned char offsets[] = {
....@@ -1947,24 +1972,6 @@
19471972 prctl_map->start_data))
19481973 goto out;
19491974
1950
- /*
1951
- * Someone is trying to cheat the auxv vector.
1952
- */
1953
- if (prctl_map->auxv_size) {
1954
- if (!prctl_map->auxv || prctl_map->auxv_size > sizeof(mm->saved_auxv))
1955
- goto out;
1956
- }
1957
-
1958
- /*
1959
- * Finally, make sure the caller has the rights to
1960
- * change /proc/pid/exe link: only local sys admin should
1961
- * be allowed to.
1962
- */
1963
- if (prctl_map->exe_fd != (u32)-1) {
1964
- if (!ns_capable(current_user_ns(), CAP_SYS_ADMIN))
1965
- goto out;
1966
- }
1967
-
19681975 error = 0;
19691976 out:
19701977 return error;
....@@ -1991,11 +1998,18 @@
19911998 if (copy_from_user(&prctl_map, addr, sizeof(prctl_map)))
19921999 return -EFAULT;
19932000
1994
- error = validate_prctl_map(&prctl_map);
2001
+ error = validate_prctl_map_addr(&prctl_map);
19952002 if (error)
19962003 return error;
19972004
19982005 if (prctl_map.auxv_size) {
2006
+ /*
2007
+ * Someone is trying to cheat the auxv vector.
2008
+ */
2009
+ if (!prctl_map.auxv ||
2010
+ prctl_map.auxv_size > sizeof(mm->saved_auxv))
2011
+ return -EINVAL;
2012
+
19992013 memset(user_auxv, 0, sizeof(user_auxv));
20002014 if (copy_from_user(user_auxv,
20012015 (const void __user *)prctl_map.auxv,
....@@ -2008,16 +2022,27 @@
20082022 }
20092023
20102024 if (prctl_map.exe_fd != (u32)-1) {
2025
+ /*
2026
+ * Check if the current user is checkpoint/restore capable.
2027
+ * At the time of this writing, it checks for CAP_SYS_ADMIN
2028
+ * or CAP_CHECKPOINT_RESTORE.
2029
+ * Note that a user with access to ptrace can masquerade an
2030
+ * arbitrary program as any executable, even setuid ones.
2031
+ * This may have implications in the tomoyo subsystem.
2032
+ */
2033
+ if (!checkpoint_restore_ns_capable(current_user_ns()))
2034
+ return -EPERM;
2035
+
20112036 error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
20122037 if (error)
20132038 return error;
20142039 }
20152040
20162041 /*
2017
- * arg_lock protects concurent updates but we still need mmap_sem for
2042
+ * arg_lock protects concurent updates but we still need mmap_lock for
20182043 * read to exclude races with sys_brk.
20192044 */
2020
- down_read(&mm->mmap_sem);
2045
+ mmap_read_lock(mm);
20212046
20222047 /*
20232048 * We don't validate if these members are pointing to
....@@ -2025,7 +2050,7 @@
20252050 * VMAs already unmapped and kernel uses these members for statistics
20262051 * output in procfs mostly, except
20272052 *
2028
- * - @start_brk/@brk which are used in do_brk but kernel lookups
2053
+ * - @start_brk/@brk which are used in do_brk_flags but kernel lookups
20292054 * for VMAs when updating these memvers so anything wrong written
20302055 * here cause kernel to swear at userspace program but won't lead
20312056 * to any problem in kernel itself
....@@ -2056,7 +2081,7 @@
20562081 if (prctl_map.auxv_size)
20572082 memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
20582083
2059
- up_read(&mm->mmap_sem);
2084
+ mmap_read_unlock(mm);
20602085 return 0;
20612086 }
20622087 #endif /* CONFIG_CHECKPOINT_RESTORE */
....@@ -2095,7 +2120,11 @@
20952120 unsigned long arg4, unsigned long arg5)
20962121 {
20972122 struct mm_struct *mm = current->mm;
2098
- struct prctl_mm_map prctl_map;
2123
+ struct prctl_mm_map prctl_map = {
2124
+ .auxv = NULL,
2125
+ .auxv_size = 0,
2126
+ .exe_fd = -1,
2127
+ };
20992128 struct vm_area_struct *vma;
21002129 int error;
21012130
....@@ -2123,9 +2152,15 @@
21232152
21242153 error = -EINVAL;
21252154
2126
- down_write(&mm->mmap_sem);
2155
+ /*
2156
+ * arg_lock protects concurent updates of arg boundaries, we need
2157
+ * mmap_lock for a) concurrent sys_brk, b) finding VMA for addr
2158
+ * validation.
2159
+ */
2160
+ mmap_read_lock(mm);
21272161 vma = find_vma(mm, addr);
21282162
2163
+ spin_lock(&mm->arg_lock);
21292164 prctl_map.start_code = mm->start_code;
21302165 prctl_map.end_code = mm->end_code;
21312166 prctl_map.start_data = mm->start_data;
....@@ -2137,9 +2172,6 @@
21372172 prctl_map.arg_end = mm->arg_end;
21382173 prctl_map.env_start = mm->env_start;
21392174 prctl_map.env_end = mm->env_end;
2140
- prctl_map.auxv = NULL;
2141
- prctl_map.auxv_size = 0;
2142
- prctl_map.exe_fd = -1;
21432175
21442176 switch (opt) {
21452177 case PR_SET_MM_START_CODE:
....@@ -2179,7 +2211,7 @@
21792211 goto out;
21802212 }
21812213
2182
- error = validate_prctl_map(&prctl_map);
2214
+ error = validate_prctl_map_addr(&prctl_map);
21832215 if (error)
21842216 goto out;
21852217
....@@ -2216,17 +2248,18 @@
22162248
22172249 error = 0;
22182250 out:
2219
- up_write(&mm->mmap_sem);
2251
+ spin_unlock(&mm->arg_lock);
2252
+ mmap_read_unlock(mm);
22202253 return error;
22212254 }
22222255
22232256 #ifdef CONFIG_CHECKPOINT_RESTORE
2224
-static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
2257
+static int prctl_get_tid_address(struct task_struct *me, int __user * __user *tid_addr)
22252258 {
22262259 return put_user(me->clear_child_tid, tid_addr);
22272260 }
22282261 #else
2229
-static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr)
2262
+static int prctl_get_tid_address(struct task_struct *me, int __user * __user *tid_addr)
22302263 {
22312264 return -EINVAL;
22322265 }
....@@ -2358,7 +2391,7 @@
23582391 return error;
23592392 if (prev)
23602393 vma = prev->vm_next;
2361
- else /* madvise_remove dropped mmap_sem */
2394
+ else /* madvise_remove dropped mmap_lock */
23622395 vma = find_vma(current->mm, start);
23632396 }
23642397 }
....@@ -2386,7 +2419,7 @@
23862419 if (end == start)
23872420 return 0;
23882421
2389
- down_write(&mm->mmap_sem);
2422
+ mmap_write_lock(mm);
23902423
23912424 switch (opt) {
23922425 case PR_SET_VMA_ANON_NAME:
....@@ -2396,7 +2429,7 @@
23962429 error = -EINVAL;
23972430 }
23982431
2399
- up_write(&mm->mmap_sem);
2432
+ mmap_write_unlock(mm);
24002433
24012434 return error;
24022435 }
....@@ -2407,6 +2440,8 @@
24072440 return -EINVAL;
24082441 }
24092442 #endif
2443
+
2444
+#define PR_IO_FLUSHER (PF_MEMALLOC_NOIO | PF_LOCAL_THROTTLE)
24102445
24112446 SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
24122447 unsigned long, arg4, unsigned long, arg5)
....@@ -2555,7 +2590,7 @@
25552590 error = prctl_set_mm(arg2, arg3, arg4, arg5);
25562591 break;
25572592 case PR_GET_TID_ADDRESS:
2558
- error = prctl_get_tid_address(me, (int __user **)arg2);
2593
+ error = prctl_get_tid_address(me, (int __user * __user *)arg2);
25592594 break;
25602595 case PR_SET_CHILD_SUBREAPER:
25612596 me->signal->is_child_subreaper = !!arg2;
....@@ -2586,24 +2621,18 @@
25862621 case PR_SET_THP_DISABLE:
25872622 if (arg3 || arg4 || arg5)
25882623 return -EINVAL;
2589
- if (down_write_killable(&me->mm->mmap_sem))
2624
+ if (mmap_write_lock_killable(me->mm))
25902625 return -EINTR;
25912626 if (arg2)
25922627 set_bit(MMF_DISABLE_THP, &me->mm->flags);
25932628 else
25942629 clear_bit(MMF_DISABLE_THP, &me->mm->flags);
2595
- up_write(&me->mm->mmap_sem);
2630
+ mmap_write_unlock(me->mm);
25962631 break;
25972632 case PR_MPX_ENABLE_MANAGEMENT:
2598
- if (arg2 || arg3 || arg4 || arg5)
2599
- return -EINVAL;
2600
- error = MPX_ENABLE_MANAGEMENT();
2601
- break;
26022633 case PR_MPX_DISABLE_MANAGEMENT:
2603
- if (arg2 || arg3 || arg4 || arg5)
2604
- return -EINVAL;
2605
- error = MPX_DISABLE_MANAGEMENT();
2606
- break;
2634
+ /* No longer implemented: */
2635
+ return -EINVAL;
26072636 case PR_SET_FP_MODE:
26082637 error = SET_FP_MODE(me, arg2);
26092638 break;
....@@ -2629,6 +2658,21 @@
26292658 case PR_SET_VMA:
26302659 error = prctl_set_vma(arg2, arg3, arg4, arg5);
26312660 break;
2661
+ case PR_PAC_RESET_KEYS:
2662
+ if (arg3 || arg4 || arg5)
2663
+ return -EINVAL;
2664
+ error = PAC_RESET_KEYS(me, arg2);
2665
+ break;
2666
+ case PR_PAC_SET_ENABLED_KEYS:
2667
+ if (arg4 || arg5)
2668
+ return -EINVAL;
2669
+ error = PAC_SET_ENABLED_KEYS(me, arg2, arg3);
2670
+ break;
2671
+ case PR_PAC_GET_ENABLED_KEYS:
2672
+ if (arg2 || arg3 || arg4 || arg5)
2673
+ return -EINVAL;
2674
+ error = PAC_GET_ENABLED_KEYS(me);
2675
+ break;
26322676 case PR_SET_TAGGED_ADDR_CTRL:
26332677 if (arg3 || arg4 || arg5)
26342678 return -EINVAL;
....@@ -2639,10 +2683,34 @@
26392683 return -EINVAL;
26402684 error = GET_TAGGED_ADDR_CTRL();
26412685 break;
2686
+ case PR_SET_IO_FLUSHER:
2687
+ if (!capable(CAP_SYS_RESOURCE))
2688
+ return -EPERM;
2689
+
2690
+ if (arg3 || arg4 || arg5)
2691
+ return -EINVAL;
2692
+
2693
+ if (arg2 == 1)
2694
+ current->flags |= PR_IO_FLUSHER;
2695
+ else if (!arg2)
2696
+ current->flags &= ~PR_IO_FLUSHER;
2697
+ else
2698
+ return -EINVAL;
2699
+ break;
2700
+ case PR_GET_IO_FLUSHER:
2701
+ if (!capable(CAP_SYS_RESOURCE))
2702
+ return -EPERM;
2703
+
2704
+ if (arg2 || arg3 || arg4 || arg5)
2705
+ return -EINVAL;
2706
+
2707
+ error = (current->flags & PR_IO_FLUSHER) == PR_IO_FLUSHER;
2708
+ break;
26422709 default:
26432710 error = -EINVAL;
26442711 break;
26452712 }
2713
+ trace_android_vh_syscall_prctl_finished(option, me);
26462714 return error;
26472715 }
26482716
....@@ -2672,6 +2740,7 @@
26722740 memset(info, 0, sizeof(struct sysinfo));
26732741
26742742 ktime_get_boottime_ts64(&tp);
2743
+ timens_add_boottime(&tp);
26752744 info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
26762745
26772746 get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT);
....@@ -2758,6 +2827,7 @@
27582827 COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info)
27592828 {
27602829 struct sysinfo s;
2830
+ struct compat_sysinfo s_32;
27612831
27622832 do_sysinfo(&s);
27632833
....@@ -2782,23 +2852,23 @@
27822852 s.freehigh >>= bitcount;
27832853 }
27842854
2785
- if (!access_ok(VERIFY_WRITE, info, sizeof(struct compat_sysinfo)) ||
2786
- __put_user(s.uptime, &info->uptime) ||
2787
- __put_user(s.loads[0], &info->loads[0]) ||
2788
- __put_user(s.loads[1], &info->loads[1]) ||
2789
- __put_user(s.loads[2], &info->loads[2]) ||
2790
- __put_user(s.totalram, &info->totalram) ||
2791
- __put_user(s.freeram, &info->freeram) ||
2792
- __put_user(s.sharedram, &info->sharedram) ||
2793
- __put_user(s.bufferram, &info->bufferram) ||
2794
- __put_user(s.totalswap, &info->totalswap) ||
2795
- __put_user(s.freeswap, &info->freeswap) ||
2796
- __put_user(s.procs, &info->procs) ||
2797
- __put_user(s.totalhigh, &info->totalhigh) ||
2798
- __put_user(s.freehigh, &info->freehigh) ||
2799
- __put_user(s.mem_unit, &info->mem_unit))
2855
+ memset(&s_32, 0, sizeof(s_32));
2856
+ s_32.uptime = s.uptime;
2857
+ s_32.loads[0] = s.loads[0];
2858
+ s_32.loads[1] = s.loads[1];
2859
+ s_32.loads[2] = s.loads[2];
2860
+ s_32.totalram = s.totalram;
2861
+ s_32.freeram = s.freeram;
2862
+ s_32.sharedram = s.sharedram;
2863
+ s_32.bufferram = s.bufferram;
2864
+ s_32.totalswap = s.totalswap;
2865
+ s_32.freeswap = s.freeswap;
2866
+ s_32.procs = s.procs;
2867
+ s_32.totalhigh = s.totalhigh;
2868
+ s_32.freehigh = s.freehigh;
2869
+ s_32.mem_unit = s.mem_unit;
2870
+ if (copy_to_user(info, &s_32, sizeof(s_32)))
28002871 return -EFAULT;
2801
-
28022872 return 0;
28032873 }
28042874 #endif /* CONFIG_COMPAT */