aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Certner <olce@FreeBSD.org>2024-07-03 14:13:33 +0000
committerOlivier Certner <olce@FreeBSD.org>2024-12-16 14:42:35 +0000
commitadd521c1a5d21ec84454009d42d1dcd688d77008 (patch)
tree50bf4a81fe2b84e76750220eeb68b0722441900f
parent73cecc0ef78e49295cd9cd8df1bf271f5b8c437d (diff)
MAC/do: parse_rule_element(): Fix a panic, harden, simplify
The panic is caused by dereferencing 'element' at a point where it can be NULL (if string ends at the ':'). Harden and simplify by enforcing the control flow rule in this function that jumping to the end is reserved for error cases. Reviewed by: bapt Approved by: markj (mentor) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D47605
-rw-r--r--sys/security/mac_do/mac_do.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/sys/security/mac_do/mac_do.c b/sys/security/mac_do/mac_do.c
index cb166cfd6128..3327711fa9b9 100644
--- a/sys/security/mac_do/mac_do.c
+++ b/sys/security/mac_do/mac_do.c
@@ -94,7 +94,7 @@ parse_rule_element(char *element, struct rule **rule)
type = strsep(&element, "=");
if (type == NULL) {
error = EINVAL;
- goto out;
+ goto error;
}
if (strcmp(type, "uid") == 0) {
new->from_type = RULE_UID;
@@ -102,24 +102,30 @@ parse_rule_element(char *element, struct rule **rule)
new->from_type = RULE_GID;
} else {
error = EINVAL;
- goto out;
+ goto error;
}
id = strsep(&element, ":");
if (id == NULL) {
error = EINVAL;
- goto out;
+ goto error;
}
- if (new->from_type == RULE_UID)
+ switch (new->from_type) {
+ case RULE_UID:
new->f_uid = strtol(id, &p, 10);
- if (new->from_type == RULE_GID)
+ break;
+ case RULE_GID:
new->f_gid = strtol(id, &p, 10);
+ break;
+ default:
+ __assert_unreachable();
+ }
if (*p != '\0') {
error = EINVAL;
- goto out;
+ goto error;
}
- if (*element == '\0') {
+ if (element == NULL || *element == '\0') {
error = EINVAL;
- goto out;
+ goto error;
}
if (strcmp(element, "any") == 0 || strcmp(element, "*") == 0) {
new->to_type = RULE_ANY;
@@ -128,15 +134,17 @@ parse_rule_element(char *element, struct rule **rule)
new->t_uid = strtol(element, &p, 10);
if (*p != '\0') {
error = EINVAL;
- goto out;
+ goto error;
}
}
-out:
- if (error != 0) {
- free(new, M_DO);
- *rule = NULL;
- } else
- *rule = new;
+
+ MPASS(error == 0);
+ *rule = new;
+ return (0);
+error:
+ MPASS(error != 0);
+ free(new, M_DO);
+ *rule = NULL;
return (error);
}