From: Tobias Stoeckmann Date: Wed, 14 Aug 2024 15:50:34 +0000 (+0200) Subject: tools: Check snprintf return value X-Git-Tag: v34~300 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4f8a6a85c58770b3c4212780026215faab2f33a4;p=thirdparty%2Fkmod.git tools: Check snprintf return value If an excessively large root directory is supplied, subsequent operations might process unexpected parts in file system. Inform user that supplied directory paths are too long and stop program execution. Signed-off-by: Tobias Stoeckmann Reviewed-by: Emil Velikov Link: https://github.com/kmod-project/kmod/pull/72 Signed-off-by: Lucas De Marchi --- diff --git a/tools/depmod.c b/tools/depmod.c index 847b4cb5..daaa9188 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -2643,9 +2643,16 @@ static int depmod_output(struct depmod *depmod, FILE *out) int flags = O_CREAT | O_EXCL | O_WRONLY; int mode = 0644; int fd; + int n; - snprintf(tmp, sizeof(tmp), "%s.%i.%lli.%lli", itr->name, getpid(), + n = snprintf(tmp, sizeof(tmp), "%s.%i.%lli.%lli", itr->name, getpid(), (long long)tv.tv_usec, (long long)tv.tv_sec); + if (n >= (int)sizeof(tmp)) { + ERR("bad filename: %s.%i.%lli.%lli: path too long\n", + itr->name, getpid(), (long long)tv.tv_usec, + (long long)tv.tv_sec); + continue; + } fd = openat(dfd, tmp, flags, mode); if (fd < 0) { ERR("openat(%s, %s, %o, %o): %m\n", @@ -3054,10 +3061,21 @@ static int do_depmod(int argc, char *argv[]) cfg.dirnamelen = snprintf(cfg.dirname, PATH_MAX, "%s%s/%s", root ?: "", module_directory, cfg.kversion); + if (cfg.dirnamelen >= PATH_MAX) { + ERR("Bad directory %s" MODULE_DIRECTORY + "/%s: path too long\n", root ?: "", cfg.kversion); + goto cmdline_failed; + } cfg.outdirnamelen = snprintf(cfg.outdirname, PATH_MAX, "%s%s/%s", out_root ?: (root ?: ""), module_directory, cfg.kversion); + if (cfg.outdirnamelen >= PATH_MAX) { + ERR("Bad directory %s" MODULE_DIRECTORY + "/%s: path too long\n", out_root ?: (root ?: ""), + cfg.kversion); + goto cmdline_failed; + } if (optind == argc) all = 1; diff --git a/tools/modinfo.c b/tools/modinfo.c index 59ecb17e..68c7b948 100644 --- a/tools/modinfo.c +++ b/tools/modinfo.c @@ -440,6 +440,7 @@ static int do_modinfo(int argc, char *argv[]) if (root != NULL || kversion != NULL) { struct utsname u; + int n; if (root == NULL) root = ""; if (kversion == NULL) { @@ -449,8 +450,14 @@ static int do_modinfo(int argc, char *argv[]) } kversion = u.release; } - snprintf(dirname_buf, sizeof(dirname_buf), "%s" MODULE_DIRECTORY "/%s", - root, kversion); + + n = snprintf(dirname_buf, sizeof(dirname_buf), + "%s" MODULE_DIRECTORY "/%s", root, kversion); + if (n >= (int)sizeof(dirname_buf)) { + ERR("bad directory %s" MODULE_DIRECTORY + "/%s: path too long\n", root, kversion); + return EXIT_FAILURE; + } dirname = dirname_buf; } diff --git a/tools/modprobe.c b/tools/modprobe.c index 3c085e89..4070e552 100644 --- a/tools/modprobe.c +++ b/tools/modprobe.c @@ -976,6 +976,7 @@ static int do_modprobe(int argc, char **orig_argv) if (root != NULL || kversion != NULL) { struct utsname u; + int n; if (root == NULL) root = ""; if (kversion == NULL) { @@ -986,9 +987,14 @@ static int do_modprobe(int argc, char **orig_argv) } kversion = u.release; } - snprintf(dirname_buf, sizeof(dirname_buf), - "%s" MODULE_DIRECTORY "/%s", root, - kversion); + n = snprintf(dirname_buf, sizeof(dirname_buf), + "%s" MODULE_DIRECTORY "/%s", root, kversion); + if (n >= (int)sizeof(dirname_buf)) { + ERR("bad directory %s" MODULE_DIRECTORY + "/%s: path too long\n", root, kversion); + err = -1; + goto done; + } dirname = dirname_buf; } diff --git a/tools/static-nodes.c b/tools/static-nodes.c index 435e0dc1..58c06cfb 100644 --- a/tools/static-nodes.c +++ b/tools/static-nodes.c @@ -200,7 +200,13 @@ static int do_static_nodes(int argc, char *argv[]) goto finish; } - snprintf(modules, sizeof(modules), MODULE_DIRECTORY "/%s/modules.devname", kernel.release); + r = snprintf(modules, sizeof(modules), MODULE_DIRECTORY "/%s/modules.devname", kernel.release); + if (r >= (int)sizeof(modules)) { + fprintf(stderr, "Error: could not open " MODULE_DIRECTORY "/%s/modules.devname - path too long\n", + kernel.release); + ret = EXIT_FAILURE; + goto finish; + } in = fopen(modules, "re"); if (in == NULL) { if (errno == ENOENT) {