]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
apparmor: propagate -ENOMEM correctly in unpack_table
authorMaxime Bélair <maxime.belair@canonical.com>
Wed, 11 Feb 2026 13:19:32 +0000 (14:19 +0100)
committerJohn Johansen <john.johansen@canonical.com>
Sun, 14 Jun 2026 03:14:06 +0000 (20:14 -0700)
Currently, if the `kvzalloc` in `unpack_table` fails, it returns NULL.
This is masked by `aa_dfa_unpack` which interprets NULL as a -EPROTO,
leading to confusing error messages in `apparmor_parser` [1].

The fixed behavior correctly propagates -ENOMEM on allocation failure.

Link: https://gitlab.com/apparmor/apparmor/-/issues/592
Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
security/apparmor/match.c

index 3a2c6cf02b3c7ee89ad40c564ef5453380eda3f4..d43ff34d705cfb629c50079cdbd9d057a4d7636f 100644 (file)
  * @blob: data to unpack (NOT NULL)
  * @bsize: size of blob
  *
- * Returns: pointer to table else NULL on failure
+ * Returns: pointer to table else ERR_PTR on failure
  *
  * NOTE: must be freed by kvfree (not kfree)
  */
 static struct table_header *unpack_table(char *blob, size_t bsize)
 {
-       struct table_header *table = NULL;
+       struct table_header *table = ERR_PTR(-EPROTO);
        struct table_header th;
        size_t tsize;
 
@@ -74,20 +74,21 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
                else if (th.td_flags == YYTD_DATA32)
                        UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
                                     u32, __be32, get_unaligned_be32);
-               else
-                       goto fail;
+               else {
+                       kvfree(table);
+                       table = ERR_PTR(-EPROTO);
+                       goto out;
+               }
                /* if table was vmalloced make sure the page tables are synced
                 * before it is used, as it goes live to all cpus.
                 */
                if (is_vmalloc_addr(table))
                        vm_unmap_aliases();
-       }
+       } else
+               table = ERR_PTR(-ENOMEM);
 
 out:
        return table;
-fail:
-       kvfree(table);
-       return NULL;
 }
 
 /**
@@ -359,8 +360,11 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
 
        while (size > 0) {
                table = unpack_table(data, size);
-               if (!table)
+               if (IS_ERR(table)) {
+                       error = PTR_ERR(table);
+                       table = NULL;
                        goto fail;
+               }
 
                switch (table->td_id) {
                case YYTD_ID_ACCEPT: