hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
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);
....@@ -651,7 +665,7 @@
651665 old = current_cred();
652666
653667 retval = -EPERM;
654
- if (!ns_capable(old->user_ns, CAP_SETUID)) {
668
+ if (!ns_capable_setid(old->user_ns, CAP_SETUID)) {
655669 if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
656670 !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
657671 goto error;
....@@ -740,7 +754,7 @@
740754 old = current_cred();
741755
742756 retval = -EPERM;
743
- if (!ns_capable(old->user_ns, CAP_SETGID)) {
757
+ if (!ns_capable_setid(old->user_ns, CAP_SETGID)) {
744758 if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
745759 !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
746760 goto error;
....@@ -759,6 +773,10 @@
759773 if (sgid != (gid_t) -1)
760774 new->sgid = ksgid;
761775 new->fsgid = new->egid;
776
+
777
+ retval = security_task_fix_setgid(new, old, LSM_SETID_RES);
778
+ if (retval < 0)
779
+ goto error;
762780
763781 return commit_creds(new);
764782
....@@ -819,7 +837,7 @@
819837
820838 if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) ||
821839 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)) {
823841 if (!uid_eq(kuid, old->fsuid)) {
824842 new->fsuid = kuid;
825843 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
....@@ -863,10 +881,11 @@
863881
864882 if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
865883 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)) {
867885 if (!gid_eq(kgid, old->fsgid)) {
868886 new->fsgid = kgid;
869
- goto change_okay;
887
+ if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0)
888
+ goto change_okay;
870889 }
871890 }
872891
....@@ -1212,7 +1231,8 @@
12121231 /*
12131232 * Work around broken programs that cannot handle "Linux 3.0".
12141233 * 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.
12161236 */
12171237 static int override_release(char __user *release, size_t len)
12181238 {
....@@ -1563,15 +1583,6 @@
15631583 retval = -EPERM;
15641584 if (!retval)
15651585 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
- }
15751586 }
15761587 if (!retval) {
15771588 if (old_rlim)
....@@ -1582,10 +1593,9 @@
15821593 task_unlock(tsk->group_leader);
15831594
15841595 /*
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.
15891599 */
15901600 if (!retval && new_rlim && resource == RLIMIT_CPU &&
15911601 new_rlim->rlim_cur != RLIM_INFINITY &&
....@@ -1753,6 +1763,7 @@
17531763
17541764 if (who == RUSAGE_CHILDREN)
17551765 break;
1766
+ fallthrough;
17561767
17571768 case RUSAGE_SELF:
17581769 thread_group_cputime_adjusted(p, &tgutime, &tgstime);
....@@ -1778,8 +1789,8 @@
17781789 unlock_task_sighand(p, &flags);
17791790
17801791 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);
17831794
17841795 if (who != RUSAGE_CHILDREN) {
17851796 struct mm_struct *mm = get_task_mm(p);
....@@ -1858,7 +1869,7 @@
18581869 if (exe_file) {
18591870 struct vm_area_struct *vma;
18601871
1861
- down_read(&mm->mmap_sem);
1872
+ mmap_read_lock(mm);
18621873 for (vma = mm->mmap; vma; vma = vma->vm_next) {
18631874 if (!vma->vm_file)
18641875 continue;
....@@ -1867,7 +1878,7 @@
18671878 goto exit_err;
18681879 }
18691880
1870
- up_read(&mm->mmap_sem);
1881
+ mmap_read_unlock(mm);
18711882 fput(exe_file);
18721883 }
18731884
....@@ -1881,19 +1892,20 @@
18811892 fdput(exe);
18821893 return err;
18831894 exit_err:
1884
- up_read(&mm->mmap_sem);
1895
+ mmap_read_unlock(mm);
18851896 fput(exe_file);
18861897 goto exit;
18871898 }
18881899
18891900 /*
1901
+ * Check arithmetic relations of passed addresses.
1902
+ *
18901903 * WARNING: we don't require any capability here so be very careful
18911904 * in what is allowed for modification from userspace.
18921905 */
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)
18941907 {
18951908 unsigned long mmap_max_addr = TASK_SIZE;
1896
- struct mm_struct *mm = current->mm;
18971909 int error = -EINVAL, i;
18981910
18991911 static const unsigned char offsets[] = {
....@@ -1947,24 +1959,6 @@
19471959 prctl_map->start_data))
19481960 goto out;
19491961
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
-
19681962 error = 0;
19691963 out:
19701964 return error;
....@@ -1991,11 +1985,18 @@
19911985 if (copy_from_user(&prctl_map, addr, sizeof(prctl_map)))
19921986 return -EFAULT;
19931987
1994
- error = validate_prctl_map(&prctl_map);
1988
+ error = validate_prctl_map_addr(&prctl_map);
19951989 if (error)
19961990 return error;
19971991
19981992 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
+
19992000 memset(user_auxv, 0, sizeof(user_auxv));
20002001 if (copy_from_user(user_auxv,
20012002 (const void __user *)prctl_map.auxv,
....@@ -2008,16 +2009,27 @@
20082009 }
20092010
20102011 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
+
20112023 error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
20122024 if (error)
20132025 return error;
20142026 }
20152027
20162028 /*
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
20182030 * read to exclude races with sys_brk.
20192031 */
2020
- down_read(&mm->mmap_sem);
2032
+ mmap_read_lock(mm);
20212033
20222034 /*
20232035 * We don't validate if these members are pointing to
....@@ -2025,7 +2037,7 @@
20252037 * VMAs already unmapped and kernel uses these members for statistics
20262038 * output in procfs mostly, except
20272039 *
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
20292041 * for VMAs when updating these memvers so anything wrong written
20302042 * here cause kernel to swear at userspace program but won't lead
20312043 * to any problem in kernel itself
....@@ -2056,7 +2068,7 @@
20562068 if (prctl_map.auxv_size)
20572069 memcpy(mm->saved_auxv, user_auxv, sizeof(user_auxv));
20582070
2059
- up_read(&mm->mmap_sem);
2071
+ mmap_read_unlock(mm);
20602072 return 0;
20612073 }
20622074 #endif /* CONFIG_CHECKPOINT_RESTORE */
....@@ -2095,7 +2107,11 @@
20952107 unsigned long arg4, unsigned long arg5)
20962108 {
20972109 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
+ };
20992115 struct vm_area_struct *vma;
21002116 int error;
21012117
....@@ -2123,9 +2139,15 @@
21232139
21242140 error = -EINVAL;
21252141
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);
21272148 vma = find_vma(mm, addr);
21282149
2150
+ spin_lock(&mm->arg_lock);
21292151 prctl_map.start_code = mm->start_code;
21302152 prctl_map.end_code = mm->end_code;
21312153 prctl_map.start_data = mm->start_data;
....@@ -2137,9 +2159,6 @@
21372159 prctl_map.arg_end = mm->arg_end;
21382160 prctl_map.env_start = mm->env_start;
21392161 prctl_map.env_end = mm->env_end;
2140
- prctl_map.auxv = NULL;
2141
- prctl_map.auxv_size = 0;
2142
- prctl_map.exe_fd = -1;
21432162
21442163 switch (opt) {
21452164 case PR_SET_MM_START_CODE:
....@@ -2179,7 +2198,7 @@
21792198 goto out;
21802199 }
21812200
2182
- error = validate_prctl_map(&prctl_map);
2201
+ error = validate_prctl_map_addr(&prctl_map);
21832202 if (error)
21842203 goto out;
21852204
....@@ -2216,17 +2235,18 @@
22162235
22172236 error = 0;
22182237 out:
2219
- up_write(&mm->mmap_sem);
2238
+ spin_unlock(&mm->arg_lock);
2239
+ mmap_read_unlock(mm);
22202240 return error;
22212241 }
22222242
22232243 #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)
22252245 {
22262246 return put_user(me->clear_child_tid, tid_addr);
22272247 }
22282248 #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)
22302250 {
22312251 return -EINVAL;
22322252 }
....@@ -2358,7 +2378,7 @@
23582378 return error;
23592379 if (prev)
23602380 vma = prev->vm_next;
2361
- else /* madvise_remove dropped mmap_sem */
2381
+ else /* madvise_remove dropped mmap_lock */
23622382 vma = find_vma(current->mm, start);
23632383 }
23642384 }
....@@ -2386,7 +2406,7 @@
23862406 if (end == start)
23872407 return 0;
23882408
2389
- down_write(&mm->mmap_sem);
2409
+ mmap_write_lock(mm);
23902410
23912411 switch (opt) {
23922412 case PR_SET_VMA_ANON_NAME:
....@@ -2396,7 +2416,7 @@
23962416 error = -EINVAL;
23972417 }
23982418
2399
- up_write(&mm->mmap_sem);
2419
+ mmap_write_unlock(mm);
24002420
24012421 return error;
24022422 }
....@@ -2407,6 +2427,8 @@
24072427 return -EINVAL;
24082428 }
24092429 #endif
2430
+
2431
+#define PR_IO_FLUSHER (PF_MEMALLOC_NOIO | PF_LOCAL_THROTTLE)
24102432
24112433 SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
24122434 unsigned long, arg4, unsigned long, arg5)
....@@ -2555,7 +2577,7 @@
25552577 error = prctl_set_mm(arg2, arg3, arg4, arg5);
25562578 break;
25572579 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);
25592581 break;
25602582 case PR_SET_CHILD_SUBREAPER:
25612583 me->signal->is_child_subreaper = !!arg2;
....@@ -2586,24 +2608,18 @@
25862608 case PR_SET_THP_DISABLE:
25872609 if (arg3 || arg4 || arg5)
25882610 return -EINVAL;
2589
- if (down_write_killable(&me->mm->mmap_sem))
2611
+ if (mmap_write_lock_killable(me->mm))
25902612 return -EINTR;
25912613 if (arg2)
25922614 set_bit(MMF_DISABLE_THP, &me->mm->flags);
25932615 else
25942616 clear_bit(MMF_DISABLE_THP, &me->mm->flags);
2595
- up_write(&me->mm->mmap_sem);
2617
+ mmap_write_unlock(me->mm);
25962618 break;
25972619 case PR_MPX_ENABLE_MANAGEMENT:
2598
- if (arg2 || arg3 || arg4 || arg5)
2599
- return -EINVAL;
2600
- error = MPX_ENABLE_MANAGEMENT();
2601
- break;
26022620 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;
26072623 case PR_SET_FP_MODE:
26082624 error = SET_FP_MODE(me, arg2);
26092625 break;
....@@ -2629,6 +2645,21 @@
26292645 case PR_SET_VMA:
26302646 error = prctl_set_vma(arg2, arg3, arg4, arg5);
26312647 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;
26322663 case PR_SET_TAGGED_ADDR_CTRL:
26332664 if (arg3 || arg4 || arg5)
26342665 return -EINVAL;
....@@ -2639,10 +2670,34 @@
26392670 return -EINVAL;
26402671 error = GET_TAGGED_ADDR_CTRL();
26412672 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;
26422696 default:
26432697 error = -EINVAL;
26442698 break;
26452699 }
2700
+ trace_android_vh_syscall_prctl_finished(option, me);
26462701 return error;
26472702 }
26482703
....@@ -2672,6 +2727,7 @@
26722727 memset(info, 0, sizeof(struct sysinfo));
26732728
26742729 ktime_get_boottime_ts64(&tp);
2730
+ timens_add_boottime(&tp);
26752731 info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
26762732
26772733 get_avenrun(info->loads, 0, SI_LOAD_SHIFT - FSHIFT);
....@@ -2758,6 +2814,7 @@
27582814 COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info)
27592815 {
27602816 struct sysinfo s;
2817
+ struct compat_sysinfo s_32;
27612818
27622819 do_sysinfo(&s);
27632820
....@@ -2782,23 +2839,23 @@
27822839 s.freehigh >>= bitcount;
27832840 }
27842841
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)))
28002858 return -EFAULT;
2801
-
28022859 return 0;
28032860 }
28042861 #endif /* CONFIG_COMPAT */