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:
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user