diff options
author | Daniel Kolesa <daniel@octaforge.org> | 2022-10-29 18:18:02 +0200 |
---|---|---|
committer | Daniel Kolesa <daniel@octaforge.org> | 2022-12-22 15:11:09 +0100 |
commit | 790a62e9f36e82b753c3c115267516a88d48ed82 (patch) | |
tree | 35c81ee0453207c16704e568fb57f1a262a4e6bd | |
parent | 6508596be6b2e4c897034dcef72e9df09502f419 (diff) | |
download | apk-tools-790a62e9f36e82b753c3c115267516a88d48ed82.tar.gz apk-tools-790a62e9f36e82b753c3c115267516a88d48ed82.tar.bz2 apk-tools-790a62e9f36e82b753c3c115267516a88d48ed82.tar.xz apk-tools-790a62e9f36e82b753c3c115267516a88d48ed82.zip |
db: always have writable directories with --no-chown
The --no-chown flag is most useful when running apk as a regular
user, in which case we want to make sure that there are no issues
regarding permissions.
Fixes https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10854
-rw-r--r-- | src/database.c | 18 | ||||
-rw-r--r-- | src/fs_fsys.c | 4 |
2 files changed, 19 insertions, 3 deletions
diff --git a/src/database.c b/src/database.c index 270285c..71d2d68 100644 --- a/src/database.c +++ b/src/database.c @@ -82,6 +82,15 @@ struct install_ctx { struct hlist_node **file_diri_node; }; +static mode_t apk_db_dir_get_mode(struct apk_database *db, mode_t mode) +{ + // when using --no-chown, we are presumably running as a regular user, + // in which case init directories so that regular user can write in them + if (db->extract_flags & APK_FSEXTRACTF_NO_CHOWN) + return mode | S_IWUSR | S_IXUSR; + return mode; +} + static apk_blob_t apk_pkg_ctx(struct apk_package *pkg) { return APK_BLOB_PTR_LEN(pkg->name->name, strlen(pkg->name->name)+1); @@ -249,15 +258,18 @@ static struct apk_db_acl *apk_db_acl_atomize_digest(struct apk_database *db, mod static void apk_db_dir_prepare(struct apk_database *db, struct apk_db_dir *dir, mode_t newmode) { struct apk_fsdir d; + mode_t dir_mode; if (dir->namelen == 0) return; if (dir->created) return; + dir_mode = apk_db_dir_get_mode(db, dir->mode); + apk_fsdir_get(&d, APK_BLOB_PTR_LEN(dir->name, dir->namelen), db->ctx, APK_BLOB_NULL); - switch (apk_fsdir_check(&d, dir->mode, dir->uid, dir->gid)) { + switch (apk_fsdir_check(&d, dir_mode, dir->uid, dir->gid)) { default: if (!(db->ctx->flags & APK_SIMULATE)) - apk_fsdir_create(&d, dir->mode); + apk_fsdir_create(&d, dir_mode); case 0: dir->update_permissions = 1; case APK_FS_DIR_MODIFIED: @@ -2077,7 +2089,7 @@ static int update_permissions(apk_hash_item item, void *pctx) dir->seen = 0; apk_fsdir_get(&d, APK_BLOB_PTR_LEN(dir->name, dir->namelen), db->ctx, APK_BLOB_NULL); - if (apk_fsdir_update_perms(&d, dir->mode, dir->uid, dir->gid) != 0) + if (apk_fsdir_update_perms(&d, apk_db_dir_get_mode(db, dir->mode), dir->uid, dir->gid) != 0) ctx->errors++; return 0; diff --git a/src/fs_fsys.c b/src/fs_fsys.c index c11ca50..218676b 100644 --- a/src/fs_fsys.c +++ b/src/fs_fsys.c @@ -57,6 +57,10 @@ static int fsys_dir_update_perms(struct apk_fsdir *d, mode_t mode, uid_t uid, gi if (fchmodat(fd, dirname, mode, 0) < 0) rc = -errno; } + + if (d->ac->db->extract_flags & APK_FSEXTRACTF_NO_CHOWN) + return rc; + if (st.st_uid != uid || st.st_gid != gid) { if (fchownat(fd, dirname, uid, gid, 0) < 0) rc = -errno; |