Merge tag 'fs.vfsuid.ima.v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 21 Dec 2022 16:13:01 +0000 (08:13 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 21 Dec 2022 16:13:01 +0000 (08:13 -0800)
Pull vfsuid cleanup from Christian Brauner:
 "This moves the ima specific vfs{g,u}id_t comparison helpers out of the
  header and into the one file in ima where they are used.

  We shouldn't incentivize people to use them by placing them into the
  header. As discussed and suggested by Linus in [1] let's just define
  them locally in the one file in ima where they are used"

Link: https://lore.kernel.org/lkml/CAHk-=wj4BpEwUd=OkTv1F9uykvSrsBNZJVHMp+p_+e2kiV71_A@mail.gmail.com
* tag 'fs.vfsuid.ima.v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/idmapping:
  mnt_idmapping: move ima-only helpers to ima

1  2 
security/integrity/ima/ima_policy.c

@@@ -71,6 -71,30 +71,30 @@@ struct ima_rule_opt_list 
        char *items[];
  };
  
+ /*
+  * These comparators are needed nowhere outside of ima so just define them here.
+  * This pattern should hopefully never be needed outside of ima.
+  */
+ static inline bool vfsuid_gt_kuid(vfsuid_t vfsuid, kuid_t kuid)
+ {
+       return __vfsuid_val(vfsuid) > __kuid_val(kuid);
+ }
+ static inline bool vfsgid_gt_kgid(vfsgid_t vfsgid, kgid_t kgid)
+ {
+       return __vfsgid_val(vfsgid) > __kgid_val(kgid);
+ }
+ static inline bool vfsuid_lt_kuid(vfsuid_t vfsuid, kuid_t kuid)
+ {
+       return __vfsuid_val(vfsuid) < __kuid_val(kuid);
+ }
+ static inline bool vfsgid_lt_kgid(vfsgid_t vfsgid, kgid_t kgid)
+ {
+       return __vfsgid_val(vfsgid) < __kgid_val(kgid);
+ }
  struct ima_rule_entry {
        struct list_head list;
        int action;
@@@ -398,6 -422,12 +422,6 @@@ static struct ima_rule_entry *ima_lsm_c
  
                nentry->lsm[i].type = entry->lsm[i].type;
                nentry->lsm[i].args_p = entry->lsm[i].args_p;
 -              /*
 -               * Remove the reference from entry so that the associated
 -               * memory will not be freed during a later call to
 -               * ima_lsm_free_rule(entry).
 -               */
 -              entry->lsm[i].args_p = NULL;
  
                ima_filter_rule_init(nentry->lsm[i].type, Audit_equal,
                                     nentry->lsm[i].args_p,
  
  static int ima_lsm_update_rule(struct ima_rule_entry *entry)
  {
 +      int i;
        struct ima_rule_entry *nentry;
  
        nentry = ima_lsm_copy_rule(entry);
         * references and the entry itself. All other memory references will now
         * be owned by nentry.
         */
 -      ima_lsm_free_rule(entry);
 +      for (i = 0; i < MAX_LSM_RULES; i++)
 +              ima_filter_rule_free(entry->lsm[i].rule);
        kfree(entry);
  
        return 0;
@@@ -545,9 -573,6 +569,9 @@@ static bool ima_match_rules(struct ima_
                            const char *func_data)
  {
        int i;
 +      bool result = false;
 +      struct ima_rule_entry *lsm_rule = rule;
 +      bool rule_reinitialized = false;
  
        if ((rule->flags & IMA_FUNC) &&
            (rule->func != func && func != POST_SETATTR))
                int rc = 0;
                u32 osid;
  
 -              if (!rule->lsm[i].rule) {
 -                      if (!rule->lsm[i].args_p)
 +              if (!lsm_rule->lsm[i].rule) {
 +                      if (!lsm_rule->lsm[i].args_p)
                                continue;
                        else
                                return false;
                }
 +
 +retry:
                switch (i) {
                case LSM_OBJ_USER:
                case LSM_OBJ_ROLE:
                case LSM_OBJ_TYPE:
                        security_inode_getsecid(inode, &osid);
 -                      rc = ima_filter_rule_match(osid, rule->lsm[i].type,
 +                      rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type,
                                                   Audit_equal,
 -                                                 rule->lsm[i].rule);
 +                                                 lsm_rule->lsm[i].rule);
                        break;
                case LSM_SUBJ_USER:
                case LSM_SUBJ_ROLE:
                case LSM_SUBJ_TYPE:
 -                      rc = ima_filter_rule_match(secid, rule->lsm[i].type,
 +                      rc = ima_filter_rule_match(secid, lsm_rule->lsm[i].type,
                                                   Audit_equal,
 -                                                 rule->lsm[i].rule);
 +                                                 lsm_rule->lsm[i].rule);
                        break;
                default:
                        break;
                }
 -              if (!rc)
 -                      return false;
 +
 +              if (rc == -ESTALE && !rule_reinitialized) {
 +                      lsm_rule = ima_lsm_copy_rule(rule);
 +                      if (lsm_rule) {
 +                              rule_reinitialized = true;
 +                              goto retry;
 +                      }
 +              }
 +              if (!rc) {
 +                      result = false;
 +                      goto out;
 +              }
 +      }
 +      result = true;
 +
 +out:
 +      if (rule_reinitialized) {
 +              for (i = 0; i < MAX_LSM_RULES; i++)
 +                      ima_filter_rule_free(lsm_rule->lsm[i].rule);
 +              kfree(lsm_rule);
        }
 -      return true;
 +      return result;
  }
  
  /*