diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2010-10-08 13:18:34 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2010-10-08 13:20:11 +0000 |
commit | 8fff0d810d40bfaa29b5aa628ee4de1e387a4ab4 (patch) | |
tree | 81f62182f7ef43caf1dd3079eaaac7e227aa3f10 | |
parent | cf96e07a8fa3afef8ee0eb82cf08636ab8cf793c (diff) | |
download | aports-8fff0d810d40bfaa29b5aa628ee4de1e387a4ab4.tar.bz2 aports-8fff0d810d40bfaa29b5aa628ee4de1e387a4ab4.tar.xz |
main/apk-tools: id cache should be specific to db root
ref #434
-rw-r--r-- | main/apk-tools/0001-io-db-id-cache-should-be-specific-to-database-root-n.patch | 437 | ||||
-rw-r--r-- | main/apk-tools/0002-db-fix-the-previous-commit.patch | 50 | ||||
-rw-r--r-- | main/apk-tools/APKBUILD | 8 |
3 files changed, 493 insertions, 2 deletions
diff --git a/main/apk-tools/0001-io-db-id-cache-should-be-specific-to-database-root-n.patch b/main/apk-tools/0001-io-db-id-cache-should-be-specific-to-database-root-n.patch new file mode 100644 index 0000000000..228f4ffe55 --- /dev/null +++ b/main/apk-tools/0001-io-db-id-cache-should-be-specific-to-database-root-n.patch @@ -0,0 +1,437 @@ +From 19419f1a88285a0dee53bdf49201c4d3d4cbf19f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> +Date: Fri, 8 Oct 2010 15:36:54 +0300 +Subject: [PATCH 1/2] io, db: id cache should be specific to database root, not system root + +Otherwise we end up using wrong uid/gid mappings when doing install +to alternate system root. Fixes #434. +--- + src/apk.c | 2 - + src/apk_archive.h | 2 +- + src/apk_database.h | 2 + + src/apk_io.h | 18 ++++++++--- + src/apk_package.h | 5 ++- + src/archive.c | 6 ++-- + src/database.c | 22 ++++++++----- + src/io.c | 88 ++++++++++++++++++++++++++++++--------------------- + src/package.c | 9 +++-- + src/verify.c | 2 +- + 10 files changed, 93 insertions(+), 63 deletions(-) + +diff --git a/src/apk.c b/src/apk.c +index 4196f74..55628c1 100644 +--- a/src/apk.c ++++ b/src/apk.c +@@ -248,7 +248,6 @@ int main(int argc, char **argv) + memset(&dbopts, 0, sizeof(dbopts)); + list_init(&dbopts.repository_list); + umask(0); +- apk_id_cache_init(); + + applet = deduce_applet(argc, argv); + num_options = ARRAY_SIZE(generic_options) + 1; +@@ -370,7 +369,6 @@ int main(int argc, char **argv) + + r = applet->main(ctx, &db, argc, argv); + apk_db_close(&db); +- apk_id_cache_free(); + + if (r == -EINVAL) + return usage(applet); +diff --git a/src/apk_archive.h b/src/apk_archive.h +index f1b5aaf..ff4fb48 100644 +--- a/src/apk_archive.h ++++ b/src/apk_archive.h +@@ -22,7 +22,7 @@ typedef int (*apk_archive_entry_parser)(void *ctx, + + int apk_tar_parse(struct apk_istream *, + apk_archive_entry_parser parser, void *ctx, +- int soft_checksums); ++ int soft_checksums, struct apk_id_cache *); + int apk_tar_write_entry(struct apk_ostream *, const struct apk_file_info *ae, + const char *data); + int apk_tar_write_padding(struct apk_ostream *, const struct apk_file_info *ae); +diff --git a/src/apk_database.h b/src/apk_database.h +index da33289..249ddae 100644 +--- a/src/apk_database.h ++++ b/src/apk_database.h +@@ -16,6 +16,7 @@ + #include "apk_hash.h" + #include "apk_archive.h" + #include "apk_package.h" ++#include "apk_io.h" + + #define APK_MAX_REPOS 32 + #define APK_CACHE_CSUM_BYTES 4 +@@ -109,6 +110,7 @@ struct apk_database { + struct apk_dependency_array *world; + struct apk_string_array *protected_paths; + struct apk_repository repos[APK_MAX_REPOS]; ++ struct apk_id_cache id_cache; + + struct { + struct apk_hash names; +diff --git a/src/apk_io.h b/src/apk_io.h +index 3a3abff..20051a6 100644 +--- a/src/apk_io.h ++++ b/src/apk_io.h +@@ -15,6 +15,14 @@ + + #include "apk_defines.h" + #include "apk_blob.h" ++#include "apk_hash.h" ++ ++struct apk_id_cache { ++ int root_fd; ++ unsigned int genid; ++ struct apk_hash uid_cache; ++ struct apk_hash gid_cache; ++}; + + struct apk_file_info { + char *name; +@@ -95,10 +103,10 @@ int apk_file_get_info(int atfd, const char *filename, unsigned int flags, + int apk_url_download(const char *url, int atfd, const char *file); + const char *apk_url_local_file(const char *url); + +-void apk_id_cache_init(void); +-void apk_id_cache_free(void); +-void apk_id_cache_reset(void); +-uid_t apk_resolve_uid(const char *username, uid_t default_uid); +-uid_t apk_resolve_gid(const char *groupname, uid_t default_gid); ++void apk_id_cache_init(struct apk_id_cache *idc, int root_fd); ++void apk_id_cache_free(struct apk_id_cache *idc); ++void apk_id_cache_reset(struct apk_id_cache *idc); ++uid_t apk_resolve_uid(struct apk_id_cache *idc, const char *username, uid_t default_uid); ++uid_t apk_resolve_gid(struct apk_id_cache *idc, const char *groupname, uid_t default_gid); + + #endif +diff --git a/src/apk_package.h b/src/apk_package.h +index 7901ddb..55f6845 100644 +--- a/src/apk_package.h ++++ b/src/apk_package.h +@@ -143,8 +143,9 @@ void apk_pkg_uninstall(struct apk_database *db, struct apk_package *pkg); + int apk_ipkg_add_script(struct apk_installed_package *ipkg, + struct apk_istream *is, + unsigned int type, unsigned int size); +-int apk_ipkg_run_script(struct apk_installed_package *ipkg, int root_fd, +- unsigned int type, char **argv); ++int apk_ipkg_run_script(struct apk_installed_package *ipkg, ++ struct apk_database *db, ++ unsigned int type, char **argv); + + struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_t entry); + int apk_pkg_write_index_entry(struct apk_package *pkg, struct apk_ostream *os); +diff --git a/src/archive.c b/src/archive.c +index b60b3b2..6e555b4 100644 +--- a/src/archive.c ++++ b/src/archive.c +@@ -117,7 +117,7 @@ static void tar_entry_close(void *stream) + } + + int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, +- void *ctx, int soft_checksums) ++ void *ctx, int soft_checksums, struct apk_id_cache *idc) + { + struct apk_file_info entry; + struct apk_tar_entry_istream teis = { +@@ -146,8 +146,8 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, + + entry = (struct apk_file_info){ + .size = GET_OCTAL(buf.size), +- .uid = apk_resolve_uid(buf.uname, GET_OCTAL(buf.uid)), +- .gid = apk_resolve_gid(buf.gname, GET_OCTAL(buf.gid)), ++ .uid = apk_resolve_uid(idc, buf.uname, GET_OCTAL(buf.uid)), ++ .gid = apk_resolve_gid(idc, buf.gname, GET_OCTAL(buf.gid)), + .mode = GET_OCTAL(buf.mode) & 07777, + .mtime = GET_OCTAL(buf.mtime), + .name = entry.name, +diff --git a/src/database.c b/src/database.c +index 0054837..f0b8cb6 100644 +--- a/src/database.c ++++ b/src/database.c +@@ -472,7 +472,7 @@ int apk_cache_download(struct apk_database *db, const char *url, + apk_bstream_from_file(db->cachetmp_fd, cacheitem), + apk_sign_ctx_mpart_cb, &sctx); + +- r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE); ++ r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE, &db->id_cache); + is->close(is); + apk_sign_ctx_free(&sctx); + if (r != 0) { +@@ -916,7 +916,7 @@ static int apk_db_read_state(struct apk_database *db, int flags) + is = apk_istream_from_file(db->root_fd, "var/lib/apk/scripts.tar"); + if (is != NULL) { + apk_tar_parse(is, apk_read_script_archive_entry, db, +- FALSE); ++ FALSE, &db->id_cache); + } else { + is = apk_istream_from_file(db->root_fd, "var/lib/apk/scripts"); + if (is != NULL) +@@ -1177,6 +1177,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) + goto ret_r; + } + ++ apk_id_cache_init(&db->id_cache, db->root_fd); ++ + return rr; + + ret_errno: +@@ -1266,6 +1268,8 @@ void apk_db_close(struct apk_database *db) + struct hlist_node *dc, *dn; + int i; + ++ apk_id_cache_free(&db->id_cache); ++ + list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) { + hlist_for_each_entry_safe(diri, dc, dn, &ipkg->owned_dirs, pkg_dirs_list) { + apk_db_diri_free(db, diri, APK_DISALLOW_RMDIR); +@@ -1343,7 +1347,7 @@ int apk_db_run_triggers(struct apk_database *db) + continue; + + *apk_string_array_add(&ipkg->pending_triggers) = NULL; +- apk_ipkg_run_script(ipkg, db->root_fd, APK_SCRIPT_TRIGGER, ++ apk_ipkg_run_script(ipkg, db, APK_SCRIPT_TRIGGER, + ipkg->pending_triggers->item); + apk_string_array_free(&ipkg->pending_triggers); + } +@@ -1520,7 +1524,7 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs, + ctx.found = 0; + apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY, NULL, db->keys_fd); + is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx); +- r = apk_tar_parse(is, load_apkindex, &ctx, FALSE); ++ r = apk_tar_parse(is, load_apkindex, &ctx, FALSE, &db->id_cache); + is->close(is); + apk_sign_ctx_free(&ctx.sctx); + if (ctx.found == 0) +@@ -1624,7 +1628,7 @@ static int apk_db_run_pending_script(struct install_ctx *ctx) + return 0; + + ctx->script_pending = FALSE; +- r = apk_ipkg_run_script(ctx->ipkg, ctx->db->root_fd, ctx->script, ++ r = apk_ipkg_run_script(ctx->ipkg, ctx->db, ctx->script, + ctx->script_args); + if (r != 0) + apk_error("%s-%s: Failed to execute " +@@ -2043,7 +2047,7 @@ static int apk_db_unpack_pkg(struct apk_database *db, + apk_name_array_init(&ctx.replaces); + apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &pkg->csum, db->keys_fd); + tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx); +- r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE); ++ r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE, &db->id_cache); + apk_sign_ctx_free(&ctx.sctx); + apk_name_array_free(&ctx.replaces); + tar->close(tar); +@@ -2098,13 +2102,13 @@ int apk_db_install_pkg(struct apk_database *db, + if (ipkg == NULL) + return 0; + +- r = apk_ipkg_run_script(ipkg, db->root_fd, ++ r = apk_ipkg_run_script(ipkg, db, + APK_SCRIPT_PRE_DEINSTALL, script_args); + if (r != 0) + return r; + + apk_db_purge_pkg(db, ipkg, NULL); +- r = apk_ipkg_run_script(ipkg, db->root_fd, ++ r = apk_ipkg_run_script(ipkg, db, + APK_SCRIPT_POST_DEINSTALL, script_args); + apk_pkg_uninstall(db, oldpkg); + +@@ -2135,7 +2139,7 @@ int apk_db_install_pkg(struct apk_database *db, + apk_pkg_uninstall(db, oldpkg); + } + +- r = apk_ipkg_run_script(ipkg, db->root_fd, ++ r = apk_ipkg_run_script(ipkg, db, + (oldpkg == NULL) ? + APK_SCRIPT_POST_INSTALL : APK_SCRIPT_POST_UPGRADE, + script_args); +diff --git a/src/io.c b/src/io.c +index 5100d41..38bc4e6 100644 +--- a/src/io.c ++++ b/src/io.c +@@ -766,48 +766,55 @@ static struct cache_item *resolve_cache_item(struct apk_hash *hash, apk_blob_t n + return ci; + } + +-static unsigned int id_genid = 0; +-static struct apk_hash uid_cache, gid_cache; +- +-void apk_id_cache_init(void) ++void apk_id_cache_init(struct apk_id_cache *idc, int root_fd) + { +- apk_hash_init(&uid_cache, &id_hash_ops, 256); +- apk_hash_init(&gid_cache, &id_hash_ops, 256); +- id_genid = 1; ++ idc->root_fd = root_fd; ++ idc->genid = 1; ++ apk_hash_init(&idc->uid_cache, &id_hash_ops, 256); ++ apk_hash_init(&idc->gid_cache, &id_hash_ops, 256); + } + +-void apk_id_cache_free(void) ++void apk_id_cache_free(struct apk_id_cache *idc) + { +- apk_hash_free(&uid_cache); +- apk_hash_free(&gid_cache); ++ apk_hash_free(&idc->uid_cache); ++ apk_hash_free(&idc->gid_cache); + } + +-void apk_id_cache_reset(void) ++void apk_id_cache_reset(struct apk_id_cache *idc) + { +- id_genid++; +- if (id_genid == 0) +- id_genid = 1; ++ idc->genid++; ++ if (idc->genid == 0) ++ idc->genid = 1; + } + +-uid_t apk_resolve_uid(const char *username, uid_t default_uid) ++uid_t apk_resolve_uid(struct apk_id_cache *idc, const char *username, uid_t default_uid) + { + struct cache_item *ci; + struct passwd pwent, *pwd; + char buf[1024]; +- int r; ++ FILE *in; + +- ci = resolve_cache_item(&uid_cache, APK_BLOB_STR(username)); ++ ci = resolve_cache_item(&idc->uid_cache, APK_BLOB_STR(username)); + if (ci == NULL) + return default_uid; + +- if (ci->genid != id_genid) { +- r = getpwnam_r(username, &pwent, buf, sizeof(buf), &pwd); +- if (pwd != NULL) +- ci->uid = pwd->pw_uid; +- else +- ci->uid = -1; +- if (r == 0) +- ci->genid = id_genid; ++ if (ci->genid != idc->genid) { ++ ci->genid = idc->genid; ++ ci->uid = -1; ++ ++ in = fdopen(openat(idc->root_fd, "etc/passwd", O_RDONLY|O_CLOEXEC), "r"); ++ if (in != NULL) { ++ do { ++ fgetpwent_r(in, &pwent, buf, sizeof(buf), &pwd); ++ if (pwd == NULL) ++ break; ++ if (strcmp(pwd->pw_name, username) == 0) { ++ ci->uid = pwd->pw_uid; ++ break; ++ } ++ } while (1); ++ fclose(in); ++ } + } + + if (ci->uid != -1) +@@ -816,25 +823,34 @@ uid_t apk_resolve_uid(const char *username, uid_t default_uid) + return default_uid; + } + +-uid_t apk_resolve_gid(const char *groupname, uid_t default_gid) ++uid_t apk_resolve_gid(struct apk_id_cache *idc, const char *groupname, uid_t default_gid) + { + struct cache_item *ci; + struct group grent, *grp; + char buf[1024]; +- int r; ++ FILE *in; + +- ci = resolve_cache_item(&gid_cache, APK_BLOB_STR(groupname)); ++ ci = resolve_cache_item(&idc->gid_cache, APK_BLOB_STR(groupname)); + if (ci == NULL) + return default_gid; + +- if (ci->genid != id_genid) { +- r = getgrnam_r(groupname, &grent, buf, sizeof(buf), &grp); +- if (grp != NULL) +- ci->gid = grp->gr_gid; +- else +- ci->gid = -1; +- if (r == 0) +- ci->genid = id_genid; ++ if (ci->genid != idc->genid) { ++ ci->genid = idc->genid; ++ ci->gid = -1; ++ ++ in = fdopen(openat(idc->root_fd, "etc/passwd", O_RDONLY|O_CLOEXEC), "r"); ++ if (in != NULL) { ++ do { ++ fgetgrent_r(in, &grent, buf, sizeof(buf), &grp); ++ if (grp == NULL) ++ break; ++ if (strcmp(grp->gr_name, groupname) == 0) { ++ ci->gid = grp->gr_gid; ++ break; ++ } ++ } while (1); ++ fclose(in); ++ } + } + + if (ci->gid != -1) +diff --git a/src/package.c b/src/package.c +index 8f15e7a..df53d93 100644 +--- a/src/package.c ++++ b/src/package.c +@@ -793,7 +793,7 @@ int apk_pkg_read(struct apk_database *db, const char *file, + ctx.pkg->size = fi.size; + + tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, sctx); +- r = apk_tar_parse(tar, read_info_entry, &ctx, FALSE); ++ r = apk_tar_parse(tar, read_info_entry, &ctx, FALSE, &db->id_cache); + tar->close(tar); + if (r < 0 && r != -ECANCELED) + goto err; +@@ -856,7 +856,8 @@ int apk_ipkg_add_script(struct apk_installed_package *ipkg, + return 0; + } + +-int apk_ipkg_run_script(struct apk_installed_package *ipkg, int root_fd, ++int apk_ipkg_run_script(struct apk_installed_package *ipkg, ++ struct apk_database *db, + unsigned int type, char **argv) + { + static char * const environment[] = { +@@ -865,7 +866,7 @@ int apk_ipkg_run_script(struct apk_installed_package *ipkg, int root_fd, + }; + struct apk_package *pkg = ipkg->pkg; + char fn[PATH_MAX]; +- int fd, status; ++ int fd, status, root_fd = db->root_fd; + pid_t pid; + + if (type >= APK_SCRIPT_MAX) +@@ -911,7 +912,7 @@ int apk_ipkg_run_script(struct apk_installed_package *ipkg, int root_fd, + } + waitpid(pid, &status, 0); + unlinkat(root_fd, fn, 0); +- apk_id_cache_reset(); ++ apk_id_cache_reset(&db->id_cache); + + if (WIFEXITED(status)) + return WEXITSTATUS(status); +diff --git a/src/verify.c b/src/verify.c +index 006b548..b6a5cbc 100644 +--- a/src/verify.c ++++ b/src/verify.c +@@ -33,7 +33,7 @@ static int verify_main(void *ctx, struct apk_database *db, int argc, char **argv + rc++; + continue; + } +- r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE); ++ r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE, &db->id_cache); + is->close(is); + ok = sctx.control_verified && sctx.data_verified; + if (apk_verbosity >= 1) +-- +1.7.3.1 + diff --git a/main/apk-tools/0002-db-fix-the-previous-commit.patch b/main/apk-tools/0002-db-fix-the-previous-commit.patch new file mode 100644 index 0000000000..48f38ba072 --- /dev/null +++ b/main/apk-tools/0002-db-fix-the-previous-commit.patch @@ -0,0 +1,50 @@ +From 6398d338c6441f3b967a2633bbc9df4709bcb258 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi> +Date: Fri, 8 Oct 2010 16:09:03 +0300 +Subject: [PATCH 2/2] db: fix the previous commit + +id cache needs to be initialized early. and group database filename +is surprisingly 'group'. +--- + src/database.c | 4 ++-- + src/io.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/database.c b/src/database.c +index f0b8cb6..e22289a 100644 +--- a/src/database.c ++++ b/src/database.c +@@ -1079,6 +1079,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) + S_ISDIR(st.st_mode) && major(st.st_dev) != 0) + db->cache_dir = apk_linked_cache_dir; + ++ apk_id_cache_init(&db->id_cache, db->root_fd); ++ + if (dbopts->open_flags & APK_OPENF_WRITE) { + db->lock_fd = openat(db->root_fd, "var/lib/apk/lock", + O_CREAT | O_RDWR | O_CLOEXEC, 0400); +@@ -1177,8 +1179,6 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) + goto ret_r; + } + +- apk_id_cache_init(&db->id_cache, db->root_fd); +- + return rr; + + ret_errno: +diff --git a/src/io.c b/src/io.c +index 38bc4e6..0f09403 100644 +--- a/src/io.c ++++ b/src/io.c +@@ -838,7 +838,7 @@ uid_t apk_resolve_gid(struct apk_id_cache *idc, const char *groupname, uid_t def + ci->genid = idc->genid; + ci->gid = -1; + +- in = fdopen(openat(idc->root_fd, "etc/passwd", O_RDONLY|O_CLOEXEC), "r"); ++ in = fdopen(openat(idc->root_fd, "etc/group", O_RDONLY|O_CLOEXEC), "r"); + if (in != NULL) { + do { + fgetgrent_r(in, &grent, buf, sizeof(buf), &grp); +-- +1.7.3.1 + diff --git a/main/apk-tools/APKBUILD b/main/apk-tools/APKBUILD index f64df8a815..b18e056185 100644 --- a/main/apk-tools/APKBUILD +++ b/main/apk-tools/APKBUILD @@ -1,12 +1,14 @@ # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=apk-tools pkgver=2.0.6 -pkgrel=0 +pkgrel=1 pkgdesc="Alpine Package Keeper - package manager for alpine" subpackages="$pkgname-static" depends= makedepends="zlib-dev openssl-dev pkgconfig" source="http://git.alpinelinux.org/cgit/$pkgname/snapshot/$pkgname-$pkgver.tar.bz2 + 0001-io-db-id-cache-should-be-specific-to-database-root-n.patch + 0002-db-fix-the-previous-commit.patch " url="http://git.alpinelinux.org/cgit/apk-tools/" @@ -47,4 +49,6 @@ static() { "$subpkgdir"/sbin/apk.static } -md5sums="5933a61f91f44c5c534f8a62e6effb65 apk-tools-2.0.6.tar.bz2" +md5sums="5933a61f91f44c5c534f8a62e6effb65 apk-tools-2.0.6.tar.bz2 +20c2f3e406984af51c7cf69b69a1d874 0001-io-db-id-cache-should-be-specific-to-database-root-n.patch +01a86fb39a3d161221a57002b86b2a0d 0002-db-fix-the-previous-commit.patch" |