From 00850a67ca840422ea94ffe2eb22e0e65e112d88 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 10 Feb 2016 09:38:33 -0500 Subject: [PATCH] mds: deny access to directories with pool_ns layouts if feature is missing If the client feature is missing, given them EIO. Change check_access to return an error code to distinguish this from EACCES. Signed-off-by: Sage Weil --- src/mds/Locker.cc | 3 ++- src/mds/Server.cc | 19 +++++++++++-------- src/mds/SessionMap.cc | 24 ++++++++++++++++-------- src/mds/SessionMap.h | 4 ++-- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index d500f4fb047bc..ec80aeb4a703f 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -3149,7 +3149,8 @@ bool Locker::_do_cap_update(CInode *in, Capability *cap, return false; Session *session = static_cast(m->get_connection()->get_priv()); - if (!session->check_access(in, MAY_WRITE, m->caller_uid, m->caller_gid, 0, 0)) { + if (session->check_access(in, MAY_WRITE, + m->caller_uid, m->caller_gid, 0, 0) < 0) { dout(10) << "check_access failed, dropping cap update on " << *in << dendl; return false; } diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 994462ea653a1..a5b087f652e50 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -2132,14 +2132,17 @@ void Server::handle_slave_auth_pin_ack(MDRequestRef& mdr, MMDSSlaveRequest *ack) */ bool Server::check_access(MDRequestRef& mdr, CInode *in, unsigned mask) { - if (mdr->session && !mdr->session->check_access( - in, mask, - mdr->client_request->get_caller_uid(), - mdr->client_request->get_caller_gid(), - mdr->client_request->head.args.setattr.uid, - mdr->client_request->head.args.setattr.gid)) { - respond_to_request(mdr, -EACCES); - return false; + if (mdr->session) { + int r = mdr->session->check_access( + in, mask, + mdr->client_request->get_caller_uid(), + mdr->client_request->get_caller_gid(), + mdr->client_request->head.args.setattr.uid, + mdr->client_request->head.args.setattr.gid); + if (r < 0) { + respond_to_request(mdr, r); + return false; + } } return true; } diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc index 9b4bc7fa2bec0..1e858e36d4068 100644 --- a/src/mds/SessionMap.cc +++ b/src/mds/SessionMap.cc @@ -842,9 +842,9 @@ void Session::decode(bufferlist::iterator &p) _update_human_name(); } -bool Session::check_access(CInode *in, unsigned mask, - int caller_uid, int caller_gid, - int new_uid, int new_gid) +int Session::check_access(CInode *in, unsigned mask, + int caller_uid, int caller_gid, + int new_uid, int new_gid) { string path; CInode *diri = NULL; @@ -860,12 +860,20 @@ bool Session::check_access(CInode *in, unsigned mask, if (path.length()) path = path.substr(1); // drop leading / - if (auth_caps.is_capable(path, in->inode.uid, in->inode.gid, in->inode.mode, - caller_uid, caller_gid, mask, - new_uid, new_gid)) { - return true; + if (in->inode.is_dir() && + in->inode.has_layout() && + in->inode.layout.pool_ns.length() && + !connection->has_feature(CEPH_FEATURE_FS_FILE_LAYOUT_V2)) { + dout(10) << __func__ << " client doesn't support FS_FILE_LAYOUT_V2" << dendl; + return -EIO; } - return false; + + if (!auth_caps.is_capable(path, in->inode.uid, in->inode.gid, in->inode.mode, + caller_uid, caller_gid, mask, + new_uid, new_gid)) { + return -EACCES; + } + return 0; } int SessionFilter::parse( diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index 75a7d0704e555..d03e16c85ac25 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -303,8 +303,8 @@ public: completed_requests_dirty = false; } - bool check_access(CInode *in, unsigned mask, int caller_uid, int caller_gid, - int new_uid, int new_gid); + int check_access(CInode *in, unsigned mask, int caller_uid, int caller_gid, + int new_uid, int new_gid); Session() : -- 2.39.5