* 'path-fixes' of https://github.com/rudimeier/util-linux:
  hwclock: don't ifdef printf arguments
  setpriv: align --help
  tools: add segfault detection for checkusage.sh
  misc: avoid some dead initialization warnings
  lscpu: make clang analyzer happy
  lsmem: fix, using freed memory
  lib/path: add error handling to path_vcreate()
  lib/path: fix crash, pathbuf overflow
This commit is contained in:
Karel Zak 2017-06-29 15:29:33 +02:00
commit 07fd6640c8
9 changed files with 89 additions and 58 deletions

View File

@ -4,8 +4,11 @@
#include <stdio.h>
#include <stdint.h>
extern char *path_strdup(const char *path, ...)
/* Returns a pointer to a static buffer which may be destroyed by any later
path_* function call. NULL means error and errno will be set. */
extern const char *path_get(const char *path, ...)
__attribute__ ((__format__ (__printf__, 1, 2)));
extern FILE *path_fopen(const char *mode, int exit_on_err, const char *path, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
extern void path_read_str(char *result, size_t len, const char *path, ...)
@ -27,7 +30,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 */

View File

@ -151,7 +151,7 @@ static size_t mbs_insert(char *str, wint_t c, size_t *ncells)
{
/* all in bytes! */
size_t n = 1, bytes;
char *in = (char *) &c;
char *in;
#ifdef HAVE_WIDECHAR
wchar_t wc = (wchar_t) c;
@ -162,6 +162,7 @@ static size_t mbs_insert(char *str, wint_t c, size_t *ncells)
in = in_buf;
#else
*ncells = 1;
in = (char *) &c;
#endif
bytes = strlen(str);

View File

@ -38,16 +38,20 @@ static char pathbuf[PATH_MAX];
static const char *
path_vcreate(const char *path, va_list ap)
{
if (prefixlen)
vsnprintf(pathbuf + prefixlen,
sizeof(pathbuf) - prefixlen, path, ap);
else
vsnprintf(pathbuf, sizeof(pathbuf), path, ap);
int rc = vsnprintf(
pathbuf + prefixlen, sizeof(pathbuf) - prefixlen, path, ap);
if (rc < 0)
return NULL;
if ((size_t)rc >= sizeof(pathbuf)) {
errno = ENAMETOOLONG;
return NULL;
}
return pathbuf;
}
char *
path_strdup(const char *path, ...)
const char *
path_get(const char *path, ...)
{
const char *p;
va_list ap;
@ -56,7 +60,7 @@ path_strdup(const char *path, ...)
p = path_vcreate(path, ap);
va_end(ap);
return p ? strdup(p) : NULL;
return p;
}
static FILE *
@ -64,11 +68,18 @@ path_vfopen(const char *mode, int exit_on_error, const char *path, va_list ap)
{
FILE *f;
const char *p = path_vcreate(path, ap);
if (!p)
goto err;
f = fopen(p, mode);
if (!f && exit_on_error)
err(EXIT_FAILURE, _("cannot open %s"), p);
if (!f)
goto err;
return f;
err:
if (exit_on_error)
err(EXIT_FAILURE, _("cannot open %s"), p ? p : "path");
return NULL;
}
static int
@ -76,11 +87,16 @@ path_vopen(int flags, const char *path, va_list ap)
{
int fd;
const char *p = path_vcreate(path, ap);
if (!p)
goto err;
fd = open(p, flags);
if (fd == -1)
err(EXIT_FAILURE, _("cannot open %s"), p);
goto err;
return fd;
err:
err(EXIT_FAILURE, _("cannot open %s"), p ? p : "path");
}
FILE *
@ -181,7 +197,7 @@ path_exist(const char *path, ...)
p = path_vcreate(path, ap);
va_end(ap);
return access(p, F_OK) == 0;
return p && access(p, F_OK) == 0;
}
#ifdef HAVE_CPU_SET_T
@ -244,12 +260,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 */

View File

@ -126,14 +126,13 @@ done:
static int verify_target(struct verify_context *vfy)
{
const char *tgt = mnt_fs_get_target(vfy->fs);
const char *cn = tgt;
struct stat sb;
if (!tgt)
return verify_err(vfy, _("undefined target (fs_file)"));
if (!(flags & FL_NOCACHE)) {
cn = mnt_resolve_target(tgt, cache);
const char *cn = mnt_resolve_target(tgt, cache);
if (!cn)
return -ENOMEM;
if (strcmp(cn, tgt) != 0)

View File

@ -1225,10 +1225,11 @@ usage(const struct hwclock_control *ctl)
fputs(USAGE_OPTIONS, out);
fputs(_(" -u, --utc inform hwclock the RTC timescale is UTC\n"), out);
fputs(_(" -l, --localtime inform hwclock the RTC timescale is Local\n"), out);
fprintf(out, _(
#ifdef __linux__
" -f, --rtc <file> use an alternate file to %1$s\n"
printf(_(
" -f, --rtc <file> use an alternate file to %1$s\n"), _PATH_RTC_DEV);
#endif
printf(_(
" --directisa use the ISA bus instead of %1$s access\n"), _PATH_RTC_DEV);
fputs(_(" --date <time> date/time input for --set and --predict\n"), out);
#if defined(__linux__) && defined(__alpha__)
@ -1457,10 +1458,7 @@ int main(int argc, char **argv)
}
}
argc -= optind;
argv += optind;
if (argc > 0) {
if (argc > optind) {
warnx(_("%d too many arguments given"), argc);
errtryhelp(EXIT_FAILURE);
}

View File

@ -1430,37 +1430,36 @@ read_nodes(struct lscpu_desc *desc)
int i = 0;
DIR *dir;
struct dirent *d;
char *path;
const char *path;
desc->nnodes = 0;
/* number of NUMA node */
path = path_strdup(_PATH_SYS_NODE);
dir = opendir(path);
free(path);
while (dir && (d = readdir(dir))) {
if (!(path = path_get(_PATH_SYS_NODE)))
return;
if (!(dir = opendir(path)))
return;
while ((d = readdir(dir))) {
if (is_node_dirent(d))
desc->nnodes++;
}
if (!desc->nnodes) {
if (dir)
closedir(dir);
closedir(dir);
return;
}
desc->nodemaps = xcalloc(desc->nnodes, sizeof(cpu_set_t *));
desc->idx2nodenum = xmalloc(desc->nnodes * sizeof(int));
if (dir) {
rewinddir(dir);
while ((d = readdir(dir)) && i < desc->nnodes) {
if (is_node_dirent(d))
desc->idx2nodenum[i++] = strtol_or_err(((d->d_name) + 4),
_("Failed to extract the node number"));
}
closedir(dir);
qsort(desc->idx2nodenum, desc->nnodes, sizeof(int), nodecmp);
rewinddir(dir);
while ((d = readdir(dir)) && i < desc->nnodes) {
if (is_node_dirent(d))
desc->idx2nodenum[i++] = strtol_or_err(((d->d_name) + 4),
_("Failed to extract the node number"));
}
closedir(dir);
qsort(desc->idx2nodenum, desc->nnodes, sizeof(int), nodecmp);
/* information about how nodes share different CPUs */
for (i = 0; i < desc->nnodes; i++)
@ -2148,7 +2147,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':

View File

@ -248,15 +248,14 @@ static void print_summary(struct lsmem *lsmem)
static int memory_block_get_node(char *name)
{
struct dirent *de;
char *path;
const char *path;
DIR *dir;
int node;
path = path_strdup(_PATH_SYS_MEMORY"/%s", name);
dir = opendir(path);
free(path);
if (!dir)
err(EXIT_FAILURE, _("Failed to open %s"), path);
path = path_get(_PATH_SYS_MEMORY"/%s", name);
if (!path || !(dir= opendir(path)))
err(EXIT_FAILURE, _("Failed to open %s"), path ? path : name);
node = -1;
while ((de = readdir(dir)) != NULL) {
if (strncmp("node", de->d_name, 4))
@ -348,14 +347,16 @@ static int memory_block_filter(const struct dirent *de)
static void read_basic_info(struct lsmem *lsmem)
{
char *dir;
const char *dir;
if (!path_exist(_PATH_SYS_MEMORY_BLOCK_SIZE))
errx(EXIT_FAILURE, _("This system does not support memory blocks"));
dir = path_strdup(_PATH_SYS_MEMORY);
dir = path_get(_PATH_SYS_MEMORY);
if (!dir)
err(EXIT_FAILURE, _("Failed to read %s"), _PATH_SYS_MEMORY);
lsmem->ndirs = scandir(dir, &lsmem->dirs, memory_block_filter, versionsort);
free(dir);
if (lsmem->ndirs <= 0)
err(EXIT_FAILURE, _("Failed to read %s"), _PATH_SYS_MEMORY);
@ -470,7 +471,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);

View File

@ -139,7 +139,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_(" --apparmor-profile <pr> set AppArmor profile\n"), out);
fputs(USAGE_SEPARATOR, out);
print_usage_help_options(16);
print_usage_help_options(29);
fputs(USAGE_SEPARATOR, out);
fputs(_(" This tool can be dangerous. Read the manpage, and be careful.\n"), out);
fprintf(out, USAGE_MAN_TAIL("setpriv(1)"));

View File

@ -61,8 +61,8 @@ function exec_option {
# hardcoded ... nologin should always return false
if test "$cmdb" = "nologin" &&
test "$opt" = "--help" -o "$opt" = "--version"; then
if test "$ret" = "0"; then
echo "$cmdb, $opt, should return false"
if test "$ret" -eq 0 -o "$ret" -ge 128; then
echo "$cmdb, $opt, should return false: $ret"
fi
ret=0
fi
@ -123,6 +123,8 @@ function check_unknownopt {
if test $ret = 0; then
echo "$cb: $opt, returns no error"
elif test $ret -ge 128; then
echo "$cb: $opt, abnormal exit: $ret"
fi
if test -n "$out"; then
echo "$cb: $opt, non-empty stdout"