detect pkghash allocation failure

If rehash ever failed with a full hash it would return the old hash
that is already full.  get_hash_position would then loop forever
because it would never find an empty bucket.

Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
Andrew Gregory 2018-01-07 19:30:42 -05:00 committed by Allan McRae
parent 59b6fdeee1
commit 2bda849bf9
5 changed files with 28 additions and 14 deletions

View file

@ -601,7 +601,10 @@ static int local_db_populate(alpm_db_t *db)
/* add to the collection */ /* add to the collection */
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", _alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
pkg->name, db->treename); pkg->name, db->treename);
db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg); if(_alpm_pkghash_add(&db->pkgcache, pkg) == NULL) {
_alpm_pkg_free(pkg);
RET_ERR(db->handle, ALPM_ERR_MEMORY, -1);
}
count++; count++;
} }

View file

@ -413,7 +413,10 @@ static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname,
/* add to the collection */ /* add to the collection */
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", _alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
pkg->name, db->treename); pkg->name, db->treename);
db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg); if(_alpm_pkghash_add(&db->pkgcache, pkg) == NULL) {
_alpm_pkg_free(pkg);
RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL);
}
} else { } else {
free(pkgname); free(pkgname);
free(pkgver); free(pkgver);

View file

@ -589,7 +589,10 @@ int _alpm_db_add_pkgincache(alpm_db_t *db, alpm_pkg_t *pkg)
? ALPM_PKG_FROM_LOCALDB ? ALPM_PKG_FROM_LOCALDB
: ALPM_PKG_FROM_SYNCDB; : ALPM_PKG_FROM_SYNCDB;
newpkg->origin_data.db = db; newpkg->origin_data.db = db;
db->pkgcache = _alpm_pkghash_add_sorted(db->pkgcache, newpkg); if(_alpm_pkghash_add_sorted(&db->pkgcache, newpkg) == NULL) {
_alpm_pkg_free(newpkg);
RET_ERR(db->handle, ALPM_ERR_MEMORY, -1);
}
free_groupcache(db); free_groupcache(db);

View file

@ -132,8 +132,7 @@ static alpm_pkghash_t *rehash(alpm_pkghash_t *oldhash)
newhash = _alpm_pkghash_create(newsize); newhash = _alpm_pkghash_create(newsize);
if(newhash == NULL) { if(newhash == NULL) {
/* creation of newhash failed, stick with old one... */ return NULL;
return oldhash;
} }
newhash->list = oldhash->list; newhash->list = oldhash->list;
@ -156,23 +155,29 @@ static alpm_pkghash_t *rehash(alpm_pkghash_t *oldhash)
return newhash; return newhash;
} }
static alpm_pkghash_t *pkghash_add_pkg(alpm_pkghash_t *hash, alpm_pkg_t *pkg, static alpm_pkghash_t *pkghash_add_pkg(alpm_pkghash_t **hashref, alpm_pkg_t *pkg,
int sorted) int sorted)
{ {
alpm_list_t *ptr; alpm_list_t *ptr;
unsigned int position; unsigned int position;
alpm_pkghash_t *hash;
if(pkg == NULL || hash == NULL) { if(pkg == NULL || hashref == NULL || *hashref == NULL) {
return hash; return NULL;
} }
hash = *hashref;
if(hash->entries >= hash->limit) { if(hash->entries >= hash->limit) {
hash = rehash(hash); if((hash = rehash(hash)) == NULL) {
/* resizing failed and there are no more open buckets */
return NULL;
}
*hashref = hash;
} }
position = get_hash_position(pkg->name_hash, hash); position = get_hash_position(pkg->name_hash, hash);
MALLOC(ptr, sizeof(alpm_list_t), return hash); MALLOC(ptr, sizeof(alpm_list_t), return NULL);
ptr->data = pkg; ptr->data = pkg;
ptr->prev = ptr; ptr->prev = ptr;
@ -189,12 +194,12 @@ static alpm_pkghash_t *pkghash_add_pkg(alpm_pkghash_t *hash, alpm_pkg_t *pkg,
return hash; return hash;
} }
alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t *hash, alpm_pkg_t *pkg) alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t **hash, alpm_pkg_t *pkg)
{ {
return pkghash_add_pkg(hash, pkg, 0); return pkghash_add_pkg(hash, pkg, 0);
} }
alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t *hash, alpm_pkg_t *pkg) alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t **hash, alpm_pkg_t *pkg)
{ {
return pkghash_add_pkg(hash, pkg, 1); return pkghash_add_pkg(hash, pkg, 1);
} }

View file

@ -49,8 +49,8 @@ typedef struct __alpm_pkghash_t alpm_pkghash_t;
alpm_pkghash_t *_alpm_pkghash_create(unsigned int size); alpm_pkghash_t *_alpm_pkghash_create(unsigned int size);
alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t *hash, alpm_pkg_t *pkg); alpm_pkghash_t *_alpm_pkghash_add(alpm_pkghash_t **hash, alpm_pkg_t *pkg);
alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t *hash, alpm_pkg_t *pkg); alpm_pkghash_t *_alpm_pkghash_add_sorted(alpm_pkghash_t **hash, alpm_pkg_t *pkg);
alpm_pkghash_t *_alpm_pkghash_remove(alpm_pkghash_t *hash, alpm_pkg_t *pkg, alpm_pkg_t **data); alpm_pkghash_t *_alpm_pkghash_remove(alpm_pkghash_t *hash, alpm_pkg_t *pkg, alpm_pkg_t **data);
void _alpm_pkghash_free(alpm_pkghash_t *hash); void _alpm_pkghash_free(alpm_pkghash_t *hash);