Merge tag 'mtd/for-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
[linux-2.6-microblaze.git] / kernel / module.c
index e7b4ff7..8fa2600 100644 (file)
@@ -1520,18 +1520,34 @@ struct module_sect_attrs {
        struct module_sect_attr attrs[];
 };
 
+#define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4))
 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(battr, struct module_sect_attr, battr);
+       char bounce[MODULE_SECT_READ_SIZE + 1];
+       size_t wrote;
 
        if (pos != 0)
                return -EINVAL;
 
-       return sprintf(buf, "0x%px\n",
-                      kallsyms_show_value(file->f_cred) ? (void *)sattr->address : NULL);
+       /*
+        * Since we're a binary read handler, we must account for the
+        * trailing NUL byte that sprintf will write: if "buf" is
+        * too small to hold the NUL, or the NUL is exactly the last
+        * byte, the read will look like it got truncated by one byte.
+        * Since there is no way to ask sprintf nicely to not write
+        * the NUL, we have to use a bounce buffer.
+        */
+       wrote = scnprintf(bounce, sizeof(bounce), "0x%px\n",
+                        kallsyms_show_value(file->f_cred)
+                               ? (void *)sattr->address : NULL);
+       count = min(count, wrote);
+       memcpy(buf, bounce, count);
+
+       return count;
 }
 
 static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
@@ -1580,7 +1596,7 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
                        goto out;
                sect_attrs->nsections++;
                sattr->battr.read = module_sect_read;
-               sattr->battr.size = 3 /* "0x", "\n" */ + (BITS_PER_LONG / 4);
+               sattr->battr.size = MODULE_SECT_READ_SIZE;
                sattr->battr.attr.mode = 0400;
                *(gattr++) = &(sattr++)->battr;
        }