Skip to content

Commit

Permalink
common-lib: Use wrapper for string to integer conversion
Browse files Browse the repository at this point in the history
In order to detect an value overflow error during
the string to integer conversion with strtoul/strtoull,
the errno variable must be set to zero before the execution and
checked after the conversion is performed. This is achieved by
using the wrapper function strtoul_err and strtoull_err.

Signed-off-by: Swen Schillig <[email protected]>
Reviewed-by: Ralph Böhme <[email protected]>
Reviewed-by: Jeremy Allison <[email protected]>
  • Loading branch information
sswen authored and jrasamba committed Mar 1, 2019
1 parent ebeae5d commit e7b7c63
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 23 deletions.
23 changes: 18 additions & 5 deletions lib/ldb-samba/ldb_matching_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,16 +383,22 @@ static int dsdb_match_for_dns_to_tombstone_time(struct ldb_context *ldb,
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
} else {
char *p = NULL;
int error = 0;
char s[value_to_match->length+1];

memcpy(s, value_to_match->data, value_to_match->length);
s[value_to_match->length] = 0;
if (s[0] == '\0' || s[0] == '-') {
DBG_ERR("Empty timestamp passed\n");
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
}
tombstone_time = strtoull(s, &p, 10);
if (p == NULL || p == s || *p != '\0' ||
tombstone_time == ULLONG_MAX) {
tombstone_time = strtoull_err(s, &p, 10, &error);
if (p == NULL ||
p == s ||
*p != '\0' ||
error != 0 ||
tombstone_time == ULLONG_MAX)
{
DBG_ERR("Invalid timestamp string passed\n");
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
}
Expand Down Expand Up @@ -514,14 +520,21 @@ static int dsdb_match_for_expunge(struct ldb_context *ldb,
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
} else {
char *p = NULL;
int error = 0;
char s[value_to_match->length+1];

memcpy(s, value_to_match->data, value_to_match->length);
s[value_to_match->length] = 0;
if (s[0] == '\0' || s[0] == '-') {
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
}
tombstone_time = strtoull(s, &p, 10);
if (p == NULL || p == s || *p != '\0' || tombstone_time == ULLONG_MAX) {
tombstone_time = strtoull_err(s, &p, 10, &error);
if (p == NULL ||
p == s ||
*p != '\0' ||
error != 0 ||
tombstone_time == ULLONG_MAX)
{
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
}
}
Expand Down
7 changes: 5 additions & 2 deletions lib/ldb-samba/ldif_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,8 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,

line = string;
while (line && line[0]) {
int error = 0;

p=strchr(line, ';');
if (p) {
p[0] = '\0';
Expand All @@ -619,9 +621,10 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
return -1;
}

blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].id_prefix = strtoul(line, &oid, 10);
blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].id_prefix =
strtoul_err(line, &oid, 10, &error);

if (oid[0] != ':') {
if (oid[0] != ':' || error != 0) {
talloc_free(tmp_ctx);
return -1;
}
Expand Down
24 changes: 20 additions & 4 deletions lib/param/loadparm.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,27 +331,43 @@ int lp_int(const char *s)
*/
unsigned long lp_ulong(const char *s)
{
int error = 0;
unsigned long int ret;

if (!s || !*s) {
DEBUG(0,("lp_ulong(%s): is called with NULL!\n",s));
DBG_DEBUG("lp_ulong(%s): is called with NULL!\n",s);
return -1;
}

return strtoul(s, NULL, 0);
ret = strtoul_err(s, NULL, 0, &error);
if (error != 0) {
DBG_DEBUG("lp_ulong(%s): conversion failed\n",s);
return -1;
}

return ret;
}

/**
* convenience routine to return unsigned long long parameters.
*/
unsigned long long lp_ulonglong(const char *s)
{
int error = 0;
unsigned long long int ret;

if (!s || !*s) {
DEBUG(0, ("lp_ulonglong(%s): is called with NULL!\n", s));
DBG_DEBUG("lp_ulonglong(%s): is called with NULL!\n", s);
return -1;
}

return strtoull(s, NULL, 0);
ret = strtoull_err(s, NULL, 0, &error);
if (error != 0) {
DBG_DEBUG("lp_ulonglong(%s): conversion failed\n",s);
return -1;
}

return ret;
}

/**
Expand Down
7 changes: 5 additions & 2 deletions lib/util/access.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,11 @@ static bool masked_match(const char *tok, const char *slash, const char *s)
}
} else {
char *endp = NULL;
unsigned long val = strtoul(slash+1, &endp, 0);
if (slash+1 == endp || (endp && *endp != '\0')) {
int error = 0;
unsigned long val;

val = strtoul_err(slash+1, &endp, 0, &error);
if (slash+1 == endp || (endp && *endp != '\0') || error != 0) {
return false;
}
if (!make_netmask(&ss_mask, &ss_tok, val)) {
Expand Down
17 changes: 11 additions & 6 deletions lib/util/asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,15 +273,20 @@ bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
const char *p = (const char *)OID;
char *newp;
int i;
int error = 0;

if (!isdigit(*p)) return false;
v = strtoul(p, &newp, 10);
if (newp[0] != '.') return false;
v = strtoul_err(p, &newp, 10, &error);
if (newp[0] != '.' || error != 0) {
return false;
}
p = newp + 1;

if (!isdigit(*p)) return false;
v2 = strtoul(p, &newp, 10);
if (newp[0] != '.') return false;
v2 = strtoul_err(p, &newp, 10, &error);
if (newp[0] != '.' || error != 0) {
return false;
}
p = newp + 1;

/*the ber representation can't use more space than the string one */
Expand All @@ -293,8 +298,8 @@ bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
i = 1;
while (*p) {
if (!isdigit(*p)) return false;
v = strtoul(p, &newp, 10);
if (newp[0] == '.') {
v = strtoul_err(p, &newp, 10, &error);
if (newp[0] == '.' || error != 0) {
p = newp + 1;
/* check for empty last component */
if (!*p) return false;
Expand Down
10 changes: 6 additions & 4 deletions lib/util/util_str.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,14 @@ _PUBLIC_ bool conv_str_size_error(const char * str, uint64_t * val)
{
char * end = NULL;
unsigned long long lval;
int error = 0;

if (str == NULL || *str == '\0') {
return false;
}

lval = strtoull(str, &end, 10 /* base */);
if (end == NULL || end == str) {
lval = strtoull_err(str, &end, 10, &error);
if (end == NULL || end == str || error != 0) {
return false;
}

Expand Down Expand Up @@ -104,13 +105,14 @@ _PUBLIC_ bool conv_str_u64(const char * str, uint64_t * val)
{
char * end = NULL;
unsigned long long lval;
int error = 0;

if (str == NULL || *str == '\0') {
return false;
}

lval = strtoull(str, &end, 10 /* base */);
if (end == NULL || *end != '\0' || end == str) {
lval = strtoull_err(str, &end, 10, &error);
if (end == NULL || *end != '\0' || end == str || error != 0) {
return false;
}

Expand Down

0 comments on commit e7b7c63

Please sign in to comment.