Lines 40-45
Link Here
|
40 |
return -EISDIR; |
40 |
return -EISDIR; |
41 |
} |
41 |
} |
42 |
|
42 |
|
|
|
43 |
int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) |
44 |
{ |
45 |
struct inode *inode; |
46 |
loff_t pos; |
47 |
|
48 |
if (unlikely(count > file->f_maxcount)) |
49 |
goto Einval; |
50 |
|
51 |
pos = *ppos; |
52 |
|
53 |
if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) |
54 |
goto Einval; |
55 |
|
56 |
inode = file->f_dentry->d_inode; |
57 |
if (inode->i_flock && MANDATORY_LOCK(inode)) |
58 |
return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, *ppos, count); |
59 |
return 0; |
60 |
|
61 |
Einval: |
62 |
return -EINVAL; |
63 |
} |
64 |
|
43 |
loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) |
65 |
loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) |
44 |
{ |
66 |
{ |
45 |
long long retval; |
67 |
long long retval; |
Lines 168-175
Link Here
|
168 |
file = fget(fd); |
190 |
file = fget(fd); |
169 |
if (file) { |
191 |
if (file) { |
170 |
if (file->f_mode & FMODE_READ) { |
192 |
if (file->f_mode & FMODE_READ) { |
171 |
ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode, |
193 |
ret = rw_verify_area(READ, file, &file->f_pos, count); |
172 |
file, file->f_pos, count); |
194 |
|
173 |
if (!ret) { |
195 |
if (!ret) { |
174 |
ssize_t (*read)(struct file *, char *, size_t, loff_t *); |
196 |
ssize_t (*read)(struct file *, char *, size_t, loff_t *); |
175 |
ret = -EINVAL; |
197 |
ret = -EINVAL; |
Lines 193-201
Link Here
|
193 |
file = fget(fd); |
215 |
file = fget(fd); |
194 |
if (file) { |
216 |
if (file) { |
195 |
if (file->f_mode & FMODE_WRITE) { |
217 |
if (file->f_mode & FMODE_WRITE) { |
196 |
struct inode *inode = file->f_dentry->d_inode; |
218 |
ret = rw_verify_area(WRITE, file, &file->f_pos, count); |
197 |
ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, |
|
|
198 |
file->f_pos, count); |
199 |
if (!ret) { |
219 |
if (!ret) { |
200 |
ssize_t (*write)(struct file *, const char *, size_t, loff_t *); |
220 |
ssize_t (*write)(struct file *, const char *, size_t, loff_t *); |
201 |
ret = -EINVAL; |
221 |
ret = -EINVAL; |
Lines 224-230
Link Here
|
224 |
ssize_t ret, i; |
244 |
ssize_t ret, i; |
225 |
io_fn_t fn; |
245 |
io_fn_t fn; |
226 |
iov_fn_t fnv; |
246 |
iov_fn_t fnv; |
227 |
struct inode *inode; |
|
|
228 |
|
247 |
|
229 |
/* |
248 |
/* |
230 |
* First get the "struct iovec" from user memory and |
249 |
* First get the "struct iovec" from user memory and |
Lines 275-286
Link Here
|
275 |
goto out; |
294 |
goto out; |
276 |
} |
295 |
} |
277 |
|
296 |
|
278 |
inode = file->f_dentry->d_inode; |
|
|
279 |
/* VERIFY_WRITE actually means a read, as we write to user space */ |
297 |
/* VERIFY_WRITE actually means a read, as we write to user space */ |
280 |
ret = locks_verify_area((type == VERIFY_WRITE |
298 |
ret = rw_verify_area((type == VERIFY_WRITE ? READ : WRITE), |
281 |
? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE), |
299 |
file, &file->f_pos, tot_len); |
282 |
inode, file, file->f_pos, tot_len); |
300 |
if (ret) |
283 |
if (ret) goto out; |
301 |
goto out; |
284 |
|
302 |
|
285 |
fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev); |
303 |
fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev); |
286 |
if (fnv) { |
304 |
if (fnv) { |
Lines 383-390
Link Here
|
383 |
goto bad_file; |
401 |
goto bad_file; |
384 |
if (!(file->f_mode & FMODE_READ)) |
402 |
if (!(file->f_mode & FMODE_READ)) |
385 |
goto out; |
403 |
goto out; |
386 |
ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode, |
404 |
ret = rw_verify_area(READ, file, &pos, count); |
387 |
file, pos, count); |
405 |
|
388 |
if (ret) |
406 |
if (ret) |
389 |
goto out; |
407 |
goto out; |
390 |
ret = -EINVAL; |
408 |
ret = -EINVAL; |
Lines 414-421
Link Here
|
414 |
goto bad_file; |
432 |
goto bad_file; |
415 |
if (!(file->f_mode & FMODE_WRITE)) |
433 |
if (!(file->f_mode & FMODE_WRITE)) |
416 |
goto out; |
434 |
goto out; |
417 |
ret = locks_verify_area(FLOCK_VERIFY_WRITE, file->f_dentry->d_inode, |
435 |
ret = rw_verify_area(WRITE, file, &pos, count); |
418 |
file, pos, count); |
436 |
|
419 |
if (ret) |
437 |
if (ret) |
420 |
goto out; |
438 |
goto out; |
421 |
ret = -EINVAL; |
439 |
ret = -EINVAL; |