diff --git a/contrib/fix-mode.py b/contrib/fix-mode.py index 533002a..ed0e024 100755 --- a/contrib/fix-mode.py +++ b/contrib/fix-mode.py @@ -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) diff --git a/direct.c b/direct.c index a1a5d7d..272631f 100644 --- a/direct.c +++ b/direct.c @@ -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; } diff --git a/main.c b/main.c index 5bd1993..85abb01 100644 --- a/main.c +++ b/main.c @@ -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: @@ -5792,13 +5796,22 @@ 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 && errno == ENODATA && lo.xattr_permissions == 2) + { + s = fgetxattr (get_upper_layer (&lo)->fd, XATTR_OVERRIDE_STAT, data, sizeof (data)); + if (s >= 0) + { + get_upper_layer (&lo)->stat_override_mode = STAT_OVERRIDE_USER; + name = XATTR_OVERRIDE_STAT; + } + } if (s < 0) { bool found = false; @@ -5809,15 +5822,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);