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

Acked-by: Luis Chamberlain <mcg...@kernel.org>
Reviewed-by: Petr Pavlu <petr.pa...@suse.com>
Reported-by: kernel test robot <l...@intel.com>
Closes: 
https://lore.kernel.org/oe-kbuild-all/202409010016.3xifsmra-...@intel.com/
Signed-off-by: Xion Wang <xion.w...@mediatek.com>
Signed-off-by: Chunhui Li <chunhui...@mediatek.com>
---
 kernel/module/sysfs.c | 57 +++++++++++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 21 deletions(-)

diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c
index 26efe1305c12..0e0a9137a273 100644
--- a/kernel/module/sysfs.c
+++ b/kernel/module/sysfs.c
@@ -69,12 +69,13 @@ static void free_sect_attrs(struct module_sect_attrs 
*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];
        struct module_sect_attrs *sect_attrs;
        struct module_sect_attr *sattr;
        struct bin_attribute **gattr;
+       int ret;
 
        /* Count loaded sections and allocate structures */
        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)
        size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
        sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
        if (!sect_attrs)
-               return;
+               return -ENOMEM;
 
        /* Setup section attributes. */
        sect_attrs->grp.name = "sections";
@@ -103,8 +104,10 @@ static void add_sect_attrs(struct module *mod, const 
struct load_info *info)
                sattr->address = sec->sh_addr;
                sattr->battr.attr.name =
                        kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
-               if (!sattr->battr.attr.name)
+               if (!sattr->battr.attr.name) {
+                       ret = -ENOMEM;
                        goto out;
+               }
                sect_attrs->nsections++;
                sattr->battr.read = module_sect_read;
                sattr->battr.size = MODULE_SECT_READ_SIZE;
@@ -113,13 +116,15 @@ static void add_sect_attrs(struct module *mod, const 
struct load_info *info)
        }
        *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;
 
        mod->sect_attrs = sect_attrs;
-       return;
+       return 0;
 out:
        free_sect_attrs(sect_attrs);
+       return ret;
 }
 
 static void remove_sect_attrs(struct module *mod)
@@ -158,15 +163,12 @@ static void free_notes_attrs(struct module_notes_attrs 
*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;
        struct module_notes_attrs *notes_attrs;
        struct bin_attribute *nattr;
-
-       /* failed to create section attributes, so can't create notes */
-       if (!mod->sect_attrs)
-               return;
+       int ret;
 
        /* Count notes sections and allocate structures.  */
        notes = 0;
@@ -176,12 +178,12 @@ static void add_notes_attrs(struct module *mod, const 
struct load_info *info)
                        ++notes;
 
        if (notes == 0)
-               return;
+               return 0;
 
        notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes),
                              GFP_KERNEL);
        if (!notes_attrs)
-               return;
+               return -ENOMEM;
 
        notes_attrs->notes = notes;
        nattr = &notes_attrs->attrs[0];
@@ -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);
-       if (!notes_attrs->dir)
+       if (!notes_attrs->dir) {
+               ret = -ENOMEM;
                goto out;
+       }
 
-       for (i = 0; i < notes; ++i)
-               if (sysfs_create_bin_file(notes_attrs->dir,
-                                         &notes_attrs->attrs[i]))
+       for (i = 0; i < notes; ++i) {
+               ret = sysfs_create_bin_file(notes_attrs->dir, 
&notes_attrs->attrs[i]);
+               if (ret)
                        goto out;
+       }
 
        mod->notes_attrs = notes_attrs;
-       return;
+       return 0;
 
 out:
        free_notes_attrs(notes_attrs, i);
+       return ret;
 }
 
 static void remove_notes_attrs(struct module *mod)
@@ -223,9 +229,9 @@ static void remove_notes_attrs(struct module *mod)
 }
 
 #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) { }
 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) { }
 static inline void remove_notes_attrs(struct module *mod) { }
 #endif /* CONFIG_KALLSYMS */
 
@@ -385,11 +391,20 @@ int mod_sysfs_setup(struct module *mod,
        if (err)
                goto out_unreg_modinfo_attrs;
 
-       add_sect_attrs(mod, info);
-       add_notes_attrs(mod, info);
+       err = add_sect_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;
 
+out_unreg_sect_attrs:
+       remove_sect_attrs(mod);
+out_del_usage_links:
+       del_usage_links(mod);
 out_unreg_modinfo_attrs:
        module_remove_modinfo_attrs(mod, -1);
 out_unreg_param:
-- 
2.45.2


Reply via email to