mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
Merge pull request #30482 from YHNdnzj/ferror-handling
A few fixes for ferror() handling
This commit is contained in:
commit
ccf695a4cf
@ -2141,15 +2141,14 @@ int cg_kernel_controllers(Set **ret) {
|
||||
_cleanup_free_ char *controller = NULL;
|
||||
int enabled = 0;
|
||||
|
||||
errno = 0;
|
||||
if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) {
|
||||
|
||||
if (ferror(f))
|
||||
return -errno;
|
||||
|
||||
if (feof(f))
|
||||
break;
|
||||
|
||||
if (ferror(f))
|
||||
return errno_or_else(EIO);
|
||||
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,30 @@ bool uid_range_covers(const UidRange *range, uid_t start, uid_t nr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int uid_map_read_one(FILE *f, uid_t *ret_base, uid_t *ret_shift, uid_t *ret_range) {
|
||||
uid_t uid_base, uid_shift, uid_range;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(ret_base);
|
||||
assert(ret_shift);
|
||||
assert(ret_range);
|
||||
|
||||
errno = 0;
|
||||
r = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range);
|
||||
if (r == EOF)
|
||||
return errno_or_else(ENOMSG);
|
||||
assert(r >= 0);
|
||||
if (r != 3)
|
||||
return -EBADMSG;
|
||||
|
||||
*ret_base = uid_base;
|
||||
*ret_shift = uid_shift;
|
||||
*ret_range = uid_range;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uid_range_load_userns(UidRange **ret, const char *path) {
|
||||
_cleanup_(uid_range_freep) UidRange *range = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
@ -212,18 +236,12 @@ int uid_range_load_userns(UidRange **ret, const char *path) {
|
||||
|
||||
for (;;) {
|
||||
uid_t uid_base, uid_shift, uid_range;
|
||||
int k;
|
||||
|
||||
errno = 0;
|
||||
k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range);
|
||||
if (k == EOF) {
|
||||
if (ferror(f))
|
||||
return errno_or_else(EIO);
|
||||
|
||||
r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range);
|
||||
if (r == -ENOMSG)
|
||||
break;
|
||||
}
|
||||
if (k != 3)
|
||||
return -EBADMSG;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = uid_range_add_internal(&range, uid_base, uid_range, /* coalesce = */ false);
|
||||
if (r < 0)
|
||||
|
@ -31,4 +31,6 @@ static inline bool uid_range_contains(const UidRange *range, uid_t uid) {
|
||||
return uid_range_covers(range, uid, 1);
|
||||
}
|
||||
|
||||
int uid_map_read_one(FILE *f, uid_t *ret_base, uid_t *ret_shift, uid_t *ret_range);
|
||||
|
||||
int uid_range_load_userns(UidRange **ret, const char *path);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "stat-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "uid-range.h"
|
||||
#include "virt.h"
|
||||
|
||||
enum {
|
||||
@ -814,7 +815,7 @@ Virtualization detect_virtualization(void) {
|
||||
|
||||
static int userns_has_mapping(const char *name) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
uid_t a, b, c;
|
||||
uid_t base, shift, range;
|
||||
int r;
|
||||
|
||||
f = fopen(name, "re");
|
||||
@ -823,26 +824,22 @@ static int userns_has_mapping(const char *name) {
|
||||
return errno == ENOENT ? false : -errno;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
r = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &a, &b, &c);
|
||||
if (r == EOF) {
|
||||
if (ferror(f))
|
||||
return log_debug_errno(errno_or_else(EIO), "Failed to read %s: %m", name);
|
||||
|
||||
log_debug("%s is empty, we're in an uninitialized user namespace", name);
|
||||
r = uid_map_read_one(f, &base, &shift, &range);
|
||||
if (r == -ENOMSG) {
|
||||
log_debug("%s is empty, we're in an uninitialized user namespace.", name);
|
||||
return true;
|
||||
}
|
||||
if (r != 3)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse %s: %m", name);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to read %s: %m", name);
|
||||
|
||||
if (a == 0 && b == 0 && c == UINT32_MAX) {
|
||||
if (base == 0 && shift == 0 && range == UINT32_MAX) {
|
||||
/* The kernel calls mappings_overlap() and does not allow overlaps */
|
||||
log_debug("%s has a full 1:1 mapping", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Anything else implies that we are in a user namespace */
|
||||
log_debug("Mapping found in %s, we're in a user namespace", name);
|
||||
log_debug("Mapping found in %s, we're in a user namespace.", name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ static int process_progress(int fd, FILE* console) {
|
||||
else if (feof(f))
|
||||
r = 0;
|
||||
else
|
||||
r = log_warning_errno(SYNTHETIC_ERRNO(errno), "Failed to parse progress pipe data");
|
||||
r = log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse progress pipe data.");
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "string-table.h"
|
||||
#include "terminal-util.h"
|
||||
#include "tmpfile-util.h"
|
||||
#include "uid-range.h"
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
|
||||
@ -658,7 +659,7 @@ int machine_get_uid_shift(Machine *m, uid_t *ret) {
|
||||
uid_t uid_base, uid_shift, uid_range;
|
||||
gid_t gid_base, gid_shift, gid_range;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int k, r;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(ret);
|
||||
@ -690,14 +691,9 @@ int machine_get_uid_shift(Machine *m, uid_t *ret) {
|
||||
}
|
||||
|
||||
/* Read the first line. There's at least one. */
|
||||
errno = 0;
|
||||
k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT "\n", &uid_base, &uid_shift, &uid_range);
|
||||
if (k != 3) {
|
||||
if (ferror(f))
|
||||
return errno_or_else(EIO);
|
||||
|
||||
return -EBADMSG;
|
||||
}
|
||||
r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Not a mapping starting at 0? Then it's a complex mapping we can't expose here. */
|
||||
if (uid_base != 0)
|
||||
@ -722,13 +718,12 @@ int machine_get_uid_shift(Machine *m, uid_t *ret) {
|
||||
|
||||
/* Read the first line. There's at least one. */
|
||||
errno = 0;
|
||||
k = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT "\n", &gid_base, &gid_shift, &gid_range);
|
||||
if (k != 3) {
|
||||
if (ferror(f))
|
||||
return errno_or_else(EIO);
|
||||
|
||||
r = fscanf(f, GID_FMT " " GID_FMT " " GID_FMT "\n", &gid_base, &gid_shift, &gid_range);
|
||||
if (r == EOF)
|
||||
return errno_or_else(ENOMSG);
|
||||
assert(r >= 0);
|
||||
if (r != 3)
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
/* If there's more than one line, then we don't support this file. */
|
||||
r = safe_fgetc(f, NULL);
|
||||
@ -757,6 +752,7 @@ static int machine_owns_uid_internal(
|
||||
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
/* This is a generic implementation for both uids and gids, under the assumptions they have the same types and semantics. */
|
||||
assert_cc(sizeof(uid_t) == sizeof(gid_t));
|
||||
@ -778,18 +774,12 @@ static int machine_owns_uid_internal(
|
||||
|
||||
for (;;) {
|
||||
uid_t uid_base, uid_shift, uid_range, converted;
|
||||
int k;
|
||||
|
||||
errno = 0;
|
||||
k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
|
||||
if (k < 0 && feof(f))
|
||||
r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range);
|
||||
if (r == -ENOMSG)
|
||||
break;
|
||||
if (k != 3) {
|
||||
if (ferror(f))
|
||||
return errno_or_else(EIO);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* The private user namespace is disabled, ignoring. */
|
||||
if (uid_shift == 0)
|
||||
@ -831,6 +821,7 @@ static int machine_translate_uid_internal(
|
||||
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
/* This is a generic implementation for both uids and gids, under the assumptions they have the same types and semantics. */
|
||||
assert_cc(sizeof(uid_t) == sizeof(gid_t));
|
||||
@ -850,18 +841,12 @@ static int machine_translate_uid_internal(
|
||||
|
||||
for (;;) {
|
||||
uid_t uid_base, uid_shift, uid_range, converted;
|
||||
int k;
|
||||
|
||||
errno = 0;
|
||||
k = fscanf(f, UID_FMT " " UID_FMT " " UID_FMT, &uid_base, &uid_shift, &uid_range);
|
||||
if (k < 0 && feof(f))
|
||||
r = uid_map_read_one(f, &uid_base, &uid_shift, &uid_range);
|
||||
if (r == -ENOMSG)
|
||||
break;
|
||||
if (k != 3) {
|
||||
if (ferror(f))
|
||||
return errno_or_else(EIO);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (uid < uid_base || uid >= uid_base + uid_range)
|
||||
continue;
|
||||
@ -872,6 +857,7 @@ static int machine_translate_uid_internal(
|
||||
|
||||
if (ret_host_uid)
|
||||
*ret_host_uid = converted;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user