Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp3954586imm; Mon, 8 Oct 2018 12:15:00 -0700 (PDT) X-Google-Smtp-Source: ACcGV60JzSyueH1OZyebhvPkRWJU9m984sjEwAw/gqHE5j/KGfUpFWMUIL/b6YDNrf0Al821sGjn X-Received: by 2002:a62:1d16:: with SMTP id d22-v6mr26837844pfd.159.1539026100082; Mon, 08 Oct 2018 12:15:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539026100; cv=none; d=google.com; s=arc-20160816; b=zRTxaAbmAcD6H8vtmGboGQU15tYAZBfeQNF12KmEO2FN5ZhFI7CuHy0a+AZrf1vaA6 /CHfdy1JBN13arqHq2WaxDTezCj6+IlUmeZ75OSfCehrUQKqT3fMhhdz84hhDmp+glhf Bs+0Ak9Fdog4dLencOKCcHD0DrHj/UTSw5stIO/caoQUWrjuW/nI2gLO+kz++a26KI4n BhqezRgHmD8VFqQLrmEvvTP2Bx6T/miAYyDTwff/Loowunsf9WUmJBFv4wrOCpV4NatG wPuKJ+cV9RoFrCZ4s7I0ITuBYL+zyMpUcs3AXuPY3JDjhI8rpurZY6E0Yao+QWUlvmnv 308g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=T2QymXAMJDOMyeAJU8JmYjrvCq0bAn4ZNNkGFqigHFE=; b=GitQlbHial/L+4vI0pwt3gzD3pB0B1rrajDNevl8OLgSBiwZab3+CAeRsfpU2zWgCD jo3Hx6ZABe8uI61NtF4qo5qXrfjnmAMA76QSOGktOCEH/xYGAz/pmVRATmySJahw6M3B xYjJoiK+RY7tr7szb2ZoRwth4aGWPbL3okIpG5rmp2/sW3RLGmXpIRTIjUTOOx3gaFjd aFdxWXBdfuCIK3rLHxkgHx8f9iXG7TVHhPBV2us9KciGRpdxaFeKvxtosTy6w8H7Qz48 1hh0X193u2IrlI85rxPxnzPlSoqCs/8IJ6CZ2VwmdZue7mJou8P4J+/HkJHLsx/dcQaX 7ujQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=VRCUlpsD; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g15-v6si20384398pli.239.2018.10.08.12.14.44; Mon, 08 Oct 2018 12:15:00 -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=@kernel.org header.s=default header.b=VRCUlpsD; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728963AbeJIBun (ORCPT + 99 others); Mon, 8 Oct 2018 21:50:43 -0400 Received: from mail.kernel.org ([198.145.29.99]:37020 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726427AbeJIBum (ORCPT ); Mon, 8 Oct 2018 21:50:42 -0400 Received: from localhost (ip-213-127-77-176.ip.prioritytelecom.net [213.127.77.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 7A3BC2064A; Mon, 8 Oct 2018 18:37:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1539023858; bh=IAsHHYCztPpcIkrmwwH35uXzDptgbAegAocotLal+g4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VRCUlpsDI0qIR0B6nlvtLGlK3UoCn8Dzdi1efStx2dtVPMhLEhfjC2syvq1X7QNL7 ZRRpwh1+13HtUZzsJyQCbf7q9zvf5iwbFJhlGlc2F5C6v+hWoIsnh0yOGfJdEAr2ML CUSUk3nSJI77CycFU/5cm/AyKNYCPZklbEv+gP/0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Aurelien Aptel , Paulo Alcantara , Ronnie Sahlberg , Steve French Subject: [PATCH 4.4 109/113] smb2: fix missing files in root share directory listing Date: Mon, 8 Oct 2018 20:31:50 +0200 Message-Id: <20181008175537.301997288@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181008175530.864641368@linuxfoundation.org> References: <20181008175530.864641368@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Aurelien Aptel commit 0595751f267994c3c7027377058e4185b3a28e75 upstream. When mounting a Windows share that is the root of a drive (eg. C$) the server does not return . and .. directory entries. This results in the smb2 code path erroneously skipping the 2 first entries. Pseudo-code of the readdir() code path: cifs_readdir(struct file, struct dir_context) initiate_cifs_search <-- if no reponse cached yet server->ops->query_dir_first dir_emit_dots dir_emit <-- adds "." and ".." if we're at pos=0 find_cifs_entry initiate_cifs_search <-- if pos < start of current response (restart search) server->ops->query_dir_next <-- if pos > end of current response (fetch next search res) for(...) <-- loops over cur response entries starting at pos cifs_filldir <-- skip . and .., emit entry cifs_fill_dirent dir_emit pos++ A) dir_emit_dots() always adds . & .. and sets the current dir pos to 2 (0 and 1 are done). Therefore we always want the index_to_find to be 2 regardless of if the response has . and .. B) smb1 code initializes index_of_last_entry with a +2 offset in cifssmb.c CIFSFindFirst(): psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + psrch_inf->entries_in_buffer; Later in find_cifs_entry() we want to find the next dir entry at pos=2 as a result of (A) first_entry_in_buffer = cfile->srch_inf.index_of_last_entry - cfile->srch_inf.entries_in_buffer; This var is the dir pos that the first entry in the buffer will have therefore it must be 2 in the first call. If we don't offset index_of_last_entry by 2 (like in (B)), first_entry_in_buffer=0 but we were instructed to get pos=2 so this code in find_cifs_entry() skips the 2 first which is ok for non-root shares, as it skips . and .. from the response but is not ok for root shares where the 2 first are actual files pos_in_buf = index_to_find - first_entry_in_buffer; // pos_in_buf=2 // we skip 2 first response entries :( for (i = 0; (i < (pos_in_buf)) && (cur_ent != NULL); i++) { /* go entry by entry figuring out which is first */ cur_ent = nxt_dir_entry(cur_ent, end_of_smb, cfile->srch_inf.info_level); } C) cifs_filldir() skips . and .. so we can safely ignore them for now. Sample program: int main(int argc, char **argv) { const char *path = argc >= 2 ? argv[1] : "."; DIR *dh; struct dirent *de; printf("listing path <%s>\n", path); dh = opendir(path); if (!dh) { printf("opendir error %d\n", errno); return 1; } while (1) { de = readdir(dh); if (!de) { if (errno) { printf("readdir error %d\n", errno); return 1; } printf("end of listing\n"); break; } printf("off=%lu <%s>\n", de->d_off, de->d_name); } return 0; } Before the fix with SMB1 on root shares: <.> off=1 <..> off=2 <$Recycle.Bin> off=3 off=4 and on non-root shares: <.> off=1 <..> off=4 <-- after adding .., the offsets jumps to +2 because <2536> off=5 we skipped . and .. from response buffer (C) <411> off=6 but still incremented pos off=7 off=8 Therefore the fix for smb2 is to mimic smb1 behaviour and offset the index_of_last_entry by 2. Test results comparing smb1 and smb2 before/after the fix on root share, non-root shares and on large directories (ie. multi-response dir listing): PRE FIX ======= pre-1-root VS pre-2-root: ERR pre-2-root is missing [bootmgr, $Recycle.Bin] pre-1-nonroot VS pre-2-nonroot: OK~ same files, same order, different offsets pre-1-nonroot-large VS pre-2-nonroot-large: OK~ same files, same order, different offsets POST FIX ======== post-1-root VS post-2-root: OK same files, same order, same offsets post-1-nonroot VS post-2-nonroot: OK same files, same order, same offsets post-1-nonroot-large VS post-2-nonroot-large: OK same files, same order, same offsets REGRESSION? =========== pre-1-root VS post-1-root: OK same files, same order, same offsets pre-1-nonroot VS post-1-nonroot: OK same files, same order, same offsets BugLink: https://bugzilla.samba.org/show_bug.cgi?id=13107 Signed-off-by: Aurelien Aptel Signed-off-by: Paulo Alcantara Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French CC: Stable Signed-off-by: Greg Kroah-Hartman --- fs/cifs/smb2ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -914,7 +914,7 @@ smb2_query_dir_first(const unsigned int } srch_inf->entries_in_buffer = 0; - srch_inf->index_of_last_entry = 0; + srch_inf->index_of_last_entry = 2; rc = SMB2_query_directory(xid, tcon, fid->persistent_fid, fid->volatile_fid, 0, srch_inf);