Merge branch 'path-fixes' of https://github.com/rudimeier/util-linux
* '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:
commit
07fd6640c8
|
@ -4,8 +4,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.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)));
|
__attribute__ ((__format__ (__printf__, 1, 2)));
|
||||||
|
|
||||||
extern FILE *path_fopen(const char *mode, int exit_on_err, const char *path, ...)
|
extern FILE *path_fopen(const char *mode, int exit_on_err, const char *path, ...)
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||||
extern void path_read_str(char *result, size_t len, const char *path, ...)
|
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)));
|
__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 */
|
||||||
|
|
|
@ -151,7 +151,7 @@ static size_t mbs_insert(char *str, wint_t c, size_t *ncells)
|
||||||
{
|
{
|
||||||
/* all in bytes! */
|
/* all in bytes! */
|
||||||
size_t n = 1, bytes;
|
size_t n = 1, bytes;
|
||||||
char *in = (char *) &c;
|
char *in;
|
||||||
|
|
||||||
#ifdef HAVE_WIDECHAR
|
#ifdef HAVE_WIDECHAR
|
||||||
wchar_t wc = (wchar_t) c;
|
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;
|
in = in_buf;
|
||||||
#else
|
#else
|
||||||
*ncells = 1;
|
*ncells = 1;
|
||||||
|
in = (char *) &c;
|
||||||
#endif
|
#endif
|
||||||
bytes = strlen(str);
|
bytes = strlen(str);
|
||||||
|
|
||||||
|
|
54
lib/path.c
54
lib/path.c
|
@ -38,16 +38,20 @@ static char pathbuf[PATH_MAX];
|
||||||
static const char *
|
static const char *
|
||||||
path_vcreate(const char *path, va_list ap)
|
path_vcreate(const char *path, va_list ap)
|
||||||
{
|
{
|
||||||
if (prefixlen)
|
int rc = vsnprintf(
|
||||||
vsnprintf(pathbuf + prefixlen,
|
pathbuf + prefixlen, sizeof(pathbuf) - prefixlen, path, ap);
|
||||||
sizeof(pathbuf) - prefixlen, path, ap);
|
|
||||||
else
|
if (rc < 0)
|
||||||
vsnprintf(pathbuf, sizeof(pathbuf), path, ap);
|
return NULL;
|
||||||
|
if ((size_t)rc >= sizeof(pathbuf)) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return pathbuf;
|
return pathbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
const char *
|
||||||
path_strdup(const char *path, ...)
|
path_get(const char *path, ...)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -56,7 +60,7 @@ path_strdup(const char *path, ...)
|
||||||
p = path_vcreate(path, ap);
|
p = path_vcreate(path, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return p ? strdup(p) : NULL;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *
|
static FILE *
|
||||||
|
@ -64,11 +68,18 @@ path_vfopen(const char *mode, int exit_on_error, const char *path, va_list ap)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
const char *p = path_vcreate(path, ap);
|
const char *p = path_vcreate(path, ap);
|
||||||
|
if (!p)
|
||||||
|
goto err;
|
||||||
|
|
||||||
f = fopen(p, mode);
|
f = fopen(p, mode);
|
||||||
if (!f && exit_on_error)
|
if (!f)
|
||||||
err(EXIT_FAILURE, _("cannot open %s"), p);
|
goto err;
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
|
err:
|
||||||
|
if (exit_on_error)
|
||||||
|
err(EXIT_FAILURE, _("cannot open %s"), p ? p : "path");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -76,11 +87,16 @@ path_vopen(int flags, const char *path, va_list ap)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
const char *p = path_vcreate(path, ap);
|
const char *p = path_vcreate(path, ap);
|
||||||
|
if (!p)
|
||||||
|
goto err;
|
||||||
|
|
||||||
fd = open(p, flags);
|
fd = open(p, flags);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
err(EXIT_FAILURE, _("cannot open %s"), p);
|
goto err;
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
|
err:
|
||||||
|
err(EXIT_FAILURE, _("cannot open %s"), p ? p : "path");
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *
|
FILE *
|
||||||
|
@ -181,7 +197,7 @@ path_exist(const char *path, ...)
|
||||||
p = path_vcreate(path, ap);
|
p = path_vcreate(path, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return access(p, F_OK) == 0;
|
return p && access(p, F_OK) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CPU_SET_T
|
#ifdef HAVE_CPU_SET_T
|
||||||
|
@ -244,12 +260,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 */
|
||||||
|
|
|
@ -126,14 +126,13 @@ done:
|
||||||
static int verify_target(struct verify_context *vfy)
|
static int verify_target(struct verify_context *vfy)
|
||||||
{
|
{
|
||||||
const char *tgt = mnt_fs_get_target(vfy->fs);
|
const char *tgt = mnt_fs_get_target(vfy->fs);
|
||||||
const char *cn = tgt;
|
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
if (!tgt)
|
if (!tgt)
|
||||||
return verify_err(vfy, _("undefined target (fs_file)"));
|
return verify_err(vfy, _("undefined target (fs_file)"));
|
||||||
|
|
||||||
if (!(flags & FL_NOCACHE)) {
|
if (!(flags & FL_NOCACHE)) {
|
||||||
cn = mnt_resolve_target(tgt, cache);
|
const char *cn = mnt_resolve_target(tgt, cache);
|
||||||
if (!cn)
|
if (!cn)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if (strcmp(cn, tgt) != 0)
|
if (strcmp(cn, tgt) != 0)
|
||||||
|
|
|
@ -1225,10 +1225,11 @@ usage(const struct hwclock_control *ctl)
|
||||||
fputs(USAGE_OPTIONS, out);
|
fputs(USAGE_OPTIONS, out);
|
||||||
fputs(_(" -u, --utc inform hwclock the RTC timescale is UTC\n"), 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);
|
fputs(_(" -l, --localtime inform hwclock the RTC timescale is Local\n"), out);
|
||||||
fprintf(out, _(
|
|
||||||
#ifdef __linux__
|
#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
|
#endif
|
||||||
|
printf(_(
|
||||||
" --directisa use the ISA bus instead of %1$s access\n"), _PATH_RTC_DEV);
|
" --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);
|
fputs(_(" --date <time> date/time input for --set and --predict\n"), out);
|
||||||
#if defined(__linux__) && defined(__alpha__)
|
#if defined(__linux__) && defined(__alpha__)
|
||||||
|
@ -1457,10 +1458,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argc -= optind;
|
if (argc > optind) {
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (argc > 0) {
|
|
||||||
warnx(_("%d too many arguments given"), argc);
|
warnx(_("%d too many arguments given"), argc);
|
||||||
errtryhelp(EXIT_FAILURE);
|
errtryhelp(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1430,37 +1430,36 @@ read_nodes(struct lscpu_desc *desc)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
char *path;
|
const char *path;
|
||||||
|
|
||||||
|
desc->nnodes = 0;
|
||||||
|
|
||||||
/* number of NUMA node */
|
/* number of NUMA node */
|
||||||
path = path_strdup(_PATH_SYS_NODE);
|
if (!(path = path_get(_PATH_SYS_NODE)))
|
||||||
dir = opendir(path);
|
return;
|
||||||
free(path);
|
if (!(dir = opendir(path)))
|
||||||
|
return;
|
||||||
while (dir && (d = readdir(dir))) {
|
while ((d = readdir(dir))) {
|
||||||
if (is_node_dirent(d))
|
if (is_node_dirent(d))
|
||||||
desc->nnodes++;
|
desc->nnodes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!desc->nnodes) {
|
if (!desc->nnodes) {
|
||||||
if (dir)
|
closedir(dir);
|
||||||
closedir(dir);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->nodemaps = xcalloc(desc->nnodes, sizeof(cpu_set_t *));
|
desc->nodemaps = xcalloc(desc->nnodes, sizeof(cpu_set_t *));
|
||||||
desc->idx2nodenum = xmalloc(desc->nnodes * sizeof(int));
|
desc->idx2nodenum = xmalloc(desc->nnodes * sizeof(int));
|
||||||
|
|
||||||
if (dir) {
|
rewinddir(dir);
|
||||||
rewinddir(dir);
|
while ((d = readdir(dir)) && i < desc->nnodes) {
|
||||||
while ((d = readdir(dir)) && i < desc->nnodes) {
|
if (is_node_dirent(d))
|
||||||
if (is_node_dirent(d))
|
desc->idx2nodenum[i++] = strtol_or_err(((d->d_name) + 4),
|
||||||
desc->idx2nodenum[i++] = strtol_or_err(((d->d_name) + 4),
|
_("Failed to extract the node number"));
|
||||||
_("Failed to extract the node number"));
|
|
||||||
}
|
|
||||||
closedir(dir);
|
|
||||||
qsort(desc->idx2nodenum, desc->nnodes, sizeof(int), nodecmp);
|
|
||||||
}
|
}
|
||||||
|
closedir(dir);
|
||||||
|
qsort(desc->idx2nodenum, desc->nnodes, sizeof(int), nodecmp);
|
||||||
|
|
||||||
/* information about how nodes share different CPUs */
|
/* information about how nodes share different CPUs */
|
||||||
for (i = 0; i < desc->nnodes; i++)
|
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;
|
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':
|
||||||
|
|
|
@ -248,15 +248,14 @@ static void print_summary(struct lsmem *lsmem)
|
||||||
static int memory_block_get_node(char *name)
|
static int memory_block_get_node(char *name)
|
||||||
{
|
{
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
char *path;
|
const char *path;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
int node;
|
int node;
|
||||||
|
|
||||||
path = path_strdup(_PATH_SYS_MEMORY"/%s", name);
|
path = path_get(_PATH_SYS_MEMORY"/%s", name);
|
||||||
dir = opendir(path);
|
if (!path || !(dir= opendir(path)))
|
||||||
free(path);
|
err(EXIT_FAILURE, _("Failed to open %s"), path ? path : name);
|
||||||
if (!dir)
|
|
||||||
err(EXIT_FAILURE, _("Failed to open %s"), path);
|
|
||||||
node = -1;
|
node = -1;
|
||||||
while ((de = readdir(dir)) != NULL) {
|
while ((de = readdir(dir)) != NULL) {
|
||||||
if (strncmp("node", de->d_name, 4))
|
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)
|
static void read_basic_info(struct lsmem *lsmem)
|
||||||
{
|
{
|
||||||
char *dir;
|
const char *dir;
|
||||||
|
|
||||||
if (!path_exist(_PATH_SYS_MEMORY_BLOCK_SIZE))
|
if (!path_exist(_PATH_SYS_MEMORY_BLOCK_SIZE))
|
||||||
errx(EXIT_FAILURE, _("This system does not support memory blocks"));
|
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);
|
lsmem->ndirs = scandir(dir, &lsmem->dirs, memory_block_filter, versionsort);
|
||||||
free(dir);
|
|
||||||
if (lsmem->ndirs <= 0)
|
if (lsmem->ndirs <= 0)
|
||||||
err(EXIT_FAILURE, _("Failed to read %s"), _PATH_SYS_MEMORY);
|
err(EXIT_FAILURE, _("Failed to read %s"), _PATH_SYS_MEMORY);
|
||||||
|
|
||||||
|
@ -470,7 +471,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);
|
||||||
|
|
|
@ -139,7 +139,7 @@ static void __attribute__((__noreturn__)) usage(void)
|
||||||
fputs(_(" --apparmor-profile <pr> set AppArmor profile\n"), out);
|
fputs(_(" --apparmor-profile <pr> set AppArmor profile\n"), out);
|
||||||
|
|
||||||
fputs(USAGE_SEPARATOR, out);
|
fputs(USAGE_SEPARATOR, out);
|
||||||
print_usage_help_options(16);
|
print_usage_help_options(29);
|
||||||
fputs(USAGE_SEPARATOR, out);
|
fputs(USAGE_SEPARATOR, out);
|
||||||
fputs(_(" This tool can be dangerous. Read the manpage, and be careful.\n"), out);
|
fputs(_(" This tool can be dangerous. Read the manpage, and be careful.\n"), out);
|
||||||
fprintf(out, USAGE_MAN_TAIL("setpriv(1)"));
|
fprintf(out, USAGE_MAN_TAIL("setpriv(1)"));
|
||||||
|
|
|
@ -61,8 +61,8 @@ function exec_option {
|
||||||
# hardcoded ... nologin should always return false
|
# hardcoded ... nologin should always return false
|
||||||
if test "$cmdb" = "nologin" &&
|
if test "$cmdb" = "nologin" &&
|
||||||
test "$opt" = "--help" -o "$opt" = "--version"; then
|
test "$opt" = "--help" -o "$opt" = "--version"; then
|
||||||
if test "$ret" = "0"; then
|
if test "$ret" -eq 0 -o "$ret" -ge 128; then
|
||||||
echo "$cmdb, $opt, should return false"
|
echo "$cmdb, $opt, should return false: $ret"
|
||||||
fi
|
fi
|
||||||
ret=0
|
ret=0
|
||||||
fi
|
fi
|
||||||
|
@ -123,6 +123,8 @@ function check_unknownopt {
|
||||||
|
|
||||||
if test $ret = 0; then
|
if test $ret = 0; then
|
||||||
echo "$cb: $opt, returns no error"
|
echo "$cb: $opt, returns no error"
|
||||||
|
elif test $ret -ge 128; then
|
||||||
|
echo "$cb: $opt, abnormal exit: $ret"
|
||||||
fi
|
fi
|
||||||
if test -n "$out"; then
|
if test -n "$out"; then
|
||||||
echo "$cb: $opt, non-empty stdout"
|
echo "$cb: $opt, non-empty stdout"
|
||||||
|
|
Loading…
Reference in New Issue