Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp3924190imm; Mon, 8 Oct 2018 11:46:09 -0700 (PDT) X-Google-Smtp-Source: ACcGV61an5u9OILEvrizGQLgmmgGL5ln6uu9ZpWDWi5iPtP7UBxWST7JOElFeqcSrbkiCisqk6Ff X-Received: by 2002:a17:902:8502:: with SMTP id bj2-v6mr24880327plb.295.1539024369764; Mon, 08 Oct 2018 11:46:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539024369; cv=none; d=google.com; s=arc-20160816; b=ykyRZRoCRQDqGOKTbBlJjBpUG37Pgm7Q63ZemUk9+j18ZVyOc2lUX2znjOAuKdjn83 i8c8bM84Kgn/ghLy+Ef9YiLbyxuvtQwAncmnPGTz/x9MXphCL3LKS67RW2VZEHO+P982 sphz0p59Gy33/HL6Qhxl80sty4t5LkxAsFhBYEHLeC6s/4g6jvC++7x4meKvkNvsx8Bp 0M//h2RzYSG4aa0KNDQ06tIL1yT5RX2tQQvMX5xDPe4ZLAd8Xu1tcglQs6ppr6DCxwLt SR2o7KQjpg+FrdeT8ffOGNOABnN2qaFFbAIGyjFNBjmGdT4c1xmf1wOC3aNp5GY2IV90 /ohg== 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=jaVLyr8mzu9V0z9H7ML5d44qfBOmR0jqcPNfNvn5q7A=; b=GgRORo72kI6b2LyTqyJvJaPGBBwDi/s++ahmRczY4Sq1xKY33DESaK5Ovg/cPDmrzP OvnYKAxp6paOTKkriAV1ZySWgRLMNybdoQOrwTVqvvtRcE0kg7SArnPxOOjC51/g25az Dpu4WdY0oXWr3SZ0aCxcKoQd76bZqqHepCtDWGWYAyLlxznCggYVIt2KlJTIqXnJoCrb 21I2E5UdQzjzYmt+5Ekzd9xqGSpqRV+7K0KNhasA3DHwlJwVOdzjBHj4+kRGdRlKQdzr eFFEAR55Q9jlikMoJZr6gCA3dmbSIEekPQUCMEK80hEWP3Tfe6D00uW9hH7OehBSCxf3 o2tw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=yRVp5xel; 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 t65-v6si18676383pgt.248.2018.10.08.11.45.55; Mon, 08 Oct 2018 11:46:09 -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=yRVp5xel; 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 S1730980AbeJIB6b (ORCPT + 99 others); Mon, 8 Oct 2018 21:58:31 -0400 Received: from mail.kernel.org ([198.145.29.99]:46580 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728570AbeJIB6b (ORCPT ); Mon, 8 Oct 2018 21:58:31 -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 DD3AB2087D; Mon, 8 Oct 2018 18:45:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1539024324; bh=khEJpZhISYkxJirKwzzONEZN3GiBEQuFMY5Gm15ZqeI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=yRVp5xela4e1ctxm4+bqxOYI1ylCpGLKDbYzq1n8XBvu/ckP8+qZf4oZlX34yMUow c1K8GHIqtlhVfvX7r/MjZgOOCEu8aeSum+yYZPiOhmmQGjXwkST8tep49feG1MNNfo h4pYfUkJZ72nxVt7UeLZtDGb2d/qBJeAD0GfC6c4= 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.14 83/94] smb2: fix missing files in root share directory listing Date: Mon, 8 Oct 2018 20:32:04 +0200 Message-Id: <20181008175610.483263330@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181008175605.067676667@linuxfoundation.org> References: <20181008175605.067676667@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.14-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 @@ -1239,7 +1239,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);