about summary refs log tree commit diff
path: root/nixpkgs/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch')
-rw-r--r--nixpkgs/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch81
1 files changed, 81 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch b/nixpkgs/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch
new file mode 100644
index 000000000000..33c4ffff6fe5
--- /dev/null
+++ b/nixpkgs/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch
@@ -0,0 +1,81 @@
+diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
+index 45e9a1f9b0..494ee00c66 100644
+--- a/hw/9pfs/9p-local.c
++++ b/hw/9pfs/9p-local.c
+@@ -84,6 +84,23 @@ static void unlinkat_preserve_errno(int dirfd, const char *path, int flags)
+ 
+ #define VIRTFS_META_DIR ".virtfs_metadata"
+ 
++static int is_in_store_path(const char *path)
++{
++    static char *store_path = NULL;
++    int store_path_len = -1;
++
++    if (store_path_len == -1) {
++        if ((store_path = getenv("NIX_STORE")) != NULL)
++            store_path_len = strlen(store_path);
++        else
++            store_path_len = 0;
++    }
++
++    if (store_path_len > 0)
++        return strncmp(path, store_path, strlen(store_path)) == 0;
++    return 0;
++}
++
+ static FILE *local_fopenat(int dirfd, const char *name, const char *mode)
+ {
+     int fd, o_mode = 0;
+@@ -161,6 +178,8 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
+     if (err) {
+         goto err_out;
+     }
++    stbuf->st_uid = 0;
++    stbuf->st_gid = 0;
+     if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
+         /* Actual credentials are part of extended attrs */
+         uid_t tmp_uid;
+@@ -280,6 +299,9 @@ static int fchmodat_nofollow(int dirfd, const char *name, mode_t mode)
+ {
+     int fd, ret;
+ 
++    if (is_in_store_path(name))
++        return 0;
++
+     /* FIXME: this should be handled with fchmodat(AT_SYMLINK_NOFOLLOW).
+      * Unfortunately, the linux kernel doesn't implement it yet. As an
+      * alternative, let's open the file and use fchmod() instead. This
+@@ -661,6 +683,8 @@ static int local_fstat(FsContext *fs_ctx, int fid_type,
+     if (err) {
+         return err;
+     }
++    stbuf->st_uid = 0;
++    stbuf->st_gid = 0;
+     if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
+         /* Actual credentials are part of extended attrs */
+         uid_t tmp_uid;
+@@ -795,8 +819,11 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
+         if (err) {
+             goto out;
+         }
+-        err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
+-                       AT_SYMLINK_NOFOLLOW);
++        if (is_in_store_path(name))
++            err = 0;
++        else
++            err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
++                           AT_SYMLINK_NOFOLLOW);
+         if (err == -1) {
+             /*
+              * If we fail to change ownership and if we are
+@@ -911,7 +938,9 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
+         goto out;
+     }
+ 
+-    if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
++    if (is_in_store_path(name)) {
++        ret = 0;
++    } else if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
+         (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+         (fs_ctx->export_flags & V9FS_SM_NONE)) {
+         ret = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,