diff options
author | Ruediger Meier | 2017-06-27 20:32:52 +0200 |
---|---|---|
committer | Ruediger Meier | 2017-06-27 21:39:35 +0200 |
commit | e230ae7b68814a2ea560e5138188a58128e34417 (patch) | |
tree | 8eaab2a06c417004a5477ad6cba769639eb72a76 | |
parent | setpriv: add --ambient-caps to usage() (diff) | |
download | kernel-qcow2-util-linux-e230ae7b68814a2ea560e5138188a58128e34417.tar.gz kernel-qcow2-util-linux-e230ae7b68814a2ea560e5138188a58128e34417.tar.xz kernel-qcow2-util-linux-e230ae7b68814a2ea560e5138188a58128e34417.zip |
lib/path: fix crash, pathbuf overflow
Before:
$ lscpu -s "$(tr '\0' 'x' < /dev/zero | head -c 10000)"
Segmentation fault (core dumped)
After:
$ lscpu -s "$(tr '\0' 'x' < /dev/zero | head -c 10000)"
lscpu: invalid argument to --sysroot: File name too long
Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
-rw-r--r-- | include/path.h | 6 | ||||
-rw-r--r-- | lib/path.c | 14 | ||||
-rw-r--r-- | sys-utils/lscpu.c | 3 | ||||
-rw-r--r-- | sys-utils/lsmem.c | 3 |
4 files changed, 19 insertions, 7 deletions
diff --git a/include/path.h b/include/path.h index 45da692f8..11c336759 100644 --- a/include/path.h +++ b/include/path.h @@ -27,7 +27,11 @@ extern cpu_set_t *path_read_cpuset(int, const char *path, ...) __attribute__ ((__format__ (__printf__, 2, 3))); extern cpu_set_t *path_read_cpulist(int, const char *path, ...) __attribute__ ((__format__ (__printf__, 2, 3))); -extern void path_set_prefix(const char *); + +/* Returns: 0 on success, sets errno on error. */ +extern int path_set_prefix(const char *) + __attribute__((warn_unused_result)); + #endif /* HAVE_CPU_SET_T */ #endif /* UTIL_LINUX_PATH_H */ diff --git a/lib/path.c b/lib/path.c index 1a623bc6d..eaa6d881c 100644 --- a/lib/path.c +++ b/lib/path.c @@ -244,12 +244,18 @@ path_read_cpulist(int maxcpus, const char *path, ...) return set; } -void +int path_set_prefix(const char *prefix) { - prefixlen = strlen(prefix); - strncpy(pathbuf, prefix, sizeof(pathbuf)); - pathbuf[sizeof(pathbuf) - 1] = '\0'; + size_t len = strlen(prefix); + + if (len >= sizeof(pathbuf) - 1) { + errno = ENAMETOOLONG; + return -1; + } + prefixlen = len; + strcpy(pathbuf, prefix); + return 0; } #endif /* HAVE_CPU_SET_T */ diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index 424b9de0e..f6e47277e 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -2148,7 +2148,8 @@ int main(int argc, char *argv[]) mod->mode = c == 'p' ? OUTPUT_PARSABLE : OUTPUT_READABLE; break; case 's': - path_set_prefix(optarg); + if(path_set_prefix(optarg)) + err(EXIT_FAILURE, _("invalid argument to %s"), "--sysroot"); mod->system = SYSTEM_SNAPSHOT; break; case 'x': diff --git a/sys-utils/lsmem.c b/sys-utils/lsmem.c index 04e7d20be..e1ee5a5ce 100644 --- a/sys-utils/lsmem.c +++ b/sys-utils/lsmem.c @@ -470,7 +470,8 @@ int main(int argc, char **argv) lsmem->want_summary = 0; break; case 's': - path_set_prefix(optarg); + if(path_set_prefix(optarg)) + err(EXIT_FAILURE, _("invalid argument to %s"), "--sysroot"); break; case 'V': printf(UTIL_LINUX_VERSION); |