aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/compat.c')
-rw-r--r--kernel/compat.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index f6c204f07ea6..5adab05a3172 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -25,6 +25,7 @@
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#include <linux/ptrace.h>
28#include <linux/gfp.h>
28 29
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30 31
@@ -494,29 +495,26 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
494{ 495{
495 int ret; 496 int ret;
496 cpumask_var_t mask; 497 cpumask_var_t mask;
497 unsigned long *k;
498 unsigned int min_length = cpumask_size();
499
500 if (nr_cpu_ids <= BITS_PER_COMPAT_LONG)
501 min_length = sizeof(compat_ulong_t);
502 498
503 if (len < min_length) 499 if ((len * BITS_PER_BYTE) < nr_cpu_ids)
500 return -EINVAL;
501 if (len & (sizeof(compat_ulong_t)-1))
504 return -EINVAL; 502 return -EINVAL;
505 503
506 if (!alloc_cpumask_var(&mask, GFP_KERNEL)) 504 if (!alloc_cpumask_var(&mask, GFP_KERNEL))
507 return -ENOMEM; 505 return -ENOMEM;
508 506
509 ret = sched_getaffinity(pid, mask); 507 ret = sched_getaffinity(pid, mask);
510 if (ret < 0) 508 if (ret == 0) {
511 goto out; 509 size_t retlen = min_t(size_t, len, cpumask_size());
512 510
513 k = cpumask_bits(mask); 511 if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
514 ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8); 512 ret = -EFAULT;
515 if (ret == 0) 513 else
516 ret = min_length; 514 ret = retlen;
517 515 }
518out:
519 free_cpumask_var(mask); 516 free_cpumask_var(mask);
517
520 return ret; 518 return ret;
521} 519}
522 520