mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
module: Correctly truncate sysfs sections output
The only-root-readable /sys/module/$module/sections/$section files
did not truncate their output to the available buffer size. While most
paths into the kernfs read handlers end up using PAGE_SIZE buffers,
it's possible to get there through other paths (e.g. splice, sendfile).
Actually limit the output to the "count" passed into the read function,
and report it back correctly. *sigh*
Reported-by: kernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/lkml/20200805002015.GE23458@shao2-debian
Fixes: ed66f991bb
("module: Refactor section attr into bin attribute")
Cc: stable@vger.kernel.org
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Jessica Yu <jeyu@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
bcf876870b
commit
11990a5bd7
@ -1520,18 +1520,34 @@ struct module_sect_attrs {
|
|||||||
struct module_sect_attr 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,
|
static ssize_t module_sect_read(struct file *file, struct kobject *kobj,
|
||||||
struct bin_attribute *battr,
|
struct bin_attribute *battr,
|
||||||
char *buf, loff_t pos, size_t count)
|
char *buf, loff_t pos, size_t count)
|
||||||
{
|
{
|
||||||
struct module_sect_attr *sattr =
|
struct module_sect_attr *sattr =
|
||||||
container_of(battr, struct module_sect_attr, battr);
|
container_of(battr, struct module_sect_attr, battr);
|
||||||
|
char bounce[MODULE_SECT_READ_SIZE + 1];
|
||||||
|
size_t wrote;
|
||||||
|
|
||||||
if (pos != 0)
|
if (pos != 0)
|
||||||
return -EINVAL;
|
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)
|
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;
|
goto out;
|
||||||
sect_attrs->nsections++;
|
sect_attrs->nsections++;
|
||||||
sattr->battr.read = module_sect_read;
|
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;
|
sattr->battr.attr.mode = 0400;
|
||||||
*(gattr++) = &(sattr++)->battr;
|
*(gattr++) = &(sattr++)->battr;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user