xattr-util: rework getxattr_at_malloc()

Let's return the size in a return parameter instead of the return value.
And if NULL is specified this tells us the caller doesn't care about the
size and expects a NUL terminated string. In that case look for an
embedded NUL byte, and refuse in that case.

This should lock things down a bit, as we'll systematically refuse
embedded NUL strings now when we expect strings.
This commit is contained in:
Lennart Poettering
2025-03-18 07:17:10 +01:00
parent 147511c643
commit 33cbda04eb
15 changed files with 104 additions and 76 deletions
+4 -4
View File
@@ -186,13 +186,13 @@ static int show_cgroup_name(
NULSTR_FOREACH(xa, nl) {
_cleanup_free_ char *x = NULL, *y = NULL, *buf = NULL;
int n;
if (!STARTSWITH_SET(xa, "user.", "trusted."))
continue;
n = fgetxattr_malloc(fd, xa, &buf);
if (n < 0) {
size_t buf_size;
r = fgetxattr_malloc(fd, xa, &buf, &buf_size);
if (r < 0) {
log_debug_errno(r, "Failed to read xattr '%s' off '%s', ignoring: %m", xa, path);
continue;
}
@@ -201,7 +201,7 @@ static int show_cgroup_name(
if (!x)
return -ENOMEM;
y = cescape_length(buf, n);
y = cescape_length(buf, buf_size);
if (!y)
return -ENOMEM;
+4 -4
View File
@@ -1670,18 +1670,18 @@ int copy_xattr(int df, const char *from, int dt, const char *to, CopyFlags copy_
return r;
NULSTR_FOREACH(p, names) {
_cleanup_free_ char *value = NULL;
if (!FLAGS_SET(copy_flags, COPY_ALL_XATTRS) && !startswith(p, "user."))
continue;
r = getxattr_at_malloc(df, from, p, 0, &value);
_cleanup_free_ char *value = NULL;
size_t value_size;
r = getxattr_at_malloc(df, from, p, 0, &value, &value_size);
if (r == -ENODATA)
continue; /* gone by now */
if (r < 0)
return r;
RET_GATHER(ret, xsetxattr_full(dt, to, /* at_flags = */ 0, p, value, r, /* xattr_flags = */ 0));
RET_GATHER(ret, xsetxattr_full(dt, to, /* at_flags = */ 0, p, value, value_size, /* xattr_flags = */ 0));
}
return ret;
+2 -2
View File
@@ -3248,7 +3248,7 @@ int verity_settings_load(
* that doesn't exist for /usr */
if (designator < 0 || designator == PARTITION_ROOT) {
r = getxattr_malloc(image, "user.verity.roothash", &text);
r = getxattr_malloc(image, "user.verity.roothash", &text, /* ret_size= */ NULL);
if (r < 0) {
_cleanup_free_ char *p = NULL;
@@ -3277,7 +3277,7 @@ int verity_settings_load(
* `usrhash`, because `usrroothash` or `rootusrhash` would just be too
* confusing. We thus drop the reference to the root of the Merkle tree, and
* just indicate which file system it's about. */
r = getxattr_malloc(image, "user.verity.usrhash", &text);
r = getxattr_malloc(image, "user.verity.usrhash", &text, /* ret_size= */ NULL);
if (r < 0) {
_cleanup_free_ char *p = NULL;
+2 -2
View File
@@ -60,7 +60,7 @@ int mac_smack_read_at(int fd, const char *path, SmackAttr attr, char **ret) {
return 0;
}
return getxattr_at_malloc(fd, path, smack_attr_to_string(attr), /* at_flags = */ 0, ret);
return getxattr_at_malloc(fd, path, smack_attr_to_string(attr), /* at_flags = */ 0, ret, /* ret_size= */ NULL);
}
int mac_smack_apply_at(int fd, const char *path, SmackAttr attr, const char *label) {
@@ -136,7 +136,7 @@ static int smack_fix_fd(
/* If the old label is identical to the new one, suppress any kind of error */
_cleanup_free_ char *old_label = NULL;
if (fgetxattr_malloc(fd, "security.SMACK64", &old_label) >= 0 &&
if (fgetxattr_malloc(fd, "security.SMACK64", &old_label, /* ret_size= */ NULL) >= 0 &&
streq(old_label, label))
return 0;