summaryrefslogtreecommitdiff
path: root/source3/registry
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2018-10-02 13:16:23 +0200
committerJeremy Allison <jra@samba.org>2018-10-08 22:17:09 +0200
commita9ed0e93bbd6cd32ed1d35b1279b401d1755d1e5 (patch)
treea8801ccb8a383894886a01aa495abf07dc574dba /source3/registry
parent2a35cbb02f09e490f2b533849a08100881f12230 (diff)
downloadsamba-a9ed0e93bbd6cd32ed1d35b1279b401d1755d1e5.tar.gz
registry: Add error checks to regdb_unpack_values
This makes "regdb_unpack_values" take a size_t as buflen. The only caller calls it with TDB_DATA.dsize, which *is* size_t. Convert the internal "len" variable to the unsigned size_t as well and add overflow checks. This depends on tdb_unpack to either return -1 or a positive value less than or equal to the passed-in "size_t" buflen; Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/registry')
-rw-r--r--source3/registry/reg_backend_db.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index a0db5eab9ce..32189101e31 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -1833,9 +1833,12 @@ static int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
Unpack a list of registry values frem the TDB
***************************************************************************/
-static int regdb_unpack_values(struct regval_ctr *values, uint8_t *buf, int buflen)
+static int regdb_unpack_values(struct regval_ctr *values,
+ uint8_t *buf,
+ size_t buflen)
{
- int len = 0;
+ int this_len;
+ size_t len = 0;
uint32_t type;
fstring valuename;
uint32_t size;
@@ -1845,7 +1848,13 @@ static int regdb_unpack_values(struct regval_ctr *values, uint8_t *buf, int bufl
/* loop and unpack the rest of the registry values */
- len += tdb_unpack(buf+len, buflen-len, "d", &num_values);
+ this_len = tdb_unpack(buf, buflen, "d", &num_values);
+ if (this_len == -1) {
+ DBG_WARNING("Invalid registry data, "
+ "tdb_unpack failed\n");
+ return -1;
+ }
+ len = this_len;
for ( i=0; i<num_values; i++ ) {
/* unpack the next regval */
@@ -1854,11 +1863,22 @@ static int regdb_unpack_values(struct regval_ctr *values, uint8_t *buf, int bufl
size = 0;
data_p = NULL;
valuename[0] = '\0';
- len += tdb_unpack(buf+len, buflen-len, "fdB",
- valuename,
- &type,
- &size,
- &data_p);
+ this_len = tdb_unpack(buf+len, buflen-len, "fdB",
+ valuename,
+ &type,
+ &size,
+ &data_p);
+ if (this_len == -1) {
+ DBG_WARNING("Invalid registry data, "
+ "tdb_unpack failed\n");
+ return -1;
+ }
+ len += this_len;
+ if (len < (size_t)this_len) {
+ DBG_WARNING("Invalid registry data, "
+ "integer overflow\n");
+ return -1;
+ }
regval_ctr_addvalue(values, valuename, type,
(uint8_t *)data_p, size);