diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/events/core.c | 70 | ||||
-rw-r--r-- | kernel/sys.c | 16 | ||||
-rw-r--r-- | kernel/taskstats.c | 11 |
3 files changed, 43 insertions, 54 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 2bd199bfaef..bd9c5bca42a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -467,14 +467,13 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, | |||
467 | { | 467 | { |
468 | struct perf_cgroup *cgrp; | 468 | struct perf_cgroup *cgrp; |
469 | struct cgroup_subsys_state *css; | 469 | struct cgroup_subsys_state *css; |
470 | struct file *file; | 470 | struct fd f = fdget(fd); |
471 | int ret = 0, fput_needed; | 471 | int ret = 0; |
472 | 472 | ||
473 | file = fget_light(fd, &fput_needed); | 473 | if (!f.file) |
474 | if (!file) | ||
475 | return -EBADF; | 474 | return -EBADF; |
476 | 475 | ||
477 | css = cgroup_css_from_dir(file, perf_subsys_id); | 476 | css = cgroup_css_from_dir(f.file, perf_subsys_id); |
478 | if (IS_ERR(css)) { | 477 | if (IS_ERR(css)) { |
479 | ret = PTR_ERR(css); | 478 | ret = PTR_ERR(css); |
480 | goto out; | 479 | goto out; |
@@ -500,7 +499,7 @@ static inline int perf_cgroup_connect(int fd, struct perf_event *event, | |||
500 | ret = -EINVAL; | 499 | ret = -EINVAL; |
501 | } | 500 | } |
502 | out: | 501 | out: |
503 | fput_light(file, fput_needed); | 502 | fdput(f); |
504 | return ret; | 503 | return ret; |
505 | } | 504 | } |
506 | 505 | ||
@@ -3233,21 +3232,18 @@ unlock: | |||
3233 | 3232 | ||
3234 | static const struct file_operations perf_fops; | 3233 | static const struct file_operations perf_fops; |
3235 | 3234 | ||
3236 | static struct file *perf_fget_light(int fd, int *fput_needed) | 3235 | static inline int perf_fget_light(int fd, struct fd *p) |
3237 | { | 3236 | { |
3238 | struct file *file; | 3237 | struct fd f = fdget(fd); |
3239 | 3238 | if (!f.file) | |
3240 | file = fget_light(fd, fput_needed); | 3239 | return -EBADF; |
3241 | if (!file) | ||
3242 | return ERR_PTR(-EBADF); | ||
3243 | 3240 | ||
3244 | if (file->f_op != &perf_fops) { | 3241 | if (f.file->f_op != &perf_fops) { |
3245 | fput_light(file, *fput_needed); | 3242 | fdput(f); |
3246 | *fput_needed = 0; | 3243 | return -EBADF; |
3247 | return ERR_PTR(-EBADF); | ||
3248 | } | 3244 | } |
3249 | 3245 | *p = f; | |
3250 | return file; | 3246 | return 0; |
3251 | } | 3247 | } |
3252 | 3248 | ||
3253 | static int perf_event_set_output(struct perf_event *event, | 3249 | static int perf_event_set_output(struct perf_event *event, |
@@ -3279,22 +3275,19 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3279 | 3275 | ||
3280 | case PERF_EVENT_IOC_SET_OUTPUT: | 3276 | case PERF_EVENT_IOC_SET_OUTPUT: |
3281 | { | 3277 | { |
3282 | struct file *output_file = NULL; | ||
3283 | struct perf_event *output_event = NULL; | ||
3284 | int fput_needed = 0; | ||
3285 | int ret; | 3278 | int ret; |
3286 | |||
3287 | if (arg != -1) { | 3279 | if (arg != -1) { |
3288 | output_file = perf_fget_light(arg, &fput_needed); | 3280 | struct perf_event *output_event; |
3289 | if (IS_ERR(output_file)) | 3281 | struct fd output; |
3290 | return PTR_ERR(output_file); | 3282 | ret = perf_fget_light(arg, &output); |
3291 | output_event = output_file->private_data; | 3283 | if (ret) |
3284 | return ret; | ||
3285 | output_event = output.file->private_data; | ||
3286 | ret = perf_event_set_output(event, output_event); | ||
3287 | fdput(output); | ||
3288 | } else { | ||
3289 | ret = perf_event_set_output(event, NULL); | ||
3292 | } | 3290 | } |
3293 | |||
3294 | ret = perf_event_set_output(event, output_event); | ||
3295 | if (output_event) | ||
3296 | fput_light(output_file, fput_needed); | ||
3297 | |||
3298 | return ret; | 3291 | return ret; |
3299 | } | 3292 | } |
3300 | 3293 | ||
@@ -6229,12 +6222,11 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6229 | struct perf_event_attr attr; | 6222 | struct perf_event_attr attr; |
6230 | struct perf_event_context *ctx; | 6223 | struct perf_event_context *ctx; |
6231 | struct file *event_file = NULL; | 6224 | struct file *event_file = NULL; |
6232 | struct file *group_file = NULL; | 6225 | struct fd group = {NULL, 0}; |
6233 | struct task_struct *task = NULL; | 6226 | struct task_struct *task = NULL; |
6234 | struct pmu *pmu; | 6227 | struct pmu *pmu; |
6235 | int event_fd; | 6228 | int event_fd; |
6236 | int move_group = 0; | 6229 | int move_group = 0; |
6237 | int fput_needed = 0; | ||
6238 | int err; | 6230 | int err; |
6239 | 6231 | ||
6240 | /* for future expandability... */ | 6232 | /* for future expandability... */ |
@@ -6269,12 +6261,10 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6269 | return event_fd; | 6261 | return event_fd; |
6270 | 6262 | ||
6271 | if (group_fd != -1) { | 6263 | if (group_fd != -1) { |
6272 | group_file = perf_fget_light(group_fd, &fput_needed); | 6264 | err = perf_fget_light(group_fd, &group); |
6273 | if (IS_ERR(group_file)) { | 6265 | if (err) |
6274 | err = PTR_ERR(group_file); | ||
6275 | goto err_fd; | 6266 | goto err_fd; |
6276 | } | 6267 | group_leader = group.file->private_data; |
6277 | group_leader = group_file->private_data; | ||
6278 | if (flags & PERF_FLAG_FD_OUTPUT) | 6268 | if (flags & PERF_FLAG_FD_OUTPUT) |
6279 | output_event = group_leader; | 6269 | output_event = group_leader; |
6280 | if (flags & PERF_FLAG_FD_NO_GROUP) | 6270 | if (flags & PERF_FLAG_FD_NO_GROUP) |
@@ -6450,7 +6440,7 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6450 | * of the group leader will find the pointer to itself in | 6440 | * of the group leader will find the pointer to itself in |
6451 | * perf_group_detach(). | 6441 | * perf_group_detach(). |
6452 | */ | 6442 | */ |
6453 | fput_light(group_file, fput_needed); | 6443 | fdput(group); |
6454 | fd_install(event_fd, event_file); | 6444 | fd_install(event_fd, event_file); |
6455 | return event_fd; | 6445 | return event_fd; |
6456 | 6446 | ||
@@ -6464,7 +6454,7 @@ err_task: | |||
6464 | if (task) | 6454 | if (task) |
6465 | put_task_struct(task); | 6455 | put_task_struct(task); |
6466 | err_group_fd: | 6456 | err_group_fd: |
6467 | fput_light(group_file, fput_needed); | 6457 | fdput(group); |
6468 | err_fd: | 6458 | err_fd: |
6469 | put_unused_fd(event_fd); | 6459 | put_unused_fd(event_fd); |
6470 | return err; | 6460 | return err; |
diff --git a/kernel/sys.c b/kernel/sys.c index 0cb4283df88..f9492284e5d 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1788,15 +1788,15 @@ SYSCALL_DEFINE1(umask, int, mask) | |||
1788 | #ifdef CONFIG_CHECKPOINT_RESTORE | 1788 | #ifdef CONFIG_CHECKPOINT_RESTORE |
1789 | static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) | 1789 | static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) |
1790 | { | 1790 | { |
1791 | struct file *exe_file; | 1791 | struct fd exe; |
1792 | struct dentry *dentry; | 1792 | struct dentry *dentry; |
1793 | int err, fput_needed; | 1793 | int err; |
1794 | 1794 | ||
1795 | exe_file = fget_light(fd, &fput_needed); | 1795 | exe = fdget(fd); |
1796 | if (!exe_file) | 1796 | if (!exe.file) |
1797 | return -EBADF; | 1797 | return -EBADF; |
1798 | 1798 | ||
1799 | dentry = exe_file->f_path.dentry; | 1799 | dentry = exe.file->f_path.dentry; |
1800 | 1800 | ||
1801 | /* | 1801 | /* |
1802 | * Because the original mm->exe_file points to executable file, make | 1802 | * Because the original mm->exe_file points to executable file, make |
@@ -1805,7 +1805,7 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) | |||
1805 | */ | 1805 | */ |
1806 | err = -EACCES; | 1806 | err = -EACCES; |
1807 | if (!S_ISREG(dentry->d_inode->i_mode) || | 1807 | if (!S_ISREG(dentry->d_inode->i_mode) || |
1808 | exe_file->f_path.mnt->mnt_flags & MNT_NOEXEC) | 1808 | exe.file->f_path.mnt->mnt_flags & MNT_NOEXEC) |
1809 | goto exit; | 1809 | goto exit; |
1810 | 1810 | ||
1811 | err = inode_permission(dentry->d_inode, MAY_EXEC); | 1811 | err = inode_permission(dentry->d_inode, MAY_EXEC); |
@@ -1839,12 +1839,12 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd) | |||
1839 | goto exit_unlock; | 1839 | goto exit_unlock; |
1840 | 1840 | ||
1841 | err = 0; | 1841 | err = 0; |
1842 | set_mm_exe_file(mm, exe_file); /* this grabs a reference to exe_file */ | 1842 | set_mm_exe_file(mm, exe.file); /* this grabs a reference to exe.file */ |
1843 | exit_unlock: | 1843 | exit_unlock: |
1844 | up_write(&mm->mmap_sem); | 1844 | up_write(&mm->mmap_sem); |
1845 | 1845 | ||
1846 | exit: | 1846 | exit: |
1847 | fput_light(exe_file, fput_needed); | 1847 | fdput(exe); |
1848 | return err; | 1848 | return err; |
1849 | } | 1849 | } |
1850 | 1850 | ||
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index d0a32796550..5116b7e5962 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
@@ -415,16 +415,15 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | |||
415 | struct nlattr *na; | 415 | struct nlattr *na; |
416 | size_t size; | 416 | size_t size; |
417 | u32 fd; | 417 | u32 fd; |
418 | struct file *file; | 418 | struct fd f; |
419 | int fput_needed; | ||
420 | 419 | ||
421 | na = info->attrs[CGROUPSTATS_CMD_ATTR_FD]; | 420 | na = info->attrs[CGROUPSTATS_CMD_ATTR_FD]; |
422 | if (!na) | 421 | if (!na) |
423 | return -EINVAL; | 422 | return -EINVAL; |
424 | 423 | ||
425 | fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); | 424 | fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); |
426 | file = fget_light(fd, &fput_needed); | 425 | f = fdget(fd); |
427 | if (!file) | 426 | if (!f.file) |
428 | return 0; | 427 | return 0; |
429 | 428 | ||
430 | size = nla_total_size(sizeof(struct cgroupstats)); | 429 | size = nla_total_size(sizeof(struct cgroupstats)); |
@@ -444,7 +443,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | |||
444 | stats = nla_data(na); | 443 | stats = nla_data(na); |
445 | memset(stats, 0, sizeof(*stats)); | 444 | memset(stats, 0, sizeof(*stats)); |
446 | 445 | ||
447 | rc = cgroupstats_build(stats, file->f_dentry); | 446 | rc = cgroupstats_build(stats, f.file->f_dentry); |
448 | if (rc < 0) { | 447 | if (rc < 0) { |
449 | nlmsg_free(rep_skb); | 448 | nlmsg_free(rep_skb); |
450 | goto err; | 449 | goto err; |
@@ -453,7 +452,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | |||
453 | rc = send_reply(rep_skb, info); | 452 | rc = send_reply(rep_skb, info); |
454 | 453 | ||
455 | err: | 454 | err: |
456 | fput_light(file, fput_needed); | 455 | fdput(f); |
457 | return rc; | 456 | return rc; |
458 | } | 457 | } |
459 | 458 | ||