From patchwork Thu Nov 21 19:35:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 1199113 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="J2DV5nPO"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JqXV2vGPz9sPV for ; Fri, 22 Nov 2019 06:35:22 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726293AbfKUTfV (ORCPT ); Thu, 21 Nov 2019 14:35:21 -0500 Received: from mail-pg1-f196.google.com ([209.85.215.196]:44987 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726379AbfKUTfV (ORCPT ); Thu, 21 Nov 2019 14:35:21 -0500 Received: by mail-pg1-f196.google.com with SMTP id e6so2105787pgi.11 for ; Thu, 21 Nov 2019 11:35:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=h9W6RxF7x1shdmxCUUG6hVBc35iudolC+xIcbEzFS1Q=; b=J2DV5nPO3g8m2NO0UiF54VtILEqGu+0hsJ9SHoE7cRt+e77jSbVmOSn05tLBszPUQH g0b1iS5V3EM3rYanOQd5kEy130ggKZiRygMHA3+WwX7i8KKMTd0Znw5qOJILpgs9VbJz f+f8kHShNgJe0vCfavQYM2pcY6YuuBOi5ZgnFxTzzxFUUVzbTPNCitydeoHoA79Z4RMb UYvXFF3GlA98adwtjt2aFiRELN7v5GEag1dYyOvGtIQ7mb0JhWjuK37kV839/Pii+f3l /mfnDeWOYrbjWW79gXd0dicLAnaTXEm/gRMgEssL1DV1Ighvc5SzbUjtg1rA5Ddn2YHG xcgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=h9W6RxF7x1shdmxCUUG6hVBc35iudolC+xIcbEzFS1Q=; b=rn8PgqxoBLsyrFO4RWlddN/gpNF+Cq/30uy8yWL31TKKDqlq7gepny1ra1DhY6ALS3 ajy6XDyuxptwUwBhzh1brZ5KS1rtvreaqkvJqzu56jhakrRdHWrZUJgQKwXgarT5aeFC yzhBRLGC8bU0Td4RRZZd9WrdjHYamQRUCpF/OxTzQNR3xmP7nAgduhpqVaYQWnX/BUEE D/B7gCNpVJPFVjNwNlZCzbl3wS1XyWrFwFS7eAbXxxDXyRA3eZVG1qD5HfxhwBWhh5/j EGL0Ifkz5ERWTL4eJoyd9S8PgRkpZYx1ha/aFsCZQT4y5Rnwp3N4CRT7kxL86cMZ0U/1 beyw== X-Gm-Message-State: APjAAAWweeKTC0BXIbHXCnp4hHbCeLQEZJQwpyT0TT/WbrwpiGyc0F0V 5wgFsQUZDsWiM20lmgJHQw== X-Google-Smtp-Source: APXvYqxPxecy82FWJbcGAKM3RjqgTpW+W7Hl3M3xtySr3arVF4Q91gF66ZL5QS94PJJvZnUdZIowxw== X-Received: by 2002:a65:60c7:: with SMTP id r7mr11364486pgv.420.1574364920606; Thu, 21 Nov 2019 11:35:20 -0800 (PST) Received: from ubuntu-vm.mshome.net ([167.220.2.106]) by smtp.gmail.com with ESMTPSA id h185sm3972216pgc.87.2019.11.21.11.35.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Nov 2019 11:35:19 -0800 (PST) From: Pavel Shilovsky X-Google-Original-From: Pavel Shilovsky To: Steve French , Ronnie Sahlberg , Frank Sorenson , linux-cifs Subject: [PATCH 1/3] CIFS: Close open handle after interrupted close Date: Thu, 21 Nov 2019 11:35:12 -0800 Message-Id: <20191121193514.3086-1-pshilov@microsoft.com> X-Mailer: git-send-email 2.17.1 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org If Close command is interrupted before sending a request to the server the client ends up leaking an open file handle. This wastes server resources and can potentially block applications that try to remove the file or any directory containing this file. Fix this by putting the close command into a worker queue, so another thread retries it later. Cc: Stable Signed-off-by: Pavel Shilovsky --- fs/cifs/smb2misc.c | 59 ++++++++++++++++++++++++++++++++++----------- fs/cifs/smb2pdu.c | 16 +++++++++++- fs/cifs/smb2proto.h | 3 +++ 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index 527c9efd3de0..80a8f4b2daab 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -725,36 +725,67 @@ smb2_cancelled_close_fid(struct work_struct *work) kfree(cancelled); } +/* Caller should already has an extra reference to @tcon */ +static int +__smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid, + __u64 volatile_fid) +{ + struct close_cancelled_open *cancelled; + + cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); + if (!cancelled) + return -ENOMEM; + + cancelled->fid.persistent_fid = persistent_fid; + cancelled->fid.volatile_fid = volatile_fid; + cancelled->tcon = tcon; + INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); + WARN_ON(queue_work(cifsiod_wq, &cancelled->work) == false); + + return 0; +} + +int +smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid, + __u64 volatile_fid) +{ + int rc; + + cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count); + spin_lock(&cifs_tcp_ses_lock); + tcon->tc_count++; + spin_unlock(&cifs_tcp_ses_lock); + + rc = __smb2_handle_cancelled_close(tcon, persistent_fid, volatile_fid); + if (rc) + cifs_put_tcon(tcon); + + return rc; +} + int smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) { struct smb2_sync_hdr *sync_hdr = (struct smb2_sync_hdr *)buffer; struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; struct cifs_tcon *tcon; - struct close_cancelled_open *cancelled; + int rc; if (sync_hdr->Command != SMB2_CREATE || sync_hdr->Status != STATUS_SUCCESS) return 0; - cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); - if (!cancelled) - return -ENOMEM; - tcon = smb2_find_smb_tcon(server, sync_hdr->SessionId, sync_hdr->TreeId); - if (!tcon) { - kfree(cancelled); + if (!tcon) return -ENOENT; - } - cancelled->fid.persistent_fid = rsp->PersistentFileId; - cancelled->fid.volatile_fid = rsp->VolatileFileId; - cancelled->tcon = tcon; - INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); - queue_work(cifsiod_wq, &cancelled->work); + rc = __smb2_handle_cancelled_close(tcon, rsp->PersistentFileId, + rsp->VolatileFileId); + if (rc) + cifs_put_tcon(tcon); - return 0; + return rc; } /** diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 0aa40129dfb5..2f541e9efba1 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2942,7 +2942,21 @@ int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid) { - return SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0); + int rc; + int tmp_rc; + + rc = SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0); + + /* retry close in a worker thread if this one is interrupted */ + if (rc == -EINTR) { + tmp_rc = smb2_handle_cancelled_close(tcon, persistent_fid, + volatile_fid); + if (tmp_rc) + cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n", + persistent_fid, tmp_rc); + } + + return rc; } int diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 07ca72486cfa..e239f98093a9 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -203,6 +203,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, const u64 persistent_fid, const u64 volatile_fid, const __u8 oplock_level); +extern int smb2_handle_cancelled_close(struct cifs_tcon *tcon, + __u64 persistent_fid, + __u64 volatile_fid); extern int smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server); void smb2_cancelled_close_fid(struct work_struct *work); From patchwork Thu Nov 21 19:35:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 1199114 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Zi85fZsT"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JqXW0MjGz9sPW for ; Fri, 22 Nov 2019 06:35:23 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726541AbfKUTfW (ORCPT ); Thu, 21 Nov 2019 14:35:22 -0500 Received: from mail-pg1-f196.google.com ([209.85.215.196]:45151 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726379AbfKUTfW (ORCPT ); Thu, 21 Nov 2019 14:35:22 -0500 Received: by mail-pg1-f196.google.com with SMTP id k1so2103657pgg.12 for ; Thu, 21 Nov 2019 11:35:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=A4i9vGteXzznrRtlUFwaID48FmlFRXabJu6tjiCk2aY=; b=Zi85fZsTYNRkBlyNWe04DRZpfqLMFJBx8zAN/FYeCtHFpMp0K1BtVxrF1Z0msI/q6h HnA6ZDqFaD6PldUBfXXa9W0t1J/YdLYYsbeWvP963Z4MoQuwRqlJM+DDE0m8Ov/9Z8MK cYvG7d4AEPTIE0UAcZRZyxbPU9rPzlPCfusJkAFgkJ83whr1bawPI/WRF4WwH+TTe+zD Z1BHx4ENsQREd0r+rUJTJ5KBMToj4mVWIlzATqfGJyNAMlWR+z18BGuwbaKnLCsLqezj 6tlA/XoWrU1UxUEayqaYx1GU5SwXpmn8zoKkDkn0fwMSDEXoCZhhyllXvTLvguF0nelp hrpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=A4i9vGteXzznrRtlUFwaID48FmlFRXabJu6tjiCk2aY=; b=GoD31rgKeZC3X/r6WKP8IDtw8a5+K21a2XtqdNZnXjYLkyOXk/027DMPgFvGbHPgj+ /DWmWyLi8GGlFvEnJZQptrrA9DJdW7utW4dTenEhdtSGFZKgHgrQXxO41GxYhEWjqSRe F/pd5JR0v8sNjrLN7sv78uF8/HOtnF1q42g28LeSW8MvAWfY6vxgHweLESAyO9C9uFFI 4rPeRaltWZofU0hpLrwOrnWj1oqmBDOMHGBmCIRmfqyG7zcIqrFOgMm+kIkD+8RXcmCm VDOOHECd7S+F1KsnsPrSdeje7dRSaD/MHzudWxRW9d2gkWzoIV58PGvF1j7U4VkBhMBE lXdw== X-Gm-Message-State: APjAAAXsl+Qi1meQK4nDcMCd5URsFehCc5ycEdFiQb5vDEup03OKttLi QHHeMWp7vstY0ZRqrXpEEg== X-Google-Smtp-Source: APXvYqxdHvU6rmC3Qg/jCMTTh8Zw9JzR3ePuiVovFjaSsTtgxYDPrSWLVcV3/dOz5WqYqpmKNk4SyQ== X-Received: by 2002:a63:750f:: with SMTP id q15mr11496514pgc.422.1574364921859; Thu, 21 Nov 2019 11:35:21 -0800 (PST) Received: from ubuntu-vm.mshome.net ([167.220.2.106]) by smtp.gmail.com with ESMTPSA id h185sm3972216pgc.87.2019.11.21.11.35.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Nov 2019 11:35:21 -0800 (PST) From: Pavel Shilovsky X-Google-Original-From: Pavel Shilovsky To: Steve French , Ronnie Sahlberg , Frank Sorenson , linux-cifs Subject: [PATCH 2/3] CIFS: Fix NULL pointer dereference in mid callback Date: Thu, 21 Nov 2019 11:35:13 -0800 Message-Id: <20191121193514.3086-2-pshilov@microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191121193514.3086-1-pshilov@microsoft.com> References: <20191121193514.3086-1-pshilov@microsoft.com> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org There is a race between a system call processing thread and the demultiplex thread when mid->resp_buf becomes NULL and later is being accessed to get credits. It happens when the 1st thread wakes up before a mid callback is called in the 2nd one but the mid state has already been set to MID_RESPONSE_RECEIVED. This causes NULL pointer dereference in mid callback. Fix this by saving credits from the response before we update the mid state and then use this value in the mid callback rather then accessing a response buffer. Cc: Stable Fixes: ee258d79159afed5 ("CIFS: Move credit processing to mid callbacks for SMB3") Signed-off-by: Pavel Shilovsky --- fs/cifs/cifsglob.h | 1 + fs/cifs/connect.c | 15 +++++++++++++++ fs/cifs/smb2ops.c | 8 +------- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 12b356b3799b..128364af4c37 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1510,6 +1510,7 @@ struct mid_q_entry { struct TCP_Server_Info *server; /* server corresponding to this mid */ __u64 mid; /* multiplex id */ __u16 credits; /* number of credits consumed by this mid */ + __u16 credits_received; /* number of credits from the response */ __u32 pid; /* process id */ __u32 sequence_number; /* for CIFS signing */ unsigned long when_alloc; /* when mid was created */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 8995c03056e3..e63d16d8048a 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -897,6 +897,20 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed) spin_unlock(&GlobalMid_Lock); } +static unsigned int +smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server) +{ + struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer; + + /* + * SMB1 does not use credits. + */ + if (server->vals->header_preamble_size) + return 0; + + return le16_to_cpu(shdr->CreditRequest); +} + static void handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, char *buf, int malformed) @@ -904,6 +918,7 @@ handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, if (server->ops->check_trans2 && server->ops->check_trans2(mid, server, buf, malformed)) return; + mid->credits_received = smb2_get_credits_from_hdr(buf, server); mid->resp_buf = buf; mid->large_buf = server->large_buf; /* Was previous buf put in mpx struct for multi-rsp? */ diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 3bbb65e58dd6..5a13687bf547 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -151,13 +151,7 @@ smb2_get_credits_field(struct TCP_Server_Info *server, const int optype) static unsigned int smb2_get_credits(struct mid_q_entry *mid) { - struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)mid->resp_buf; - - if (mid->mid_state == MID_RESPONSE_RECEIVED - || mid->mid_state == MID_RESPONSE_MALFORMED) - return le16_to_cpu(shdr->CreditRequest); - - return 0; + return mid->credits_received; } static int From patchwork Thu Nov 21 19:35:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 1199115 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="SOZcT6w/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47JqXX2gvSz9sPV for ; Fri, 22 Nov 2019 06:35:24 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726546AbfKUTfY (ORCPT ); Thu, 21 Nov 2019 14:35:24 -0500 Received: from mail-pl1-f195.google.com ([209.85.214.195]:41271 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726379AbfKUTfX (ORCPT ); Thu, 21 Nov 2019 14:35:23 -0500 Received: by mail-pl1-f195.google.com with SMTP id t8so1957127plr.8 for ; Thu, 21 Nov 2019 11:35:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=Oh6L/EgpvxQaek7Or4Sg912pIEDcIEQsJoueynkkgp0=; b=SOZcT6w/LpiUfOpXqqBdhPT0fYb1phIH4NXSvrvYCUw6uESMwHUYsdjCceT2BAefVe fezgQG6m+fzA/NsuQ2u/p3gjxlCaTCbMtW6brsnDTBYKGaSmdzet43B8wAOddBqaQ/9u 510cIF92YUCCsZtWksB5Dcmu/MXQbxkx+WQ9qM1ytjut/1817rylbga8OgpNCT+z7Rc1 PPFoZCimiraydppTrx8BDs2RJgnlAURLg2sBHz63BzycV9t2iMbu+a7IQTPncIcCYQIB ebQ+WzbVeLgvt2S3bqmE/FFNgk6NXQyZqk2o8pUhAbPTKYAu7Oew+2lrCsr8Yt+0jnF+ N0pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=Oh6L/EgpvxQaek7Or4Sg912pIEDcIEQsJoueynkkgp0=; b=EBudXVnw9/HJ7gfeAgmGVSwRW6d8Rexrf2L4LwRHFilCRh1TJtv9IV0tz63unX1/NQ 106P4Kn3GSQVb3CMfHC/a6wOkLdTqcfxb8YiHdLHPGjiCWXwQ3J2Ior59VH10ZHJAYfW d0J4Qzog9FhlUSsQpGKpTmjBGBnmrtIy1mr+YjzlbS9sPuzNbSjfWVWwlFSyQgF/fXtl IkEK0fAl16GkVI329h7YwxskJRARTz8b0c716XWleepv9Bkih5JVtPSpCoi/sowl3Tde XwvUQsTFvMQnsHZ+ritLR65aAgrOPV+5rAGW1cny/zGMzd+ZDIVzZ0967b9OXCujBlSO Rx+Q== X-Gm-Message-State: APjAAAWZ/wmoJZKjAoVP6gcWE2xoaHNFmIA82wp1oRUx6wnAiTnDqDTQ LZH9tI+tP6wuorOXUmf0ViOTLfA= X-Google-Smtp-Source: APXvYqzVBdnaXBCA8SngBy8L1nvxZIM85IE0xDZgfhhr4ZIN3K14L5LC4fd44poh9UvsFRsFhV4zeg== X-Received: by 2002:a17:902:760b:: with SMTP id k11mr10269829pll.126.1574364923212; Thu, 21 Nov 2019 11:35:23 -0800 (PST) Received: from ubuntu-vm.mshome.net ([167.220.2.106]) by smtp.gmail.com with ESMTPSA id h185sm3972216pgc.87.2019.11.21.11.35.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Nov 2019 11:35:22 -0800 (PST) From: Pavel Shilovsky X-Google-Original-From: Pavel Shilovsky To: Steve French , Ronnie Sahlberg , Frank Sorenson , linux-cifs Subject: [PATCH 3/3] CIFS: Do not miss cancelled OPEN responses Date: Thu, 21 Nov 2019 11:35:14 -0800 Message-Id: <20191121193514.3086-3-pshilov@microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191121193514.3086-1-pshilov@microsoft.com> References: <20191121193514.3086-1-pshilov@microsoft.com> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org When an OPEN command is cancelled we mark a mid as cancelled and let the demultiplex thread process it by closing an open handle. The problem is there is a race between a system call thread and the demultiplex thread and there may be a situation when the mid has been already processed before it is set as cancelled. Fix this by processing cancelled requests when mids are being destroyed which means that there is only one thread referencing a particular mid. Also set mids as cancelled unconditionally on their state. Cc: Stable Signed-off-by: Pavel Shilovsky Reviewed-by: Ronnie Sahlberg resp_buf_size = server->pdu_size; - if ((mids[i]->mid_flags & MID_WAIT_CANCELLED) && - mids[i]->mid_state == MID_RESPONSE_RECEIVED && - server->ops->handle_cancelled_mid) - server->ops->handle_cancelled_mid( - mids[i]->resp_buf, - server); if (!mids[i]->multiRsp || mids[i]->multiEnd) mids[i]->callback(mids[i]); diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index bb52751ba783..987ffcd5ca3a 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -93,8 +93,14 @@ static void _cifs_mid_q_entry_release(struct kref *refcount) __u16 smb_cmd = le16_to_cpu(midEntry->command); unsigned long now; unsigned long roundtrip_time; - struct TCP_Server_Info *server = midEntry->server; #endif + struct TCP_Server_Info *server = midEntry->server; + + if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && + midEntry->mid_state == MID_RESPONSE_RECEIVED && + server->ops->handle_cancelled_mid) + server->ops->handle_cancelled_mid(midEntry->resp_buf, server); + midEntry->mid_state = MID_FREE; atomic_dec(&midCount); if (midEntry->large_buf) @@ -1115,8 +1121,8 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, midQ[i]->mid, le16_to_cpu(midQ[i]->command)); send_cancel(server, &rqst[i], midQ[i]); spin_lock(&GlobalMid_Lock); + midQ[i]->mid_flags |= MID_WAIT_CANCELLED; if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { - midQ[i]->mid_flags |= MID_WAIT_CANCELLED; midQ[i]->callback = cifs_cancelled_callback; cancelled_mid[i] = true; credits[i].value = 0;