diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 53 | 
1 files changed, 28 insertions, 25 deletions
| diff --git a/kernel/module.c b/kernel/module.c index 0c6573b98c36..aa183c9ac0a2 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1510,8 +1510,7 @@ static inline bool sect_empty(const Elf_Shdr *sect)  }  struct module_sect_attr { -	struct module_attribute mattr; -	char *name; +	struct bin_attribute battr;  	unsigned long address;  }; @@ -1521,13 +1520,18 @@ struct module_sect_attrs {  	struct module_sect_attr attrs[];  }; -static ssize_t module_sect_show(struct module_attribute *mattr, -				struct module_kobject *mk, char *buf) +static ssize_t module_sect_read(struct file *file, struct kobject *kobj, +				struct bin_attribute *battr, +				char *buf, loff_t pos, size_t count)  {  	struct module_sect_attr *sattr = -		container_of(mattr, struct module_sect_attr, mattr); -	return sprintf(buf, "0x%px\n", kptr_restrict < 2 ? -		       (void *)sattr->address : NULL); +		container_of(battr, struct module_sect_attr, battr); + +	if (pos != 0) +		return -EINVAL; + +	return sprintf(buf, "0x%px\n", +		       kallsyms_show_value(file->f_cred) ? (void *)sattr->address : NULL);  }  static void free_sect_attrs(struct module_sect_attrs *sect_attrs) @@ -1535,7 +1539,7 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)  	unsigned int section;  	for (section = 0; section < sect_attrs->nsections; section++) -		kfree(sect_attrs->attrs[section].name); +		kfree(sect_attrs->attrs[section].battr.attr.name);  	kfree(sect_attrs);  } @@ -1544,42 +1548,41 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)  	unsigned int nloaded = 0, i, size[2];  	struct module_sect_attrs *sect_attrs;  	struct module_sect_attr *sattr; -	struct attribute **gattr; +	struct bin_attribute **gattr;  	/* Count loaded sections and allocate structures */  	for (i = 0; i < info->hdr->e_shnum; i++)  		if (!sect_empty(&info->sechdrs[i]))  			nloaded++;  	size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded), -			sizeof(sect_attrs->grp.attrs[0])); -	size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]); +			sizeof(sect_attrs->grp.bin_attrs[0])); +	size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);  	sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);  	if (sect_attrs == NULL)  		return;  	/* Setup section attributes. */  	sect_attrs->grp.name = "sections"; -	sect_attrs->grp.attrs = (void *)sect_attrs + size[0]; +	sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0];  	sect_attrs->nsections = 0;  	sattr = §_attrs->attrs[0]; -	gattr = §_attrs->grp.attrs[0]; +	gattr = §_attrs->grp.bin_attrs[0];  	for (i = 0; i < info->hdr->e_shnum; i++) {  		Elf_Shdr *sec = &info->sechdrs[i];  		if (sect_empty(sec))  			continue; +		sysfs_bin_attr_init(&sattr->battr);  		sattr->address = sec->sh_addr; -		sattr->name = kstrdup(info->secstrings + sec->sh_name, -					GFP_KERNEL); -		if (sattr->name == NULL) +		sattr->battr.attr.name = +			kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL); +		if (sattr->battr.attr.name == NULL)  			goto out;  		sect_attrs->nsections++; -		sysfs_attr_init(&sattr->mattr.attr); -		sattr->mattr.show = module_sect_show; -		sattr->mattr.store = NULL; -		sattr->mattr.attr.name = sattr->name; -		sattr->mattr.attr.mode = S_IRUSR; -		*(gattr++) = &(sattr++)->mattr.attr; +		sattr->battr.read = module_sect_read; +		sattr->battr.size = 3 /* "0x", "\n" */ + (BITS_PER_LONG / 4); +		sattr->battr.attr.mode = 0400; +		*(gattr++) = &(sattr++)->battr;  	}  	*gattr = NULL; @@ -1669,7 +1672,7 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)  			continue;  		if (info->sechdrs[i].sh_type == SHT_NOTE) {  			sysfs_bin_attr_init(nattr); -			nattr->attr.name = mod->sect_attrs->attrs[loaded].name; +			nattr->attr.name = mod->sect_attrs->attrs[loaded].battr.attr.name;  			nattr->attr.mode = S_IRUGO;  			nattr->size = info->sechdrs[i].sh_size;  			nattr->private = (void *) info->sechdrs[i].sh_addr; @@ -2785,7 +2788,7 @@ void * __weak module_alloc(unsigned long size)  {  	return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,  			GFP_KERNEL, PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS, -			NUMA_NO_NODE, __func__); +			NUMA_NO_NODE, __builtin_return_address(0));  }  bool __weak module_init_section(const char *name) @@ -4379,7 +4382,7 @@ static int modules_open(struct inode *inode, struct file *file)  	if (!err) {  		struct seq_file *m = file->private_data; -		m->private = kallsyms_show_value() ? NULL : (void *)8ul; +		m->private = kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul;  	}  	return err; | 
