libmount: don't use sscanf() for swaps parsing
Addresses: https://github.com/karelzak/util-linux/issues/780 Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
86673b3a46
commit
6c9ab254ae
|
@ -16,7 +16,6 @@
|
|||
|
||||
/* used by kernel in /proc (e.g. /proc/swaps) for deleted files */
|
||||
#define PATH_DELETED_SUFFIX " (deleted)"
|
||||
#define PATH_DELETED_SUFFIX_SZ (sizeof(PATH_DELETED_SUFFIX) - 1)
|
||||
|
||||
/* DEFPATHs from <paths.h> don't include /usr/local */
|
||||
#undef _PATH_DEFPATH
|
||||
|
|
|
@ -43,25 +43,35 @@ static void parser_cleanup(struct libmnt_parser *pa)
|
|||
memset(pa, 0, sizeof(*pa));
|
||||
}
|
||||
|
||||
static const char *next_number(const char *s, int *num, int *rc)
|
||||
static const char *next_s32(const char *s, int *num, int *rc)
|
||||
{
|
||||
char *end = NULL;
|
||||
|
||||
if (!s || !*s)
|
||||
return s;
|
||||
|
||||
assert(num);
|
||||
assert(rc);
|
||||
|
||||
*rc = -EINVAL;
|
||||
*num = strtol(s, &end, 10);
|
||||
if (end == NULL || s == end)
|
||||
return s;
|
||||
|
||||
/* valid end of number is a space or a terminator */
|
||||
if (*end == ' ' || *end == '\t' || *end == '\0')
|
||||
*rc = 0;
|
||||
return end;
|
||||
}
|
||||
|
||||
static const char *next_u64(const char *s, uint64_t *num, int *rc)
|
||||
{
|
||||
char *end = NULL;
|
||||
|
||||
if (!s || !*s)
|
||||
return s;
|
||||
|
||||
*rc = -EINVAL;
|
||||
*num = (uint64_t) strtoumax(s, &end, 10);
|
||||
if (end == NULL || s == end)
|
||||
return s;
|
||||
if (*end == ' ' || *end == '\t' || *end == '\0')
|
||||
*rc = 0;
|
||||
return end;
|
||||
}
|
||||
|
||||
|
@ -130,7 +140,7 @@ static int mnt_parse_table_line(struct libmnt_fs *fs, const char *s)
|
|||
goto done;
|
||||
|
||||
/* (5) freq (optional) */
|
||||
s = next_number(s, &fs->freq, &rc);
|
||||
s = next_s32(s, &fs->freq, &rc);
|
||||
if (s && *s && rc) {
|
||||
DBG(TAB, ul_debug("tab parse error: [freq]"));
|
||||
goto fail;
|
||||
|
@ -141,7 +151,7 @@ static int mnt_parse_table_line(struct libmnt_fs *fs, const char *s)
|
|||
goto done;
|
||||
|
||||
/* (6) freq (optional) */
|
||||
s = next_number(s, &fs->passno, &rc);
|
||||
s = next_s32(s, &fs->passno, &rc);
|
||||
if (s && *s && rc) {
|
||||
DBG(TAB, ul_debug("tab parse error: [passno]"));
|
||||
goto fail;
|
||||
|
@ -169,7 +179,7 @@ static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, const char *s)
|
|||
fs->flags |= MNT_FS_KERNEL;
|
||||
|
||||
/* (1) id */
|
||||
s = next_number(s, &fs->id, &rc);
|
||||
s = next_s32(s, &fs->id, &rc);
|
||||
if (!s || !*s || rc) {
|
||||
DBG(TAB, ul_debug("tab parse error: [id]"));
|
||||
goto fail;
|
||||
|
@ -178,7 +188,7 @@ static int mnt_parse_mountinfo_line(struct libmnt_fs *fs, const char *s)
|
|||
s = skip_separator(s);
|
||||
|
||||
/* (2) parent */
|
||||
s = next_number(s, &fs->parent, &rc);
|
||||
s = next_s32(s, &fs->parent, &rc);
|
||||
if (!s || !*s || rc) {
|
||||
DBG(TAB, ul_debug("tab parse error: [parent]"));
|
||||
goto fail;
|
||||
|
@ -355,48 +365,66 @@ enomem:
|
|||
*/
|
||||
static int mnt_parse_swaps_line(struct libmnt_fs *fs, const char *s)
|
||||
{
|
||||
uintmax_t fsz, usz;
|
||||
uint64_t num;
|
||||
int rc;
|
||||
char *src = NULL;
|
||||
char *p;
|
||||
|
||||
rc = sscanf(s, UL_SCNsA" " /* (1) source */
|
||||
UL_SCNsA" " /* (2) type */
|
||||
"%ju" /* (3) size */
|
||||
"%ju" /* (4) used */
|
||||
"%d", /* priority */
|
||||
|
||||
&src,
|
||||
&fs->swaptype,
|
||||
&fsz,
|
||||
&usz,
|
||||
&fs->priority);
|
||||
|
||||
if (rc == 5) {
|
||||
size_t sz;
|
||||
|
||||
fs->size = fsz;
|
||||
fs->usedsize = usz;
|
||||
|
||||
/* remove "\040(deleted)" suffix */
|
||||
sz = strlen(src);
|
||||
if (sz > PATH_DELETED_SUFFIX_SZ) {
|
||||
char *p = src + (sz - PATH_DELETED_SUFFIX_SZ);
|
||||
if (strcmp(p, PATH_DELETED_SUFFIX) == 0)
|
||||
*p = '\0';
|
||||
/* (1) source */
|
||||
p = unmangle(s, &s);
|
||||
if (p) {
|
||||
char *x = (char *) endswith(p, PATH_DELETED_SUFFIX);
|
||||
if (x && *x)
|
||||
*x = '\0';
|
||||
}
|
||||
if (!p || (rc = __mnt_fs_set_source_ptr(fs, p))) {
|
||||
DBG(TAB, ul_debug("tab parse error: [source]"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
unmangle_string(src);
|
||||
s = skip_separator(s);
|
||||
|
||||
/* (2) type */
|
||||
fs->swaptype = unmangle(s, &s);
|
||||
if (!fs->swaptype) {
|
||||
DBG(TAB, ul_debug("tab parse error: [swaptype]"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
s = skip_separator(s);
|
||||
|
||||
/* (3) size */
|
||||
s = next_u64(s, &num, &rc);
|
||||
if (!s || !*s || rc) {
|
||||
DBG(TAB, ul_debug("tab parse error: [size]"));
|
||||
goto fail;
|
||||
}
|
||||
fs->size = num;
|
||||
|
||||
s = skip_separator(s);
|
||||
|
||||
/* (4) size */
|
||||
s = next_u64(s, &num, &rc);
|
||||
if (!s || !*s || rc) {
|
||||
DBG(TAB, ul_debug("tab parse error: [used size]"));
|
||||
goto fail;
|
||||
}
|
||||
fs->usedsize = num;
|
||||
|
||||
s = skip_separator(s);
|
||||
|
||||
/* (5) priority */
|
||||
s = next_s32(s, &fs->priority, &rc);
|
||||
if (rc) {
|
||||
DBG(TAB, ul_debug("tab parse error: [priority]"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = mnt_fs_set_source(fs, src);
|
||||
if (!rc)
|
||||
mnt_fs_set_fstype(fs, "swap");
|
||||
} else {
|
||||
DBG(TAB, ul_debug("tab parse error: [sscanf rc=%d]: '%s'", rc, s));
|
||||
return 0;
|
||||
fail:
|
||||
if (rc == 0)
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
free(src);
|
||||
|
||||
DBG(TAB, ul_debug("tab parse error on: '%s' [rc=%d]", s, rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue