diff --git a/sys/security/mac_do/mac_do.c b/sys/security/mac_do/mac_do.c --- a/sys/security/mac_do/mac_do.c +++ b/sys/security/mac_do/mac_do.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -85,6 +86,24 @@ return (rules); } +/* + * String to non-negative int. + * + * Returns minus an error (EINVAL or EOVERFLOW) in case of failure. + */ +static int +strtonni(const char *const restrict s, char **const restrict endptr, int base) +{ + const long l = strtol(s, endptr, base); + + if (l < 0) + return (-EINVAL); + else if (l == LONG_MAX || l > INT_MAX) + return (-EOVERFLOW); + + return ((int)l); +} + static int parse_rule_element(char *element, struct rule **rule) { @@ -109,7 +128,10 @@ if (from_id == NULL || *from_id == '\0') goto einval; - new->from_id = strtol(from_id, &p, 10); + new->from_id = strtonni(from_id, &p, 10); + if (*p != '\0' || new->from_id < 0) + goto einval; + if (*p != '\0') goto einval; @@ -121,8 +143,8 @@ new->to_type = RULE_ANY; else { new->to_type = RULE_UID; - new->to_id = strtol(to, &p, 10); - if (*p != '\0') + new->to_id = strtonni(to, &p, 10); + if (*p != '\0' || new->to_id < 0) goto einval; }