diff options
| author | Grant Likely <grant.likely@secretlab.ca> | 2011-01-14 14:09:49 -0500 |
|---|---|---|
| committer | Grant Likely <grant.likely@secretlab.ca> | 2011-01-14 14:09:49 -0500 |
| commit | 42a9fa9957e369240936891c9a521ab671eed4e7 (patch) | |
| tree | 7a9367594a367085c6a4a4433f687ec5c8dac8b7 /fs/read_write.c | |
| parent | 5f35765d836befebdfabf745fdbf2e070c887fac (diff) | |
| parent | c289ef41431144a538b5fb5f94fc83c81b3020e2 (diff) | |
Merge branch 'devicetree/next' into spi/next
Diffstat (limited to 'fs/read_write.c')
| -rw-r--r-- | fs/read_write.c | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/fs/read_write.c b/fs/read_write.c index 5d431bacbea9..5520f8ad5504 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
| @@ -30,18 +30,9 @@ const struct file_operations generic_ro_fops = { | |||
| 30 | 30 | ||
| 31 | EXPORT_SYMBOL(generic_ro_fops); | 31 | EXPORT_SYMBOL(generic_ro_fops); |
| 32 | 32 | ||
| 33 | static int | 33 | static inline int unsigned_offsets(struct file *file) |
| 34 | __negative_fpos_check(struct file *file, loff_t pos, size_t count) | ||
| 35 | { | 34 | { |
| 36 | /* | 35 | return file->f_mode & FMODE_UNSIGNED_OFFSET; |
| 37 | * pos or pos+count is negative here, check overflow. | ||
| 38 | * too big "count" will be caught in rw_verify_area(). | ||
| 39 | */ | ||
| 40 | if ((pos < 0) && (pos + count < pos)) | ||
| 41 | return -EOVERFLOW; | ||
| 42 | if (file->f_mode & FMODE_UNSIGNED_OFFSET) | ||
| 43 | return 0; | ||
| 44 | return -EINVAL; | ||
| 45 | } | 36 | } |
| 46 | 37 | ||
| 47 | /** | 38 | /** |
| @@ -75,7 +66,7 @@ generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin) | |||
| 75 | break; | 66 | break; |
| 76 | } | 67 | } |
| 77 | 68 | ||
| 78 | if (offset < 0 && __negative_fpos_check(file, offset, 0)) | 69 | if (offset < 0 && !unsigned_offsets(file)) |
| 79 | return -EINVAL; | 70 | return -EINVAL; |
| 80 | if (offset > inode->i_sb->s_maxbytes) | 71 | if (offset > inode->i_sb->s_maxbytes) |
| 81 | return -EINVAL; | 72 | return -EINVAL; |
| @@ -152,7 +143,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin) | |||
| 152 | offset += file->f_pos; | 143 | offset += file->f_pos; |
| 153 | } | 144 | } |
| 154 | retval = -EINVAL; | 145 | retval = -EINVAL; |
| 155 | if (offset >= 0 || !__negative_fpos_check(file, offset, 0)) { | 146 | if (offset >= 0 || unsigned_offsets(file)) { |
| 156 | if (offset != file->f_pos) { | 147 | if (offset != file->f_pos) { |
| 157 | file->f_pos = offset; | 148 | file->f_pos = offset; |
| 158 | file->f_version = 0; | 149 | file->f_version = 0; |
| @@ -252,9 +243,13 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count | |||
| 252 | if (unlikely((ssize_t) count < 0)) | 243 | if (unlikely((ssize_t) count < 0)) |
| 253 | return retval; | 244 | return retval; |
| 254 | pos = *ppos; | 245 | pos = *ppos; |
| 255 | if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) { | 246 | if (unlikely(pos < 0)) { |
| 256 | retval = __negative_fpos_check(file, pos, count); | 247 | if (!unsigned_offsets(file)) |
| 257 | if (retval) | 248 | return retval; |
| 249 | if (count >= -pos) /* both values are in 0..LLONG_MAX */ | ||
| 250 | return -EOVERFLOW; | ||
| 251 | } else if (unlikely((loff_t) (pos + count) < 0)) { | ||
| 252 | if (!unsigned_offsets(file)) | ||
| 258 | return retval; | 253 | return retval; |
| 259 | } | 254 | } |
| 260 | 255 | ||
