From patchwork Fri Jan 28 12:24:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 514671 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0SCOS46008809 for ; Fri, 28 Jan 2011 12:24:29 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755137Ab1A1MY2 (ORCPT ); Fri, 28 Jan 2011 07:24:28 -0500 Received: from mail-gw0-f46.google.com ([74.125.83.46]:54463 "EHLO mail-gw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753896Ab1A1MY1 (ORCPT ); Fri, 28 Jan 2011 07:24:27 -0500 Received: by gwj20 with SMTP id 20so1047759gwj.19 for ; Fri, 28 Jan 2011 04:24:27 -0800 (PST) Received: by 10.100.60.12 with SMTP id i12mr1532993ana.161.1296217467132; Fri, 28 Jan 2011 04:24:27 -0800 (PST) Received: from salusa.poochiereds.net (cpe-071-070-153-003.nc.res.rr.com [71.70.153.3]) by mx.google.com with ESMTPS id b27sm21749448ana.28.2011.01.28.04.24.26 (version=SSLv3 cipher=RC4-MD5); Fri, 28 Jan 2011 04:24:26 -0800 (PST) From: Jeff Layton To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org Subject: [PATCH] cifs: fix length checks in checkSMB (try #2) Date: Fri, 28 Jan 2011 07:24:23 -0500 Message-Id: <1296217463-4584-1-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: References: Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 28 Jan 2011 12:24:29 +0000 (UTC) diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 72e99ec..77dc732 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -467,25 +467,26 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) return 0; /* bcc wrapped */ } - cFYI(1, "Calculated size %d vs length %d mismatch for mid %d", + cFYI(1, "Calculated size %u vs length %u mismatch for mid=%u", clc_len, 4 + len, smb->Mid); - /* Windows XP can return a few bytes too much, presumably - an illegal pad, at the end of byte range lock responses - so we allow for that three byte pad, as long as actual - received length is as long or longer than calculated length */ - /* We have now had to extend this more, since there is a - case in which it needs to be bigger still to handle a - malformed response to transact2 findfirst from WinXP when - access denied is returned and thus bcc and wct are zero - but server says length is 0x21 bytes too long as if the server - forget to reset the smb rfc1001 length when it reset the - wct and bcc to minimum size and drop the t2 parms and data */ - if ((4+len > clc_len) && (len <= clc_len + 512)) - return 0; - else { - cERROR(1, "RFC1001 size %d bigger than SMB for Mid=%d", + + if (4 + len < clc_len) { + cERROR(1, "RFC1001 size %u smaller than SMB for mid=%u", len, smb->Mid); return 1; + } else if (len > clc_len + 512) { + /* + * Some servers (Windows XP in particular) send more + * data than the lengths in the SMB packet would + * indicate on certain calls (byte range locks and + * trans2 find first calls in particular). While the + * client can handle such a frame by ignoring the + * trailing data, we choose limit the amount of extra + * data to 512 bytes. + */ + cERROR(1, "RFC1001 size %u more than 512 bytes larger " + "than SMB for mid=%u", len, smb->Mid); + return 1; } } return 0;