From abc6dd7411c57cad0805b3cf51271847d9d0679e Mon Sep 17 00:00:00 2001 From: morganamilo Date: Thu, 15 Feb 2024 03:40:40 +0000 Subject: [PATCH] libalpm: check calloc in alpm_list_cmp_unsorted --- lib/libalpm/alpm_list.c | 3 +++ lib/libalpm/alpm_list.h | 2 +- lib/libalpm/sync.c | 38 ++++++++++++++++++++++++++------------ 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c index bd012acc..daeb5140 100644 --- a/lib/libalpm/alpm_list.c +++ b/lib/libalpm/alpm_list.c @@ -535,6 +535,9 @@ int SYMEXPORT alpm_list_cmp_unsorted(const alpm_list_t *left, } matched = calloc(alpm_list_count(right), sizeof(int)); + if(matched == NULL) { + return -1; + } for(l = left; l; l = l->next) { int found = 0; diff --git a/lib/libalpm/alpm_list.h b/lib/libalpm/alpm_list.h index a82483ac..914734bc 100644 --- a/lib/libalpm/alpm_list.h +++ b/lib/libalpm/alpm_list.h @@ -339,7 +339,7 @@ char *alpm_list_find_str(const alpm_list_t *haystack, const char *needle); * @param right the second list * @param fn the comparison function * - * @return 1 if the lists are equal, 0 otherwise. + * @return 1 if the lists are equal, 0 if not equal, -1 on error. */ int alpm_list_cmp_unsorted(const alpm_list_t *left, const alpm_list_t *right, alpm_list_fn_cmp fn); diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index f88229f9..98878736 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -1079,20 +1079,32 @@ static int dep_not_equal(const alpm_depend_t *left, const alpm_depend_t *right) static int check_pkg_field_matches_db(alpm_handle_t *handle, const char *field, alpm_list_t *left, alpm_list_t *right, alpm_list_fn_cmp cmp) { - if(!alpm_list_cmp_unsorted(left, right, cmp)) { - _alpm_log(handle, ALPM_LOG_DEBUG, - "internal package %s mismatch\n", field); - return 1; + switch(alpm_list_cmp_unsorted(left, right, cmp)) { + case 0: + _alpm_log(handle, ALPM_LOG_DEBUG, + "internal package %s mismatch\n", field); + return 1; + case 1: + return 0; + default: + RET_ERR(handle, ALPM_ERR_MEMORY, -1); } - - return 0; } static int check_pkg_matches_db(alpm_pkg_t *spkg, alpm_pkg_t *pkgfile) { - alpm_handle_t *handle = spkg->handle; + alpm_handle_t *handle = spkg->handle; int error = 0; +#define CHECK_FIELD(STR, FIELD, CMP) do { \ + int ok = check_pkg_field_matches_db(handle, STR, spkg->FIELD, pkgfile->FIELD, (alpm_list_fn_cmp)CMP); \ + if(ok == -1) { \ + return 1; \ + } else if(ok != 0) { \ + error = 1; \ + } \ +} while(0) + if(strcmp(spkg->name, pkgfile->name) != 0) { _alpm_log(handle, ALPM_LOG_DEBUG, "internal package name mismatch, expected: '%s', actual: '%s'\n", @@ -1112,11 +1124,13 @@ static int check_pkg_matches_db(alpm_pkg_t *spkg, alpm_pkg_t *pkgfile) error = 1; } - error |= check_pkg_field_matches_db(handle, "depends", spkg->depends, pkgfile->depends, (alpm_list_fn_cmp)dep_not_equal); - error |= check_pkg_field_matches_db(handle, "conflicts", spkg->conflicts, pkgfile->conflicts, (alpm_list_fn_cmp)dep_not_equal); - error |= check_pkg_field_matches_db(handle, "replaces", spkg->replaces, pkgfile->replaces, (alpm_list_fn_cmp)dep_not_equal); - error |= check_pkg_field_matches_db(handle, "provides", spkg->provides, pkgfile->provides, (alpm_list_fn_cmp)dep_not_equal); - error |= check_pkg_field_matches_db(handle, "groups", spkg->groups, pkgfile->groups, (alpm_list_fn_cmp)strcmp); + CHECK_FIELD("depends", depends, dep_not_equal); + CHECK_FIELD("conflicts", conflicts, dep_not_equal); + CHECK_FIELD("replaces", replaces, dep_not_equal); + CHECK_FIELD("provides", provides, dep_not_equal); + CHECK_FIELD("groups", groups, strcmp); + +#undef CHECK_FIELD return error; }