aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c122
1 files changed, 108 insertions, 14 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 8a94b4eabcaa..2855ee73acd0 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -886,7 +886,7 @@ SYSCALL_DEFINE0(getegid)
886 return from_kgid_munged(current_user_ns(), current_egid()); 886 return from_kgid_munged(current_user_ns(), current_egid());
887} 887}
888 888
889void do_sys_times(struct tms *tms) 889static void do_sys_times(struct tms *tms)
890{ 890{
891 u64 tgutime, tgstime, cutime, cstime; 891 u64 tgutime, tgstime, cutime, cstime;
892 892
@@ -912,6 +912,32 @@ SYSCALL_DEFINE1(times, struct tms __user *, tbuf)
912 return (long) jiffies_64_to_clock_t(get_jiffies_64()); 912 return (long) jiffies_64_to_clock_t(get_jiffies_64());
913} 913}
914 914
915#ifdef CONFIG_COMPAT
916static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
917{
918 return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
919}
920
921COMPAT_SYSCALL_DEFINE1(times, struct compat_tms __user *, tbuf)
922{
923 if (tbuf) {
924 struct tms tms;
925 struct compat_tms tmp;
926
927 do_sys_times(&tms);
928 /* Convert our struct tms to the compat version. */
929 tmp.tms_utime = clock_t_to_compat_clock_t(tms.tms_utime);
930 tmp.tms_stime = clock_t_to_compat_clock_t(tms.tms_stime);
931 tmp.tms_cutime = clock_t_to_compat_clock_t(tms.tms_cutime);
932 tmp.tms_cstime = clock_t_to_compat_clock_t(tms.tms_cstime);
933 if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
934 return -EFAULT;
935 }
936 force_successful_syscall_return();
937 return compat_jiffies_to_clock_t(jiffies);
938}
939#endif
940
915/* 941/*
916 * This needs some heavy checking ... 942 * This needs some heavy checking ...
917 * I just haven't the stomach for it. I also don't fully 943 * I just haven't the stomach for it. I also don't fully
@@ -1306,6 +1332,54 @@ SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim)
1306 return ret; 1332 return ret;
1307} 1333}
1308 1334
1335#ifdef CONFIG_COMPAT
1336
1337COMPAT_SYSCALL_DEFINE2(setrlimit, unsigned int, resource,
1338 struct compat_rlimit __user *, rlim)
1339{
1340 struct rlimit r;
1341 struct compat_rlimit r32;
1342
1343 if (copy_from_user(&r32, rlim, sizeof(struct compat_rlimit)))
1344 return -EFAULT;
1345
1346 if (r32.rlim_cur == COMPAT_RLIM_INFINITY)
1347 r.rlim_cur = RLIM_INFINITY;
1348 else
1349 r.rlim_cur = r32.rlim_cur;
1350 if (r32.rlim_max == COMPAT_RLIM_INFINITY)
1351 r.rlim_max = RLIM_INFINITY;
1352 else
1353 r.rlim_max = r32.rlim_max;
1354 return do_prlimit(current, resource, &r, NULL);
1355}
1356
1357COMPAT_SYSCALL_DEFINE2(getrlimit, unsigned int, resource,
1358 struct compat_rlimit __user *, rlim)
1359{
1360 struct rlimit r;
1361 int ret;
1362
1363 ret = do_prlimit(current, resource, NULL, &r);
1364 if (!ret) {
1365 struct compat_rlimit r32;
1366 if (r.rlim_cur > COMPAT_RLIM_INFINITY)
1367 r32.rlim_cur = COMPAT_RLIM_INFINITY;
1368 else
1369 r32.rlim_cur = r.rlim_cur;
1370 if (r.rlim_max > COMPAT_RLIM_INFINITY)
1371 r32.rlim_max = COMPAT_RLIM_INFINITY;
1372 else
1373 r32.rlim_max = r.rlim_max;
1374
1375 if (copy_to_user(rlim, &r32, sizeof(struct compat_rlimit)))
1376 return -EFAULT;
1377 }
1378 return ret;
1379}
1380
1381#endif
1382
1309#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT 1383#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
1310 1384
1311/* 1385/*
@@ -1328,6 +1402,30 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
1328 return copy_to_user(rlim, &x, sizeof(x)) ? -EFAULT : 0; 1402 return copy_to_user(rlim, &x, sizeof(x)) ? -EFAULT : 0;
1329} 1403}
1330 1404
1405#ifdef CONFIG_COMPAT
1406COMPAT_SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
1407 struct compat_rlimit __user *, rlim)
1408{
1409 struct rlimit r;
1410
1411 if (resource >= RLIM_NLIMITS)
1412 return -EINVAL;
1413
1414 task_lock(current->group_leader);
1415 r = current->signal->rlim[resource];
1416 task_unlock(current->group_leader);
1417 if (r.rlim_cur > 0x7FFFFFFF)
1418 r.rlim_cur = 0x7FFFFFFF;
1419 if (r.rlim_max > 0x7FFFFFFF)
1420 r.rlim_max = 0x7FFFFFFF;
1421
1422 if (put_user(r.rlim_cur, &rlim->rlim_cur) ||
1423 put_user(r.rlim_max, &rlim->rlim_max))
1424 return -EFAULT;
1425 return 0;
1426}
1427#endif
1428
1331#endif 1429#endif
1332 1430
1333static inline bool rlim64_is_infinity(__u64 rlim64) 1431static inline bool rlim64_is_infinity(__u64 rlim64)
@@ -1552,7 +1650,7 @@ static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r)
1552 r->ru_oublock += task_io_get_oublock(t); 1650 r->ru_oublock += task_io_get_oublock(t);
1553} 1651}
1554 1652
1555static void k_getrusage(struct task_struct *p, int who, struct rusage *r) 1653void getrusage(struct task_struct *p, int who, struct rusage *r)
1556{ 1654{
1557 struct task_struct *t; 1655 struct task_struct *t;
1558 unsigned long flags; 1656 unsigned long flags;
@@ -1626,20 +1724,16 @@ out:
1626 r->ru_maxrss = maxrss * (PAGE_SIZE / 1024); /* convert pages to KBs */ 1724 r->ru_maxrss = maxrss * (PAGE_SIZE / 1024); /* convert pages to KBs */
1627} 1725}
1628 1726
1629int getrusage(struct task_struct *p, int who, struct rusage __user *ru) 1727SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru)
1630{ 1728{
1631 struct rusage r; 1729 struct rusage r;
1632 1730
1633 k_getrusage(p, who, &r);
1634 return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
1635}
1636
1637SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru)
1638{
1639 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN && 1731 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN &&
1640 who != RUSAGE_THREAD) 1732 who != RUSAGE_THREAD)
1641 return -EINVAL; 1733 return -EINVAL;
1642 return getrusage(current, who, ru); 1734
1735 getrusage(current, who, &r);
1736 return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
1643} 1737}
1644 1738
1645#ifdef CONFIG_COMPAT 1739#ifdef CONFIG_COMPAT
@@ -1651,7 +1745,7 @@ COMPAT_SYSCALL_DEFINE2(getrusage, int, who, struct compat_rusage __user *, ru)
1651 who != RUSAGE_THREAD) 1745 who != RUSAGE_THREAD)
1652 return -EINVAL; 1746 return -EINVAL;
1653 1747
1654 k_getrusage(current, who, &r); 1748 getrusage(current, who, &r);
1655 return put_compat_rusage(&r, ru); 1749 return put_compat_rusage(&r, ru);
1656} 1750}
1657#endif 1751#endif
@@ -2266,7 +2360,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
2266 case PR_GET_THP_DISABLE: 2360 case PR_GET_THP_DISABLE:
2267 if (arg2 || arg3 || arg4 || arg5) 2361 if (arg2 || arg3 || arg4 || arg5)
2268 return -EINVAL; 2362 return -EINVAL;
2269 error = !!(me->mm->def_flags & VM_NOHUGEPAGE); 2363 error = !!test_bit(MMF_DISABLE_THP, &me->mm->flags);
2270 break; 2364 break;
2271 case PR_SET_THP_DISABLE: 2365 case PR_SET_THP_DISABLE:
2272 if (arg3 || arg4 || arg5) 2366 if (arg3 || arg4 || arg5)
@@ -2274,9 +2368,9 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
2274 if (down_write_killable(&me->mm->mmap_sem)) 2368 if (down_write_killable(&me->mm->mmap_sem))
2275 return -EINTR; 2369 return -EINTR;
2276 if (arg2) 2370 if (arg2)
2277 me->mm->def_flags |= VM_NOHUGEPAGE; 2371 set_bit(MMF_DISABLE_THP, &me->mm->flags);
2278 else 2372 else
2279 me->mm->def_flags &= ~VM_NOHUGEPAGE; 2373 clear_bit(MMF_DISABLE_THP, &me->mm->flags);
2280 up_write(&me->mm->mmap_sem); 2374 up_write(&me->mm->mmap_sem);
2281 break; 2375 break;
2282 case PR_MPX_ENABLE_MANAGEMENT: 2376 case PR_MPX_ENABLE_MANAGEMENT: