Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at devShellTools-shell 81 lines 2.9 kB view raw
1diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c 2index 45e9a1f9b0..494ee00c66 100644 3--- a/hw/9pfs/9p-local.c 4+++ b/hw/9pfs/9p-local.c 5@@ -84,6 +84,23 @@ static void unlinkat_preserve_errno(int dirfd, const char *path, int flags) 6 7 #define VIRTFS_META_DIR ".virtfs_metadata" 8 9+static int is_in_store_path(const char *path) 10+{ 11+ static char *store_path = NULL; 12+ int store_path_len = -1; 13+ 14+ if (store_path_len == -1) { 15+ if ((store_path = getenv("NIX_STORE")) != NULL) 16+ store_path_len = strlen(store_path); 17+ else 18+ store_path_len = 0; 19+ } 20+ 21+ if (store_path_len > 0) 22+ return strncmp(path, store_path, strlen(store_path)) == 0; 23+ return 0; 24+} 25+ 26 static FILE *local_fopenat(int dirfd, const char *name, const char *mode) 27 { 28 int fd, o_mode = 0; 29@@ -161,6 +178,8 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf) 30 if (err) { 31 goto err_out; 32 } 33+ stbuf->st_uid = 0; 34+ stbuf->st_gid = 0; 35 if (fs_ctx->export_flags & V9FS_SM_MAPPED) { 36 /* Actual credentials are part of extended attrs */ 37 uid_t tmp_uid; 38@@ -280,6 +299,9 @@ static int fchmodat_nofollow(int dirfd, const char *name, mode_t mode) 39 { 40 int fd, ret; 41 42+ if (is_in_store_path(name)) 43+ return 0; 44+ 45 /* FIXME: this should be handled with fchmodat(AT_SYMLINK_NOFOLLOW). 46 * Unfortunately, the linux kernel doesn't implement it yet. As an 47 * alternative, let's open the file and use fchmod() instead. This 48@@ -661,6 +683,8 @@ static int local_fstat(FsContext *fs_ctx, int fid_type, 49 if (err) { 50 return err; 51 } 52+ stbuf->st_uid = 0; 53+ stbuf->st_gid = 0; 54 if (fs_ctx->export_flags & V9FS_SM_MAPPED) { 55 /* Actual credentials are part of extended attrs */ 56 uid_t tmp_uid; 57@@ -795,8 +819,11 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath, 58 if (err) { 59 goto out; 60 } 61- err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid, 62- AT_SYMLINK_NOFOLLOW); 63+ if (is_in_store_path(name)) 64+ err = 0; 65+ else 66+ err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid, 67+ AT_SYMLINK_NOFOLLOW); 68 if (err == -1) { 69 /* 70 * If we fail to change ownership and if we are 71@@ -911,7 +938,9 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) 72 goto out; 73 } 74 75- if ((credp->fc_uid == -1 && credp->fc_gid == -1) || 76+ if (is_in_store_path(name)) { 77+ ret = 0; 78+ } else if ((credp->fc_uid == -1 && credp->fc_gid == -1) || 79 (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || 80 (fs_ctx->export_flags & V9FS_SM_NONE)) { 81 ret = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,