Commit ce47f7cb authored by Chunhui Li's avatar Chunhui Li Committed by Luis Chamberlain

module: abort module loading when sysfs setup suffer errors

When insmod a kernel module, if fails in add_notes_attrs or
add_sysfs_attrs such as memory allocation fail, mod_sysfs_setup
will still return success, but we can't access user interface
on android device.

Patch for make mod_sysfs_setup can check the error of
add_notes_attrs and add_sysfs_attrs

[mcgrof: the section stuff comes from linux history.git [0]]
Fixes: 3f7b0672 ("Module section offsets in /sys/module") [0]
Fixes: 6d760133 ("Add /sys/module/name/notes")
Acked-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
Reviewed-by: default avatarPetr Pavlu <petr.pavlu@suse.com>
Reported-by: default avatarkernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202409010016.3XIFSmRA-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202409072018.qfEzZbO7-lkp@intel.com/
Link: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=3f7b0672086b97b2d7f322bdc289cbfa203f10ef [0]
Signed-off-by: default avatarXion Wang <xion.wang@mediatek.com>
Signed-off-by: default avatarChunhui Li <chunhui.li@mediatek.com>
Signed-off-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
parent 907fa79d
...@@ -69,12 +69,13 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs) ...@@ -69,12 +69,13 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
kfree(sect_attrs); kfree(sect_attrs);
} }
static void add_sect_attrs(struct module *mod, const struct load_info *info) static int add_sect_attrs(struct module *mod, const struct load_info *info)
{ {
unsigned int nloaded = 0, i, size[2]; unsigned int nloaded = 0, i, size[2];
struct module_sect_attrs *sect_attrs; struct module_sect_attrs *sect_attrs;
struct module_sect_attr *sattr; struct module_sect_attr *sattr;
struct bin_attribute **gattr; struct bin_attribute **gattr;
int ret;
/* Count loaded sections and allocate structures */ /* Count loaded sections and allocate structures */
for (i = 0; i < info->hdr->e_shnum; i++) for (i = 0; i < info->hdr->e_shnum; i++)
...@@ -85,7 +86,7 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info) ...@@ -85,7 +86,7 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
size[1] = (nloaded + 1) * 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); sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
if (!sect_attrs) if (!sect_attrs)
return; return -ENOMEM;
/* Setup section attributes. */ /* Setup section attributes. */
sect_attrs->grp.name = "sections"; sect_attrs->grp.name = "sections";
...@@ -103,8 +104,10 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info) ...@@ -103,8 +104,10 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
sattr->address = sec->sh_addr; sattr->address = sec->sh_addr;
sattr->battr.attr.name = sattr->battr.attr.name =
kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL); kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
if (!sattr->battr.attr.name) if (!sattr->battr.attr.name) {
ret = -ENOMEM;
goto out; goto out;
}
sect_attrs->nsections++; sect_attrs->nsections++;
sattr->battr.read = module_sect_read; sattr->battr.read = module_sect_read;
sattr->battr.size = MODULE_SECT_READ_SIZE; sattr->battr.size = MODULE_SECT_READ_SIZE;
...@@ -113,13 +116,15 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info) ...@@ -113,13 +116,15 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
} }
*gattr = NULL; *gattr = NULL;
if (sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp)) ret = sysfs_create_group(&mod->mkobj.kobj, &sect_attrs->grp);
if (ret)
goto out; goto out;
mod->sect_attrs = sect_attrs; mod->sect_attrs = sect_attrs;
return; return 0;
out: out:
free_sect_attrs(sect_attrs); free_sect_attrs(sect_attrs);
return ret;
} }
static void remove_sect_attrs(struct module *mod) static void remove_sect_attrs(struct module *mod)
...@@ -158,15 +163,12 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs, ...@@ -158,15 +163,12 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
kfree(notes_attrs); kfree(notes_attrs);
} }
static void add_notes_attrs(struct module *mod, const struct load_info *info) static int add_notes_attrs(struct module *mod, const struct load_info *info)
{ {
unsigned int notes, loaded, i; unsigned int notes, loaded, i;
struct module_notes_attrs *notes_attrs; struct module_notes_attrs *notes_attrs;
struct bin_attribute *nattr; struct bin_attribute *nattr;
int ret;
/* failed to create section attributes, so can't create notes */
if (!mod->sect_attrs)
return;
/* Count notes sections and allocate structures. */ /* Count notes sections and allocate structures. */
notes = 0; notes = 0;
...@@ -176,12 +178,12 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info) ...@@ -176,12 +178,12 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)
++notes; ++notes;
if (notes == 0) if (notes == 0)
return; return 0;
notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes), notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes),
GFP_KERNEL); GFP_KERNEL);
if (!notes_attrs) if (!notes_attrs)
return; return -ENOMEM;
notes_attrs->notes = notes; notes_attrs->notes = notes;
nattr = &notes_attrs->attrs[0]; nattr = &notes_attrs->attrs[0];
...@@ -201,19 +203,23 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info) ...@@ -201,19 +203,23 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)
} }
notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj); notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
if (!notes_attrs->dir) if (!notes_attrs->dir) {
ret = -ENOMEM;
goto out; goto out;
}
for (i = 0; i < notes; ++i) for (i = 0; i < notes; ++i) {
if (sysfs_create_bin_file(notes_attrs->dir, ret = sysfs_create_bin_file(notes_attrs->dir, &notes_attrs->attrs[i]);
&notes_attrs->attrs[i])) if (ret)
goto out; goto out;
}
mod->notes_attrs = notes_attrs; mod->notes_attrs = notes_attrs;
return; return 0;
out: out:
free_notes_attrs(notes_attrs, i); free_notes_attrs(notes_attrs, i);
return ret;
} }
static void remove_notes_attrs(struct module *mod) static void remove_notes_attrs(struct module *mod)
...@@ -223,9 +229,15 @@ static void remove_notes_attrs(struct module *mod) ...@@ -223,9 +229,15 @@ static void remove_notes_attrs(struct module *mod)
} }
#else /* !CONFIG_KALLSYMS */ #else /* !CONFIG_KALLSYMS */
static inline void add_sect_attrs(struct module *mod, const struct load_info *info) { } static inline int add_sect_attrs(struct module *mod, const struct load_info *info)
{
return 0;
}
static inline void remove_sect_attrs(struct module *mod) { } static inline void remove_sect_attrs(struct module *mod) { }
static inline void add_notes_attrs(struct module *mod, const struct load_info *info) { } static inline int add_notes_attrs(struct module *mod, const struct load_info *info)
{
return 0;
}
static inline void remove_notes_attrs(struct module *mod) { } static inline void remove_notes_attrs(struct module *mod) { }
#endif /* CONFIG_KALLSYMS */ #endif /* CONFIG_KALLSYMS */
...@@ -385,11 +397,20 @@ int mod_sysfs_setup(struct module *mod, ...@@ -385,11 +397,20 @@ int mod_sysfs_setup(struct module *mod,
if (err) if (err)
goto out_unreg_modinfo_attrs; goto out_unreg_modinfo_attrs;
add_sect_attrs(mod, info); err = add_sect_attrs(mod, info);
add_notes_attrs(mod, info); if (err)
goto out_del_usage_links;
err = add_notes_attrs(mod, info);
if (err)
goto out_unreg_sect_attrs;
return 0; return 0;
out_unreg_sect_attrs:
remove_sect_attrs(mod);
out_del_usage_links:
del_usage_links(mod);
out_unreg_modinfo_attrs: out_unreg_modinfo_attrs:
module_remove_modinfo_attrs(mod, -1); module_remove_modinfo_attrs(mod, -1);
out_unreg_param: out_unreg_param:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment