diff mbox series

libkmod: fix possible out-of-bounds memory access

Message ID 20230518110000.62061-1-dmantipov@yandex.ru (mailing list archive)
State New, archived
Headers show
Series libkmod: fix possible out-of-bounds memory access | expand

Commit Message

Dmitry Antipov May 18, 2023, 11 a.m. UTC
An attempt to pass too long module name to, say, rmmod, may
cause an out-of-bounds memory access (as repoted by UBSan):

$ rmmod $(for i in $(seq 0 4200); do echo -ne x; done)
libkmod/libkmod-module.c:1828:8: runtime error: index 4107 out of bounds for type 'char [4096]'

This is because 'snprintf(path, sizeof(path), ...)' may return the
value which exceeds 'sizeof(path)' (which happens when an output
gets truncated). To play it safe, such a suspicious output is
better to be rejected explicitly.

Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
 libkmod/libkmod-module.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Christophe Leroy May 19, 2023, 7 a.m. UTC | #1
Le 18/05/2023 à 13:00, Dmitry Antipov a écrit :
> [Vous ne recevez pas souvent de courriers de dmantipov@yandex.ru. Découvrez pourquoi ceci est important à https://aka.ms/LearnAboutSenderIdentification ]
> 
> An attempt to pass too long module name to, say, rmmod, may
> cause an out-of-bounds memory access (as repoted by UBSan):
> 
> $ rmmod $(for i in $(seq 0 4200); do echo -ne x; done)
> libkmod/libkmod-module.c:1828:8: runtime error: index 4107 out of bounds for type 'char [4096]'
> 
> This is because 'snprintf(path, sizeof(path), ...)' may return the
> value which exceeds 'sizeof(path)' (which happens when an output
> gets truncated). To play it safe, such a suspicious output is
> better to be rejected explicitly.
> 
> Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
> ---
>   libkmod/libkmod-module.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
> index 1da64b3..074001e 100644
> --- a/libkmod/libkmod-module.c
> +++ b/libkmod/libkmod-module.c
> @@ -1810,6 +1810,10 @@ KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
> 
>          pathlen = snprintf(path, sizeof(path),
>                                  "/sys/module/%s/initstate", mod->name);
> +       if (pathlen >= (int)sizeof(path)) {
> +               /* Too long path was truncated */
> +               return -EINVAL;

Why not ENAMETOOLONG ?


> +       }
>          fd = open(path, O_RDONLY|O_CLOEXEC);
>          if (fd < 0) {
>                  err = -errno;
> --
> 2.40.1
>
diff mbox series

Patch

diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
index 1da64b3..074001e 100644
--- a/libkmod/libkmod-module.c
+++ b/libkmod/libkmod-module.c
@@ -1810,6 +1810,10 @@  KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
 
 	pathlen = snprintf(path, sizeof(path),
 				"/sys/module/%s/initstate", mod->name);
+	if (pathlen >= (int)sizeof(path)) {
+		/* Too long path was truncated */
+		return -EINVAL;
+	}
 	fd = open(path, O_RDONLY|O_CLOEXEC);
 	if (fd < 0) {
 		err = -errno;