git: 6b76b0f95c62 - stable/14 - MAC/do: parse_rule_element(): Fix a panic, harden, simplify
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 03 Apr 2025 19:32:08 UTC
The branch stable/14 has been updated by olce:
URL: https://cgit.FreeBSD.org/src/commit/?id=6b76b0f95c6255237a462eb20bf7966e3e7e35a9
commit 6b76b0f95c6255237a462eb20bf7966e3e7e35a9
Author: Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2024-07-03 14:13:33 +0000
Commit: Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-04-03 19:30:59 +0000
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
(cherry picked from commit add521c1a5d21ec84454009d42d1dcd688d77008)
---
sys/security/mac_do/mac_do.c | 38 +++++++++++++++++++++++---------------
1 file 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);
}