Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+36 -19
+1 -1
fs/cifs/cifsglob.h
··· 513 513 static inline unsigned int 514 514 get_rfc1002_length(void *buf) 515 515 { 516 - return be32_to_cpu(*((__be32 *)buf)); 516 + return be32_to_cpu(*((__be32 *)buf)) & 0xffffff; 517 517 } 518 518 519 519 static inline void
+6 -18
fs/cifs/file.c
··· 2579 2579 struct cifsInodeInfo *cinode = CIFS_I(inode); 2580 2580 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; 2581 2581 ssize_t rc = -EACCES; 2582 + loff_t lock_pos = pos; 2582 2583 2583 - BUG_ON(iocb->ki_pos != pos); 2584 - 2584 + if (file->f_flags & O_APPEND) 2585 + lock_pos = i_size_read(inode); 2585 2586 /* 2586 2587 * We need to hold the sem to be sure nobody modifies lock list 2587 2588 * with a brlock that prevents writing. 2588 2589 */ 2589 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 2592 server->vals->exclusive_lock_type, NULL, 2592 - CIFS_WRITE_OP)) { 2593 - mutex_lock(&inode->i_mutex); 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 - 2593 + CIFS_WRITE_OP)) 2594 + rc = generic_file_aio_write(iocb, iov, nr_segs, pos); 2607 2595 up_read(&cinode->lock_sem); 2608 2596 return rc; 2609 2597 }
+29
fs/cifs/transport.c
··· 270 270 iov->iov_len = rqst->rq_pagesz; 271 271 } 272 272 273 + static unsigned long 274 + rqst_len(struct smb_rqst *rqst) 275 + { 276 + unsigned int i; 277 + struct kvec *iov = rqst->rq_iov; 278 + unsigned long buflen = 0; 279 + 280 + /* total up iov array first */ 281 + for (i = 0; i < rqst->rq_nvec; i++) 282 + buflen += iov[i].iov_len; 283 + 284 + /* add in the page array if there is one */ 285 + if (rqst->rq_npages) { 286 + buflen += rqst->rq_pagesz * (rqst->rq_npages - 1); 287 + buflen += rqst->rq_tailsz; 288 + } 289 + 290 + return buflen; 291 + } 292 + 273 293 static int 274 294 smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) 275 295 { ··· 297 277 struct kvec *iov = rqst->rq_iov; 298 278 int n_vec = rqst->rq_nvec; 299 279 unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base); 280 + unsigned long send_length; 300 281 unsigned int i; 301 282 size_t total_len = 0, sent; 302 283 struct socket *ssocket = server->ssocket; ··· 305 284 306 285 if (ssocket == NULL) 307 286 return -ENOTSOCK; 287 + 288 + /* sanity check send length */ 289 + send_length = rqst_len(rqst); 290 + if (send_length != smb_buf_length + 4) { 291 + WARN(1, "Send length mismatch(send_length=%lu smb_buf_length=%u)\n", 292 + send_length, smb_buf_length); 293 + return -EIO; 294 + } 308 295 309 296 cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length); 310 297 dump_smb(iov[0].iov_base, iov[0].iov_len);