aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/trans_sock.c1
-rw-r--r--fs/bio.c38
-rw-r--r--fs/compat.c2
-rw-r--r--fs/nfs/callback.c3
-rw-r--r--fs/read_write.c34
5 files changed, 60 insertions, 18 deletions
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
index a93c2bf94c33..6a9a75d40f73 100644
--- a/fs/9p/trans_sock.c
+++ b/fs/9p/trans_sock.c
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28#include <linux/config.h> 28#include <linux/config.h>
29#include <linux/in.h>
29#include <linux/module.h> 30#include <linux/module.h>
30#include <linux/net.h> 31#include <linux/net.h>
31#include <linux/ipv6.h> 32#include <linux/ipv6.h>
diff --git a/fs/bio.c b/fs/bio.c
index 460554b07ff9..38d3e8023a07 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -313,7 +313,8 @@ int bio_get_nr_vecs(struct block_device *bdev)
313} 313}
314 314
315static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page 315static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
316 *page, unsigned int len, unsigned int offset) 316 *page, unsigned int len, unsigned int offset,
317 unsigned short max_sectors)
317{ 318{
318 int retried_segments = 0; 319 int retried_segments = 0;
319 struct bio_vec *bvec; 320 struct bio_vec *bvec;
@@ -327,7 +328,7 @@ static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
327 if (bio->bi_vcnt >= bio->bi_max_vecs) 328 if (bio->bi_vcnt >= bio->bi_max_vecs)
328 return 0; 329 return 0;
329 330
330 if (((bio->bi_size + len) >> 9) > q->max_sectors) 331 if (((bio->bi_size + len) >> 9) > max_sectors)
331 return 0; 332 return 0;
332 333
333 /* 334 /*
@@ -386,6 +387,25 @@ static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
386} 387}
387 388
388/** 389/**
390 * bio_add_pc_page - attempt to add page to bio
391 * @bio: destination bio
392 * @page: page to add
393 * @len: vec entry length
394 * @offset: vec entry offset
395 *
396 * Attempt to add a page to the bio_vec maplist. This can fail for a
397 * number of reasons, such as the bio being full or target block
398 * device limitations. The target block device must allow bio's
399 * smaller than PAGE_SIZE, so it is always possible to add a single
400 * page to an empty bio. This should only be used by REQ_PC bios.
401 */
402int bio_add_pc_page(request_queue_t *q, struct bio *bio, struct page *page,
403 unsigned int len, unsigned int offset)
404{
405 return __bio_add_page(q, bio, page, len, offset, q->max_hw_sectors);
406}
407
408/**
389 * bio_add_page - attempt to add page to bio 409 * bio_add_page - attempt to add page to bio
390 * @bio: destination bio 410 * @bio: destination bio
391 * @page: page to add 411 * @page: page to add
@@ -401,8 +421,8 @@ static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
401int bio_add_page(struct bio *bio, struct page *page, unsigned int len, 421int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
402 unsigned int offset) 422 unsigned int offset)
403{ 423{
404 return __bio_add_page(bdev_get_queue(bio->bi_bdev), bio, page, 424 struct request_queue *q = bdev_get_queue(bio->bi_bdev);
405 len, offset); 425 return __bio_add_page(q, bio, page, len, offset, q->max_sectors);
406} 426}
407 427
408struct bio_map_data { 428struct bio_map_data {
@@ -514,7 +534,7 @@ struct bio *bio_copy_user(request_queue_t *q, unsigned long uaddr,
514 break; 534 break;
515 } 535 }
516 536
517 if (__bio_add_page(q, bio, page, bytes, 0) < bytes) { 537 if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) {
518 ret = -EINVAL; 538 ret = -EINVAL;
519 break; 539 break;
520 } 540 }
@@ -628,7 +648,8 @@ static struct bio *__bio_map_user_iov(request_queue_t *q,
628 /* 648 /*
629 * sorry... 649 * sorry...
630 */ 650 */
631 if (__bio_add_page(q, bio, pages[j], bytes, offset) < bytes) 651 if (bio_add_pc_page(q, bio, pages[j], bytes, offset) <
652 bytes)
632 break; 653 break;
633 654
634 len -= bytes; 655 len -= bytes;
@@ -801,8 +822,8 @@ static struct bio *__bio_map_kern(request_queue_t *q, void *data,
801 if (bytes > len) 822 if (bytes > len)
802 bytes = len; 823 bytes = len;
803 824
804 if (__bio_add_page(q, bio, virt_to_page(data), bytes, 825 if (bio_add_pc_page(q, bio, virt_to_page(data), bytes,
805 offset) < bytes) 826 offset) < bytes)
806 break; 827 break;
807 828
808 data += bytes; 829 data += bytes;
@@ -1228,6 +1249,7 @@ EXPORT_SYMBOL(bio_clone);
1228EXPORT_SYMBOL(bio_phys_segments); 1249EXPORT_SYMBOL(bio_phys_segments);
1229EXPORT_SYMBOL(bio_hw_segments); 1250EXPORT_SYMBOL(bio_hw_segments);
1230EXPORT_SYMBOL(bio_add_page); 1251EXPORT_SYMBOL(bio_add_page);
1252EXPORT_SYMBOL(bio_add_pc_page);
1231EXPORT_SYMBOL(bio_get_nr_vecs); 1253EXPORT_SYMBOL(bio_get_nr_vecs);
1232EXPORT_SYMBOL(bio_map_user); 1254EXPORT_SYMBOL(bio_map_user);
1233EXPORT_SYMBOL(bio_unmap_user); 1255EXPORT_SYMBOL(bio_unmap_user);
diff --git a/fs/compat.c b/fs/compat.c
index 818634120b69..55ac0324aaf1 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1170,7 +1170,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
1170 } 1170 }
1171 1171
1172 ret = rw_verify_area(type, file, pos, tot_len); 1172 ret = rw_verify_area(type, file, pos, tot_len);
1173 if (ret) 1173 if (ret < 0)
1174 goto out; 1174 goto out;
1175 1175
1176 fnv = NULL; 1176 fnv = NULL;
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index f2ca782aba33..30cae3602867 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -14,6 +14,9 @@
14#include <linux/sunrpc/svc.h> 14#include <linux/sunrpc/svc.h>
15#include <linux/sunrpc/svcsock.h> 15#include <linux/sunrpc/svcsock.h>
16#include <linux/nfs_fs.h> 16#include <linux/nfs_fs.h>
17
18#include <net/inet_sock.h>
19
17#include "nfs4_fs.h" 20#include "nfs4_fs.h"
18#include "callback.h" 21#include "callback.h"
19 22
diff --git a/fs/read_write.c b/fs/read_write.c
index a091ee4f430d..df3468a22fea 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -14,6 +14,7 @@
14#include <linux/security.h> 14#include <linux/security.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/syscalls.h> 16#include <linux/syscalls.h>
17#include <linux/pagemap.h>
17 18
18#include <asm/uaccess.h> 19#include <asm/uaccess.h>
19#include <asm/unistd.h> 20#include <asm/unistd.h>
@@ -182,22 +183,33 @@ bad:
182} 183}
183#endif 184#endif
184 185
186/*
187 * rw_verify_area doesn't like huge counts. We limit
188 * them to something that fits in "int" so that others
189 * won't have to do range checks all the time.
190 */
191#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
185 192
186int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) 193int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count)
187{ 194{
188 struct inode *inode; 195 struct inode *inode;
189 loff_t pos; 196 loff_t pos;
190 197
191 if (unlikely(count > INT_MAX)) 198 if (unlikely((ssize_t) count < 0))
192 goto Einval; 199 goto Einval;
193 pos = *ppos; 200 pos = *ppos;
194 if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) 201 if (unlikely((pos < 0) || (loff_t) (pos + count) < 0))
195 goto Einval; 202 goto Einval;
196 203
197 inode = file->f_dentry->d_inode; 204 inode = file->f_dentry->d_inode;
198 if (inode->i_flock && MANDATORY_LOCK(inode)) 205 if (inode->i_flock && MANDATORY_LOCK(inode)) {
199 return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count); 206 int retval = locks_mandatory_area(
200 return 0; 207 read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
208 inode, file, pos, count);
209 if (retval < 0)
210 return retval;
211 }
212 return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
201 213
202Einval: 214Einval:
203 return -EINVAL; 215 return -EINVAL;
@@ -244,7 +256,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
244 return -EFAULT; 256 return -EFAULT;
245 257
246 ret = rw_verify_area(READ, file, pos, count); 258 ret = rw_verify_area(READ, file, pos, count);
247 if (!ret) { 259 if (ret >= 0) {
260 count = ret;
248 ret = security_file_permission (file, MAY_READ); 261 ret = security_file_permission (file, MAY_READ);
249 if (!ret) { 262 if (!ret) {
250 if (file->f_op->read) 263 if (file->f_op->read)
@@ -295,7 +308,8 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
295 return -EFAULT; 308 return -EFAULT;
296 309
297 ret = rw_verify_area(WRITE, file, pos, count); 310 ret = rw_verify_area(WRITE, file, pos, count);
298 if (!ret) { 311 if (ret >= 0) {
312 count = ret;
299 ret = security_file_permission (file, MAY_WRITE); 313 ret = security_file_permission (file, MAY_WRITE);
300 if (!ret) { 314 if (!ret) {
301 if (file->f_op->write) 315 if (file->f_op->write)
@@ -497,7 +511,7 @@ static ssize_t do_readv_writev(int type, struct file *file,
497 } 511 }
498 512
499 ret = rw_verify_area(type, file, pos, tot_len); 513 ret = rw_verify_area(type, file, pos, tot_len);
500 if (ret) 514 if (ret < 0)
501 goto out; 515 goto out;
502 ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE); 516 ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE);
503 if (ret) 517 if (ret)
@@ -653,8 +667,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
653 if (!(in_file->f_mode & FMODE_PREAD)) 667 if (!(in_file->f_mode & FMODE_PREAD))
654 goto fput_in; 668 goto fput_in;
655 retval = rw_verify_area(READ, in_file, ppos, count); 669 retval = rw_verify_area(READ, in_file, ppos, count);
656 if (retval) 670 if (retval < 0)
657 goto fput_in; 671 goto fput_in;
672 count = retval;
658 673
659 retval = security_file_permission (in_file, MAY_READ); 674 retval = security_file_permission (in_file, MAY_READ);
660 if (retval) 675 if (retval)
@@ -674,8 +689,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
674 goto fput_out; 689 goto fput_out;
675 out_inode = out_file->f_dentry->d_inode; 690 out_inode = out_file->f_dentry->d_inode;
676 retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); 691 retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
677 if (retval) 692 if (retval < 0)
678 goto fput_out; 693 goto fput_out;
694 count = retval;
679 695
680 retval = security_file_permission (out_file, MAY_WRITE); 696 retval = security_file_permission (out_file, MAY_WRITE);
681 if (retval) 697 if (retval)