diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-06 23:57:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-06 23:57:13 -0400 |
commit | c856863988ebf612d159e55eeddbcd27de63b40d (patch) | |
tree | 88ce68d58f66679aabe029a93230280191b58d32 /kernel/sys.c | |
parent | 771d3feb4b79f8569bf0033b9075a434d0365fa2 (diff) | |
parent | 0d0606060baefdb13d3d80dba1b4c816b0676e16 (diff) |
Merge branch 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc compat stuff updates from Al Viro:
"This part is basically untangling various compat stuff. Compat
syscalls moved to their native counterparts, getting rid of quite a
bit of double-copying and/or set_fs() uses. A lot of field-by-field
copyin/copyout killed off.
- kernel/compat.c is much closer to containing just the
copyin/copyout of compat structs. Not all compat syscalls are gone
from it yet, but it's getting there.
- ipc/compat_mq.c killed off completely.
- block/compat_ioctl.c cleaned up; floppy compat ioctls moved to
drivers/block/floppy.c where they belong. Yes, there are several
drivers that implement some of the same ioctls. Some are m68k and
one is 32bit-only pmac. drivers/block/floppy.c is the only one in
that bunch that can be built on biarch"
* 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
mqueue: move compat syscalls to native ones
usbdevfs: get rid of field-by-field copyin
compat_hdio_ioctl: get rid of set_fs()
take floppy compat ioctls to sodding floppy.c
ipmi: get rid of field-by-field __get_user()
ipmi: get COMPAT_IPMICTL_RECEIVE_MSG in sync with the native one
rt_sigtimedwait(): move compat to native
select: switch compat_{get,put}_fd_set() to compat_{get,put}_bitmap()
put_compat_rusage(): switch to copy_to_user()
sigpending(): move compat to native
getrlimit()/setrlimit(): move compat to native
times(2): move compat to native
compat_{get,put}_bitmap(): use unsafe_{get,put}_user()
fb_get_fscreeninfo(): don't bother with do_fb_ioctl()
do_sigaltstack(): lift copying to/from userland into callers
take compat_sys_old_getrlimit() to native syscall
trim __ARCH_WANT_SYS_OLD_GETRLIMIT
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 100 |
1 files changed, 99 insertions, 1 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index dab1a0658a92..47d901586b4e 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 | ||
889 | void do_sys_times(struct tms *tms) | 889 | static 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 | ||
916 | static 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 | |||
921 | COMPAT_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 | |||
1337 | COMPAT_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 | |||
1357 | COMPAT_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 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 | ||
1406 | COMPAT_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 | ||
1333 | static inline bool rlim64_is_infinity(__u64 rlim64) | 1431 | static inline bool rlim64_is_infinity(__u64 rlim64) |