Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757703Ab0DVTzL (ORCPT ); Thu, 22 Apr 2010 15:55:11 -0400 Received: from kroah.org ([198.145.64.141]:40857 "EHLO coco.kroah.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756427Ab0DVT2g (ORCPT ); Thu, 22 Apr 2010 15:28:36 -0400 X-Mailbox-Line: From gregkh@kvm.kroah.org Thu Apr 22 12:09:14 2010 Message-Id: <20100422190914.729285199@kvm.kroah.org> User-Agent: quilt/0.48-4.4 Date: Thu, 22 Apr 2010 12:08:53 -0700 From: Greg KH To: linux-kernel@vger.kernel.org, stable@kernel.org Cc: stable-review@kernel.org, torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Suresh Jayaraman , Steve French Subject: [082/197] cifs: Fix a kernel BUG with remote OS/2 server (try #3) In-Reply-To: <20100422191857.GA13268@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2469 Lines: 73 2.6.32-stable review patch. If anyone has any objections, please let us know. ------------------ From: Suresh Jayaraman commit 6513a81e9325d712f1bfb9a1d7b750134e49ff18 upstream. While chasing a bug report involving a OS/2 server, I noticed the server sets pSMBr->CountHigh to a incorrect value even in case of normal writes. This results in 'nbytes' being computed wrongly and triggers a kernel BUG at mm/filemap.c. void iov_iter_advance(struct iov_iter *i, size_t bytes) { BUG_ON(i->count < bytes); <--- BUG here Why the server is setting 'CountHigh' is not clear but only does so after writing 64k bytes. Though this looks like the server bug, the client side crash may not be acceptable. The workaround is to mask off high 16 bits if the number of bytes written as returned by the server is greater than the bytes requested by the client as suggested by Jeff Layton. Reviewed-by: Jeff Layton Signed-off-by: Suresh Jayaraman Signed-off-by: Steve French Signed-off-by: Greg Kroah-Hartman --- fs/cifs/cifssmb.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1517,6 +1517,14 @@ CIFSSMBWrite(const int xid, struct cifsT *nbytes = le16_to_cpu(pSMBr->CountHigh); *nbytes = (*nbytes) << 16; *nbytes += le16_to_cpu(pSMBr->Count); + + /* + * Mask off high 16 bits when bytes written as returned by the + * server is greater than bytes requested by the client. Some + * OS/2 servers are known to set incorrect CountHigh values. + */ + if (*nbytes > count) + *nbytes &= 0xFFFF; } cifs_buf_release(pSMB); @@ -1605,6 +1613,14 @@ CIFSSMBWrite2(const int xid, struct cifs *nbytes = le16_to_cpu(pSMBr->CountHigh); *nbytes = (*nbytes) << 16; *nbytes += le16_to_cpu(pSMBr->Count); + + /* + * Mask off high 16 bits when bytes written as returned by the + * server is greater than bytes requested by the client. OS/2 + * servers are known to set incorrect CountHigh values. + */ + if (*nbytes > count) + *nbytes &= 0xFFFF; } /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/