[PATCH] configfs: inherit file and directory owners

From: Gwendal Grignou
Date: Fri Apr 13 2018 - 06:51:55 EST


All entries in configfs are currently owned by root,
regardless of context. Instead, this preserves the
current ownership, allowing userspace to choose who
has permissions to configure the system through
any particular configfs subsystem.

This means anyone who can create a group will now
have the ability to create any groups inside of that
group.

Signed-off-by: Daniel Rosenberg <drosen@xxxxxxxxxx>
Signed-off-by: Gwendal Grignou <gwendal@xxxxxxxxxxxx>
---
fs/configfs/inode.c | 38 +++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index ad718e5e37bb..1b55374de953 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -54,6 +54,28 @@ static const struct inode_operations configfs_inode_operations ={
.setattr = configfs_setattr,
};

+static struct iattr *alloc_iattr(struct configfs_dirent *sd_parent,
+ struct configfs_dirent *sd)
+{
+ struct iattr *sd_iattr;
+
+ sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
+ if (!sd_iattr)
+ return NULL;
+ /* assign default attributes */
+ sd_iattr->ia_mode = sd->s_mode;
+ if (sd_parent && sd_parent->s_iattr) {
+ sd_iattr->ia_uid = sd_parent->s_iattr->ia_uid;
+ sd_iattr->ia_gid = sd_parent->s_iattr->ia_gid;
+ } else {
+ sd_iattr->ia_uid = GLOBAL_ROOT_UID;
+ sd_iattr->ia_gid = GLOBAL_ROOT_GID;
+ }
+ sd_iattr->ia_atime = sd_iattr->ia_mtime =
+ sd_iattr->ia_ctime = CURRENT_TIME;
+ return sd_iattr;
+}
+
int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
{
struct inode * inode = d_inode(dentry);
@@ -68,15 +90,9 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
sd_iattr = sd->s_iattr;
if (!sd_iattr) {
/* setting attributes for the first time, allocate now */
- sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
+ sd_iattr = alloc_iattr(NULL, sd);
if (!sd_iattr)
return -ENOMEM;
- /* assign default attributes */
- sd_iattr->ia_mode = sd->s_mode;
- sd_iattr->ia_uid = GLOBAL_ROOT_UID;
- sd_iattr->ia_gid = GLOBAL_ROOT_GID;
- sd_iattr->ia_atime = sd_iattr->ia_mtime =
- sd_iattr->ia_ctime = current_time(inode);
sd->s_iattr = sd_iattr;
}
/* attributes were changed atleast once in past */
@@ -184,6 +200,7 @@ int configfs_create(struct dentry * dentry, umode_t mode, void (*init)(struct in
struct inode *inode = NULL;
struct configfs_dirent *sd;
struct inode *p_inode;
+ struct dentry *parent;

if (!dentry)
return -ENOENT;
@@ -192,6 +209,13 @@ int configfs_create(struct dentry * dentry, umode_t mode, void (*init)(struct in
return -EEXIST;

sd = dentry->d_fsdata;
+ parent = dget_parent(dentry);
+ if (parent && !sd->s_iattr) {
+ sd->s_iattr = alloc_iattr(parent->d_fsdata, sd);
+ if (!sd->s_iattr)
+ return -ENOMEM;
+ }
+ dput(parent);
inode = configfs_new_inode(mode, sd, dentry->d_sb);
if (!inode)
return -ENOMEM;
--
2.17.0.484.g0c8726318c-goog