forked from mirrors/linux
		
	module: Refactor section attr into bin attribute
In order to gain access to the open file's f_cred for kallsym visibility permission checks, refactor the module section attributes to use the bin_attribute instead of attribute interface. Additionally removes the redundant "name" struct member. Cc: stable@vger.kernel.org Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Tested-by: Jessica Yu <jeyu@kernel.org> Acked-by: Jessica Yu <jeyu@kernel.org> Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
		
							parent
							
								
									160251842c
								
							
						
					
					
						commit
						ed66f991bb
					
				
					 1 changed files with 24 additions and 21 deletions
				
			
		|  | @ -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,11 +1520,16 @@ 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); | ||||
| 		container_of(battr, struct module_sect_attr, battr); | ||||
| 
 | ||||
| 	if (pos != 0) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	return sprintf(buf, "0x%px\n", kptr_restrict < 2 ? | ||||
| 		       (void *)sattr->address : NULL); | ||||
| } | ||||
|  | @ -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; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Kees Cook
						Kees Cook