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>
This commit is contained in:
Ruediger Meier 2017-06-27 20:32:52 +02:00
parent 4fb515f900
commit e230ae7b68
4 changed files with 19 additions and 7 deletions

View File

@ -27,7 +27,11 @@ extern cpu_set_t *path_read_cpuset(int, const char *path, ...)
__attribute__ ((__format__ (__printf__, 2, 3))); __attribute__ ((__format__ (__printf__, 2, 3)));
extern cpu_set_t *path_read_cpulist(int, const char *path, ...) extern cpu_set_t *path_read_cpulist(int, const char *path, ...)
__attribute__ ((__format__ (__printf__, 2, 3))); __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 /* HAVE_CPU_SET_T */
#endif /* UTIL_LINUX_PATH_H */ #endif /* UTIL_LINUX_PATH_H */

View File

@ -244,12 +244,18 @@ path_read_cpulist(int maxcpus, const char *path, ...)
return set; return set;
} }
void int
path_set_prefix(const char *prefix) path_set_prefix(const char *prefix)
{ {
prefixlen = strlen(prefix); size_t len = strlen(prefix);
strncpy(pathbuf, prefix, sizeof(pathbuf));
pathbuf[sizeof(pathbuf) - 1] = '\0'; if (len >= sizeof(pathbuf) - 1) {
errno = ENAMETOOLONG;
return -1;
}
prefixlen = len;
strcpy(pathbuf, prefix);
return 0;
} }
#endif /* HAVE_CPU_SET_T */ #endif /* HAVE_CPU_SET_T */

View File

@ -2148,7 +2148,8 @@ int main(int argc, char *argv[])
mod->mode = c == 'p' ? OUTPUT_PARSABLE : OUTPUT_READABLE; mod->mode = c == 'p' ? OUTPUT_PARSABLE : OUTPUT_READABLE;
break; break;
case 's': case 's':
path_set_prefix(optarg); if(path_set_prefix(optarg))
err(EXIT_FAILURE, _("invalid argument to %s"), "--sysroot");
mod->system = SYSTEM_SNAPSHOT; mod->system = SYSTEM_SNAPSHOT;
break; break;
case 'x': case 'x':

View File

@ -470,7 +470,8 @@ int main(int argc, char **argv)
lsmem->want_summary = 0; lsmem->want_summary = 0;
break; break;
case 's': case 's':
path_set_prefix(optarg); if(path_set_prefix(optarg))
err(EXIT_FAILURE, _("invalid argument to %s"), "--sysroot");
break; break;
case 'V': case 'V':
printf(UTIL_LINUX_VERSION); printf(UTIL_LINUX_VERSION);