diff options
Diffstat (limited to 'ipc/mqueue.c')
| -rw-r--r-- | ipc/mqueue.c | 31 |
1 files changed, 10 insertions, 21 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index b3b69fd51330..96fb36cd9874 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
| @@ -207,7 +207,7 @@ static int mqueue_get_sb(struct file_system_type *fs_type, | |||
| 207 | return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt); | 207 | return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static void init_once(struct kmem_cache *cachep, void *foo) | 210 | static void init_once(void *foo) |
| 211 | { | 211 | { |
| 212 | struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo; | 212 | struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo; |
| 213 | 213 | ||
| @@ -314,15 +314,11 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry) | |||
| 314 | * through std routines) | 314 | * through std routines) |
| 315 | */ | 315 | */ |
| 316 | static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, | 316 | static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, |
| 317 | size_t count, loff_t * off) | 317 | size_t count, loff_t *off) |
| 318 | { | 318 | { |
| 319 | struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); | 319 | struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode); |
| 320 | char buffer[FILENT_SIZE]; | 320 | char buffer[FILENT_SIZE]; |
| 321 | size_t slen; | 321 | ssize_t ret; |
| 322 | loff_t o; | ||
| 323 | |||
| 324 | if (!count) | ||
| 325 | return 0; | ||
| 326 | 322 | ||
| 327 | spin_lock(&info->lock); | 323 | spin_lock(&info->lock); |
| 328 | snprintf(buffer, sizeof(buffer), | 324 | snprintf(buffer, sizeof(buffer), |
| @@ -335,21 +331,14 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, | |||
| 335 | pid_vnr(info->notify_owner)); | 331 | pid_vnr(info->notify_owner)); |
| 336 | spin_unlock(&info->lock); | 332 | spin_unlock(&info->lock); |
| 337 | buffer[sizeof(buffer)-1] = '\0'; | 333 | buffer[sizeof(buffer)-1] = '\0'; |
| 338 | slen = strlen(buffer)+1; | ||
| 339 | |||
| 340 | o = *off; | ||
| 341 | if (o > slen) | ||
| 342 | return 0; | ||
| 343 | |||
| 344 | if (o + count > slen) | ||
| 345 | count = slen - o; | ||
| 346 | 334 | ||
| 347 | if (copy_to_user(u_data, buffer + o, count)) | 335 | ret = simple_read_from_buffer(u_data, count, off, buffer, |
| 348 | return -EFAULT; | 336 | strlen(buffer)); |
| 337 | if (ret <= 0) | ||
| 338 | return ret; | ||
| 349 | 339 | ||
| 350 | *off = o + count; | ||
| 351 | filp->f_path.dentry->d_inode->i_atime = filp->f_path.dentry->d_inode->i_ctime = CURRENT_TIME; | 340 | filp->f_path.dentry->d_inode->i_atime = filp->f_path.dentry->d_inode->i_ctime = CURRENT_TIME; |
| 352 | return count; | 341 | return ret; |
| 353 | } | 342 | } |
| 354 | 343 | ||
| 355 | static int mqueue_flush_file(struct file *filp, fl_owner_t id) | 344 | static int mqueue_flush_file(struct file *filp, fl_owner_t id) |
| @@ -649,7 +638,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, | |||
| 649 | return ERR_PTR(-EINVAL); | 638 | return ERR_PTR(-EINVAL); |
| 650 | } | 639 | } |
| 651 | 640 | ||
| 652 | if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) { | 641 | if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) { |
| 653 | dput(dentry); | 642 | dput(dentry); |
| 654 | mntput(mqueue_mnt); | 643 | mntput(mqueue_mnt); |
| 655 | return ERR_PTR(-EACCES); | 644 | return ERR_PTR(-EACCES); |
| @@ -1054,7 +1043,7 @@ retry: | |||
| 1054 | } | 1043 | } |
| 1055 | 1044 | ||
| 1056 | timeo = MAX_SCHEDULE_TIMEOUT; | 1045 | timeo = MAX_SCHEDULE_TIMEOUT; |
| 1057 | ret = netlink_attachskb(sock, nc, 0, &timeo, NULL); | 1046 | ret = netlink_attachskb(sock, nc, &timeo, NULL); |
| 1058 | if (ret == 1) | 1047 | if (ret == 1) |
| 1059 | goto retry; | 1048 | goto retry; |
| 1060 | if (ret) { | 1049 | if (ret) { |
