From dca2223cb70af5476c7bb1e51dfb229f7d19a95a Mon Sep 17 00:00:00 2001 From: Duncan Overbruck Date: Mon, 10 Feb 2020 00:20:13 +0100 Subject: [PATCH] lib/transaction_store.c: store a copy in transaction packages array This fixes multiple use after frees, found with AddressSanitizers. * xbps_package_register: the pkgdb dictionary is replaced with the new one. * xbps_pkgdb_update: here the pkgdb is externalized, freed and internalized. --- lib/transaction_store.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/transaction_store.c b/lib/transaction_store.c index 1c6d8510..53976e50 100644 --- a/lib/transaction_store.c +++ b/lib/transaction_store.c @@ -32,21 +32,25 @@ int HIDDEN xbps_transaction_store(struct xbps_handle *xhp, xbps_array_t pkgs, - xbps_dictionary_t pkgd, const char *tract, bool autoinst) + xbps_dictionary_t pkgrd, const char *tract, bool autoinst) { + xbps_dictionary_t pkgd; xbps_array_t replaces; const char *pkgver, *repo; char pkgname[XBPS_NAME_SIZE], *self_replaced; - xbps_dictionary_get_cstring_nocopy(pkgd, "repository", &repo); - xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver); + xbps_dictionary_get_cstring_nocopy(pkgrd, "pkgver", &pkgver); if (xbps_find_pkg_in_array(pkgs, pkgver, NULL)) return 0; + + if ((pkgd = xbps_dictionary_copy_mutable(pkgrd)) == NULL) + return ENOMEM; + /* * Add required objects into package dep's dictionary. */ if (autoinst && !xbps_dictionary_set_bool(pkgd, "automatic-install", true)) - return EINVAL; + goto err; /* * Set a replaces to itself, so that virtual packages are always replaced. @@ -62,13 +66,15 @@ xbps_transaction_store(struct xbps_handle *xhp, xbps_array_t pkgs, free(self_replaced); if (!xbps_dictionary_set(pkgd, "replaces", replaces)) - return EINVAL; + goto err; /* * Add the dictionary into the unsorted queue. */ if (!xbps_array_add(pkgs, pkgd)) - return EINVAL; + goto err; + + xbps_dictionary_get_cstring_nocopy(pkgd, "repository", &repo); xbps_set_cb_state(xhp, XBPS_STATE_TRANS_ADDPKG, 0, pkgver, "Found %s (%s) in repository %s", pkgver, tract, repo); @@ -79,4 +85,7 @@ xbps_transaction_store(struct xbps_handle *xhp, xbps_array_t pkgs, xbps_object_release(pkgd); return 0; +err: + xbps_object_release(pkgd); + return EINVAL; }