Linux kernel -stable discussions
 help / color / mirror / Atom feed
* [PATCH 1/2] module: Correctly truncate sysfs sections output
       [not found] <20200807063539.2620154-1-keescook@chromium.org>
@ 2020-08-07  6:35 ` Kees Cook
  2020-08-07  6:47   ` Greg Kroah-Hartman
  2020-08-07 13:18   ` Jessica Yu
  0 siblings, 2 replies; 3+ messages in thread
From: Kees Cook @ 2020-08-07  6:35 UTC (permalink / raw)
  To: linux-kernel
  Cc: Kees Cook, kernel test robot, stable, Jessica Yu, Shuah Khan,
	Greg Kroah-Hartman, Masahiro Yamada, linux-kselftest

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: ed66f991bb19 ("module: Refactor section attr into bin attribute")
Cc: stable@vger.kernel.org
Cc: Jessica Yu <jeyu@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 kernel/module.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index aa183c9ac0a2..08c46084d8cc 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -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;
 	}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] module: Correctly truncate sysfs sections output
  2020-08-07  6:35 ` [PATCH 1/2] module: Correctly truncate sysfs sections output Kees Cook
@ 2020-08-07  6:47   ` Greg Kroah-Hartman
  2020-08-07 13:18   ` Jessica Yu
  1 sibling, 0 replies; 3+ messages in thread
From: Greg Kroah-Hartman @ 2020-08-07  6:47 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-kernel, kernel test robot, stable, Jessica Yu, Shuah Khan,
	Masahiro Yamada, linux-kselftest

On Thu, Aug 06, 2020 at 11:35:38PM -0700, Kees Cook wrote:
> 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*

Ugh, never thought about that...

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] module: Correctly truncate sysfs sections output
  2020-08-07  6:35 ` [PATCH 1/2] module: Correctly truncate sysfs sections output Kees Cook
  2020-08-07  6:47   ` Greg Kroah-Hartman
@ 2020-08-07 13:18   ` Jessica Yu
  1 sibling, 0 replies; 3+ messages in thread
From: Jessica Yu @ 2020-08-07 13:18 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-kernel, kernel test robot, stable, Shuah Khan,
	Greg Kroah-Hartman, Masahiro Yamada, linux-kselftest

+++ Kees Cook [06/08/20 23:35 -0700]:
>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: ed66f991bb19 ("module: Refactor section attr into bin attribute")
>Cc: stable@vger.kernel.org
>Cc: Jessica Yu <jeyu@kernel.org>
>Signed-off-by: Kees Cook <keescook@chromium.org>

Oof, thanks for fixing this!

Acked-by: Jessica Yu <jeyu@kernel.org>

>---
> kernel/module.c | 22 +++++++++++++++++++---
> 1 file changed, 19 insertions(+), 3 deletions(-)
>
>diff --git a/kernel/module.c b/kernel/module.c
>index aa183c9ac0a2..08c46084d8cc 100644
>--- a/kernel/module.c
>+++ b/kernel/module.c
>@@ -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;
> 	}
>-- 
>2.25.1
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-08-07 13:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20200807063539.2620154-1-keescook@chromium.org>
2020-08-07  6:35 ` [PATCH 1/2] module: Correctly truncate sysfs sections output Kees Cook
2020-08-07  6:47   ` Greg Kroah-Hartman
2020-08-07 13:18   ` Jessica Yu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox