Message ID | 1531497949-1766-2-git-send-email-tyhicks@canonical.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
Series | Make /sys/class/net per net namespace objects belong to container | expand |
Hi Dmitry, I love your patch! Yet something to improve: [auto build test ERROR on net-next/master] url: https://github.com/0day-ci/linux/commits/Tyler-Hicks/Make-sys-class-net-per-net-namespace-objects-belong-to-container/20180716-020459 config: x86_64-randconfig-u0-07161309 (attached as .config) compiler: gcc-5 (Debian 5.5.0-3) 5.4.1 20171010 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 :::::: branch date: 13 hours ago :::::: commit date: 13 hours ago All errors (new ones prefixed by >>): arch/x86/kernel/cpu/intel_rdt_rdtgroup.c: In function 'rdtgroup_add_file': >> arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:149:7: error: incompatible type for argument 4 of '__kernfs_create_file' 0, rft->kf_ops, rft, NULL, NULL); ^ In file included from include/linux/sysfs.h:16:0, from include/linux/kobject.h:20, from include/linux/device.h:16, from include/linux/node.h:18, from include/linux/cpu.h:17, from arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:23: include/linux/kernfs.h:333:21: note: expected 'kuid_t {aka struct <anonymous>}' but argument is of type 'int' struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, ^ arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:149:10: error: incompatible type for argument 5 of '__kernfs_create_file' 0, rft->kf_ops, rft, NULL, NULL); ^ In file included from include/linux/sysfs.h:16:0, from include/linux/kobject.h:20, from include/linux/device.h:16, from include/linux/node.h:18, from include/linux/cpu.h:17, from arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:23: include/linux/kernfs.h:333:21: note: expected 'kgid_t {aka struct <anonymous>}' but argument is of type 'struct kernfs_ops *' struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, ^ arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:149:23: warning: passing argument 6 of '__kernfs_create_file' makes integer from pointer without a cast [-Wint-conversion] 0, rft->kf_ops, rft, NULL, NULL); ^ In file included from include/linux/sysfs.h:16:0, from include/linux/kobject.h:20, from include/linux/device.h:16, from include/linux/node.h:18, from include/linux/cpu.h:17, from arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:23: include/linux/kernfs.h:333:21: note: expected 'loff_t {aka long long int}' but argument is of type 'struct rftype *' struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, ^ >> arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:148:7: error: too few arguments to function '__kernfs_create_file' kn = __kernfs_create_file(parent_kn, rft->name, rft->mode, ^ In file included from include/linux/sysfs.h:16:0, from include/linux/kobject.h:20, from include/linux/device.h:16, from include/linux/node.h:18, from include/linux/cpu.h:17, from arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:23: include/linux/kernfs.h:333:21: note: declared here struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, ^ arch/x86/kernel/cpu/intel_rdt_rdtgroup.c: In function 'mon_addfile': arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:1506:51: error: incompatible type for argument 4 of '__kernfs_create_file' kn = __kernfs_create_file(parent_kn, name, 0444, 0, ^ In file included from include/linux/sysfs.h:16:0, from include/linux/kobject.h:20, from include/linux/device.h:16, from include/linux/node.h:18, from include/linux/cpu.h:17, from arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:23: include/linux/kernfs.h:333:21: note: expected 'kuid_t {aka struct <anonymous>}' but argument is of type 'int' struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, ^ arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:1507:7: error: incompatible type for argument 5 of '__kernfs_create_file' &kf_mondata_ops, priv, NULL, NULL); ^ In file included from include/linux/sysfs.h:16:0, from include/linux/kobject.h:20, from include/linux/device.h:16, from include/linux/node.h:18, from include/linux/cpu.h:17, from arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:23: include/linux/kernfs.h:333:21: note: expected 'kgid_t {aka struct <anonymous>}' but argument is of type 'struct kernfs_ops *' struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, ^ arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:1507:24: warning: passing argument 6 of '__kernfs_create_file' makes integer from pointer without a cast [-Wint-conversion] &kf_mondata_ops, priv, NULL, NULL); ^ In file included from include/linux/sysfs.h:16:0, from include/linux/kobject.h:20, from include/linux/device.h:16, from include/linux/node.h:18, from include/linux/cpu.h:17, from arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:23: include/linux/kernfs.h:333:21: note: expected 'loff_t {aka long long int}' but argument is of type 'void *' struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, ^ arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:1506:7: error: too few arguments to function '__kernfs_create_file' kn = __kernfs_create_file(parent_kn, name, 0444, 0, ^ In file included from include/linux/sysfs.h:16:0, from include/linux/kobject.h:20, from include/linux/device.h:16, from include/linux/node.h:18, from include/linux/cpu.h:17, from arch/x86/kernel/cpu/intel_rdt_rdtgroup.c:23: include/linux/kernfs.h:333:21: note: declared here struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, ^ # https://github.com/0day-ci/linux/commit/d5f7e84e70937f0546d774162a3f9425caec5687 git remote add linux-review https://github.com/0day-ci/linux git remote update linux-review git checkout d5f7e84e70937f0546d774162a3f9425caec5687 vim +/__kernfs_create_file +149 arch/x86/kernel/cpu/intel_rdt_rdtgroup.c 5ff193fb Fenghua Yu 2016-10-28 22 12e0110c Tony Luck 2016-10-28 @23 #include <linux/cpu.h> 5ff193fb Fenghua Yu 2016-10-28 24 #include <linux/fs.h> 5ff193fb Fenghua Yu 2016-10-28 25 #include <linux/sysfs.h> 5ff193fb Fenghua Yu 2016-10-28 26 #include <linux/kernfs.h> 9b3a7fd0 Tony Luck 2017-09-25 27 #include <linux/seq_buf.h> 4e978d06 Fenghua Yu 2016-10-28 28 #include <linux/seq_file.h> 3f07c014 Ingo Molnar 2017-02-08 29 #include <linux/sched/signal.h> 29930025 Ingo Molnar 2017-02-08 30 #include <linux/sched/task.h> 5ff193fb Fenghua Yu 2016-10-28 31 #include <linux/slab.h> e02737d5 Fenghua Yu 2016-10-28 32 #include <linux/task_work.h> 5ff193fb Fenghua Yu 2016-10-28 33 5ff193fb Fenghua Yu 2016-10-28 34 #include <uapi/linux/magic.h> 5ff193fb Fenghua Yu 2016-10-28 35 05830204 Vikas Shivappa 2017-07-25 36 #include <asm/intel_rdt_sched.h> 05830204 Vikas Shivappa 2017-07-25 37 #include "intel_rdt.h" 5ff193fb Fenghua Yu 2016-10-28 38 4af4a88e Vikas Shivappa 2017-07-25 39 DEFINE_STATIC_KEY_FALSE(rdt_enable_key); 4af4a88e Vikas Shivappa 2017-07-25 40 DEFINE_STATIC_KEY_FALSE(rdt_mon_enable_key); 1b5c0b75 Vikas Shivappa 2017-07-25 41 DEFINE_STATIC_KEY_FALSE(rdt_alloc_enable_key); cb2200e9 Reinette Chatre 2017-07-25 42 static struct kernfs_root *rdt_root; 5ff193fb Fenghua Yu 2016-10-28 43 struct rdtgroup rdtgroup_default; 5ff193fb Fenghua Yu 2016-10-28 44 LIST_HEAD(rdt_all_groups); 5ff193fb Fenghua Yu 2016-10-28 45 4e978d06 Fenghua Yu 2016-10-28 46 /* Kernel fs node for "info" directory under root */ 4e978d06 Fenghua Yu 2016-10-28 47 static struct kernfs_node *kn_info; 4e978d06 Fenghua Yu 2016-10-28 48 4af4a88e Vikas Shivappa 2017-07-25 49 /* Kernel fs node for "mon_groups" directory under root */ 4af4a88e Vikas Shivappa 2017-07-25 50 static struct kernfs_node *kn_mongrp; 4af4a88e Vikas Shivappa 2017-07-25 51 4af4a88e Vikas Shivappa 2017-07-25 52 /* Kernel fs node for "mon_data" directory under root */ 4af4a88e Vikas Shivappa 2017-07-25 53 static struct kernfs_node *kn_mondata; 4af4a88e Vikas Shivappa 2017-07-25 54 9b3a7fd0 Tony Luck 2017-09-25 55 static struct seq_buf last_cmd_status; 9b3a7fd0 Tony Luck 2017-09-25 56 static char last_cmd_status_buf[512]; 9b3a7fd0 Tony Luck 2017-09-25 57 9b3a7fd0 Tony Luck 2017-09-25 58 void rdt_last_cmd_clear(void) 9b3a7fd0 Tony Luck 2017-09-25 59 { 9b3a7fd0 Tony Luck 2017-09-25 60 lockdep_assert_held(&rdtgroup_mutex); 9b3a7fd0 Tony Luck 2017-09-25 61 seq_buf_clear(&last_cmd_status); 9b3a7fd0 Tony Luck 2017-09-25 62 } 9b3a7fd0 Tony Luck 2017-09-25 63 9b3a7fd0 Tony Luck 2017-09-25 64 void rdt_last_cmd_puts(const char *s) 9b3a7fd0 Tony Luck 2017-09-25 65 { 9b3a7fd0 Tony Luck 2017-09-25 66 lockdep_assert_held(&rdtgroup_mutex); 9b3a7fd0 Tony Luck 2017-09-25 67 seq_buf_puts(&last_cmd_status, s); 9b3a7fd0 Tony Luck 2017-09-25 68 } 9b3a7fd0 Tony Luck 2017-09-25 69 9b3a7fd0 Tony Luck 2017-09-25 70 void rdt_last_cmd_printf(const char *fmt, ...) 9b3a7fd0 Tony Luck 2017-09-25 71 { 9b3a7fd0 Tony Luck 2017-09-25 72 va_list ap; 9b3a7fd0 Tony Luck 2017-09-25 73 9b3a7fd0 Tony Luck 2017-09-25 74 va_start(ap, fmt); 9b3a7fd0 Tony Luck 2017-09-25 75 lockdep_assert_held(&rdtgroup_mutex); 9b3a7fd0 Tony Luck 2017-09-25 76 seq_buf_vprintf(&last_cmd_status, fmt, ap); 9b3a7fd0 Tony Luck 2017-09-25 77 va_end(ap); 9b3a7fd0 Tony Luck 2017-09-25 78 } 9b3a7fd0 Tony Luck 2017-09-25 79 60cf5e10 Fenghua Yu 2016-10-28 80 /* 60cf5e10 Fenghua Yu 2016-10-28 81 * Trivial allocator for CLOSIDs. Since h/w only supports a small number, 60cf5e10 Fenghua Yu 2016-10-28 82 * we can keep a bitmap of free CLOSIDs in a single integer. 60cf5e10 Fenghua Yu 2016-10-28 83 * 60cf5e10 Fenghua Yu 2016-10-28 84 * Using a global CLOSID across all resources has some advantages and 60cf5e10 Fenghua Yu 2016-10-28 85 * some drawbacks: 60cf5e10 Fenghua Yu 2016-10-28 86 * + We can simply set "current->closid" to assign a task to a resource 60cf5e10 Fenghua Yu 2016-10-28 87 * group. 60cf5e10 Fenghua Yu 2016-10-28 88 * + Context switch code can avoid extra memory references deciding which 60cf5e10 Fenghua Yu 2016-10-28 89 * CLOSID to load into the PQR_ASSOC MSR 60cf5e10 Fenghua Yu 2016-10-28 90 * - We give up some options in configuring resource groups across multi-socket 60cf5e10 Fenghua Yu 2016-10-28 91 * systems. 60cf5e10 Fenghua Yu 2016-10-28 92 * - Our choices on how to configure each resource become progressively more 60cf5e10 Fenghua Yu 2016-10-28 93 * limited as the number of resources grows. 60cf5e10 Fenghua Yu 2016-10-28 94 */ 60cf5e10 Fenghua Yu 2016-10-28 95 static int closid_free_map; 60cf5e10 Fenghua Yu 2016-10-28 96 60cf5e10 Fenghua Yu 2016-10-28 97 static void closid_init(void) 60cf5e10 Fenghua Yu 2016-10-28 98 { 60cf5e10 Fenghua Yu 2016-10-28 99 struct rdt_resource *r; 60cf5e10 Fenghua Yu 2016-10-28 100 int rdt_min_closid = 32; 60cf5e10 Fenghua Yu 2016-10-28 101 60cf5e10 Fenghua Yu 2016-10-28 102 /* Compute rdt_min_closid across all resources */ 1b5c0b75 Vikas Shivappa 2017-07-25 103 for_each_alloc_enabled_rdt_resource(r) 60cf5e10 Fenghua Yu 2016-10-28 104 rdt_min_closid = min(rdt_min_closid, r->num_closid); 60cf5e10 Fenghua Yu 2016-10-28 105 60cf5e10 Fenghua Yu 2016-10-28 106 closid_free_map = BIT_MASK(rdt_min_closid) - 1; 60cf5e10 Fenghua Yu 2016-10-28 107 60cf5e10 Fenghua Yu 2016-10-28 108 /* CLOSID 0 is always reserved for the default group */ 60cf5e10 Fenghua Yu 2016-10-28 109 closid_free_map &= ~1; 60cf5e10 Fenghua Yu 2016-10-28 110 } 60cf5e10 Fenghua Yu 2016-10-28 111 cb2200e9 Reinette Chatre 2017-07-25 112 static int closid_alloc(void) 60cf5e10 Fenghua Yu 2016-10-28 113 { 0734ded1 Vikas Shivappa 2017-07-25 114 u32 closid = ffs(closid_free_map); 60cf5e10 Fenghua Yu 2016-10-28 115 60cf5e10 Fenghua Yu 2016-10-28 116 if (closid == 0) 60cf5e10 Fenghua Yu 2016-10-28 117 return -ENOSPC; 60cf5e10 Fenghua Yu 2016-10-28 118 closid--; 60cf5e10 Fenghua Yu 2016-10-28 119 closid_free_map &= ~(1 << closid); 60cf5e10 Fenghua Yu 2016-10-28 120 60cf5e10 Fenghua Yu 2016-10-28 121 return closid; 60cf5e10 Fenghua Yu 2016-10-28 122 } 60cf5e10 Fenghua Yu 2016-10-28 123 60cf5e10 Fenghua Yu 2016-10-28 124 static void closid_free(int closid) 60cf5e10 Fenghua Yu 2016-10-28 125 { 60cf5e10 Fenghua Yu 2016-10-28 126 closid_free_map |= 1 << closid; 60cf5e10 Fenghua Yu 2016-10-28 127 } 60cf5e10 Fenghua Yu 2016-10-28 128 4e978d06 Fenghua Yu 2016-10-28 129 /* set uid and gid of rdtgroup dirs and files to that of the creator */ 4e978d06 Fenghua Yu 2016-10-28 130 static int rdtgroup_kn_set_ugid(struct kernfs_node *kn) 4e978d06 Fenghua Yu 2016-10-28 131 { 4e978d06 Fenghua Yu 2016-10-28 132 struct iattr iattr = { .ia_valid = ATTR_UID | ATTR_GID, 4e978d06 Fenghua Yu 2016-10-28 133 .ia_uid = current_fsuid(), 4e978d06 Fenghua Yu 2016-10-28 134 .ia_gid = current_fsgid(), }; 4e978d06 Fenghua Yu 2016-10-28 135 4e978d06 Fenghua Yu 2016-10-28 136 if (uid_eq(iattr.ia_uid, GLOBAL_ROOT_UID) && 4e978d06 Fenghua Yu 2016-10-28 137 gid_eq(iattr.ia_gid, GLOBAL_ROOT_GID)) 4e978d06 Fenghua Yu 2016-10-28 138 return 0; 4e978d06 Fenghua Yu 2016-10-28 139 4e978d06 Fenghua Yu 2016-10-28 140 return kernfs_setattr(kn, &iattr); 4e978d06 Fenghua Yu 2016-10-28 141 } 4e978d06 Fenghua Yu 2016-10-28 142 4e978d06 Fenghua Yu 2016-10-28 143 static int rdtgroup_add_file(struct kernfs_node *parent_kn, struct rftype *rft) 4e978d06 Fenghua Yu 2016-10-28 144 { 4e978d06 Fenghua Yu 2016-10-28 145 struct kernfs_node *kn; 4e978d06 Fenghua Yu 2016-10-28 146 int ret; 4e978d06 Fenghua Yu 2016-10-28 147 4e978d06 Fenghua Yu 2016-10-28 @148 kn = __kernfs_create_file(parent_kn, rft->name, rft->mode, 4e978d06 Fenghua Yu 2016-10-28 @149 0, rft->kf_ops, rft, NULL, NULL); 4e978d06 Fenghua Yu 2016-10-28 150 if (IS_ERR(kn)) 4e978d06 Fenghua Yu 2016-10-28 151 return PTR_ERR(kn); 4e978d06 Fenghua Yu 2016-10-28 152 4e978d06 Fenghua Yu 2016-10-28 153 ret = rdtgroup_kn_set_ugid(kn); 4e978d06 Fenghua Yu 2016-10-28 154 if (ret) { 4e978d06 Fenghua Yu 2016-10-28 155 kernfs_remove(kn); 4e978d06 Fenghua Yu 2016-10-28 156 return ret; 4e978d06 Fenghua Yu 2016-10-28 157 } 4e978d06 Fenghua Yu 2016-10-28 158 4e978d06 Fenghua Yu 2016-10-28 159 return 0; 4e978d06 Fenghua Yu 2016-10-28 160 } 4e978d06 Fenghua Yu 2016-10-28 161 :::::: The code at line 149 was first introduced by commit :::::: 4e978d06dedb8207b298a5a8a49fce4b2ab80d12 x86/intel_rdt: Add "info" files to resctrl file system :::::: TO: Fenghua Yu <fenghua.yu@intel.com> :::::: CC: Thomas Gleixner <tglx@linutronix.de> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index d66cc0777303..4ca0b5c18192 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -619,6 +619,7 @@ struct kernfs_node *kernfs_node_from_dentry(struct dentry *dentry) static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, const char *name, umode_t mode, + kuid_t uid, kgid_t gid, unsigned flags) { struct kernfs_node *kn; @@ -661,8 +662,22 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, kn->mode = mode; kn->flags = flags; + if (!uid_eq(uid, GLOBAL_ROOT_UID) || !gid_eq(gid, GLOBAL_ROOT_GID)) { + struct iattr iattr = { + .ia_valid = ATTR_UID | ATTR_GID, + .ia_uid = uid, + .ia_gid = gid, + }; + + ret = __kernfs_setattr(kn, &iattr); + if (ret < 0) + goto err_out3; + } + return kn; + err_out3: + idr_remove(&root->ino_idr, kn->id.ino); err_out2: kmem_cache_free(kernfs_node_cache, kn); err_out1: @@ -672,11 +687,13 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, const char *name, umode_t mode, + kuid_t uid, kgid_t gid, unsigned flags) { struct kernfs_node *kn; - kn = __kernfs_new_node(kernfs_root(parent), name, mode, flags); + kn = __kernfs_new_node(kernfs_root(parent), + name, mode, uid, gid, flags); if (kn) { kernfs_get(parent); kn->parent = parent; @@ -946,6 +963,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops, root->next_generation = 1; kn = __kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO, + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, KERNFS_DIR); if (!kn) { idr_destroy(&root->ino_idr); @@ -984,6 +1002,8 @@ void kernfs_destroy_root(struct kernfs_root *root) * @parent: parent in which to create a new directory * @name: name of the new directory * @mode: mode of the new directory + * @uid: uid of the new directory + * @gid: gid of the new directory * @priv: opaque data associated with the new directory * @ns: optional namespace tag of the directory * @@ -991,13 +1011,15 @@ void kernfs_destroy_root(struct kernfs_root *root) */ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, umode_t mode, + kuid_t uid, kgid_t gid, void *priv, const void *ns) { struct kernfs_node *kn; int rc; /* allocate */ - kn = kernfs_new_node(parent, name, mode | S_IFDIR, KERNFS_DIR); + kn = kernfs_new_node(parent, name, mode | S_IFDIR, + uid, gid, KERNFS_DIR); if (!kn) return ERR_PTR(-ENOMEM); @@ -1028,7 +1050,8 @@ struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent, int rc; /* allocate */ - kn = kernfs_new_node(parent, name, S_IRUGO|S_IXUGO|S_IFDIR, KERNFS_DIR); + kn = kernfs_new_node(parent, name, S_IRUGO|S_IXUGO|S_IFDIR, + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, KERNFS_DIR); if (!kn) return ERR_PTR(-ENOMEM); diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 2015d8c45e4a..dbf5bc250bfd 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -965,6 +965,8 @@ const struct file_operations kernfs_file_fops = { * @parent: directory to create the file in * @name: name of the file * @mode: mode of the file + * @uid: uid of the file + * @gid: gid of the file * @size: size of the file * @ops: kernfs operations for the file * @priv: private data for the file @@ -975,7 +977,8 @@ const struct file_operations kernfs_file_fops = { */ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, const char *name, - umode_t mode, loff_t size, + umode_t mode, kuid_t uid, kgid_t gid, + loff_t size, const struct kernfs_ops *ops, void *priv, const void *ns, struct lock_class_key *key) @@ -986,7 +989,8 @@ struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, flags = KERNFS_FILE; - kn = kernfs_new_node(parent, name, (mode & S_IALLUGO) | S_IFREG, flags); + kn = kernfs_new_node(parent, name, (mode & S_IALLUGO) | S_IFREG, + uid, gid, flags); if (!kn) return ERR_PTR(-ENOMEM); diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 3d73fe9d56e2..80cebcd94c90 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -63,7 +63,7 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) return ret; } -static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) +int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) { struct kernfs_iattrs *attrs; struct iattr *iattrs; diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 0f260dcca177..3d83b114bb08 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h @@ -90,6 +90,7 @@ int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr); int kernfs_iop_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags); ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size); +int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr); /* * dir.c @@ -104,6 +105,7 @@ void kernfs_put_active(struct kernfs_node *kn); int kernfs_add_one(struct kernfs_node *kn); struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, const char *name, umode_t mode, + kuid_t uid, kgid_t gid, unsigned flags); struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root, unsigned int ino); diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 08ccabd7047f..5ffed48f3d0e 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -21,6 +21,7 @@ * @target: target node for the symlink to point to * * Returns the created node on success, ERR_PTR() value on error. + * Ownership of the link matches ownership of the target. */ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, const char *name, @@ -28,8 +29,16 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, { struct kernfs_node *kn; int error; + kuid_t uid = GLOBAL_ROOT_UID; + kgid_t gid = GLOBAL_ROOT_GID; - kn = kernfs_new_node(parent, name, S_IFLNK|S_IRWXUGO, KERNFS_LINK); + if (target->iattr) { + uid = target->iattr->ia_iattr.ia_uid; + gid = target->iattr->ia_iattr.ia_gid; + } + + kn = kernfs_new_node(parent, name, S_IFLNK|S_IRWXUGO, uid, gid, + KERNFS_LINK); if (!kn) return ERR_PTR(-ENOMEM); diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 58eba92a0e41..e39b884f0867 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -52,7 +52,9 @@ int sysfs_create_dir_ns(struct kobject *kobj, const void *ns) return -ENOENT; kn = kernfs_create_dir_ns(parent, kobject_name(kobj), - S_IRWXU | S_IRUGO | S_IXUGO, kobj, ns); + S_IRWXU | S_IRUGO | S_IXUGO, + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, + kobj, ns); if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(parent, kobject_name(kobj)); diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 5c13f29bfcdb..513fa691ecbd 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -302,8 +302,9 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, if (!attr->ignore_lockdep) key = attr->key ?: (struct lock_class_key *)&attr->skey; #endif - kn = __kernfs_create_file(parent, attr->name, mode & 0777, size, ops, - (void *)attr, ns, key); + kn = __kernfs_create_file(parent, attr->name, + mode & 0777, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, + size, ops, (void *)attr, ns, key); if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(parent, attr->name); diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index ab25c8b6d9e3..814643f7ee52 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -15,6 +15,7 @@ #include <linux/lockdep.h> #include <linux/rbtree.h> #include <linux/atomic.h> +#include <linux/uidgid.h> #include <linux/wait.h> struct file; @@ -325,12 +326,14 @@ void kernfs_destroy_root(struct kernfs_root *root); struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, umode_t mode, + kuid_t uid, kgid_t gid, void *priv, const void *ns); struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent, const char *name); struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent, - const char *name, - umode_t mode, loff_t size, + const char *name, umode_t mode, + kuid_t uid, kgid_t gid, + loff_t size, const struct kernfs_ops *ops, void *priv, const void *ns, struct lock_class_key *key); @@ -415,12 +418,14 @@ static inline void kernfs_destroy_root(struct kernfs_root *root) { } static inline struct kernfs_node * kernfs_create_dir_ns(struct kernfs_node *parent, const char *name, - umode_t mode, void *priv, const void *ns) + umode_t mode, kuid_t uid, kgid_t gid, + void *priv, const void *ns) { return ERR_PTR(-ENOSYS); } static inline struct kernfs_node * __kernfs_create_file(struct kernfs_node *parent, const char *name, - umode_t mode, loff_t size, const struct kernfs_ops *ops, + umode_t mode, kuid_t uid, kgid_t gid, + loff_t size, const struct kernfs_ops *ops, void *priv, const void *ns, struct lock_class_key *key) { return ERR_PTR(-ENOSYS); } @@ -498,12 +503,15 @@ static inline struct kernfs_node * kernfs_create_dir(struct kernfs_node *parent, const char *name, umode_t mode, void *priv) { - return kernfs_create_dir_ns(parent, name, mode, priv, NULL); + return kernfs_create_dir_ns(parent, name, mode, + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, + priv, NULL); } static inline struct kernfs_node * kernfs_create_file_ns(struct kernfs_node *parent, const char *name, - umode_t mode, loff_t size, const struct kernfs_ops *ops, + umode_t mode, kuid_t uid, kgid_t gid, + loff_t size, const struct kernfs_ops *ops, void *priv, const void *ns) { struct lock_class_key *key = NULL; @@ -511,15 +519,17 @@ kernfs_create_file_ns(struct kernfs_node *parent, const char *name, #ifdef CONFIG_DEBUG_LOCK_ALLOC key = (struct lock_class_key *)&ops->lockdep_key; #endif - return __kernfs_create_file(parent, name, mode, size, ops, priv, ns, - key); + return __kernfs_create_file(parent, name, mode, uid, gid, + size, ops, priv, ns, key); } static inline struct kernfs_node * kernfs_create_file(struct kernfs_node *parent, const char *name, umode_t mode, loff_t size, const struct kernfs_ops *ops, void *priv) { - return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL); + return kernfs_create_file_ns(parent, name, mode, + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, + size, ops, priv, NULL); } static inline int kernfs_remove_by_name(struct kernfs_node *parent, diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 077370bf8964..35cf3d71f8aa 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -3557,7 +3557,9 @@ static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp, key = &cft->lockdep_key; #endif kn = __kernfs_create_file(cgrp->kn, cgroup_file_name(cgrp, cft, name), - cgroup_file_mode(cft), 0, cft->kf_ops, cft, + cgroup_file_mode(cft), + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, + 0, cft->kf_ops, cft, NULL, key); if (IS_ERR(kn)) return PTR_ERR(kn);