summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <daniel@octaforge.org>2022-10-29 18:18:02 +0200
committerDaniel Kolesa <daniel@octaforge.org>2022-12-22 15:11:09 +0100
commit790a62e9f36e82b753c3c115267516a88d48ed82 (patch)
tree35c81ee0453207c16704e568fb57f1a262a4e6bd
parent6508596be6b2e4c897034dcef72e9df09502f419 (diff)
downloadapk-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.c18
-rw-r--r--src/fs_fsys.c4
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;