From dea8d1ee373399a21851690a9753388b659b8ede Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Wed, 22 Feb 2017 14:57:59 -0500 Subject: [PATCH 1/2] rgw_file: rgw_lookup: don't ref for "/" or ".." These refs won't be returned by nfs-ganesha, and are sufficiently magical that other consumers should be persuaded to understand their specialness. Fixes: http://tracker.ceph.com/issues/19060 Signed-off-by: Matt Benjamin --- src/rgw/rgw_file.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 4e5108c87e660..1803109ddedb8 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -1377,9 +1377,10 @@ int rgw_lookup(struct rgw_fs *rgw_fs, LookupFHResult fhr; if (parent->is_root()) { - /* special: lookup on root itself */ - if (strcmp(path, "/") == 0) { - rgw_fh = fs->ref(parent); + /* special: parent lookup--note lack of ref()! */ + if (unlikely((strcmp(path, "..") == 0) || + (strcmp(path, "/") == 0))) { + rgw_fh = parent; } else { fhr = fs->stat_bucket(parent, path, RGWFileHandle::FLAG_NONE); rgw_fh = get<0>(fhr); From 70ef7d45e0abf2661bd4e23161d4e70cf5178079 Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Thu, 23 Feb 2017 10:21:38 -0500 Subject: [PATCH 2/2] rgw_file: return of RGWFileHandle::FLAG_EXACT_MATCH Allow callers of rgw_lookup() on objects attested in an rgw_readdir() callback the ability to bypass exact match in RGWLibFS::stat_leaf() case 2, but restore exact match enforcement for general lookups. This preserves required common_prefix namespace behavior, but prevents clients from eerily permitting things like "cd sara0" via partial name match on "sara01." Fixes: http://tracker.ceph.com/issues/19059 Signed-off-by: Matt Benjamin --- src/include/rados/rgw_file.h | 3 ++- src/rgw/rgw_file.cc | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/include/rados/rgw_file.h b/src/include/rados/rgw_file.h index dfa1ede18c93f..01551001e8754 100644 --- a/src/include/rados/rgw_file.h +++ b/src/include/rados/rgw_file.h @@ -27,7 +27,7 @@ extern "C" { #define LIBRGW_FILE_VER_MAJOR 1 #define LIBRGW_FILE_VER_MINOR 1 -#define LIBRGW_FILE_VER_EXTRA 1 +#define LIBRGW_FILE_VER_EXTRA 2 #define LIBRGW_FILE_VERSION(maj, min, extra) ((maj << 16) + (min << 8) + extra) #define LIBRGW_FILE_VERSION_CODE LIBRGW_FILE_VERSION(LIBRGW_FILE_VER_MAJOR, LIBRGW_FILE_VER_MINOR, LIBRGW_FILE_VER_EXTRA) @@ -91,6 +91,7 @@ void rgwfile_version(int *major, int *minor, int *extra); */ #define RGW_LOOKUP_FLAG_NONE 0x0000 #define RGW_LOOKUP_FLAG_CREATE 0x0001 +#define RGW_LOOKUP_FLAG_RCB 0x0002 /* readdir callback hint */ int rgw_lookup(struct rgw_fs *rgw_fs, struct rgw_file_handle *parent_fh, const char *path, diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 1803109ddedb8..9d5e9f4ab6f8d 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -1388,7 +1388,11 @@ int rgw_lookup(struct rgw_fs *rgw_fs, return -ENOENT; } } else { - fhr = fs->stat_leaf(parent, path, RGWFileHandle::FLAG_NONE); + /* lookup in a readdir callback */ + uint32_t sl_flags = (flags & RGW_LOOKUP_FLAG_RCB) + ? RGWFileHandle::FLAG_NONE + : RGWFileHandle::FLAG_EXACT_MATCH; + fhr = fs->stat_leaf(parent, path, sl_flags); if (! get<0>(fhr)) { if (! (flags & RGW_LOOKUP_FLAG_CREATE)) return -ENOENT;