.. | .. |
---|
49 | 49 | #include <linux/syscalls.h> |
---|
50 | 50 | #include <linux/kprobes.h> |
---|
51 | 51 | #include <linux/user_namespace.h> |
---|
| 52 | +#include <linux/time_namespace.h> |
---|
52 | 53 | #include <linux/binfmts.h> |
---|
53 | 54 | |
---|
54 | 55 | #include <linux/sched.h> |
---|
.. | .. |
---|
74 | 75 | #include <asm/unistd.h> |
---|
75 | 76 | |
---|
76 | 77 | #include "uid16.h" |
---|
| 78 | + |
---|
| 79 | +#include <trace/hooks/sys.h> |
---|
77 | 80 | |
---|
78 | 81 | #ifndef SET_UNALIGN_CTL |
---|
79 | 82 | # define SET_UNALIGN_CTL(a, b) (-EINVAL) |
---|
.. | .. |
---|
105 | 108 | #ifndef SET_TSC_CTL |
---|
106 | 109 | # define SET_TSC_CTL(a) (-EINVAL) |
---|
107 | 110 | #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 |
---|
114 | 111 | #ifndef GET_FP_MODE |
---|
115 | 112 | # define GET_FP_MODE(a) (-EINVAL) |
---|
116 | 113 | #endif |
---|
.. | .. |
---|
122 | 119 | #endif |
---|
123 | 120 | #ifndef SVE_GET_VL |
---|
124 | 121 | # 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) |
---|
125 | 131 | #endif |
---|
126 | 132 | #ifndef SET_TAGGED_ADDR_CTRL |
---|
127 | 133 | # define SET_TAGGED_ADDR_CTRL(a) (-EINVAL) |
---|
.. | .. |
---|
377 | 383 | if (rgid != (gid_t) -1) { |
---|
378 | 384 | if (gid_eq(old->gid, krgid) || |
---|
379 | 385 | gid_eq(old->egid, krgid) || |
---|
380 | | - ns_capable(old->user_ns, CAP_SETGID)) |
---|
| 386 | + ns_capable_setid(old->user_ns, CAP_SETGID)) |
---|
381 | 387 | new->gid = krgid; |
---|
382 | 388 | else |
---|
383 | 389 | goto error; |
---|
.. | .. |
---|
386 | 392 | if (gid_eq(old->gid, kegid) || |
---|
387 | 393 | gid_eq(old->egid, kegid) || |
---|
388 | 394 | gid_eq(old->sgid, kegid) || |
---|
389 | | - ns_capable(old->user_ns, CAP_SETGID)) |
---|
| 395 | + ns_capable_setid(old->user_ns, CAP_SETGID)) |
---|
390 | 396 | new->egid = kegid; |
---|
391 | 397 | else |
---|
392 | 398 | goto error; |
---|
.. | .. |
---|
396 | 402 | (egid != (gid_t) -1 && !gid_eq(kegid, old->gid))) |
---|
397 | 403 | new->sgid = new->egid; |
---|
398 | 404 | new->fsgid = new->egid; |
---|
| 405 | + |
---|
| 406 | + retval = security_task_fix_setgid(new, old, LSM_SETID_RE); |
---|
| 407 | + if (retval < 0) |
---|
| 408 | + goto error; |
---|
399 | 409 | |
---|
400 | 410 | return commit_creds(new); |
---|
401 | 411 | |
---|
.. | .. |
---|
432 | 442 | old = current_cred(); |
---|
433 | 443 | |
---|
434 | 444 | retval = -EPERM; |
---|
435 | | - if (ns_capable(old->user_ns, CAP_SETGID)) |
---|
| 445 | + if (ns_capable_setid(old->user_ns, CAP_SETGID)) |
---|
436 | 446 | new->gid = new->egid = new->sgid = new->fsgid = kgid; |
---|
437 | 447 | else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid)) |
---|
438 | 448 | new->egid = new->fsgid = kgid; |
---|
439 | 449 | else |
---|
| 450 | + goto error; |
---|
| 451 | + |
---|
| 452 | + retval = security_task_fix_setgid(new, old, LSM_SETID_ID); |
---|
| 453 | + if (retval < 0) |
---|
440 | 454 | goto error; |
---|
441 | 455 | |
---|
442 | 456 | return commit_creds(new); |
---|
.. | .. |
---|
521 | 535 | new->uid = kruid; |
---|
522 | 536 | if (!uid_eq(old->uid, kruid) && |
---|
523 | 537 | !uid_eq(old->euid, kruid) && |
---|
524 | | - !ns_capable(old->user_ns, CAP_SETUID)) |
---|
| 538 | + !ns_capable_setid(old->user_ns, CAP_SETUID)) |
---|
525 | 539 | goto error; |
---|
526 | 540 | } |
---|
527 | 541 | |
---|
.. | .. |
---|
530 | 544 | if (!uid_eq(old->uid, keuid) && |
---|
531 | 545 | !uid_eq(old->euid, keuid) && |
---|
532 | 546 | !uid_eq(old->suid, keuid) && |
---|
533 | | - !ns_capable(old->user_ns, CAP_SETUID)) |
---|
| 547 | + !ns_capable_setid(old->user_ns, CAP_SETUID)) |
---|
534 | 548 | goto error; |
---|
535 | 549 | } |
---|
536 | 550 | |
---|
.. | .. |
---|
589 | 603 | old = current_cred(); |
---|
590 | 604 | |
---|
591 | 605 | retval = -EPERM; |
---|
592 | | - if (ns_capable(old->user_ns, CAP_SETUID)) { |
---|
| 606 | + if (ns_capable_setid(old->user_ns, CAP_SETUID)) { |
---|
593 | 607 | new->suid = new->uid = kuid; |
---|
594 | 608 | if (!uid_eq(kuid, old->uid)) { |
---|
595 | 609 | retval = set_user(new); |
---|
.. | .. |
---|
651 | 665 | old = current_cred(); |
---|
652 | 666 | |
---|
653 | 667 | retval = -EPERM; |
---|
654 | | - if (!ns_capable(old->user_ns, CAP_SETUID)) { |
---|
| 668 | + if (!ns_capable_setid(old->user_ns, CAP_SETUID)) { |
---|
655 | 669 | if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) && |
---|
656 | 670 | !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid)) |
---|
657 | 671 | goto error; |
---|
.. | .. |
---|
740 | 754 | old = current_cred(); |
---|
741 | 755 | |
---|
742 | 756 | retval = -EPERM; |
---|
743 | | - if (!ns_capable(old->user_ns, CAP_SETGID)) { |
---|
| 757 | + if (!ns_capable_setid(old->user_ns, CAP_SETGID)) { |
---|
744 | 758 | if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) && |
---|
745 | 759 | !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid)) |
---|
746 | 760 | goto error; |
---|
.. | .. |
---|
759 | 773 | if (sgid != (gid_t) -1) |
---|
760 | 774 | new->sgid = ksgid; |
---|
761 | 775 | new->fsgid = new->egid; |
---|
| 776 | + |
---|
| 777 | + retval = security_task_fix_setgid(new, old, LSM_SETID_RES); |
---|
| 778 | + if (retval < 0) |
---|
| 779 | + goto error; |
---|
762 | 780 | |
---|
763 | 781 | return commit_creds(new); |
---|
764 | 782 | |
---|
.. | .. |
---|
819 | 837 | |
---|
820 | 838 | if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) || |
---|
821 | 839 | uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) || |
---|
822 | | - ns_capable(old->user_ns, CAP_SETUID)) { |
---|
| 840 | + ns_capable_setid(old->user_ns, CAP_SETUID)) { |
---|
823 | 841 | if (!uid_eq(kuid, old->fsuid)) { |
---|
824 | 842 | new->fsuid = kuid; |
---|
825 | 843 | if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) |
---|
.. | .. |
---|
863 | 881 | |
---|
864 | 882 | if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) || |
---|
865 | 883 | gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) || |
---|
866 | | - ns_capable(old->user_ns, CAP_SETGID)) { |
---|
| 884 | + ns_capable_setid(old->user_ns, CAP_SETGID)) { |
---|
867 | 885 | if (!gid_eq(kgid, old->fsgid)) { |
---|
868 | 886 | new->fsgid = kgid; |
---|
869 | | - goto change_okay; |
---|
| 887 | + if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0) |
---|
| 888 | + goto change_okay; |
---|
870 | 889 | } |
---|
871 | 890 | } |
---|
872 | 891 | |
---|
.. | .. |
---|
1212 | 1231 | /* |
---|
1213 | 1232 | * Work around broken programs that cannot handle "Linux 3.0". |
---|
1214 | 1233 | * 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. |
---|
| 1234 | + * And we map 4.x and later versions to 2.6.60+x, so 4.0/5.0/6.0/... would be |
---|
| 1235 | + * 2.6.60. |
---|
1216 | 1236 | */ |
---|
1217 | 1237 | static int override_release(char __user *release, size_t len) |
---|
1218 | 1238 | { |
---|
.. | .. |
---|
1563 | 1583 | retval = -EPERM; |
---|
1564 | 1584 | if (!retval) |
---|
1565 | 1585 | 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 | | - } |
---|
1575 | 1586 | } |
---|
1576 | 1587 | if (!retval) { |
---|
1577 | 1588 | if (old_rlim) |
---|
.. | .. |
---|
1582 | 1593 | task_unlock(tsk->group_leader); |
---|
1583 | 1594 | |
---|
1584 | 1595 | /* |
---|
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 |
---|
| 1596 | + * RLIMIT_CPU handling. Arm the posix CPU timer if the limit is not |
---|
| 1597 | + * infite. In case of RLIM_INFINITY the posix CPU timer code |
---|
| 1598 | + * ignores the rlimit. |
---|
1589 | 1599 | */ |
---|
1590 | 1600 | if (!retval && new_rlim && resource == RLIMIT_CPU && |
---|
1591 | 1601 | new_rlim->rlim_cur != RLIM_INFINITY && |
---|
.. | .. |
---|
1753 | 1763 | |
---|
1754 | 1764 | if (who == RUSAGE_CHILDREN) |
---|
1755 | 1765 | break; |
---|
| 1766 | + fallthrough; |
---|
1756 | 1767 | |
---|
1757 | 1768 | case RUSAGE_SELF: |
---|
1758 | 1769 | thread_group_cputime_adjusted(p, &tgutime, &tgstime); |
---|
.. | .. |
---|
1778 | 1789 | unlock_task_sighand(p, &flags); |
---|
1779 | 1790 | |
---|
1780 | 1791 | out: |
---|
1781 | | - r->ru_utime = ns_to_timeval(utime); |
---|
1782 | | - r->ru_stime = ns_to_timeval(stime); |
---|
| 1792 | + r->ru_utime = ns_to_kernel_old_timeval(utime); |
---|
| 1793 | + r->ru_stime = ns_to_kernel_old_timeval(stime); |
---|
1783 | 1794 | |
---|
1784 | 1795 | if (who != RUSAGE_CHILDREN) { |
---|
1785 | 1796 | struct mm_struct *mm = get_task_mm(p); |
---|
.. | .. |
---|
1858 | 1869 | if (exe_file) { |
---|
1859 | 1870 | struct vm_area_struct *vma; |
---|
1860 | 1871 | |
---|
1861 | | - down_read(&mm->mmap_sem); |
---|
| 1872 | + mmap_read_lock(mm); |
---|
1862 | 1873 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
---|
1863 | 1874 | if (!vma->vm_file) |
---|
1864 | 1875 | continue; |
---|
.. | .. |
---|
1867 | 1878 | goto exit_err; |
---|
1868 | 1879 | } |
---|
1869 | 1880 | |
---|
1870 | | - up_read(&mm->mmap_sem); |
---|
| 1881 | + mmap_read_unlock(mm); |
---|
1871 | 1882 | fput(exe_file); |
---|
1872 | 1883 | } |
---|
1873 | 1884 | |
---|
.. | .. |
---|
1881 | 1892 | fdput(exe); |
---|
1882 | 1893 | return err; |
---|
1883 | 1894 | exit_err: |
---|
1884 | | - up_read(&mm->mmap_sem); |
---|
| 1895 | + mmap_read_unlock(mm); |
---|
1885 | 1896 | fput(exe_file); |
---|
1886 | 1897 | goto exit; |
---|
1887 | 1898 | } |
---|
1888 | 1899 | |
---|
1889 | 1900 | /* |
---|
| 1901 | + * Check arithmetic relations of passed addresses. |
---|
| 1902 | + * |
---|
1890 | 1903 | * WARNING: we don't require any capability here so be very careful |
---|
1891 | 1904 | * in what is allowed for modification from userspace. |
---|
1892 | 1905 | */ |
---|
1893 | | -static int validate_prctl_map(struct prctl_mm_map *prctl_map) |
---|
| 1906 | +static int validate_prctl_map_addr(struct prctl_mm_map *prctl_map) |
---|
1894 | 1907 | { |
---|
1895 | 1908 | unsigned long mmap_max_addr = TASK_SIZE; |
---|
1896 | | - struct mm_struct *mm = current->mm; |
---|
1897 | 1909 | int error = -EINVAL, i; |
---|
1898 | 1910 | |
---|
1899 | 1911 | static const unsigned char offsets[] = { |
---|
.. | .. |
---|
1947 | 1959 | prctl_map->start_data)) |
---|
1948 | 1960 | goto out; |
---|
1949 | 1961 | |
---|
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 | | - |
---|
1968 | 1962 | error = 0; |
---|
1969 | 1963 | out: |
---|
1970 | 1964 | return error; |
---|
.. | .. |
---|
1991 | 1985 | if (copy_from_user(&prctl_map, addr, sizeof(prctl_map))) |
---|
1992 | 1986 | return -EFAULT; |
---|
1993 | 1987 | |
---|
1994 | | - error = validate_prctl_map(&prctl_map); |
---|
| 1988 | + error = validate_prctl_map_addr(&prctl_map); |
---|
1995 | 1989 | if (error) |
---|
1996 | 1990 | return error; |
---|
1997 | 1991 | |
---|
1998 | 1992 | if (prctl_map.auxv_size) { |
---|
| 1993 | + /* |
---|
| 1994 | + * Someone is trying to cheat the auxv vector. |
---|
| 1995 | + */ |
---|
| 1996 | + if (!prctl_map.auxv || |
---|
| 1997 | + prctl_map.auxv_size > sizeof(mm->saved_auxv)) |
---|
| 1998 | + return -EINVAL; |
---|
| 1999 | + |
---|
1999 | 2000 | memset(user_auxv, 0, sizeof(user_auxv)); |
---|
2000 | 2001 | if (copy_from_user(user_auxv, |
---|
2001 | 2002 | (const void __user *)prctl_map.auxv, |
---|
.. | .. |
---|
2008 | 2009 | } |
---|
2009 | 2010 | |
---|
2010 | 2011 | if (prctl_map.exe_fd != (u32)-1) { |
---|
| 2012 | + /* |
---|
| 2013 | + * Check if the current user is checkpoint/restore capable. |
---|
| 2014 | + * At the time of this writing, it checks for CAP_SYS_ADMIN |
---|
| 2015 | + * or CAP_CHECKPOINT_RESTORE. |
---|
| 2016 | + * Note that a user with access to ptrace can masquerade an |
---|
| 2017 | + * arbitrary program as any executable, even setuid ones. |
---|
| 2018 | + * This may have implications in the tomoyo subsystem. |
---|
| 2019 | + */ |
---|
| 2020 | + if (!checkpoint_restore_ns_capable(current_user_ns())) |
---|
| 2021 | + return -EPERM; |
---|
| 2022 | + |
---|
2011 | 2023 | error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd); |
---|
2012 | 2024 | if (error) |
---|
2013 | 2025 | return error; |
---|
2014 | 2026 | } |
---|
2015 | 2027 | |
---|
2016 | 2028 | /* |
---|
2017 | | - * arg_lock protects concurent updates but we still need mmap_sem for |
---|
| 2029 | + * arg_lock protects concurent updates but we still need mmap_lock for |
---|
2018 | 2030 | * read to exclude races with sys_brk. |
---|
2019 | 2031 | */ |
---|
2020 | | - down_read(&mm->mmap_sem); |
---|
| 2032 | + mmap_read_lock(mm); |
---|
2021 | 2033 | |
---|
2022 | 2034 | /* |
---|
2023 | 2035 | * We don't validate if these members are pointing to |
---|
.. | .. |
---|
2025 | 2037 | * VMAs already unmapped and kernel uses these members for statistics |
---|
2026 | 2038 | * output in procfs mostly, except |
---|
2027 | 2039 | * |
---|
2028 | | - * - @start_brk/@brk which are used in do_brk but kernel lookups |
---|
| 2040 | + * - @start_brk/@brk which are used in do_brk_flags but kernel lookups |
---|
2029 | 2041 | * for VMAs when updating these memvers so anything wrong written |
---|
2030 | 2042 | * here cause kernel to swear at userspace program but won't lead |
---|
2031 | 2043 | * to any problem in kernel itself |
---|
.. | .. |
---|
2056 | 2068 | if (prctl_map.auxv_size) |
---|
2057 | 2069 | memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv)); |
---|
2058 | 2070 | |
---|
2059 | | - up_read(&mm->mmap_sem); |
---|
| 2071 | + mmap_read_unlock(mm); |
---|
2060 | 2072 | return 0; |
---|
2061 | 2073 | } |
---|
2062 | 2074 | #endif /* CONFIG_CHECKPOINT_RESTORE */ |
---|
.. | .. |
---|
2095 | 2107 | unsigned long arg4, unsigned long arg5) |
---|
2096 | 2108 | { |
---|
2097 | 2109 | struct mm_struct *mm = current->mm; |
---|
2098 | | - struct prctl_mm_map prctl_map; |
---|
| 2110 | + struct prctl_mm_map prctl_map = { |
---|
| 2111 | + .auxv = NULL, |
---|
| 2112 | + .auxv_size = 0, |
---|
| 2113 | + .exe_fd = -1, |
---|
| 2114 | + }; |
---|
2099 | 2115 | struct vm_area_struct *vma; |
---|
2100 | 2116 | int error; |
---|
2101 | 2117 | |
---|
.. | .. |
---|
2123 | 2139 | |
---|
2124 | 2140 | error = -EINVAL; |
---|
2125 | 2141 | |
---|
2126 | | - down_write(&mm->mmap_sem); |
---|
| 2142 | + /* |
---|
| 2143 | + * arg_lock protects concurent updates of arg boundaries, we need |
---|
| 2144 | + * mmap_lock for a) concurrent sys_brk, b) finding VMA for addr |
---|
| 2145 | + * validation. |
---|
| 2146 | + */ |
---|
| 2147 | + mmap_read_lock(mm); |
---|
2127 | 2148 | vma = find_vma(mm, addr); |
---|
2128 | 2149 | |
---|
| 2150 | + spin_lock(&mm->arg_lock); |
---|
2129 | 2151 | prctl_map.start_code = mm->start_code; |
---|
2130 | 2152 | prctl_map.end_code = mm->end_code; |
---|
2131 | 2153 | prctl_map.start_data = mm->start_data; |
---|
.. | .. |
---|
2137 | 2159 | prctl_map.arg_end = mm->arg_end; |
---|
2138 | 2160 | prctl_map.env_start = mm->env_start; |
---|
2139 | 2161 | prctl_map.env_end = mm->env_end; |
---|
2140 | | - prctl_map.auxv = NULL; |
---|
2141 | | - prctl_map.auxv_size = 0; |
---|
2142 | | - prctl_map.exe_fd = -1; |
---|
2143 | 2162 | |
---|
2144 | 2163 | switch (opt) { |
---|
2145 | 2164 | case PR_SET_MM_START_CODE: |
---|
.. | .. |
---|
2179 | 2198 | goto out; |
---|
2180 | 2199 | } |
---|
2181 | 2200 | |
---|
2182 | | - error = validate_prctl_map(&prctl_map); |
---|
| 2201 | + error = validate_prctl_map_addr(&prctl_map); |
---|
2183 | 2202 | if (error) |
---|
2184 | 2203 | goto out; |
---|
2185 | 2204 | |
---|
.. | .. |
---|
2216 | 2235 | |
---|
2217 | 2236 | error = 0; |
---|
2218 | 2237 | out: |
---|
2219 | | - up_write(&mm->mmap_sem); |
---|
| 2238 | + spin_unlock(&mm->arg_lock); |
---|
| 2239 | + mmap_read_unlock(mm); |
---|
2220 | 2240 | return error; |
---|
2221 | 2241 | } |
---|
2222 | 2242 | |
---|
2223 | 2243 | #ifdef CONFIG_CHECKPOINT_RESTORE |
---|
2224 | | -static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr) |
---|
| 2244 | +static int prctl_get_tid_address(struct task_struct *me, int __user * __user *tid_addr) |
---|
2225 | 2245 | { |
---|
2226 | 2246 | return put_user(me->clear_child_tid, tid_addr); |
---|
2227 | 2247 | } |
---|
2228 | 2248 | #else |
---|
2229 | | -static int prctl_get_tid_address(struct task_struct *me, int __user **tid_addr) |
---|
| 2249 | +static int prctl_get_tid_address(struct task_struct *me, int __user * __user *tid_addr) |
---|
2230 | 2250 | { |
---|
2231 | 2251 | return -EINVAL; |
---|
2232 | 2252 | } |
---|
.. | .. |
---|
2358 | 2378 | return error; |
---|
2359 | 2379 | if (prev) |
---|
2360 | 2380 | vma = prev->vm_next; |
---|
2361 | | - else /* madvise_remove dropped mmap_sem */ |
---|
| 2381 | + else /* madvise_remove dropped mmap_lock */ |
---|
2362 | 2382 | vma = find_vma(current->mm, start); |
---|
2363 | 2383 | } |
---|
2364 | 2384 | } |
---|
.. | .. |
---|
2386 | 2406 | if (end == start) |
---|
2387 | 2407 | return 0; |
---|
2388 | 2408 | |
---|
2389 | | - down_write(&mm->mmap_sem); |
---|
| 2409 | + mmap_write_lock(mm); |
---|
2390 | 2410 | |
---|
2391 | 2411 | switch (opt) { |
---|
2392 | 2412 | case PR_SET_VMA_ANON_NAME: |
---|
.. | .. |
---|
2396 | 2416 | error = -EINVAL; |
---|
2397 | 2417 | } |
---|
2398 | 2418 | |
---|
2399 | | - up_write(&mm->mmap_sem); |
---|
| 2419 | + mmap_write_unlock(mm); |
---|
2400 | 2420 | |
---|
2401 | 2421 | return error; |
---|
2402 | 2422 | } |
---|
.. | .. |
---|
2407 | 2427 | return -EINVAL; |
---|
2408 | 2428 | } |
---|
2409 | 2429 | #endif |
---|
| 2430 | + |
---|
| 2431 | +#define PR_IO_FLUSHER (PF_MEMALLOC_NOIO | PF_LOCAL_THROTTLE) |
---|
2410 | 2432 | |
---|
2411 | 2433 | SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, |
---|
2412 | 2434 | unsigned long, arg4, unsigned long, arg5) |
---|
.. | .. |
---|
2555 | 2577 | error = prctl_set_mm(arg2, arg3, arg4, arg5); |
---|
2556 | 2578 | break; |
---|
2557 | 2579 | case PR_GET_TID_ADDRESS: |
---|
2558 | | - error = prctl_get_tid_address(me, (int __user **)arg2); |
---|
| 2580 | + error = prctl_get_tid_address(me, (int __user * __user *)arg2); |
---|
2559 | 2581 | break; |
---|
2560 | 2582 | case PR_SET_CHILD_SUBREAPER: |
---|
2561 | 2583 | me->signal->is_child_subreaper = !!arg2; |
---|
.. | .. |
---|
2586 | 2608 | case PR_SET_THP_DISABLE: |
---|
2587 | 2609 | if (arg3 || arg4 || arg5) |
---|
2588 | 2610 | return -EINVAL; |
---|
2589 | | - if (down_write_killable(&me->mm->mmap_sem)) |
---|
| 2611 | + if (mmap_write_lock_killable(me->mm)) |
---|
2590 | 2612 | return -EINTR; |
---|
2591 | 2613 | if (arg2) |
---|
2592 | 2614 | set_bit(MMF_DISABLE_THP, &me->mm->flags); |
---|
2593 | 2615 | else |
---|
2594 | 2616 | clear_bit(MMF_DISABLE_THP, &me->mm->flags); |
---|
2595 | | - up_write(&me->mm->mmap_sem); |
---|
| 2617 | + mmap_write_unlock(me->mm); |
---|
2596 | 2618 | break; |
---|
2597 | 2619 | case PR_MPX_ENABLE_MANAGEMENT: |
---|
2598 | | - if (arg2 || arg3 || arg4 || arg5) |
---|
2599 | | - return -EINVAL; |
---|
2600 | | - error = MPX_ENABLE_MANAGEMENT(); |
---|
2601 | | - break; |
---|
2602 | 2620 | case PR_MPX_DISABLE_MANAGEMENT: |
---|
2603 | | - if (arg2 || arg3 || arg4 || arg5) |
---|
2604 | | - return -EINVAL; |
---|
2605 | | - error = MPX_DISABLE_MANAGEMENT(); |
---|
2606 | | - break; |
---|
| 2621 | + /* No longer implemented: */ |
---|
| 2622 | + return -EINVAL; |
---|
2607 | 2623 | case PR_SET_FP_MODE: |
---|
2608 | 2624 | error = SET_FP_MODE(me, arg2); |
---|
2609 | 2625 | break; |
---|
.. | .. |
---|
2629 | 2645 | case PR_SET_VMA: |
---|
2630 | 2646 | error = prctl_set_vma(arg2, arg3, arg4, arg5); |
---|
2631 | 2647 | break; |
---|
| 2648 | + case PR_PAC_RESET_KEYS: |
---|
| 2649 | + if (arg3 || arg4 || arg5) |
---|
| 2650 | + return -EINVAL; |
---|
| 2651 | + error = PAC_RESET_KEYS(me, arg2); |
---|
| 2652 | + break; |
---|
| 2653 | + case PR_PAC_SET_ENABLED_KEYS: |
---|
| 2654 | + if (arg4 || arg5) |
---|
| 2655 | + return -EINVAL; |
---|
| 2656 | + error = PAC_SET_ENABLED_KEYS(me, arg2, arg3); |
---|
| 2657 | + break; |
---|
| 2658 | + case PR_PAC_GET_ENABLED_KEYS: |
---|
| 2659 | + if (arg2 || arg3 || arg4 || arg5) |
---|
| 2660 | + return -EINVAL; |
---|
| 2661 | + error = PAC_GET_ENABLED_KEYS(me); |
---|
| 2662 | + break; |
---|
2632 | 2663 | case PR_SET_TAGGED_ADDR_CTRL: |
---|
2633 | 2664 | if (arg3 || arg4 || arg5) |
---|
2634 | 2665 | return -EINVAL; |
---|
.. | .. |
---|
2639 | 2670 | return -EINVAL; |
---|
2640 | 2671 | error = GET_TAGGED_ADDR_CTRL(); |
---|
2641 | 2672 | break; |
---|
| 2673 | + case PR_SET_IO_FLUSHER: |
---|
| 2674 | + if (!capable(CAP_SYS_RESOURCE)) |
---|
| 2675 | + return -EPERM; |
---|
| 2676 | + |
---|
| 2677 | + if (arg3 || arg4 || arg5) |
---|
| 2678 | + return -EINVAL; |
---|
| 2679 | + |
---|
| 2680 | + if (arg2 == 1) |
---|
| 2681 | + current->flags |= PR_IO_FLUSHER; |
---|
| 2682 | + else if (!arg2) |
---|
| 2683 | + current->flags &= ~PR_IO_FLUSHER; |
---|
| 2684 | + else |
---|
| 2685 | + return -EINVAL; |
---|
| 2686 | + break; |
---|
| 2687 | + case PR_GET_IO_FLUSHER: |
---|
| 2688 | + if (!capable(CAP_SYS_RESOURCE)) |
---|
| 2689 | + return -EPERM; |
---|
| 2690 | + |
---|
| 2691 | + if (arg2 || arg3 || arg4 || arg5) |
---|
| 2692 | + return -EINVAL; |
---|
| 2693 | + |
---|
| 2694 | + error = (current->flags & PR_IO_FLUSHER) == PR_IO_FLUSHER; |
---|
| 2695 | + break; |
---|
2642 | 2696 | default: |
---|
2643 | 2697 | error = -EINVAL; |
---|
2644 | 2698 | break; |
---|
2645 | 2699 | } |
---|
| 2700 | + trace_android_vh_syscall_prctl_finished(option, me); |
---|
2646 | 2701 | return error; |
---|
2647 | 2702 | } |
---|
2648 | 2703 | |
---|
.. | .. |
---|
2672 | 2727 | memset(info, 0, sizeof(struct sysinfo)); |
---|
2673 | 2728 | |
---|
2674 | 2729 | ktime_get_boottime_ts64(&tp); |
---|
| 2730 | + timens_add_boottime(&tp); |
---|
2675 | 2731 | info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); |
---|
2676 | 2732 | |
---|
2677 | 2733 | get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT); |
---|
.. | .. |
---|
2758 | 2814 | COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info) |
---|
2759 | 2815 | { |
---|
2760 | 2816 | struct sysinfo s; |
---|
| 2817 | + struct compat_sysinfo s_32; |
---|
2761 | 2818 | |
---|
2762 | 2819 | do_sysinfo(&s); |
---|
2763 | 2820 | |
---|
.. | .. |
---|
2782 | 2839 | s.freehigh >>= bitcount; |
---|
2783 | 2840 | } |
---|
2784 | 2841 | |
---|
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)) |
---|
| 2842 | + memset(&s_32, 0, sizeof(s_32)); |
---|
| 2843 | + s_32.uptime = s.uptime; |
---|
| 2844 | + s_32.loads[0] = s.loads[0]; |
---|
| 2845 | + s_32.loads[1] = s.loads[1]; |
---|
| 2846 | + s_32.loads[2] = s.loads[2]; |
---|
| 2847 | + s_32.totalram = s.totalram; |
---|
| 2848 | + s_32.freeram = s.freeram; |
---|
| 2849 | + s_32.sharedram = s.sharedram; |
---|
| 2850 | + s_32.bufferram = s.bufferram; |
---|
| 2851 | + s_32.totalswap = s.totalswap; |
---|
| 2852 | + s_32.freeswap = s.freeswap; |
---|
| 2853 | + s_32.procs = s.procs; |
---|
| 2854 | + s_32.totalhigh = s.totalhigh; |
---|
| 2855 | + s_32.freehigh = s.freehigh; |
---|
| 2856 | + s_32.mem_unit = s.mem_unit; |
---|
| 2857 | + if (copy_to_user(info, &s_32, sizeof(s_32))) |
---|
2800 | 2858 | return -EFAULT; |
---|
2801 | | - |
---|
2802 | 2859 | return 0; |
---|
2803 | 2860 | } |
---|
2804 | 2861 | #endif /* CONFIG_COMPAT */ |
---|