diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-11 14:53:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-03-11 14:53:42 -0400 |
commit | 33807f4f0daec3b00565c2932d95f614f5833adf (patch) | |
tree | 07a90339612d799a56ce74fad0d4d27c943b875b /fs/cifs/file.c | |
parent | adf961d7e8006d2cb16ceee07582b145b9ef69f7 (diff) | |
parent | dca1c8d17a2feae056f9e334ea75a462ae4cb52a (diff) |
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
Pull CIFS fixes from Steve French:
"A fix for the problem which Al spotted in cifs_writev and a followup
(noticed when fixing CVE-2014-0069) patch to ensure that cifs never
sends more than the smb frame length over the socket (as we saw with
that cifs_iovec_write problem that Jeff fixed last month)"
* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
cifs: mask off top byte in get_rfc1002_length()
cifs: sanity check length of data to send before sending
CIFS: Fix wrong pos argument of cifs_find_lock_conflict
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 24 |
1 files changed, 6 insertions, 18 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 53c15074bb36..834fce759d80 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -2579,31 +2579,19 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov, | |||
2579 | struct cifsInodeInfo *cinode = CIFS_I(inode); | 2579 | struct cifsInodeInfo *cinode = CIFS_I(inode); |
2580 | struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; | 2580 | struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; |
2581 | ssize_t rc = -EACCES; | 2581 | ssize_t rc = -EACCES; |
2582 | loff_t lock_pos = pos; | ||
2582 | 2583 | ||
2583 | BUG_ON(iocb->ki_pos != pos); | 2584 | if (file->f_flags & O_APPEND) |
2584 | 2585 | lock_pos = i_size_read(inode); | |
2585 | /* | 2586 | /* |
2586 | * We need to hold the sem to be sure nobody modifies lock list | 2587 | * We need to hold the sem to be sure nobody modifies lock list |
2587 | * with a brlock that prevents writing. | 2588 | * with a brlock that prevents writing. |
2588 | */ | 2589 | */ |
2589 | down_read(&cinode->lock_sem); | 2590 | down_read(&cinode->lock_sem); |
2590 | if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), | 2591 | if (!cifs_find_lock_conflict(cfile, lock_pos, iov_length(iov, nr_segs), |
2591 | server->vals->exclusive_lock_type, NULL, | 2592 | server->vals->exclusive_lock_type, NULL, |
2592 | CIFS_WRITE_OP)) { | 2593 | CIFS_WRITE_OP)) |
2593 | mutex_lock(&inode->i_mutex); | 2594 | rc = generic_file_aio_write(iocb, iov, nr_segs, pos); |
2594 | rc = __generic_file_aio_write(iocb, iov, nr_segs, | ||
2595 | &iocb->ki_pos); | ||
2596 | mutex_unlock(&inode->i_mutex); | ||
2597 | } | ||
2598 | |||
2599 | if (rc > 0) { | ||
2600 | ssize_t err; | ||
2601 | |||
2602 | err = generic_write_sync(file, iocb->ki_pos - rc, rc); | ||
2603 | if (err < 0) | ||
2604 | rc = err; | ||
2605 | } | ||
2606 | |||
2607 | up_read(&cinode->lock_sem); | 2595 | up_read(&cinode->lock_sem); |
2608 | return rc; | 2596 | return rc; |
2609 | } | 2597 | } |