The branch main has been updated by olce:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=add521c1a5d21ec84454009d42d1dcd688d77008

commit add521c1a5d21ec84454009d42d1dcd688d77008
Author:     Olivier Certner <o...@freebsd.org>
AuthorDate: 2024-07-03 14:13:33 +0000
Commit:     Olivier Certner <o...@freebsd.org>
CommitDate: 2024-12-16 14:42:35 +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
---
 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);
 }
 

Reply via email to