diff options
author | James Morris <jmorris@namei.org> | 2008-01-12 06:05:48 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-01-24 19:29:52 -0500 |
commit | c43e259cc756ece387faae849af0058b56d78466 (patch) | |
tree | 1f1541560256b9fe2eeda5b07100baa14f39df59 /fs/read_write.c | |
parent | bced95283e9434611cbad8f2ff903cd396eaea72 (diff) |
security: call security_file_permission from rw_verify_area
All instances of rw_verify_area() are followed by a call to
security_file_permission(), so just call the latter from the former.
Acked-by: Eric Paris <eparis@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'fs/read_write.c')
-rw-r--r-- | fs/read_write.c | 63 |
1 files changed, 24 insertions, 39 deletions
diff --git a/fs/read_write.c b/fs/read_write.c index ea1f94cc722e..c4d3d17923f1 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -197,25 +197,27 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count | |||
197 | { | 197 | { |
198 | struct inode *inode; | 198 | struct inode *inode; |
199 | loff_t pos; | 199 | loff_t pos; |
200 | int retval = -EINVAL; | ||
200 | 201 | ||
201 | inode = file->f_path.dentry->d_inode; | 202 | inode = file->f_path.dentry->d_inode; |
202 | if (unlikely((ssize_t) count < 0)) | 203 | if (unlikely((ssize_t) count < 0)) |
203 | goto Einval; | 204 | return retval; |
204 | pos = *ppos; | 205 | pos = *ppos; |
205 | if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) | 206 | if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) |
206 | goto Einval; | 207 | return retval; |
207 | 208 | ||
208 | if (unlikely(inode->i_flock && mandatory_lock(inode))) { | 209 | if (unlikely(inode->i_flock && mandatory_lock(inode))) { |
209 | int retval = locks_mandatory_area( | 210 | retval = locks_mandatory_area( |
210 | read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, | 211 | read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, |
211 | inode, file, pos, count); | 212 | inode, file, pos, count); |
212 | if (retval < 0) | 213 | if (retval < 0) |
213 | return retval; | 214 | return retval; |
214 | } | 215 | } |
216 | retval = security_file_permission(file, | ||
217 | read_write == READ ? MAY_READ : MAY_WRITE); | ||
218 | if (retval) | ||
219 | return retval; | ||
215 | return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; | 220 | return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; |
216 | |||
217 | Einval: | ||
218 | return -EINVAL; | ||
219 | } | 221 | } |
220 | 222 | ||
221 | static void wait_on_retry_sync_kiocb(struct kiocb *iocb) | 223 | static void wait_on_retry_sync_kiocb(struct kiocb *iocb) |
@@ -267,18 +269,15 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) | |||
267 | ret = rw_verify_area(READ, file, pos, count); | 269 | ret = rw_verify_area(READ, file, pos, count); |
268 | if (ret >= 0) { | 270 | if (ret >= 0) { |
269 | count = ret; | 271 | count = ret; |
270 | ret = security_file_permission (file, MAY_READ); | 272 | if (file->f_op->read) |
271 | if (!ret) { | 273 | ret = file->f_op->read(file, buf, count, pos); |
272 | if (file->f_op->read) | 274 | else |
273 | ret = file->f_op->read(file, buf, count, pos); | 275 | ret = do_sync_read(file, buf, count, pos); |
274 | else | 276 | if (ret > 0) { |
275 | ret = do_sync_read(file, buf, count, pos); | 277 | fsnotify_access(file->f_path.dentry); |
276 | if (ret > 0) { | 278 | add_rchar(current, ret); |
277 | fsnotify_access(file->f_path.dentry); | ||
278 | add_rchar(current, ret); | ||
279 | } | ||
280 | inc_syscr(current); | ||
281 | } | 279 | } |
280 | inc_syscr(current); | ||
282 | } | 281 | } |
283 | 282 | ||
284 | return ret; | 283 | return ret; |
@@ -325,18 +324,15 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ | |||
325 | ret = rw_verify_area(WRITE, file, pos, count); | 324 | ret = rw_verify_area(WRITE, file, pos, count); |
326 | if (ret >= 0) { | 325 | if (ret >= 0) { |
327 | count = ret; | 326 | count = ret; |
328 | ret = security_file_permission (file, MAY_WRITE); | 327 | if (file->f_op->write) |
329 | if (!ret) { | 328 | ret = file->f_op->write(file, buf, count, pos); |
330 | if (file->f_op->write) | 329 | else |
331 | ret = file->f_op->write(file, buf, count, pos); | 330 | ret = do_sync_write(file, buf, count, pos); |
332 | else | 331 | if (ret > 0) { |
333 | ret = do_sync_write(file, buf, count, pos); | 332 | fsnotify_modify(file->f_path.dentry); |
334 | if (ret > 0) { | 333 | add_wchar(current, ret); |
335 | fsnotify_modify(file->f_path.dentry); | ||
336 | add_wchar(current, ret); | ||
337 | } | ||
338 | inc_syscw(current); | ||
339 | } | 334 | } |
335 | inc_syscw(current); | ||
340 | } | 336 | } |
341 | 337 | ||
342 | return ret; | 338 | return ret; |
@@ -603,9 +599,6 @@ static ssize_t do_readv_writev(int type, struct file *file, | |||
603 | ret = rw_verify_area(type, file, pos, tot_len); | 599 | ret = rw_verify_area(type, file, pos, tot_len); |
604 | if (ret < 0) | 600 | if (ret < 0) |
605 | goto out; | 601 | goto out; |
606 | ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE); | ||
607 | if (ret) | ||
608 | goto out; | ||
609 | 602 | ||
610 | fnv = NULL; | 603 | fnv = NULL; |
611 | if (type == READ) { | 604 | if (type == READ) { |
@@ -737,10 +730,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
737 | goto fput_in; | 730 | goto fput_in; |
738 | count = retval; | 731 | count = retval; |
739 | 732 | ||
740 | retval = security_file_permission (in_file, MAY_READ); | ||
741 | if (retval) | ||
742 | goto fput_in; | ||
743 | |||
744 | /* | 733 | /* |
745 | * Get output file, and verify that it is ok.. | 734 | * Get output file, and verify that it is ok.. |
746 | */ | 735 | */ |
@@ -759,10 +748,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
759 | goto fput_out; | 748 | goto fput_out; |
760 | count = retval; | 749 | count = retval; |
761 | 750 | ||
762 | retval = security_file_permission (out_file, MAY_WRITE); | ||
763 | if (retval) | ||
764 | goto fput_out; | ||
765 | |||
766 | if (!max) | 751 | if (!max) |
767 | max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); | 752 | max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); |
768 | 753 | ||