From: Yan, Zheng Date: Tue, 29 Sep 2015 08:41:19 +0000 (+0800) Subject: client: permission check for setxattr/removexattr X-Git-Tag: v10.0.3~48^2~3^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a3dae8c1881f07ad7f3b72e35f53b26a2f7b6a13;p=ceph.git client: permission check for setxattr/removexattr Signed-off-by: Yan, Zheng --- diff --git a/src/client/Client.cc b/src/client/Client.cc index c1fe9c38825c..7ae066a53a4e 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -4847,6 +4847,30 @@ int Client::inode_permission(Inode *in, uid_t uid, UserGroups& groups, unsigned return 0; } +int Client::xattr_permission(Inode *in, const char *name, unsigned want, int uid, int gid) +{ + if (uid < 0) + uid = get_uid(); + if (gid < 0) + gid = get_gid(); + RequestUserGroups groups(this, uid, gid); + + int r = _getattr(in, CEPH_STAT_CAP_MODE, uid, gid); + if (r < 0) + goto out; + + r = 0; + if (strncmp(name, "system.", 7) == 0) { + if ((want & MAY_WRITE) && (uid != 0 && (uid_t)uid != in->uid)) + r = -EPERM; + } else { + r = inode_permission(in, uid, groups, want); + } +out: + ldout(cct, 3) << __func__ << " " << in << " = " << r << dendl; + return r; +} + int Client::may_setattr(Inode *in, struct stat *st, int mask, int uid, int gid) { if (uid < 0) @@ -9392,6 +9416,12 @@ int Client::ll_getxattr(Inode *in, const char *name, void *value, tout(cct) << vino.ino.val << std::endl; tout(cct) << name << std::endl; + if (!cct->_conf->fuse_default_permissions) { + int r = xattr_permission(in, name, MAY_READ, uid, gid); + if (r < 0) + return r; + } + return _getxattr(in, name, value, size, uid, gid); } @@ -9612,6 +9642,12 @@ int Client::ll_setxattr(Inode *in, const char *name, const void *value, tout(cct) << vino.ino.val << std::endl; tout(cct) << name << std::endl; + if (!cct->_conf->fuse_default_permissions) { + int r = xattr_permission(in, name, MAY_WRITE, uid, gid); + if (r < 0) + return r; + } + return _setxattr(in, name, value, size, flags, uid, gid); } @@ -9659,6 +9695,12 @@ int Client::ll_removexattr(Inode *in, const char *name, int uid, int gid) tout(cct) << vino.ino.val << std::endl; tout(cct) << name << std::endl; + if (!cct->_conf->fuse_default_permissions) { + int r = xattr_permission(in, name, MAY_WRITE, uid, gid); + if (r < 0) + return r; + } + return _removexattr(in, name, uid, gid); } diff --git a/src/client/Client.h b/src/client/Client.h index 38874f6ae6c1..b630b7a165ac 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -783,6 +783,7 @@ private: }; int inode_permission(Inode *in, uid_t uid, UserGroups& groups, unsigned want); + int xattr_permission(Inode *in, const char *name, unsigned want, int uid=-1, int gid=-1); int may_setattr(Inode *in, struct stat *st, int mask, int uid=-1, int gid=-1); int may_open(Inode *in, int flags, int uid=-1, int gid=-1); int may_lookup(Inode *dir, int uid=-1, int gid=-1);