From patchwork Mon Jan 30 21:39:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovskiy X-Patchwork-Id: 9546143 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B290060425 for ; Mon, 30 Jan 2017 21:58:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE12D283EB for ; Mon, 30 Jan 2017 21:58:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A1210283EF; Mon, 30 Jan 2017 21:58:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 533FB283EB for ; Mon, 30 Jan 2017 21:58:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752943AbdA3V6o (ORCPT ); Mon, 30 Jan 2017 16:58:44 -0500 Received: from mail-co1nam03on0131.outbound.protection.outlook.com ([104.47.40.131]:2714 "EHLO NAM03-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752901AbdA3V6l (ORCPT ); Mon, 30 Jan 2017 16:58:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=bfawo6uwQ1Fv+iM72EL/I/rk8lX+x1aGNHtNEqdsCdM=; b=nd7cCZOFhWKfeVzOVDAuVBRvGZNvvD142OXATUjGlGnKODYnlmOOt/3BspF6A0ZzsHC19E77eS9r7EHe0pKAsGkbuUNffJJrOeYuAoUGSrqyS+GRb0O8CbcwMn3+lpC7y1ZoE86me1afWequLh08DegAv0wdV7lAuz7GuTZVzB0= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=pshilov@microsoft.com; Received: from ubuntu-vm.corp.microsoft.com (2001:4898:80e8:b::63b) by BN6PR03MB2545.namprd03.prod.outlook.com (10.173.142.148) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.874.12; Mon, 30 Jan 2017 21:39:58 +0000 From: Pavel Shilovsky To: Subject: [PATCH v2 07/15] CIFS: Add capability to transform requests before sending Date: Mon, 30 Jan 2017 13:39:36 -0800 Message-ID: <1485812384-28870-8-git-send-email-pshilov@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1485812384-28870-1-git-send-email-pshilov@microsoft.com> References: <1485812384-28870-1-git-send-email-pshilov@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:b::63b] X-ClientProxiedBy: BN6PR1401CA0011.namprd14.prod.outlook.com (10.174.237.149) To BN6PR03MB2545.namprd03.prod.outlook.com (10.173.142.148) X-MS-Office365-Filtering-Correlation-Id: b2affa71-1a10-45b5-2c62-08d4495889e7 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:BN6PR03MB2545; X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2545; 3:zH1gNchrflt5fcab8L9fWmpuXb2JbgQKYOMrh6Uno6HIHhpiH/3m2m/rNdja0ohcIvsZH/M04BRvuQCk0Q3akiQLNdtHSWCm9he7dwK0x91usdVaNRNJzLeyXS4ZkODA5h7LbMOKcZn3SNh2KFD3zQoVlBz5/P67hmZX2EO003/bf5Fd96HZ3WtevbuRGM06OEhXK3gnwuo1MzfXvXd3q+IIvyTonp5fI+l1FkvszogCn5I4k7x+16c/aP76p+a92vwLux3IcHKHhn8j8rPdHw== X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2545; 25:OtkyQ8SfXm23ub3htDSJNhVv7/mGwSXw4woKQHXv34H1gQiQ22dPvEwKpCYPM4cBXV84JCn6HUjOkYh220vHpW6yfNQvtiPtP2ncu0+CAI5dPnVFMAVKZh2xXLRoUREoJO11aHknncAVwW0JRhsDSXAqyxqhWNi2ZdX94VNiW1oVUQw3vuqZ/cil9ZOiQcDeV7fqOgyob52Lj+0gbf0juVEPR8vcXIKovri0J8YfZGvkSOJt2itNyJvVoxn3skjvXux85rVFxbeQooPK8EPLGkhKyLjU1k/cKMoe37GKCSsa+5dhE++ZbuJPfps2HsbUGXXZJwEwG/MvKjpdg8SsM7gXRNp84BleVqbv2dOAi2t0pSHio5Qe++rzb+T44QKSpZ9Fyt/CEju5rKUVzk5bBYnkGnHjB1qSyRMFDkOwxHQlmOojgW+pROjpckP5Y6TVkhnixrXKi0WPr7RjKj6m/Sh+b793m1s7n/C4gspeVm5Yoiwb7sAAAfvoCC9dsSpHsUljKW23N//j9HuTIYCwkvgGHvFzkk5+az1uQv0gI0/RjLQyG8KEUmFz19dvQJKIsDBhsjFKYtpba0IPdBgZOqZQZWmaE4zxuZDx1+QhK7pvG2O1dSqSvmqpRfCr6d3Hh/v34QrcUbJhXNTc62YlLOGgNeugUGNG9cf+HgXoj+++HeRXJsropfd42STWNYNwBaPcO74WDgKz8K/yRAyAmel6rK8ez+ocFXTJKmHMxxk= X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2545; 31:WH/DizTwalXQdX14xz0QkR4PTVaEti1nEGRMoMbRyH4Z9HucwTOytWiPenvIMII6zmT/FedtTJraupv5ItTJzRnLxH1lCC5UluS8HKP1z2SkNCbIUVOmY1zPsibw8S3kdN3JuvInO02vMDU/B3xM6bsm+EiGfLUO+F8a/dtuoB9s+wHZvztFhOb82svSwn2mLqou3HKqff8nNIUX/a9S1WA7QL8+jFR9gdiZSZlNkLFo4xZAJRglrHpe+lkOi+58/vRhLPpdVVArYwdslQRpGw==; 20:4IBgnZfcNEXjNprAkTzgNmopP0ktu0i7ZNqOFDAClT+SDZMUHIcY5Sqk1cTSkF3qqvqTgcsRl9B60CDaigOSXcCplNTL8qujJ1zH59n3a4+6GTVByWHzli3fltb0JmYxKFQbDvA5F+i0HWWLYc/rzl9ZOeDYnv7MfjHKLMJVHjbAlVtdsBKtjAHZxg7Gd6515tQJXGlFO0Ml8CNPyJ7vzZT8iZzcBc+vTsgha6k3yerKN0H9NgGMcw+W1VrP87vwM2OyHcGuZeZzfqsNgHNF9k10QU7kjWZnmNCv0U7XVOmKQ55WkhBdrqYLp65/P4954MT4TC9QmggwbYxOT4N6OO5c4gzcarZM00HejHInqrG/YifgniqAYsSNGBd7laC0wB8K1Zo2E1aaBnyS4h/o2WLA/vewE0e7f+Au6Z2LiIYX5YaoUrFMpRgZ+3q/fIj2PJAEQ+v+zZdm9/AIKs12JfSESFB+rLWzvSOJQqRR1aNy5Jp02tL4jvF3UaWu0mjd X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(158342451672863)(192374486261705); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026)(6041248)(20161123555025)(20161123564025)(20161123562025)(20161123560025)(6042181)(6072148)(6047074); SRVR:BN6PR03MB2545; BCL:0; PCL:0; RULEID:; SRVR:BN6PR03MB2545; X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2545; 4:30wssk+VX1RKFFyBf0oaFy4T0nT8K0/5aKZNEgV4fJX6a+VL68i8bl5Lqm0lRHTG0pSxSfmUzTPypPJM6bd8VbzWhdTdVw5gMyQQXJc9Sir8urZdnuLh07TEorgo5+JTZ+imlxTYmtB0eSIHQpbHTu6XNPQidI23wjEYxk/dG9IjRUyuQgt1iIxqOMgqjmm4os8CbaDo8xvtbM7wZ25VOKwKXDxglpoGAertu9a7H8OuSH1DsGZswyB+V9vcW73wlG2iCwgF52IZEmh7iA4VZ1Nge4s7brOPFZWRV3tOPlUtj3JS4ojpY9+4Nmyv9uQWbnHJ8K6N9Kwc1/UH9USo0eP2+AVafM/9eWGtKAWWnupJlPcd6tl3SWIl57FIoRD2Sd2vlwa10U5bgURFhxi4yPYrKFdf43SVjpCQFa+KpqyCJobmf5HKeGOBT1/gClzC1wmsyGlaMK7uudWlB1rARNsnaVBSIdSWi8YhrM4gnA/nkrVJdqz6tOfBAdkOegFVeCVHiyQmbO1TilpdZwNrkxJV316uaW0PskDzhDvwoTbs2dOM+ribqe4NZxY49WeYLlt9giRG1kKkZ+xBdj1dccy/78oTsa7midgURFYWmlV2SQSe7OIJxrYuH4QulGG1qWg4NBGEQdXha+q8mHm3YdUwwx8HvstoHaxN7PSSJxX8Xf79L/USueprNFlTgXRAyACA/RRGWxDdYG1BM6r3mQ== X-Forefront-PRVS: 0203C93D51 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(189002)(199003)(69234005)(86612001)(38730400001)(25786008)(6916009)(6666003)(106356001)(2950100002)(189998001)(50986999)(76176999)(86362001)(50226002)(105586002)(68736007)(107886002)(97736004)(2906002)(450100001)(6486002)(53936002)(101416001)(42186005)(8676002)(5660300001)(81166006)(305945005)(50466002)(81156014)(48376002)(5003940100001)(6116002)(36756003)(2351001)(92566002)(10290500002)(110136003)(7736002)(10090500001)(33646002)(47776003)(5005710100001); DIR:OUT; SFP:1102; SCL:1; SRVR:BN6PR03MB2545; H:ubuntu-vm.corp.microsoft.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN6PR03MB2545; 23:DDi6Cu2a6jxsAPmKYJ4FnNSsG2OVk/fe23Tsgn+gd?= =?us-ascii?Q?OvxfDiTOeMCpHTj2NACAnhqzC6DLPLOH+YK0iUSlIjtYPMXg4WNITPOJ86Ib?= =?us-ascii?Q?nuDMqy+ZDMGbwXjFHCRDgRmpcaRDLz+EHZCSfW0/dk22R2VDW7+lf+DZ54uc?= =?us-ascii?Q?K52FBQYIyiJpp/yqHAqP2mWZ88pBMARqMPTbqrtto3vem+yAnoC2Fy0+nTri?= =?us-ascii?Q?wlW2ACEe+k+woSE3nheoHtzXwPBLbZrItSgM5LdsHOgQx8+dTQVECy/IhMwf?= =?us-ascii?Q?gsz2oK32YXlwGIeZNTXy4hxZV8LNplD8adi05mnUeplFoqY3LS84moH5xPCP?= =?us-ascii?Q?QNK2YwL0VgoKIPQC0YMX5aPqHPxqbpkosrvhYz4L3GPhdeMbIwKZMBNyfI2w?= =?us-ascii?Q?BS2F/O0dnZvxLH24X4VYJEDUCGCohcCmPmOFcKLurjZ3/OjJltomDhjDmZy0?= =?us-ascii?Q?qtYo30e3b+ROK7dcXSQUeXrcaqynSw4P/OWFKLWrU/2QMuBI61psIOg8Wesu?= =?us-ascii?Q?QwZp285Xcc/pwJuWobax0RxVDUjdor6r8CiMxx23USCJTyZ7x2Tdk74v64Xr?= =?us-ascii?Q?K592OMH284z5TXRJnWYg7NNnPvzh6HfXfrlWI2m53ClfNEHNeBuWKuZedwN9?= =?us-ascii?Q?tADV7Qw9LYt8tHf64w+s70Wtm8fsHa75id9pe2sCBX3CYsGTiNBFwAFrNtIX?= =?us-ascii?Q?E+4vRDDhilob0jZ/YysjMNVUW6LSe7ee+aBZnnxUG+jqurfbhRKMpb7AyQQw?= =?us-ascii?Q?sns2gBszYklw6UWbJ+eqvvUoWSpEtycbTF3Phlya46G/OY/HUP2iN2+pH3aI?= =?us-ascii?Q?uNHSuCArwPmo7DyOY2YvsDbVInD5Omsaiwb4b1o/jbc0IQzb6jdIWTmVoHFV?= =?us-ascii?Q?Jx/NQ9vSLURQ8JKXjvr88fUAXnEgmX/wReXjm4TTi/mOvVbbLFWLy+WX9fNa?= =?us-ascii?Q?qemGCG4Amsd61wjFM4NjWT6Wd7UFkorbcRVqroCJ2DrS3xeJvYBGtEMgxgRl?= =?us-ascii?Q?lmbvkoe1KAcbbmdYi88h5LFSWrWeddxQlVV2g/qfnzN1UW1xi7/9sconWsfc?= =?us-ascii?Q?6uH0BXq1HawO81d4Yy2smZIB55bpH9NIc1EnRT18/ip9fArlrDQM2mKTWTtJ?= =?us-ascii?Q?hewxkpNoHXwmeEmvX10Vj39lfgkh3cKMbRRIGL5u41f6TBGbPsZ9A=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2545; 6:Bg9GCiK7J2mBa9NR0Twu9YaoVhIlnRny8l8z+2+qncW9dkqbBBAJiQt9NH7p2km0GrqTMVKkzfmbbwcOi1pNGcTwIjEV8x6qw1QGKIKhbdjO2Y7uoG1NsuOXTZN9AX3/ARhXOuh5/7jrAup0WvPX+T+RPgqL+ZSDJurvQGKP21wE97HHeB+onBaOYRQh7oGlygJ8YU1c3UR/+PXHQsGGJLBEAF9pRW2Z+bsveX9lA3xv9ITYOlOVKHa/J9SrL9Cd2iUFs9UPG5HAbhfP3el1NNHXUWlrh6AL9QbdfK5kCeejHcq8FRzJ/rjEH/GjFn7JNQLgfl5U2d8tM3m5s2bnkfpX2Att513QKWDDBaJX0oL0EgQzOgp6o28xhDuvbCB4Z1qvqbbKiVMbSzaFWzUZ5ogc106Rl4Ol8B3AtVHOX2/nvosss1RUQLoDzS6/Vjqa; 5:acsZwOguRCEe1spHQzWgSk94c6fvGLWJo2Lx3zTl8ujDg8c09A2k4g/9gFhq7ZPguklYvXvB5AWPr6XQKiiwFitfsXazDDm+GB0bwRLIJ5plAMopbh28Na6KF7Y+qMSfe6vaCcaiRYDJcwgJkytH69sK89aGt1GXwcK/l34quJs=; 24:bQqOgMtXGL8XTF3LCWOhVHJ3ZZSixEBYOjJfynUEi6Fnc5IsexOy28VBTkkb20J9u8jAFkIm8SgvqEO8x968cEZ9FgMX+FENcr+S5A2w/1E= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2545; 7:t0OUgeUTRRuJ4vvaasqnVqVZXckbmBzt3Ni2p9cFRkxBeS9IYZ/p15Ayj86RTaETlwj+XUr50VH9CuoPGtw5TbnUlT+AnerWjX0dH1QocmP18U5An81Fu+mDUUsaIRcRvQwRs+QyS1ODn2m9eBl6qwgIHtUD4AV1W4hFteCkoa/xYdzzVHzws2mRntd65BoMGvlXKinB8R6YT505VNnu0H/AxoOAIC+FkGkaEy0+zC2H7pNRIOKKZj42/LhkYE3eJYLU1y8Ns6eg2eN1a7SHbq9pCPY8nMwaWsus0NO523ZHNeKK7/wSwHP8VJ+WsC6Ntiel4IiX1irwZieLyJd8tstzSX9CJbprxBGzJ9qHWRZijKj/semn77B/7JSCCcfcPUb1Uf3qZVmr1zthV0dLF5zv/HF04hTY0NURm1ya7K1zNHiAlm77uC6SQjEx3hN0d4ZCWZlcSOdIXly4Xwxjow== X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2017 21:39:58.3389 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR03MB2545 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This will allow us to do protocol specific tranformations of packets before sending to the server. For SMB3 it can be used to support encryption. Signed-off-by: Pavel Shilovsky --- fs/cifs/cifsglob.h | 7 +++ fs/cifs/smb2pdu.c | 129 ++++++++++++++++++++++++++++++++++++++++++---------- fs/cifs/transport.c | 33 ++++++++++---- 3 files changed, 136 insertions(+), 33 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 5a89875..8ec9e1a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -433,6 +433,11 @@ struct smb_version_operations { bool (*dir_needs_close)(struct cifsFileInfo *); long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t, loff_t); + /* init transform request - used for encryption for now */ + int (*init_transform_rq)(struct TCP_Server_Info *, struct smb_rqst *, + struct smb_rqst *); + /* free transform request */ + void (*free_transform_rq)(struct smb_rqst *); }; struct smb_version_values { @@ -1473,7 +1478,9 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, #define CIFS_OBREAK_OP 0x0100 /* oplock break request */ #define CIFS_NEG_OP 0x0200 /* negotiate request */ #define CIFS_OP_MASK 0x0380 /* mask request type */ + #define CIFS_HAS_CREDITS 0x0400 /* already has credits */ +#define CIFS_TRANSFORM_REQ 0x0800 /* transform request before sending */ /* Security Flags: indicate type of session setup needed */ #define CIFSSEC_MAY_SIGN 0x00001 diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index d1a9037..bf5b693 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -77,6 +77,13 @@ static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = { /* SMB2_OPLOCK_BREAK */ 24 /* BB this is 36 for LEASE_BREAK variant */ }; +static int encryption_required(const struct cifs_tcon *tcon) +{ + if ((tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) || + (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA)) + return 1; + return 0; +} static void smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd, @@ -130,7 +137,8 @@ smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd, /* if (tcon->share_flags & SHI1005_FLAGS_DFS) shdr->Flags |= SMB2_FLAGS_DFS_OPERATIONS; */ - if (tcon->ses && tcon->ses->server && tcon->ses->server->sign) + if (tcon->ses && tcon->ses->server && tcon->ses->server->sign && + !encryption_required(tcon)) shdr->Flags |= SMB2_FLAGS_SIGNED; out: return; @@ -423,7 +431,6 @@ static void assemble_neg_contexts(struct smb2_negotiate_req *req) } #endif /* SMB311 */ - /* * * SMB2 Worker functions follow: @@ -1070,6 +1077,7 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses) struct smb2_logoff_req *req; /* response is also trivial struct */ int rc = 0; struct TCP_Server_Info *server; + int flags = 0; cifs_dbg(FYI, "disconnect session %p\n", ses); @@ -1088,10 +1096,13 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses) /* since no tcon, smb2_init can not do this, so do here */ req->hdr.sync_hdr.SessionId = ses->Suid; - if (server->sign) + + if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) + flags |= CIFS_TRANSFORM_REQ; + else if (server->sign) req->hdr.sync_hdr.Flags |= SMB2_FLAGS_SIGNED; - rc = SendReceiveNoRsp(xid, ses, (char *) req, 0); + rc = SendReceiveNoRsp(xid, ses, (char *) req, flags); cifs_small_buf_release(req); /* * No tcon so can't do @@ -1130,6 +1141,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, int unc_path_len; struct TCP_Server_Info *server; __le16 *unc_path = NULL; + int flags = 0; cifs_dbg(FYI, "TCON\n"); @@ -1164,6 +1176,9 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, return rc; } + if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) + flags |= CIFS_TRANSFORM_REQ; + if (tcon == NULL) { /* since no tcon, smb2_init can not do this, so do here */ req->hdr.sync_hdr.SessionId = ses->Suid; @@ -1184,7 +1199,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, inc_rfc1001_len(req, unc_path_len - 1 /* pad */); - rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base; @@ -1252,6 +1267,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) int rc = 0; struct TCP_Server_Info *server; struct cifs_ses *ses = tcon->ses; + int flags = 0; cifs_dbg(FYI, "Tree Disconnect\n"); @@ -1267,7 +1283,10 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) if (rc) return rc; - rc = SendReceiveNoRsp(xid, ses, (char *)req, 0); + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + + rc = SendReceiveNoRsp(xid, ses, (char *)req, flags); cifs_small_buf_release(req); if (rc) cifs_stats_fail_inc(tcon, SMB2_TREE_DISCONNECT_HE); @@ -1539,6 +1558,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, unsigned int n_iov = 2; __u32 file_attributes = 0; char *dhc_buf = NULL, *lc_buf = NULL; + int flags = 0; cifs_dbg(FYI, "create/open\n"); @@ -1551,6 +1571,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + if (oparms->create_options & CREATE_OPTION_READONLY) file_attributes |= ATTR_READONLY; if (oparms->create_options & CREATE_OPTION_SPECIAL) @@ -1630,7 +1653,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, dhc_buf = iov[n_iov-1].iov_base; } - rc = SendReceive2(xid, ses, iov, n_iov, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, n_iov, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_create_rsp *)rsp_iov.iov_base; @@ -1684,6 +1707,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, int resp_buftype; int n_iov; int rc = 0; + int flags = 0; cifs_dbg(FYI, "SMB2 IOCTL\n"); @@ -1708,6 +1732,9 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->CtlCode = cpu_to_le32(opcode); req->PersistentFileId = persistent_fid; req->VolatileFileId = volatile_fid; @@ -1758,7 +1785,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, iov[0].iov_len = get_rfc1002_length(req) + 4; - rc = SendReceive2(xid, ses, iov, n_iov, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, n_iov, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_ioctl_rsp *)rsp_iov.iov_base; @@ -1847,6 +1874,7 @@ SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, struct kvec rsp_iov; int resp_buftype; int rc = 0; + int flags = 0; cifs_dbg(FYI, "Close\n"); @@ -1859,6 +1887,9 @@ SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->PersistentFileId = persistent_fid; req->VolatileFileId = volatile_fid; @@ -1866,7 +1897,7 @@ SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, /* 4 for rfc1002 length field */ iov[0].iov_len = get_rfc1002_length(req) + 4; - rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_close_rsp *)rsp_iov.iov_base; @@ -1952,6 +1983,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, int resp_buftype; struct TCP_Server_Info *server; struct cifs_ses *ses = tcon->ses; + int flags = 0; cifs_dbg(FYI, "Query Info\n"); @@ -1964,6 +1996,9 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->InfoType = SMB2_O_INFO_FILE; req->FileInfoClass = info_class; req->PersistentFileId = persistent_fid; @@ -1977,7 +2012,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, /* 4 for rfc1002 length field */ iov[0].iov_len = get_rfc1002_length(req) + 4; - rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; @@ -2137,6 +2172,7 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, struct kvec rsp_iov; int resp_buftype; int rc = 0; + int flags = 0; cifs_dbg(FYI, "Flush\n"); @@ -2149,6 +2185,9 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->PersistentFileId = persistent_fid; req->VolatileFileId = volatile_fid; @@ -2156,7 +2195,7 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, /* 4 for rfc1002 length field */ iov[0].iov_len = get_rfc1002_length(req) + 4; - rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); if (rc != 0) @@ -2326,6 +2365,9 @@ smb2_async_readv(struct cifs_readdata *rdata) return rc; } + if (encryption_required(io_parms.tcon)) + flags |= CIFS_TRANSFORM_REQ; + req_len = cpu_to_be32(total_len); rdata->iov[0].iov_base = &req_len; @@ -2344,7 +2386,7 @@ smb2_async_readv(struct cifs_readdata *rdata) le16_to_cpu(shdr->CreditCharge); spin_unlock(&server->req_lock); wake_up(&server->request_q); - flags = CIFS_HAS_CREDITS; + flags |= CIFS_HAS_CREDITS; } kref_get(&rdata->refcount); @@ -2374,12 +2416,17 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, __be32 req_len; struct smb_rqst rqst = { .rq_iov = iov, .rq_nvec = 2 }; + int flags = CIFS_LOG_ERROR; + struct cifs_ses *ses = io_parms->tcon->ses; *nbytes = 0; rc = smb2_new_read_req((void **)&req, &total_len, io_parms, 0, 0); if (rc) return rc; + if (encryption_required(io_parms->tcon)) + flags |= CIFS_TRANSFORM_REQ; + req_len = cpu_to_be32(total_len); iov[0].iov_base = &req_len; @@ -2387,8 +2434,7 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, iov[1].iov_base = req; iov[1].iov_len = total_len; - rc = cifs_send_recv(xid, io_parms->tcon->ses, &rqst, &resp_buftype, - CIFS_LOG_ERROR, &rsp_iov); + rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_read_rsp *)rsp_iov.iov_base; @@ -2507,6 +2553,9 @@ smb2_async_writev(struct cifs_writedata *wdata, goto async_writev_out; } + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + shdr = get_sync_hdr(req); shdr->ProcessId = cpu_to_le32(wdata->cfile->pid); @@ -2550,7 +2599,7 @@ smb2_async_writev(struct cifs_writedata *wdata, le16_to_cpu(shdr->CreditCharge); spin_unlock(&server->req_lock); wake_up(&server->request_q); - flags = CIFS_HAS_CREDITS; + flags |= CIFS_HAS_CREDITS; } kref_get(&wdata->refcount); @@ -2582,6 +2631,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, struct smb2_write_rsp *rsp = NULL; int resp_buftype; struct kvec rsp_iov; + int flags = 0; *nbytes = 0; @@ -2595,6 +2645,9 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, if (io_parms->tcon->ses->server == NULL) return -ECONNABORTED; + if (encryption_required(io_parms->tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->hdr.sync_hdr.ProcessId = cpu_to_le32(io_parms->pid); req->PersistentFileId = io_parms->persistent_fid; @@ -2617,7 +2670,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, inc_rfc1001_len(req, io_parms->length - 1 /* Buffer */); rc = SendReceive2(xid, io_parms->tcon->ses, iov, n_vec + 1, - &resp_buftype, 0, &rsp_iov); + &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_write_rsp *)rsp_iov.iov_base; @@ -2693,6 +2746,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, char *end_of_smb; unsigned int output_size = CIFSMaxBufSize; size_t info_buf_size; + int flags = 0; if (ses && (ses->server)) server = ses->server; @@ -2703,6 +2757,9 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + switch (srch_inf->info_level) { case SMB_FIND_FILE_DIRECTORY_INFO: req->FileInformationClass = FILE_DIRECTORY_INFORMATION; @@ -2747,7 +2804,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, inc_rfc1001_len(req, len - 1 /* Buffer */); - rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base; @@ -2815,6 +2872,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, unsigned int i; struct TCP_Server_Info *server; struct cifs_ses *ses = tcon->ses; + int flags = 0; if (ses && (ses->server)) server = ses->server; @@ -2834,6 +2892,9 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, return rc; } + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->hdr.sync_hdr.ProcessId = cpu_to_le32(pid); req->InfoType = SMB2_O_INFO_FILE; @@ -2861,7 +2922,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, iov[i].iov_len = size[i]; } - rc = SendReceive2(xid, ses, iov, num, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, num, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_set_info_rsp *)rsp_iov.iov_base; @@ -2991,19 +3052,22 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, { int rc; struct smb2_oplock_break *req = NULL; + int flags = CIFS_OBREAK_OP; cifs_dbg(FYI, "SMB2_oplock_break\n"); rc = small_smb2_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req); - if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->VolatileFid = volatile_fid; req->PersistentFid = persistent_fid; req->OplockLevel = oplock_level; req->hdr.sync_hdr.CreditRequest = cpu_to_le16(1); - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, CIFS_OBREAK_OP); + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, flags); cifs_small_buf_release(req); if (rc) { @@ -3069,6 +3133,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, int resp_buftype; struct cifs_ses *ses = tcon->ses; struct smb2_fs_full_size_info *info = NULL; + int flags = 0; rc = build_qfs_info_req(&iov, tcon, FS_FULL_SIZE_INFORMATION, sizeof(struct smb2_fs_full_size_info), @@ -3076,7 +3141,10 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; - rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0, &rsp_iov); + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + + rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(iov.iov_base); if (rc) { cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); @@ -3108,6 +3176,7 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, int resp_buftype, max_len, min_len; struct cifs_ses *ses = tcon->ses; unsigned int rsp_len, offset; + int flags = 0; if (level == FS_DEVICE_INFORMATION) { max_len = sizeof(FILE_SYSTEM_DEVICE_INFO); @@ -3128,7 +3197,10 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; - rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0, &rsp_iov); + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + + rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(iov.iov_base); if (rc) { cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); @@ -3173,6 +3245,7 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, struct kvec rsp_iov; int resp_buf_type; unsigned int count; + int flags = CIFS_NO_RESP; cifs_dbg(FYI, "smb2_lockv num lock %d\n", num_lock); @@ -3180,6 +3253,9 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->hdr.sync_hdr.ProcessId = cpu_to_le32(pid); req->LockCount = cpu_to_le16(num_lock); @@ -3196,7 +3272,7 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, iov[1].iov_len = count; cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); - rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP, + rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, flags, &rsp_iov); cifs_small_buf_release(req); if (rc) { @@ -3230,13 +3306,16 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon, { int rc; struct smb2_lease_ack *req = NULL; + int flags = CIFS_OBREAK_OP; cifs_dbg(FYI, "SMB2_lease_break\n"); rc = small_smb2_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req); - if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->hdr.sync_hdr.CreditRequest = cpu_to_le16(1); req->StructureSize = cpu_to_le16(36); inc_rfc1001_len(req, 12); @@ -3244,7 +3323,7 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon, memcpy(req->LeaseKey, lease_key, 16); req->LeaseState = lease_state; - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, CIFS_OBREAK_OP); + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, flags); cifs_small_buf_release(req); if (rc) { diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 713981b2..bc5f55f 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -220,7 +220,7 @@ rqst_len(struct smb_rqst *rqst) } static int -smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) +__smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) { int rc; struct kvec *iov = rqst->rq_iov; @@ -312,12 +312,27 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) } static int -smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) +smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst, int flags) { - struct smb_rqst rqst = { .rq_iov = iov, - .rq_nvec = n_vec }; + struct smb_rqst cur_rqst; + int rc; + + if (!(flags & CIFS_TRANSFORM_REQ)) + return __smb_send_rqst(server, rqst); + + if (!server->ops->init_transform_rq || + !server->ops->free_transform_rq) { + cifs_dbg(VFS, "Encryption requested but transform callbacks are missed\n"); + return -EIO; + } - return smb_send_rqst(server, &rqst); + rc = server->ops->init_transform_rq(server, &cur_rqst, rqst); + if (rc) + return rc; + + rc = __smb_send_rqst(server, &cur_rqst); + server->ops->free_transform_rq(&cur_rqst); + return rc; } int @@ -325,13 +340,15 @@ smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, unsigned int smb_buf_length) { struct kvec iov[2]; + struct smb_rqst rqst = { .rq_iov = iov, + .rq_nvec = 2 }; iov[0].iov_base = smb_buffer; iov[0].iov_len = 4; iov[1].iov_base = (char *)smb_buffer + 4; iov[1].iov_len = smb_buf_length; - return smb_sendv(server, iov, 2); + return __smb_send_rqst(server, &rqst); } static int @@ -523,7 +540,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, cifs_in_send_inc(server); - rc = smb_send_rqst(server, rqst); + rc = smb_send_rqst(server, rqst, flags); cifs_in_send_dec(server); cifs_save_when_sent(mid); @@ -717,7 +734,7 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, midQ->mid_state = MID_REQUEST_SUBMITTED; cifs_in_send_inc(ses->server); - rc = smb_send_rqst(ses->server, rqst); + rc = smb_send_rqst(ses->server, rqst, flags); cifs_in_send_dec(ses->server); cifs_save_when_sent(midQ);