summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRuediger Meier2017-06-27 20:32:52 +0200
committerRuediger Meier2017-06-27 21:39:35 +0200
commite230ae7b68814a2ea560e5138188a58128e34417 (patch)
tree8eaab2a06c417004a5477ad6cba769639eb72a76
parentsetpriv: add --ambient-caps to usage() (diff)
downloadkernel-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.h6
-rw-r--r--lib/path.c14
-rw-r--r--sys-utils/lscpu.c3
-rw-r--r--sys-utils/lsmem.c3
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);