Skip to content

Commit

Permalink
erofs: Escape overlayfs features
Browse files Browse the repository at this point in the history
This escapes overlayfs xattrs and whiteouts according to the support
in this patch series:
  https://lore.kernel.org/linux-unionfs/cover.1692198910.git.alexl@redhat.com/

Signed-off-by: Alexander Larsson <alexl@redhat.com>
  • Loading branch information
alexlarsson committed Aug 25, 2023
1 parent a6e827d commit 83123d6
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
3 changes: 3 additions & 0 deletions libcomposefs/lcfs-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ char *maybe_join_path(const char *a, const char *b);
struct lcfs_node_s *follow_links(struct lcfs_node_s *node);
int node_get_dtype(struct lcfs_node_s *node);

int lcfs_node_rename_xattr(struct lcfs_node_s *node, size_t index,
const char *new_name);

/* lcfs-writer-erofs.c */

int lcfs_write_erofs_to(struct lcfs_ctx_s *ctx);
Expand Down
55 changes: 54 additions & 1 deletion libcomposefs/lcfs-writer-erofs.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "config.h"

#include "lcfs-internal.h"
#include "lcfs-utils.h"
#include "lcfs-writer.h"
#include "lcfs-fsverity.h"
#include "lcfs-erofs.h"
Expand All @@ -33,6 +34,7 @@
#include <dirent.h>
#include <sys/xattr.h>
#include <sys/param.h>
#include <sys/sysmacros.h>
#include <assert.h>
#include <linux/fsverity.h>

Expand Down Expand Up @@ -863,11 +865,44 @@ static int write_erofs_shared_xattrs(struct lcfs_ctx_s *ctx)
return 0;
}

static char *str_join(const char *a, const char *b)
{
size_t a_len = strlen(a);
size_t b_len = strlen(b);
char *res = malloc(a_len + b_len + 1);
if (res) {
memcpy(res, a, a_len);
memcpy(res + a_len, b, b_len + 1);
}
return res;
}

static int add_overlayfs_xattrs(struct lcfs_node_s *node)
{
int type = node->inode.st_mode & S_IFMT;
int ret;

if ((node->inode.st_mode & S_IFMT) == S_IFREG && node->inode.st_size > 0) {
/* First escape all existing "trusted.overlay.*" xattrs */
for (size_t i = 0; i < lcfs_node_get_n_xattr(node); i++) {
const char *name = lcfs_node_get_xattr_name(node, i);

if (str_has_prefix(name, "trusted.overlay.")) {
cleanup_free char *renamed =
str_join("trusted.overlay.overlay.",
name + strlen("trusted.overlay."));
if (renamed == NULL) {
errno = ENOMEM;
return -1;
}
/* We rename in-place, this is safe from
collisions because we also rename any
colliding xattr */
if (lcfs_node_rename_xattr(node, i, renamed) < 0)
return -1;
}
}

if (type == S_IFREG && node->inode.st_size > 0) {
uint8_t xattr_data[4 + LCFS_DIGEST_SIZE];
size_t xattr_len = 0;

Expand Down Expand Up @@ -899,6 +934,24 @@ static int add_overlayfs_xattrs(struct lcfs_node_s *node)
}
}

/* escape whiteouts */
if (type == S_IFCHR && node->inode.st_rdev == makedev(0, 0)) {
struct lcfs_node_s *parent = lcfs_node_get_parent(node);

lcfs_node_set_mode(node,
S_IFREG | (lcfs_node_get_mode(node) & ~S_IFMT));
ret = lcfs_node_set_xattr(node, "trusted.overlay.overlay.whiteout",
"", 0);
if (ret < 0)
return ret;

/* Mark parent dir containing whiteouts */
ret = lcfs_node_set_xattr(
parent, "trusted.overlay.overlay.whiteouts", "", 0);
if (ret < 0)
return ret;
}

return 0;
}

Expand Down
24 changes: 24 additions & 0 deletions libcomposefs/lcfs-writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1201,3 +1201,27 @@ int lcfs_node_set_xattr(struct lcfs_node_s *node, const char *name,

return 0;
}

/* This is an internal function.
* Be careful to not cause duplicates if new_name already exist */
int lcfs_node_rename_xattr(struct lcfs_node_s *node, size_t index, const char *new_name)
{
struct lcfs_xattr_s *xattr;
cleanup_free char *dup = NULL;

dup = strdup(new_name);
if (dup == NULL) {
errno = ENOMEM;
return -1;
}

if (index >= node->n_xattrs) {
errno = EINVAL;
return -1;
}

xattr = &node->xattrs[index];
free(xattr->key);
xattr->key = steal_pointer(&dup);
return 0;
}

0 comments on commit 83123d6

Please sign in to comment.