Received: by 10.192.165.148 with SMTP id m20csp547348imm; Fri, 20 Apr 2018 10:59:40 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/4hYliGBMrgsCsnPjV5XUtM6qGHHiWl2YqRZdsRW2nInTW7Ja/Tj87Lfkn6GN2fhk054yr X-Received: by 2002:a17:902:8d98:: with SMTP id v24-v6mr10977695plo.146.1524247180114; Fri, 20 Apr 2018 10:59:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524247180; cv=none; d=google.com; s=arc-20160816; b=Zmf/tgj48tBrglkuRuq6dv8q3u+zdtH9XEYZDIvXyDt40/2ysNPPtWJXj76HNYAEjr 7AFLTiIB/PxMbTEXTi0TAVZFm0f0TybADvm2YlVVheM6QtXbwOWtl4PseIqljquF6UP+ W+jHsJKwln1QVxFalz7nMB3bNPVA06SItletmQOib7RVoVz8PuekLtJSQ/SBIaH+ESzU ki8fdF+cW11Oaz/1uWjrdLLxgHdObc7xuqk2S7mY2NKzQSJ5L0HfQaS4Xziq/JtnyQmT DiPa09YAkjzRgBapoEBU36Au6HS6Y8G8hloSCuqbFiYQf+Es/BtfFIqOQxSUxwMvWyMe 5mYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=6Lpu+ZQKh5qpbVybCEV1gJIOtMO6beClqjIbwbe7qvI=; b=gDMfJP5EuseVy284B6tkIHXn4Cnb1Gp218gi8N+vx+jY5T75GJpe5Dnq7R/zu2HX3f j24jqFeUsz+DVbVFMUdUhTo2MJXtpr/3rcFK0IYA2OmZ8e7SAIervvwiJ0THd7k+TRxp Amz0I/Fg/qi38w6/g5KDB7f+iu8jobX+VjYmJbKiHsdZQlIcdnromWP6MXIg9gEwg3Hu HXddS6p0ipUyDxnajU3vMphMNoTTix9jabd3THv9vJswxHX6/Yl7iL4bdd/ic9UlCrAa lE7aO/3xAGaSyPzlftJFal0gxVkyuZWhPG+eLmm9LgP+E3GpkeXuHqNXEos2ezU9p5Oz AhHw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=kkOmt2FU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g10-v6si6299747plb.272.2018.04.20.10.59.25; Fri, 20 Apr 2018 10:59:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=kkOmt2FU; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753544AbeDTR6Q (ORCPT + 99 others); Fri, 20 Apr 2018 13:58:16 -0400 Received: from mail-lf0-f66.google.com ([209.85.215.66]:43246 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752778AbeDTR6O (ORCPT ); Fri, 20 Apr 2018 13:58:14 -0400 Received: by mail-lf0-f66.google.com with SMTP id v207-v6so6276175lfa.10; Fri, 20 Apr 2018 10:58:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=6Lpu+ZQKh5qpbVybCEV1gJIOtMO6beClqjIbwbe7qvI=; b=kkOmt2FU2BaABqobmodESb7SRH/qwUVxsFhfYIinlorkCFlWwUlJoQHkwABuZgIWV9 ioEHZ0ymk2Cs2H3np5WaZrF8b57XA/AO3DCPKbqVsIYTuBbwYRY9aSTdWFlfcS4Qfoyl /7SF1KJ+IXsVLW0shM9yfcAIqxLxwR/aCjp+oLnmql6ZDOIQfusz6P9KWolaTGs0zuPR dmA502qpSM3JKls0ojMMU4VchLmuYvwCyUDKdeihSvMYbkk1OeTCsreKI64YXtnnNUIm 2PeRuJet1Ew93u1eQwekPvRV/oz4IfCBmmeilVIkcXzFu7OISHes7OcLBz0DLeskiw5a b+nA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=6Lpu+ZQKh5qpbVybCEV1gJIOtMO6beClqjIbwbe7qvI=; b=UMec8ouIfFG0pDGrTNSrUVAMQB4NiX0yjUwyWFLm7S95TRtDaUgmmszcFfWMWphlYb 2+i9t1vZToe8DC41ubLcum8ss24S81atN2zDaJFuZkB9whGjZymkNeNQZCmm6hgDixs+ FY2tLOrjV5IzmgF63IdlbOc1fDe0VSIfWHFMjveSRR+G6ih9NM+KQmLx1H4wwy/VrvmK BiJhLQL3NzVzmYV3BngWra9CpwgVBe1hb4QeFRU41J2VBywz54hQ+Epi74HCL8NQuYMR jyKH6jM8XrJXGNqk3kKg8pqeHYpzcfPqqwpTI7zLPKZ+bPvLhLEZY9o8KNSKgm6O5fiz oNxQ== X-Gm-Message-State: ALQs6tA6f3UmiB2jyFiKF0UQRJvUzedehY4prB0R0N8JmKMX172Or8fL nob/HLTrRKBgbzlr888xadvJMKQcy0XPiXh6UA== X-Received: by 2002:a19:9106:: with SMTP id t6-v6mr2368606lfd.91.1524247092085; Fri, 20 Apr 2018 10:58:12 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a19:d203:0:0:0:0:0 with HTTP; Fri, 20 Apr 2018 10:58:11 -0700 (PDT) In-Reply-To: References: <20180419213807.3128-1-longli@linuxonhyperv.com> From: Pavel Shilovsky Date: Fri, 20 Apr 2018 10:58:11 -0700 Message-ID: Subject: Re: [Patch v4] cifs: Allocate validate negotiation request through kmalloc To: Tom Talpey Cc: Long Li , Steve French , linux-cifs , samba-technical , Kernel Mailing List , linux-rdma@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 2018-04-20 7:55 GMT-07:00 Tom Talpey : > Looks good, but I have two possibly style-related comments. > > > On 4/19/2018 5:38 PM, Long Li wrote: >> >> From: Long Li >> >> The data buffer allocated on the stack can't be DMA'ed, ib_dma_map_page >> will >> return an invalid DMA address for a buffer on stack. Even worse, this >> incorrect address can't be detected by ib_dma_mapping_error. Sending data >> from this address to hardware will not fail, but the remote peer will get >> junk data. >> >> Fix this by allocating the request on the heap in smb3_validate_negotiate. >> >> Changes in v2: >> Removed duplicated code on freeing buffers on function exit. >> (Thanks to Parav Pandit ) >> Fixed typo in the patch title. >> >> Changes in v3: >> Added "Fixes" to the patch. >> Changed several sizeof() to use *pointer in place of struct. >> >> Changes in v4: >> Added detailed comments on the failure through RDMA. >> Allocate request buffer using GPF_NOFS. >> Fixed possible memory leak. >> >> Fixes: ff1c038addc4 ("Check SMB3 dialects against downgrade attacks") >> Signed-off-by: Long Li >> --- >> fs/cifs/smb2pdu.c | 61 >> ++++++++++++++++++++++++++++++------------------------- >> 1 file changed, 33 insertions(+), 28 deletions(-) >> >> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c >> index 0f044c4..caa2a1e 100644 >> --- a/fs/cifs/smb2pdu.c >> +++ b/fs/cifs/smb2pdu.c >> @@ -729,8 +729,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses >> *ses) >> int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon >> *tcon) >> { >> - int rc = 0; >> - struct validate_negotiate_info_req vneg_inbuf; >> + int ret, rc = -EIO; > > > Seems awkward to have "rc" and "ret", and based on the code below I > don't see why two variables are needed. Simplify? (see later comment) > > >> + struct validate_negotiate_info_req *pneg_inbuf; >> struct validate_negotiate_info_rsp *pneg_rsp = NULL; >> u32 rsplen; >> u32 inbuflen; /* max of 4 dialects */ >> @@ -741,7 +741,6 @@ int smb3_validate_negotiate(const unsigned int xid, >> struct cifs_tcon *tcon) >> if (tcon->ses->server->rdma) >> return 0; >> #endif >> - >> /* In SMB3.11 preauth integrity supersedes validate negotiate */ >> if (tcon->ses->server->dialect == SMB311_PROT_ID) >> return 0; >> @@ -764,63 +763,67 @@ int smb3_validate_negotiate(const unsigned int xid, >> struct cifs_tcon *tcon) >> if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) >> cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag >> sent by server\n"); >> - vneg_inbuf.Capabilities = >> + pneg_inbuf = kmalloc(sizeof(*pneg_inbuf), GFP_NOFS); >> + if (!pneg_inbuf) >> + return -ENOMEM; >> + >> + pneg_inbuf->Capabilities = >> >> cpu_to_le32(tcon->ses->server->vals->req_capabilities); >> - memcpy(vneg_inbuf.Guid, tcon->ses->server->client_guid, >> + memcpy(pneg_inbuf->Guid, tcon->ses->server->client_guid, >> SMB2_CLIENT_GUID_SIZE); >> if (tcon->ses->sign) >> - vneg_inbuf.SecurityMode = >> + pneg_inbuf->SecurityMode = >> cpu_to_le16(SMB2_NEGOTIATE_SIGNING_REQUIRED); >> else if (global_secflags & CIFSSEC_MAY_SIGN) >> - vneg_inbuf.SecurityMode = >> + pneg_inbuf->SecurityMode = >> cpu_to_le16(SMB2_NEGOTIATE_SIGNING_ENABLED); >> else >> - vneg_inbuf.SecurityMode = 0; >> + pneg_inbuf->SecurityMode = 0; >> if (strcmp(tcon->ses->server->vals->version_string, >> SMB3ANY_VERSION_STRING) == 0) { >> - vneg_inbuf.Dialects[0] = cpu_to_le16(SMB30_PROT_ID); >> - vneg_inbuf.Dialects[1] = cpu_to_le16(SMB302_PROT_ID); >> - vneg_inbuf.DialectCount = cpu_to_le16(2); >> + pneg_inbuf->Dialects[0] = cpu_to_le16(SMB30_PROT_ID); >> + pneg_inbuf->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); >> + pneg_inbuf->DialectCount = cpu_to_le16(2); >> /* structure is big enough for 3 dialects, sending only 2 >> */ >> inbuflen = sizeof(struct validate_negotiate_info_req) - 2; > > > The "- 2" is a little confusing here. This was existing code, but I > suggest you change this to a sizeof (u16) construct for consistency. > It's reducing by the length of a single Dialects[n] entry. I would suggest to make it "- sizeof(pneg_inbuf->Dialects[0])"... > >> } else if (strcmp(tcon->ses->server->vals->version_string, >> SMBDEFAULT_VERSION_STRING) == 0) { >> - vneg_inbuf.Dialects[0] = cpu_to_le16(SMB21_PROT_ID); >> - vneg_inbuf.Dialects[1] = cpu_to_le16(SMB30_PROT_ID); >> - vneg_inbuf.Dialects[2] = cpu_to_le16(SMB302_PROT_ID); >> - vneg_inbuf.DialectCount = cpu_to_le16(3); >> + pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); >> + pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); >> + pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); >> + pneg_inbuf->DialectCount = cpu_to_le16(3); >> /* structure is big enough for 3 dialects */ >> inbuflen = sizeof(struct validate_negotiate_info_req); >> } else { >> /* otherwise specific dialect was requested */ >> - vneg_inbuf.Dialects[0] = >> + pneg_inbuf->Dialects[0] = >> cpu_to_le16(tcon->ses->server->vals->protocol_id); >> - vneg_inbuf.DialectCount = cpu_to_le16(1); >> + pneg_inbuf->DialectCount = cpu_to_le16(1); >> /* structure is big enough for 3 dialects, sending only 1 >> */ >> inbuflen = sizeof(struct validate_negotiate_info_req) - 4; > > > > Ditto previous sizeof (u16) comment, with a *2 this case. ... and "- 2 * sizeof(pneg_inbuf->Dialects[0])" respectively. > >> } >> - rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, >> + ret = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, >> FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */, >> - (char *)&vneg_inbuf, sizeof(struct >> validate_negotiate_info_req), >> + (char *)pneg_inbuf, sizeof(*pneg_inbuf), >> (char **)&pneg_rsp, &rsplen); >> - if (rc != 0) { >> - cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", >> rc); >> - return -EIO; >> + if (ret) { >> + cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", >> ret); >> + goto out_free_inbuf; >> } > > > Why not leave "rc" alone, and set its value to -EIO before the goto > if the ioctl fails? That will simplify and make the code much more > readable IMO. > >> - if (rsplen != sizeof(struct validate_negotiate_info_rsp)) { >> + if (rsplen != sizeof(*pneg_rsp)) { >> cifs_dbg(VFS, "invalid protocol negotiate response size: >> %d\n", >> rsplen); >> /* relax check since Mac returns max bufsize allowed on >> ioctl */ >> if ((rsplen > CIFSMaxBufSize) >> || (rsplen < sizeof(struct >> validate_negotiate_info_rsp))) >> - goto err_rsp_free; >> + goto out_free_rsp; >> } > > > Would need an rc = -EIO here too if above comment is accepted. > > Tom. > >> /* check validate negotiate info response matches what we got >> earlier */ >> @@ -838,14 +841,16 @@ int smb3_validate_negotiate(const unsigned int xid, >> struct cifs_tcon *tcon) >> /* validate negotiate successful */ >> cifs_dbg(FYI, "validate negotiate info successful\n"); >> - kfree(pneg_rsp); >> - return 0; >> + rc = 0; >> + goto out_free_rsp; >> vneg_out: >> cifs_dbg(VFS, "protocol revalidation - security settings >> mismatch\n"); >> -err_rsp_free: >> +out_free_rsp: >> kfree(pneg_rsp); >> - return -EIO; >> +out_free_inbuf: >> + kfree(pneg_inbuf); >> + return rc; >> } >> enum securityEnum >> > -- > To unsubscribe from this list: send the line "unsubscribe linux-cifs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html