From patchwork Mon Jan 11 21:02:01 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 42665 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.samba.org (fn.samba.org [216.83.154.106]) by ozlabs.org (Postfix) with ESMTP id A8C64B7BEE for ; Tue, 12 Jan 2010 08:02:20 +1100 (EST) Received: from fn.samba.org (localhost [127.0.0.1]) by lists.samba.org (Postfix) with ESMTP id 68763AD16B; Mon, 11 Jan 2010 14:07:51 -0700 (MST) X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on fn.samba.org X-Spam-Level: X-Spam-Status: No, score=-6.5 required=3.8 tests=AWL,BAYES_00, RCVD_IN_DNSWL_MED, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.2.5 X-Original-To: linux-cifs-client@lists.samba.org Delivered-To: linux-cifs-client@lists.samba.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by lists.samba.org (Postfix) with ESMTP id 000F0AD15C for ; Mon, 11 Jan 2010 14:07:37 -0700 (MST) Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o0BL25L3014991 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 11 Jan 2010 16:02:05 -0500 Received: from localhost.localdomain (vpn-10-130.rdu.redhat.com [10.11.10.130]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o0BL21SP008631; Mon, 11 Jan 2010 16:02:04 -0500 From: Jeff Layton To: smfrench@gmail.com Date: Mon, 11 Jan 2010 16:02:01 -0500 Message-Id: <1263243721-3782-5-git-send-email-jlayton@redhat.com> In-Reply-To: <1263243721-3782-1-git-send-email-jlayton@redhat.com> References: <1263243721-3782-1-git-send-email-jlayton@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 Cc: linux-cifs-client@lists.samba.org Subject: [linux-cifs-client] [PATCH 4/4] cifs: verify lengths of QueryAllEAs reply X-BeenThere: linux-cifs-client@lists.samba.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: The Linux CIFS VFS client List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-cifs-client-bounces@lists.samba.org Errors-To: linux-cifs-client-bounces@lists.samba.org Make sure the lengths in a QUERY_ALL_EAS reply don't make the parser walk off the end of the SMB. Signed-off-by: Jeff Layton --- fs/cifs/cifssmb.c | 30 +++++++++++++++++++++++++++--- 1 files changed, 27 insertions(+), 3 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f5e1527..fb19f43 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -5285,6 +5285,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, struct fealist *ea_response_data; struct fea *temp_fea; char *temp_ptr; + char *end_of_smb; __u16 params, byte_count, data_offset; cFYI(1, ("In Query All EAs path %s", searchName)); @@ -5360,11 +5361,19 @@ QAllEAsRetry: data_offset = le16_to_cpu(pSMBr->t2.DataOffset); ea_response_data = (struct fealist *) (((char *) &pSMBr->hdr.Protocol) + data_offset); - list_len = le32_to_cpu(ea_response_data->list_len); cFYI(1, ("ea length %d", list_len)); if (list_len <= 8) { cFYI(1, ("empty EA list returned from server")); + rc = -EIO; + goto QAllEAsOut; + } + + /* make sure list_len doesn't go past end of SMB */ + end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr); + if ((char *)ea_response_data + list_len > end_of_smb) { + cFYI(1, ("list_len goes beyond SMB")); + rc = -EIO; goto QAllEAsOut; } @@ -5373,10 +5382,26 @@ QAllEAsRetry: temp_fea = ea_response_data->list; temp_ptr = (char *)temp_fea; while (list_len > 0) { + __u8 name_len; __u16 value_len; list_len -= 4; temp_ptr += 4; - rc += temp_fea->name_len; + /* make sure we can read name_len and value_len */ + if (temp_ptr > end_of_smb) { + cFYI(1, ("fealist goes beyond end of SMB")); + rc = -EIO; + goto QAllEAsOut; + } + + name_len = temp_fea->name_len; + value_len = le16_to_cpu(temp_fea->value_len); + if (temp_ptr + name_len + value_len > end_of_smb) { + cFYI(1, ("fealist goes beyond end of SMB")); + rc = -EIO; + goto QAllEAsOut; + } + + rc += name_len; /* account for prefix user. and trailing null */ rc = rc + 5 + 1; if (rc < (int) buf_size) { @@ -5399,7 +5424,6 @@ QAllEAsRetry: /* account for trailing null */ list_len--; temp_ptr++; - value_len = le16_to_cpu(temp_fea->value_len); list_len -= value_len; temp_ptr += value_len; /* BB check that temp_ptr is still