summary refs log blame commit diff
path: root/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch
blob: 33c4ffff6fe546b0958d1a3166074880f7580cbd (plain) (tree)
1
2
3
4
5
                                                    
                                   

                        
                                                                                              



















                                                                   
                                                                          
  

                                                                                                    







                                                            


                                                                                          
 

                                
 



                                                                           







                                                            





















                                                                                               

                                                        
                                                                  
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,