Merge tag 'driver-core-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / fs / sysfs / group.c
index 38240410f83143ee77b883c973829853a75896c7..1eb2d630766396846151deea670620800c10c048 100644 (file)
@@ -31,6 +31,7 @@ static void remove_files(struct kernfs_node *parent,
 }
 
 static int create_files(struct kernfs_node *parent, struct kobject *kobj,
+                       kuid_t uid, kgid_t gid,
                        const struct attribute_group *grp, int update)
 {
        struct attribute *const *attr;
@@ -60,7 +61,7 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
 
                        mode &= SYSFS_PREALLOC | 0664;
                        error = sysfs_add_file_mode_ns(parent, *attr, false,
-                                                      mode, NULL);
+                                                      mode, uid, gid, NULL);
                        if (unlikely(error))
                                break;
                }
@@ -90,7 +91,8 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
                        mode &= SYSFS_PREALLOC | 0664;
                        error = sysfs_add_file_mode_ns(parent,
                                        &(*bin_attr)->attr, true,
-                                       mode, NULL);
+                                       mode,
+                                       uid, gid, NULL);
                        if (error)
                                break;
                }
@@ -106,6 +108,8 @@ static int internal_create_group(struct kobject *kobj, int update,
                                 const struct attribute_group *grp)
 {
        struct kernfs_node *kn;
+       kuid_t uid;
+       kgid_t gid;
        int error;
 
        BUG_ON(!kobj || (!update && !kobj->sd));
@@ -118,6 +122,7 @@ static int internal_create_group(struct kobject *kobj, int update,
                        kobj->name, grp->name ?: "");
                return -EINVAL;
        }
+       kobject_get_ownership(kobj, &uid, &gid);
        if (grp->name) {
                if (update) {
                        kn = kernfs_find_and_get(kobj->sd, grp->name);
@@ -127,9 +132,9 @@ static int internal_create_group(struct kobject *kobj, int update,
                                return -EINVAL;
                        }
                } else {
-                       kn = kernfs_create_dir(kobj->sd, grp->name,
-                                              S_IRWXU | S_IRUGO | S_IXUGO,
-                                              kobj);
+                       kn = kernfs_create_dir_ns(kobj->sd, grp->name,
+                                                 S_IRWXU | S_IRUGO | S_IXUGO,
+                                                 uid, gid, kobj, NULL);
                        if (IS_ERR(kn)) {
                                if (PTR_ERR(kn) == -EEXIST)
                                        sysfs_warn_dup(kobj->sd, grp->name);
@@ -139,7 +144,7 @@ static int internal_create_group(struct kobject *kobj, int update,
        } else
                kn = kobj->sd;
        kernfs_get(kn);
-       error = create_files(kn, kobj, grp, update);
+       error = create_files(kn, kobj, uid, gid, grp, update);
        if (error) {
                if (grp->name)
                        kernfs_remove(kn);
@@ -296,6 +301,8 @@ int sysfs_merge_group(struct kobject *kobj,
                       const struct attribute_group *grp)
 {
        struct kernfs_node *parent;
+       kuid_t uid;
+       kgid_t gid;
        int error = 0;
        struct attribute *const *attr;
        int i;
@@ -304,8 +311,11 @@ int sysfs_merge_group(struct kobject *kobj,
        if (!parent)
                return -ENOENT;
 
+       kobject_get_ownership(kobj, &uid, &gid);
+
        for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr))
-               error = sysfs_add_file(parent, *attr, false);
+               error = sysfs_add_file_mode_ns(parent, *attr, false,
+                                              (*attr)->mode, uid, gid, NULL);
        if (error) {
                while (--i >= 0)
                        kernfs_remove_by_name(parent, (*--attr)->name);