On 1/21/25 03:17, Dan Carpenter wrote:
[ I don't know why this static checker warning is showing up only now
   two years later...  -dan ]

Hello John Johansen,

Commit 2e12c5f06017 ("apparmor: add additional flags to extended
permission.") from Jul 23, 2023 (linux-next), leads to the following
Smatch static checker warning:


because while it is an old commit it sat in other branches and dev
trees, while the stuff that depends on it was revised, and that stuff is
just recently starting to be merged in.

Thanks for the report, I see if I can't get this fixed today

security/apparmor/policy_unpack.c:780 unpack_pdb()
error: we previously assumed 'pdb->dfa' could be null (see line 753)

security/apparmor/policy_unpack.c
     712 static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy,
     713                       bool required_dfa, bool required_trans,
     714                       const char **info)
     715 {
     716         struct aa_policydb *pdb;
     717         void *pos = e->pos;
     718         int i, flags, error = -EPROTO;
     719         ssize_t size;
     720         u32 version = 0;
     721
     722         pdb = aa_alloc_pdb(GFP_KERNEL);
     723         if (!pdb)
     724                 return -ENOMEM;
     725
     726         size = unpack_perms_table(e, &pdb->perms);
     727         if (size < 0) {
     728                 error = size;
     729                 pdb->perms = NULL;
     730                 *info = "failed to unpack - perms";
     731                 goto fail;
     732         }
     733         pdb->size = size;
     734
     735         if (pdb->perms) {
     736                 /* perms table present accept is index */
     737                 flags = TO_ACCEPT1_FLAG(YYTD_DATA32);
     738                 if (aa_unpack_u32(e, &version, "permsv") && version > 
2)
     739                         /* accept2 used for dfa flags */
     740                         flags |= TO_ACCEPT2_FLAG(YYTD_DATA32);
     741         } else {
     742                 /* packed perms in accept1 and accept2 */
     743                 flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
     744                         TO_ACCEPT2_FLAG(YYTD_DATA32);
     745         }
     746
     747         pdb->dfa = unpack_dfa(e, flags);
     748         if (IS_ERR(pdb->dfa)) {
     749                 error = PTR_ERR(pdb->dfa);
     750                 pdb->dfa = NULL;
     751                 *info = "failed to unpack - dfa";
     752                 goto fail;
     753         } else if (!pdb->dfa) {
     754                 if (required_dfa) {
     755                         *info = "missing required dfa";
     756                         goto fail;
     757                 }

Assume required_dfa is false.


     758         } else {
     759                 /*
     760                  * only unpack the following if a dfa is present
     761                  *
     762                  * sadly start was given different names for file and 
policydb
     763                  * but since it is optional we can try both
     764                  */
     765                 if (!aa_unpack_u32(e, &pdb->start[0], "start"))
     766                         /* default start state */
     767                         pdb->start[0] = DFA_START;
     768                 if (!aa_unpack_u32(e, &pdb->start[AA_CLASS_FILE], 
"dfa_start")) {
     769                         /* default start state for xmatch and file dfa 
*/
     770                         pdb->start[AA_CLASS_FILE] = DFA_START;
     771                 }        /* setup class index */
     772                 for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) {
     773                         pdb->start[i] = aa_dfa_next(pdb->dfa, 
pdb->start[0],
     774                                                     i);
     775                 }
     776         }
     777
     778         if (pdb->perms && version <= 2) {
     779                 /* add dfa flags table missing in v2 */
--> 780                 u32 noents = pdb->dfa->tables[YYTD_ID_ACCEPT]->td_lolen;
                                      ^^^^^^^^^^
Potential NULL pointer dereference

     781                 u16 tdflags = 
pdb->dfa->tables[YYTD_ID_ACCEPT]->td_flags;
     782                 size_t tsize = table_size(noents, tdflags);
     783
     784                 pdb->dfa->tables[YYTD_ID_ACCEPT2] = kvzalloc(tsize, 
GFP_KERNEL);
     785                 if (!pdb->dfa->tables[YYTD_ID_ACCEPT2]) {
     786                         *info = "failed to alloc dfa flags table";
     787                         goto out;
     788                 }
     789                 pdb->dfa->tables[YYTD_ID_ACCEPT2]->td_lolen = noents;
     790                 pdb->dfa->tables[YYTD_ID_ACCEPT2]->td_flags = tdflags;
     791         }
     792         /*
     793          * Unfortunately due to a bug in earlier userspaces, a
     794          * transition table may be present even when the dfa is
     795          * not. For compatibility reasons unpack and discard.
     796          */
     797         if (!unpack_trans_table(e, &pdb->trans) && required_trans) {
     798                 *info = "failed to unpack profile transition table";
     799                 goto fail;
     800         }
     801
     802         if (!pdb->dfa && pdb->trans.table)
     803                 aa_free_str_table(&pdb->trans);
     804
     805         /* TODO: move compat mapping here, requires dfa merging first 
*/
     806         /* TODO: move verify here, it has to be done after compat 
mappings */
     807 out:
     808         *policy = pdb;
     809         return 0;
     810
     811 fail:
     812         aa_put_pdb(pdb);
     813         e->pos = pos;
     814         return error;
     815 }

regards,
dan carpenter


Reply via email to