aboutsummaryrefslogtreecommitdiffstats
path: root/fs/read_write.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:44:29 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:44:29 -0500
commitb47711bfbcd4eb77ca61ef0162487b20e023ae55 (patch)
treeb2a695dbd40f7ca2333664cf946ef34eda7b7dba /fs/read_write.c
parent7556afa0e0e436cad4f560ee83e5fbd5dac9359a (diff)
parent2e08c0c1c3977a5ddc88887dd3af1b26c433e9d0 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/selinux-2.6: selinux: make mls_compute_sid always polyinstantiate security/selinux: constify function pointer tables and fields security: add a secctx_to_secid() hook security: call security_file_permission from rw_verify_area security: remove security_sb_post_mountroot hook Security: remove security.h include from mm.h Security: remove security_file_mmap hook sparse-warnings (NULL as 0). Security: add get, set, and cloning of superblock security information security/selinux: Add missing "space"
Diffstat (limited to 'fs/read_write.c')
-rw-r--r--fs/read_write.c63
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
217Einval:
218 return -EINVAL;
219} 221}
220 222
221static void wait_on_retry_sync_kiocb(struct kiocb *iocb) 223static 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