In sync_db_populate() and local_db_populate(), a NULL
db->pkgcache is not caught, allowing the functions to continue
instead of exiting.

A later alpm_list_msort() call which uses alpm_list_nth()
will thus traverse invalid pointers in a non-existent
db->pkgcache->list.

pmerrno is set to PM_ERR_MEMORY as _alpm_pkghash_create() will
only return NULL when we run out of memory / exceed max hash
table size. The local/sync db_populate() functions are also
exited.

db->pkgcache_loaded is initialized to 0 in _alpm_db_new() as
this value is used to ascertain the whether db->pkgcache is
loaded.

Signed-off-by: Pang Yan Han <[email protected]>
---
 lib/libalpm/be_local.c |    4 ++++
 lib/libalpm/be_sync.c  |    8 +++++++-
 lib/libalpm/db.c       |    1 +
 3 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index c5b2498..5858270 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -393,6 +393,10 @@ static int local_db_populate(pmdb_t *db)
 
        /* initialize hash at 50% full */
        db->pkgcache = _alpm_pkghash_create(est_count * 2);
+       if(db->pkgcache == NULL){
+               closedir(dbdir);
+               RET_ERR(PM_ERR_MEMORY, -1);
+       }
 
        while((ent = readdir(dbdir)) != NULL) {
                const char *name = ent->d_name;
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index 4ad045c..4e9b4d3 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -234,6 +234,9 @@ static int sync_db_populate(pmdb_t *db)
 
        /* initialize hash at 66% full */
        db->pkgcache = _alpm_pkghash_create(est_count * 3 / 2);
+       if(db->pkgcache == NULL) {
+               RET_ERR(PM_ERR_MEMORY, -1);
+       }
 
        while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
                const struct stat *st;
@@ -348,6 +351,9 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
        if(likely_pkg && strcmp(likely_pkg->name, pkgname) == 0) {
                pkg = likely_pkg;
        } else {
+               if(db->pkgcache == NULL) {
+                       RET_ERR(PM_ERR_MEMORY, -1);
+               }
                pkg = _alpm_pkghash_find(db->pkgcache, pkgname);
        }
        if(pkg == NULL) {
@@ -459,10 +465,10 @@ pmdb_t *_alpm_db_register_sync(const char *treename)
        _alpm_log(PM_LOG_DEBUG, "registering sync database '%s'\n", treename);
 
        db = _alpm_db_new(treename, 0);
-       db->ops = &sync_db_ops;
        if(db == NULL) {
                RET_ERR(PM_ERR_DB_CREATE, NULL);
        }
+       db->ops = &sync_db_ops;
 
        handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
        return(db);
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 02f8282..d43a16b 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -370,6 +370,7 @@ pmdb_t *_alpm_db_new(const char *treename, int is_local)
        CALLOC(db, 1, sizeof(pmdb_t), RET_ERR(PM_ERR_MEMORY, NULL));
        STRDUP(db->treename, treename, RET_ERR(PM_ERR_MEMORY, NULL));
        db->is_local = is_local;
+       db->pkgcache_loaded = 0;
 
        return(db);
 }
-- 
1.7.4


Reply via email to