From: "Aurélien Aptel" <aaptel-IBi9RG/b67k@public.gmane.org>
To: linux-cifs <linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
samba-technical-w/Ol4Ecudpl8XjKLYN78aQ@public.gmane.org,
Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
Marcus Hoffmann
<marcus.hoffmann-j/7cz5qe3tpn68oJJulU0Q@public.gmane.org>
Subject: [PATCH] Making shares unaccessible at root level mountable (aka solving bsc#8950 ...again)
Date: Fri, 27 May 2016 19:43:46 +0200 [thread overview]
Message-ID: <20160527194346.08416d79@aaptelpc> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 994 bytes --]
Hi all,
I've come up with a new solution for the problem (attached). Between
the long, old and irrelevant comments on the bug report and the various
mailing-list threads it was getting hard to understand. So I've written
a summary which explains the problem in details and the 2 proposed
solutions.
http://diobla.info/stuff/bugs/bsc799133/
The new solution is basically switching to the old prefixpath system
when the normal method of querying intermediary path fails. It's much
more simpler.
*Any* feedback would be nice. I haven't noticed any problems so far but
I haven't run the xfs test suite (I still have to figure out how
to make it play nice with cifs...). I'm sending to samba-tech too in
hopes of reviews/comments.
--
Aurélien Aptel / SUSE Labs Samba Team
GPG: 1839 CB5F 9F5B FB9B AA97 8C99 03C8 A49B 521B D5D3
SUSE Linux GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG
Nürnberg)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-fs-cifs-make-share-unaccessible-at-root-level-mounta.patch --]
[-- Type: text/x-patch, Size: 4998 bytes --]
From 3e9af75bea055bf88a4700fced50a7ba38b39b6f Mon Sep 17 00:00:00 2001
From: Aurelien Aptel <aaptel-IBi9RG/b67k@public.gmane.org>
Date: Wed, 25 May 2016 19:59:09 +0200
Subject: [PATCH] fs/cifs: make share unaccessible at root level mountable
if, when mounting //HOST/share/sub/dir/foo we can query /sub/dir/foo but
not any of the path components above:
- store the /sub/dir/foo prefix in the cifs super_block info
- in the superblock, set root dentry to the subpath dentry (instead of
the share root)
- set a flag in the superblock to remember it
- use prefixpath when building path from a dentry
fixes bso#8950
Signed-off-by: Aurelien Aptel <aaptel-IBi9RG/b67k@public.gmane.org>
---
fs/cifs/cifs_fs_sb.h | 2 ++
fs/cifs/cifsfs.c | 19 +++++++++++++++++++
fs/cifs/connect.c | 3 +++
fs/cifs/dir.c | 19 +++++++++++++++++--
4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 3182273..02b9ac3 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -46,6 +46,7 @@
#define CIFS_MOUNT_CIFS_BACKUPUID 0x200000 /* backup intent bit for a user */
#define CIFS_MOUNT_CIFS_BACKUPGID 0x400000 /* backup intent bit for a group */
#define CIFS_MOUNT_MAP_SFM_CHR 0x800000 /* SFM/MAC mapping for illegal chars */
+#define CIFS_MOUNT_USE_PREFIX_PATH 0x1000000 /* make subpath with unaccessible root mountable */
struct cifs_sb_info {
struct rb_root tlink_tree;
@@ -67,5 +68,6 @@ struct cifs_sb_info {
struct backing_dev_info bdi;
struct delayed_work prune_tlinks;
struct rcu_head rcu;
+ char *prepath;
};
#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 5d8b7ed..d1fc593 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -649,6 +649,17 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
dentry = child;
} while (!IS_ERR(dentry));
kfree(full_path);
+
+ if (IS_ERR(dentry) /* && path accessible */) {
+ /* we know the path is accessible (it is tested
+ * earlier in cifs_do_mount()) so there must be a perm
+ * problem */
+ cifs_dbg(VFS, "cannot query directories between root and final path, "
+ "enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
+ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
+ dentry = dget(sb->s_root);
+ }
+
return dentry;
}
@@ -688,6 +699,14 @@ cifs_do_mount(struct file_system_type *fs_type,
goto out_cifs_sb;
}
+ if (volume_info->prepath) {
+ cifs_sb->prepath = kstrdup(volume_info->prepath, GFP_KERNEL);
+ if (cifs_sb->prepath == NULL) {
+ root = ERR_PTR(-ENOMEM);
+ goto out_cifs_sb;
+ }
+ }
+
cifs_setup_cifs_sb(volume_info, cifs_sb);
rc = cifs_mount(cifs_sb, volume_info);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 66736f5..90e57ee 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3887,6 +3887,9 @@ cifs_umount(struct cifs_sb_info *cifs_sb)
bdi_destroy(&cifs_sb->bdi);
kfree(cifs_sb->mountdata);
+ if (cifs_sb->prepath) {
+ kfree(cifs_sb->prepath);
+ }
call_rcu(&cifs_sb->rcu, delayed_free);
}
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index c3eb998..5374253 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -84,6 +84,7 @@ build_path_from_dentry(struct dentry *direntry)
struct dentry *temp;
int namelen;
int dfsplen;
+ int pplen = 0;
char *full_path;
char dirsep;
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
@@ -95,8 +96,12 @@ build_path_from_dentry(struct dentry *direntry)
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
else
dfsplen = 0;
+
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
+ pplen = cifs_sb->prepath ? strlen(cifs_sb->prepath) + 1 : 0;
+
cifs_bp_rename_retry:
- namelen = dfsplen;
+ namelen = dfsplen + pplen;
seq = read_seqbegin(&rename_lock);
rcu_read_lock();
for (temp = direntry; !IS_ROOT(temp);) {
@@ -137,7 +142,7 @@ cifs_bp_rename_retry:
}
}
rcu_read_unlock();
- if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) {
+ if (namelen != dfsplen + pplen || read_seqretry(&rename_lock, seq)) {
cifs_dbg(FYI, "did not end path lookup where expected. namelen=%ddfsplen=%d\n",
namelen, dfsplen);
/* presumably this is only possible if racing with a rename
@@ -153,6 +158,16 @@ cifs_bp_rename_retry:
those safely to '/' if any are found in the middle of the prepath */
/* BB test paths to Windows with '/' in the midst of prepath */
+ if (pplen) {
+ int i;
+ cifs_dbg(FYI, "using cifs_sb prepath <%s>\n", cifs_sb->prepath);
+ memcpy(full_path+dfsplen+1, cifs_sb->prepath, pplen-1);
+ full_path[dfsplen] = '\\';
+ for (i = 0; i < pplen-1; i++)
+ if (full_path[dfsplen+1+i] == '/')
+ full_path[dfsplen+1+i] = CIFS_DIR_SEP(cifs_sb);
+ }
+
if (dfsplen) {
strncpy(full_path, tcon->treeName, dfsplen);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
--
2.1.4
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
next reply other threads:[~2016-05-27 17:43 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-27 17:43 Aurélien Aptel [this message]
2016-06-09 16:50 ` [PATCH] Making shares unaccessible at root level mountable (aka solving bsc#8950 ...again) Aurélien Aptel
2016-06-09 19:27 ` Marcus Hoffmann
[not found] ` <5759C326.5040508-j/7cz5qe3tpn68oJJulU0Q@public.gmane.org>
2016-06-10 15:16 ` Aurélien Aptel
2016-06-12 18:01 ` Marcus Hoffmann
2016-07-01 15:44 ` Marcus Hoffmann
[not found] ` <57768FC3.7020102-j/7cz5qe3tpn68oJJulU0Q@public.gmane.org>
2016-07-01 16:02 ` Steve French
2016-07-02 7:02 ` Pavel Shilovsky
[not found] ` <CAKywueRMvJ4B6ojqA1TduS4nGFTr5m4wLO2=0M_EVv=vw2T1pw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-07-18 14:38 ` Aurélien Aptel
2016-07-19 19:21 ` Pavel Shilovsky
[not found] ` <CAKywueRFMu9nvwi_01Yz0HpOqhrK2yZVaLT2JMqw4622irQzNw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-07-20 10:57 ` Aurélien Aptel
2016-07-20 12:16 ` Aurélien Aptel
2016-07-20 18:28 ` Pavel Shilovsky
[not found] ` <CAKywueTOSD0G1k+EU-Qo_9D7S5bBw6g6T=dbQpWYWdOhr5Lsrg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-07-26 18:04 ` Steve French
[not found] ` <CAH2r5mviretFGDaHOre8BiZLmKhqwnfv9sdaiqoAG1xahbVjKA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-07-26 19:10 ` Pavel Shilovsky
[not found] ` <CAKywueR7K5OR7+NnzEtqpWGR0gApoR3X0Y6C6ACzTf1y7JOcsA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-07-28 5:02 ` Steve French
[not found] ` <CAH2r5mtiZNDyeRe_rYy4Pcg1WhbGaZtdweM=p8fG1uc0xZcAeg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-07-28 8:28 ` Aurélien Aptel
2016-07-29 13:11 ` Sachin Prabhu
[not found] ` <1469797864.14723.15.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-07-29 13:31 ` Sachin Prabhu
[not found] ` <1469799107.14723.18.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-07-29 20:20 ` Steve French
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160527194346.08416d79@aaptelpc \
--to=aaptel-ibi9rg/b67k@public.gmane.org \
--cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=marcus.hoffmann-j/7cz5qe3tpn68oJJulU0Q@public.gmane.org \
--cc=samba-technical-w/Ol4Ecudpl8XjKLYN78aQ@public.gmane.org \
--cc=smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox