X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/b10c87b38c2345d15d30da5c18c823355ac506a9..54a2a2a9983913a91ccef3aac107a159434a4714:/src/src/dbfn.c diff --git a/src/src/dbfn.c b/src/src/dbfn.c index a60775681..3aca18326 100644 --- a/src/src/dbfn.c +++ b/src/src/dbfn.c @@ -194,26 +194,29 @@ but creation of the database file failed. */ if (created && geteuid() == root_uid) { - DIR *dd; - struct dirent *ent; + DIR * dd; uschar *lastname = Ustrrchr(filename, '/') + 1; int namelen = Ustrlen(name); *lastname = 0; - dd = opendir(CS filename); - while ((ent = readdir(dd))) - if (Ustrncmp(ent->d_name, name, namelen) == 0) - { - struct stat statbuf; - Ustrcpy(lastname, ent->d_name); - if (Ustat(filename, &statbuf) >= 0 && statbuf.st_uid != exim_uid) - { - DEBUG(D_hints_lookup) debug_printf_indent("ensuring %s is owned by exim\n", filename); - if (exim_chown(filename, exim_uid, exim_gid)) - DEBUG(D_hints_lookup) debug_printf_indent("failed setting %s to owned by exim\n", filename); - } - } + if ((dd = exim_opendir(filename))) + for (struct dirent *ent; ent = readdir(dd); ) + if (Ustrncmp(ent->d_name, name, namelen) == 0) + { + struct stat statbuf; + /* Filenames from readdir() are trusted, + so use a taint-nonchecking copy */ + strcpy(CS lastname, CCS ent->d_name); + if (Ustat(filename, &statbuf) >= 0 && statbuf.st_uid != exim_uid) + { + DEBUG(D_hints_lookup) + debug_printf_indent("ensuring %s is owned by exim\n", filename); + if (exim_chown(filename, exim_uid, exim_gid)) + DEBUG(D_hints_lookup) + debug_printf_indent("failed setting %s to owned by exim\n", filename); + } + } closedir(dd); } @@ -303,7 +306,7 @@ dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length) void *yield; EXIM_DATUM key_datum, result_datum; int klen = Ustrlen(key) + 1; -uschar * key_copy = store_get(klen); +uschar * key_copy = store_get(klen, is_tainted(key)); memcpy(key_copy, key, klen); @@ -316,7 +319,10 @@ EXIM_DATUM_SIZE(key_datum) = klen; if (!EXIM_DBGET(dbblock->dbptr, key_datum, result_datum)) return NULL; -yield = store_get(EXIM_DATUM_SIZE(result_datum)); +/* Assume the data store could have been tainted. Properly, we should +store the taint status with the data. */ + +yield = store_get(EXIM_DATUM_SIZE(result_datum), TRUE); memcpy(yield, EXIM_DATUM_DATA(result_datum), EXIM_DATUM_SIZE(result_datum)); if (length != NULL) *length = EXIM_DATUM_SIZE(result_datum); @@ -347,7 +353,7 @@ dbfn_write(open_db *dbblock, const uschar *key, void *ptr, int length) EXIM_DATUM key_datum, value_datum; dbdata_generic *gptr = (dbdata_generic *)ptr; int klen = Ustrlen(key) + 1; -uschar * key_copy = store_get(klen); +uschar * key_copy = store_get(klen, is_tainted(key)); memcpy(key_copy, key, klen); gptr->time_stamp = time(NULL); @@ -381,7 +387,7 @@ int dbfn_delete(open_db *dbblock, const uschar *key) { int klen = Ustrlen(key) + 1; -uschar * key_copy = store_get(klen); +uschar * key_copy = store_get(klen, is_tainted(key)); DEBUG(D_hints_lookup) debug_printf_indent("dbfn_delete: key=%s\n", key);