Skip to content

Commit

Permalink
Prefer user.containers.override_stat over user.fuseoverlayfs.
Browse files Browse the repository at this point in the history
Previously, fuse-overlayfs always used user.fuseoverlayfs.override_stat
for the upper layer while honoring user.containers.override_stat for
lower layers so that it can consume a layer created by
containers/storage.

It turned out that containers/storage also needs to get the overriding
extended attribute set by fuse-overlayfs and to set one for the upper
layer to make the root directory of the upper layer inherit the mode
of a lower layer. Adding code to get and to set
user.fuseoverlayfs.override_stat to containers/storage is a bit ugly.

The underlying problem is that fuse-overlayfs changes what name to use
ad hoc. Fix it by always preferring user.containers.override_stat, which
containers/storage honors, over user.fuseoverlayfs.overlayfs, which is
specific to fuse-overlayfs.

Signed-off-by: Akihiko Odaki <[email protected]>
  • Loading branch information
akihikodaki committed Jun 10, 2024
1 parent 2ed8dfc commit 9a2d84f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 17 deletions.
4 changes: 2 additions & 2 deletions contrib/fix-mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
import errno

XATTR_OVERRIDE_STAT_PRIVILEGED = "security.fuseoverlayfs.override_stat"
XATTR_OVERRIDE_STAT = "user.fuseoverlayfs.override_stat"
XATTR_OVERRIDE_CONTAINERS_STAT = "user.fuseoverlayfs.override_stat"

if os.geteuid() == 0:
xattr_name = XATTR_OVERRIDE_STAT_PRIVILEGED
else:
xattr_name = XATTR_OVERRIDE_STAT
xattr_name = XATTR_OVERRIDE_CONTAINERS_STAT

cwd_fd = os.open(".", os.O_PATH)

Expand Down
4 changes: 2 additions & 2 deletions direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,10 @@ direct_load_data_source (struct ovl_layer *l, const char *opaque, const char *pa

if (fgetxattr (l->fd, XATTR_PRIVILEGED_OVERRIDE_STAT, tmp, sizeof (tmp)) >= 0)
l->stat_override_mode = STAT_OVERRIDE_PRIVILEGED;
else if (fgetxattr (l->fd, XATTR_OVERRIDE_STAT, tmp, sizeof (tmp)) >= 0)
l->stat_override_mode = STAT_OVERRIDE_USER;
else if (fgetxattr (l->fd, XATTR_OVERRIDE_CONTAINERS_STAT, tmp, sizeof (tmp)) >= 0)
l->stat_override_mode = STAT_OVERRIDE_CONTAINERS;
else if (fgetxattr (l->fd, XATTR_OVERRIDE_STAT, tmp, sizeof (tmp)) >= 0)
l->stat_override_mode = STAT_OVERRIDE_USER;

return 0;
}
Expand Down
40 changes: 27 additions & 13 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,17 +539,21 @@ write_permission_xattr (struct ovl_data *lo, int fd, const char *path, uid_t uid
int ret;
const char *name = NULL;

switch (lo->xattr_permissions)
switch (get_upper_layer (lo)->stat_override_mode)
{
case 0:
case STAT_OVERRIDE_NONE:
return 0;

case 1:
case STAT_OVERRIDE_USER:
name = XATTR_OVERRIDE_STAT;
break;

case STAT_OVERRIDE_PRIVILEGED:
name = XATTR_PRIVILEGED_OVERRIDE_STAT;
break;

case 2:
name = XATTR_OVERRIDE_STAT;
case STAT_OVERRIDE_CONTAINERS:
name = XATTR_OVERRIDE_CONTAINERS_STAT;
break;

default:
Expand Down Expand Up @@ -5777,13 +5781,19 @@ main (int argc, char *argv[])
}
else if (lo.xattr_permissions == 2)
{
get_upper_layer (&lo)->stat_override_mode = STAT_OVERRIDE_USER;
name = XATTR_OVERRIDE_STAT;
get_upper_layer (&lo)->stat_override_mode = STAT_OVERRIDE_CONTAINERS;
name = XATTR_OVERRIDE_CONTAINERS_STAT;
}
else
error (EXIT_FAILURE, 0, "invalid value for xattr_permissions");

s = fgetxattr (get_upper_layer (&lo)->fd, name, data, sizeof (data));
if (s < 0 && lo.xattr_permissions == 2)
{
get_upper_layer (&lo)->stat_override_mode = STAT_OVERRIDE_USER;
name = XATTR_OVERRIDE_STAT;
s = fgetxattr (get_upper_layer (&lo)->fd, name, data, sizeof (data));
}
if (s < 0)
{
bool found = false;
Expand All @@ -5794,15 +5804,19 @@ main (int argc, char *argv[])

for (l = get_lower_layers (&lo); l; l = l->next)
{
s = fgetxattr (l->fd, name, data, sizeof (data));
if (s < 0 && errno != ENODATA)
error (EXIT_FAILURE, errno, "fgetxattr mode from lower layer");
if (s < 0 && lo.xattr_permissions == 2)
switch (lo.xattr_permissions)
{
case 1:
s = fgetxattr (l->fd, name, data, sizeof (data));
break;

case 2:
s = fgetxattr (l->fd, XATTR_OVERRIDE_CONTAINERS_STAT, data, sizeof (data));
if (s < 0 && errno != ENODATA)
error (EXIT_FAILURE, errno, "fgetxattr mode from lower layer");
if (s < 0 && errno == ENODATA)
s = fgetxattr (l->fd, XATTR_OVERRIDE_STAT, data, sizeof (data));
break;
}

if (s > 0)
{
ret = fsetxattr (get_upper_layer (&lo)->fd, name, data, s, 0);
Expand Down

0 comments on commit 9a2d84f

Please sign in to comment.