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.

[1] https://gitlab.com/apparmor/apparmor/-/issues/592

Signed-off-by: Maxime Bélair <[email protected]>
---
 security/apparmor/match.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/security/apparmor/match.c b/security/apparmor/match.c
index bbeb3be68572..6cca29c1f209 100644
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -33,7 +33,7 @@
  */
 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;
 }
 
 /**
@@ -343,8 +344,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:
-- 
2.51.0


Reply via email to