[exim-cvs] Lookups: fix dbmnz crash on zero-length datum. B…

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Exim Git Commits Mailing List
Ημερομηνία:  
Προς: exim-cvs
Αντικείμενο: [exim-cvs] Lookups: fix dbmnz crash on zero-length datum. Bug 3079
Gitweb: https://git.exim.org/exim.git/commitdiff/a7e6ad0ba38cf088e841c321042f81966d846b4b
Commit:     a7e6ad0ba38cf088e841c321042f81966d846b4b
Parent:     c71f869820b45b911cc8edbd0de88bbc9621fd5f
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sat Mar 16 13:50:45 2024 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sat Mar 16 13:50:45 2024 +0000


    Lookups: fix dbmnz crash on zero-length datum.  Bug 3079


    Broken-by: 6d2c02560e5c
---
 doc/doc-txt/ChangeLog                |   3 +++
 src/src/dbfn.c                       |  12 +++++++-----
 src/src/exim_dbutil.c                |  12 +++++++-----
 src/src/lookups/dbmdb.c              |   5 ++++-
 test/aux-fixed/2302.emptydbmnzlookup | Bin 0 -> 12288 bytes
 test/confs/2302                      |   3 +++
 test/scripts/2300-DBM/2302           |   4 ++++
 test/stdout/2302                     |   1 +
 8 files changed, 29 insertions(+), 11 deletions(-)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 3dc0e5512..a6da95001 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -125,6 +125,9 @@ JH/24 Bug 3081: Fix a delivery process crash.  When the router "errors_to"
       trip on the configuration data being readonly.  Instead of modifying
       in-place, copy data.  Found and fixed by Peter Benie.


+JH/25 Bug 3079: Fix crash in dbmnz.  When a key was present for zero-length
+      data a null pointer was followed.  Find and testcase by Sebastian Bugge.
+


Exim version 4.97
-----------------
diff --git a/src/src/dbfn.c b/src/src/dbfn.c
index 3c51162a4..460fd8bb7 100644
--- a/src/src/dbfn.c
+++ b/src/src/dbfn.c
@@ -239,12 +239,13 @@ Returns: a pointer to the retrieved record, or
*/

void *
-dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length)
+dbfn_read_with_length(open_db * dbblock, const uschar * key, int * length)
{
-void *yield;
+void * yield;
EXIM_DATUM key_datum, result_datum;
int klen = Ustrlen(key) + 1;
uschar * key_copy = store_get(klen, key);
+unsigned dlen;

memcpy(key_copy, key, klen);

@@ -260,9 +261,10 @@ if (!exim_dbget(dbblock->dbptr, &key_datum, &result_datum)) return NULL;
/* Assume the data store could have been tainted. Properly, we should
store the taint status with the data. */

-yield = store_get(exim_datum_size_get(&result_datum), GET_TAINTED);
-memcpy(yield, exim_datum_data_get(&result_datum), exim_datum_size_get(&result_datum));
-if (length) *length = exim_datum_size_get(&result_datum);
+dlen = exim_datum_size_get(&result_datum);
+yield = store_get(dlen, GET_TAINTED);
+memcpy(yield, exim_datum_data_get(&result_datum), dlen);
+if (length) *length = dlen;

 exim_datum_free(&result_datum);    /* Some DBM libs require freeing */
 return yield;
diff --git a/src/src/exim_dbutil.c b/src/src/exim_dbutil.c
index 3f70c2fd5..4d213773b 100644
--- a/src/src/exim_dbutil.c
+++ b/src/src/exim_dbutil.c
@@ -407,12 +407,13 @@ Returns: a pointer to the retrieved record, or
 */


void *
-dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length)
+dbfn_read_with_length(open_db * dbblock, const uschar * key, int * length)
{
-void *yield;
+void * yield;
EXIM_DATUM key_datum, result_datum;
int klen = Ustrlen(key) + 1;
uschar * key_copy = store_get(klen, key);
+unsigned dlen;

memcpy(key_copy, key, klen);

@@ -426,9 +427,10 @@ if (!exim_dbget(dbblock->dbptr, &key_datum, &result_datum)) return NULL;
/* Assume for now that anything stored could have been tainted. Properly
we should store the taint status along with the data. */

-yield = store_get(exim_datum_size_get(&result_datum), GET_TAINTED);
-memcpy(yield, exim_datum_data_get(&result_datum), exim_datum_size_get(&result_datum));
-if (length) *length = exim_datum_size_get(&result_datum);
+dlen = exim_datum_size_get(&result_datum);
+yield = store_get(dlen, GET_TAINTED);
+memcpy(yield, exim_datum_data_get(&result_datum), dlen);
+if (length) *length = dlen;

 exim_datum_free(&result_datum);    /* Some DBM libs require freeing */
 return yield;
diff --git a/src/src/lookups/dbmdb.c b/src/src/lookups/dbmdb.c
index aa930e654..96665b6e4 100644
--- a/src/src/lookups/dbmdb.c
+++ b/src/src/lookups/dbmdb.c
@@ -102,7 +102,8 @@ exim_datum_size_set(&key, length);


 if (exim_dbget(d, &key, &data))
   {
-  *result = string_copyn(exim_datum_data_get(&data), exim_datum_size_get(&data));
+  unsigned len = exim_datum_size_get(&data);
+  *result = len > 0 ? string_copyn(exim_datum_data_get(&data), len) : US"";
   exim_datum_free(&data);            /* Some DBM libraries need a free() call */
   return OK;
   }
@@ -283,3 +284,5 @@ static lookup_info *_lookup_list[] = { &dbm_lookup_info, &dbmz_lookup_info, &dbm
 lookup_module_info dbmdb_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 3 };


/* End of lookups/dbmdb.c */
+/* vi: aw ai sw=2
+*/
diff --git a/test/aux-fixed/2302.emptydbmnzlookup b/test/aux-fixed/2302.emptydbmnzlookup
new file mode 100644
index 000000000..9f64dc3fd
Binary files /dev/null and b/test/aux-fixed/2302.emptydbmnzlookup differ
diff --git a/test/confs/2302 b/test/confs/2302
new file mode 100644
index 000000000..de484356c
--- /dev/null
+++ b/test/confs/2302
@@ -0,0 +1,3 @@
+# Exim test configuration 2302
+.include DIR/aux-var/std_conf_prefix
+# End
diff --git a/test/scripts/2300-DBM/2302 b/test/scripts/2300-DBM/2302
new file mode 100644
index 000000000..4bdbc869e
--- /dev/null
+++ b/test/scripts/2300-DBM/2302
@@ -0,0 +1,4 @@
+# lookup dbmnz
+#
+exim -be '[${lookup{test}dbmnz{DIR/aux-fixed/TESTNUM.emptydbmnzlookup}}]'
+****
diff --git a/test/stdout/2302 b/test/stdout/2302
new file mode 100644
index 000000000..fe51488c7
--- /dev/null
+++ b/test/stdout/2302
@@ -0,0 +1 @@
+[]

--
## subscription configuration (requires account):
## https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/