summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <daniel@octaforge.org>2023-02-16 15:11:16 +0100
committerTimo Teräs <timo.teras@iki.fi>2023-02-16 18:55:48 +0000
commit3aa99faa83d08e45eff8a5cc95c4df16fb5bd257 (patch)
tree6628283b62f96b465405dfc859bdb8d05df35f11
parentc2e42e220af4bbf3a852fb55663b070c81519f05 (diff)
downloadapk-tools-3aa99faa83d08e45eff8a5cc95c4df16fb5bd257.tar.gz
apk-tools-3aa99faa83d08e45eff8a5cc95c4df16fb5bd257.tar.bz2
apk-tools-3aa99faa83d08e45eff8a5cc95c4df16fb5bd257.tar.xz
apk-tools-3aa99faa83d08e45eff8a5cc95c4df16fb5bd257.zip
io: reset idcache for new passwd/group (and have a root fallback)
In order to address the problem with early file ownership (before passwd/group exists), do a few changes here: 1) For root-owned things, always fall back to fixed values, as those are the ones we always know and cannot change. Since the earliest packages only have root-owned files, this fixes the problem for those. 2) During file migration, if we encounter passwd/group and this is a newly committed file, reset the idcache, similarly to how it is done for scripts. This allows the next package to reload the mappings. Since those two files are usually installed as a part of the first package, the second package onwards should have a valid, complete mapping (reset only by scripts).
-rw-r--r--src/database.c13
-rw-r--r--src/io.c16
2 files changed, 24 insertions, 5 deletions
diff --git a/src/database.c b/src/database.c
index 14dff47..39624f5 100644
--- a/src/database.c
+++ b/src/database.c
@@ -2857,7 +2857,7 @@ static uint8_t apk_db_migrate_files_for_priority(struct apk_database *db,
struct apk_fsdir d;
unsigned long hash;
apk_blob_t dirname;
- int r, ctrl;
+ int r, ctrl, inetc;
uint8_t dir_priority, next_priority = 0xff;
hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs, pkg_dirs_list) {
@@ -2870,6 +2870,8 @@ static uint8_t apk_db_migrate_files_for_priority(struct apk_database *db,
next_priority = dir_priority;
continue;
}
+ // Used for passwd/group check later
+ inetc = !apk_blob_compare(dirname, APK_BLOB_STRLIT("etc"));
dir->modified = 1;
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) {
@@ -2912,6 +2914,15 @@ static uint8_t apk_db_migrate_files_for_priority(struct apk_database *db,
DIR_FILE_PRINTF(diri->dir, file),
apk_error_str(r));
ipkg->broken_files = 1;
+ } else if (inetc && ctrl == APK_FS_CTRL_COMMIT) {
+ // This is called when we successfully migrated the files
+ // in the filesystem; we explicitly do not care about apk-new
+ // or cancel cases, as that does not change the original file
+ if (!apk_blob_compare(key.filename, APK_BLOB_STRLIT("passwd")) ||
+ !apk_blob_compare(key.filename, APK_BLOB_STRLIT("group"))) {
+ // Reset the idcache because we have a new passwd/group
+ apk_id_cache_reset(db->id_cache);
+ }
}
// Claim ownership of the file in db
diff --git a/src/io.c b/src/io.c
index 77993a2..f5a30d4 100644
--- a/src/io.c
+++ b/src/io.c
@@ -1254,7 +1254,9 @@ uid_t apk_id_cache_resolve_uid(struct apk_id_cache *idc, apk_blob_t username, ui
struct cache_item *ci;
idcache_load_users(idc->root_fd, &idc->uid_cache);
ci = idcache_by_name(&idc->uid_cache, username);
- return ci ? ci->id : default_uid;
+ if (ci) return ci->id;
+ if (!apk_blob_compare(username, APK_BLOB_STRLIT("root"))) return 0;
+ return default_uid;
}
gid_t apk_id_cache_resolve_gid(struct apk_id_cache *idc, apk_blob_t groupname, gid_t default_gid)
@@ -1262,7 +1264,9 @@ gid_t apk_id_cache_resolve_gid(struct apk_id_cache *idc, apk_blob_t groupname, g
struct cache_item *ci;
idcache_load_groups(idc->root_fd, &idc->gid_cache);
ci = idcache_by_name(&idc->gid_cache, groupname);
- return ci ? ci->id : default_gid;
+ if (ci) return ci->id;
+ if (!apk_blob_compare(groupname, APK_BLOB_STRLIT("root"))) return 0;
+ return default_gid;
}
apk_blob_t apk_id_cache_resolve_user(struct apk_id_cache *idc, uid_t uid)
@@ -1270,7 +1274,9 @@ apk_blob_t apk_id_cache_resolve_user(struct apk_id_cache *idc, uid_t uid)
struct cache_item *ci;
idcache_load_users(idc->root_fd, &idc->uid_cache);
ci = idcache_by_id(&idc->uid_cache, uid);
- return ci ? APK_BLOB_PTR_LEN(ci->name, ci->len) : APK_BLOB_STRLIT("nobody");
+ if (ci) return APK_BLOB_PTR_LEN(ci->name, ci->len);
+ if (uid == 0) return APK_BLOB_STRLIT("root");
+ return APK_BLOB_STRLIT("nobody");
}
apk_blob_t apk_id_cache_resolve_group(struct apk_id_cache *idc, gid_t gid)
@@ -1278,5 +1284,7 @@ apk_blob_t apk_id_cache_resolve_group(struct apk_id_cache *idc, gid_t gid)
struct cache_item *ci;
idcache_load_groups(idc->root_fd, &idc->gid_cache);
ci = idcache_by_id(&idc->gid_cache, gid);
- return ci ? APK_BLOB_PTR_LEN(ci->name, ci->len) : APK_BLOB_STRLIT("nobody");
+ if (ci) return APK_BLOB_PTR_LEN(ci->name, ci->len);
+ if (gid == 0) return APK_BLOB_STRLIT("root");
+ return APK_BLOB_STRLIT("nobody");
}