diff options
Diffstat (limited to 'kernel/compat.c')
-rw-r--r-- | kernel/compat.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index 8eafe3eb50d9..42d56544460f 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/migrate.h> | 24 | #include <linux/migrate.h> |
25 | #include <linux/posix-timers.h> | 25 | #include <linux/posix-timers.h> |
26 | #include <linux/times.h> | 26 | #include <linux/times.h> |
27 | #include <linux/ptrace.h> | ||
27 | 28 | ||
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
29 | 30 | ||
@@ -229,6 +230,7 @@ asmlinkage long compat_sys_times(struct compat_tms __user *tbuf) | |||
229 | if (copy_to_user(tbuf, &tmp, sizeof(tmp))) | 230 | if (copy_to_user(tbuf, &tmp, sizeof(tmp))) |
230 | return -EFAULT; | 231 | return -EFAULT; |
231 | } | 232 | } |
233 | force_successful_syscall_return(); | ||
232 | return compat_jiffies_to_clock_t(jiffies); | 234 | return compat_jiffies_to_clock_t(jiffies); |
233 | } | 235 | } |
234 | 236 | ||
@@ -454,16 +456,16 @@ asmlinkage long compat_sys_waitid(int which, compat_pid_t pid, | |||
454 | } | 456 | } |
455 | 457 | ||
456 | static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr, | 458 | static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr, |
457 | unsigned len, cpumask_t *new_mask) | 459 | unsigned len, struct cpumask *new_mask) |
458 | { | 460 | { |
459 | unsigned long *k; | 461 | unsigned long *k; |
460 | 462 | ||
461 | if (len < sizeof(cpumask_t)) | 463 | if (len < cpumask_size()) |
462 | memset(new_mask, 0, sizeof(cpumask_t)); | 464 | memset(new_mask, 0, cpumask_size()); |
463 | else if (len > sizeof(cpumask_t)) | 465 | else if (len > cpumask_size()) |
464 | len = sizeof(cpumask_t); | 466 | len = cpumask_size(); |
465 | 467 | ||
466 | k = cpus_addr(*new_mask); | 468 | k = cpumask_bits(new_mask); |
467 | return compat_get_bitmap(k, user_mask_ptr, len * 8); | 469 | return compat_get_bitmap(k, user_mask_ptr, len * 8); |
468 | } | 470 | } |
469 | 471 | ||
@@ -471,40 +473,51 @@ asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, | |||
471 | unsigned int len, | 473 | unsigned int len, |
472 | compat_ulong_t __user *user_mask_ptr) | 474 | compat_ulong_t __user *user_mask_ptr) |
473 | { | 475 | { |
474 | cpumask_t new_mask; | 476 | cpumask_var_t new_mask; |
475 | int retval; | 477 | int retval; |
476 | 478 | ||
477 | retval = compat_get_user_cpu_mask(user_mask_ptr, len, &new_mask); | 479 | if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) |
480 | return -ENOMEM; | ||
481 | |||
482 | retval = compat_get_user_cpu_mask(user_mask_ptr, len, new_mask); | ||
478 | if (retval) | 483 | if (retval) |
479 | return retval; | 484 | goto out; |
480 | 485 | ||
481 | return sched_setaffinity(pid, &new_mask); | 486 | retval = sched_setaffinity(pid, new_mask); |
487 | out: | ||
488 | free_cpumask_var(new_mask); | ||
489 | return retval; | ||
482 | } | 490 | } |
483 | 491 | ||
484 | asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, | 492 | asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, |
485 | compat_ulong_t __user *user_mask_ptr) | 493 | compat_ulong_t __user *user_mask_ptr) |
486 | { | 494 | { |
487 | int ret; | 495 | int ret; |
488 | cpumask_t mask; | 496 | cpumask_var_t mask; |
489 | unsigned long *k; | 497 | unsigned long *k; |
490 | unsigned int min_length = sizeof(cpumask_t); | 498 | unsigned int min_length = cpumask_size(); |
491 | 499 | ||
492 | if (NR_CPUS <= BITS_PER_COMPAT_LONG) | 500 | if (nr_cpu_ids <= BITS_PER_COMPAT_LONG) |
493 | min_length = sizeof(compat_ulong_t); | 501 | min_length = sizeof(compat_ulong_t); |
494 | 502 | ||
495 | if (len < min_length) | 503 | if (len < min_length) |
496 | return -EINVAL; | 504 | return -EINVAL; |
497 | 505 | ||
498 | ret = sched_getaffinity(pid, &mask); | 506 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) |
507 | return -ENOMEM; | ||
508 | |||
509 | ret = sched_getaffinity(pid, mask); | ||
499 | if (ret < 0) | 510 | if (ret < 0) |
500 | return ret; | 511 | goto out; |
501 | 512 | ||
502 | k = cpus_addr(mask); | 513 | k = cpumask_bits(mask); |
503 | ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8); | 514 | ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8); |
504 | if (ret) | 515 | if (ret == 0) |
505 | return ret; | 516 | ret = min_length; |
506 | 517 | ||
507 | return min_length; | 518 | out: |
519 | free_cpumask_var(mask); | ||
520 | return ret; | ||
508 | } | 521 | } |
509 | 522 | ||
510 | int get_compat_itimerspec(struct itimerspec *dst, | 523 | int get_compat_itimerspec(struct itimerspec *dst, |
@@ -883,8 +896,9 @@ asmlinkage long compat_sys_time(compat_time_t __user * tloc) | |||
883 | 896 | ||
884 | if (tloc) { | 897 | if (tloc) { |
885 | if (put_user(i,tloc)) | 898 | if (put_user(i,tloc)) |
886 | i = -EFAULT; | 899 | return -EFAULT; |
887 | } | 900 | } |
901 | force_successful_syscall_return(); | ||
888 | return i; | 902 | return i; |
889 | } | 903 | } |
890 | 904 | ||