diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 3d701084eac6990b597588eaf69e3bf3cabbb93c..000d13ab1a2d738e8c4c584c9019789fa7281b9c 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -106,8 +106,8 @@ struct ima_iint_cache { unsigned long flags; u8 digest[IMA_DIGEST_SIZE]; struct mutex mutex; /* protects: version, flags, digest */ - long readcount; /* measured files readcount */ - long writecount; /* measured files writecount */ + unsigned int readcount; /* measured files readcount */ + unsigned int writecount;/* measured files writecount */ struct kref refcount; /* ima_iint_cache reference count */ }; diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index 8e64313ed182c18898305225bad72c3b1c55eaa5..db71a13f27fe1bb21a023041726e56c09599b4ae 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c @@ -125,12 +125,12 @@ void iint_free(struct kref *kref) iint->version = 0; iint->flags = 0UL; if (iint->readcount != 0) { - printk(KERN_INFO "%s: readcount: %ld\n", __func__, + printk(KERN_INFO "%s: readcount: %u\n", __func__, iint->readcount); iint->readcount = 0; } if (iint->writecount != 0) { - printk(KERN_INFO "%s: writecount: %ld\n", __func__, + printk(KERN_INFO "%s: writecount: %u\n", __func__, iint->writecount); iint->writecount = 0; } diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 995bd1b98fa8cc0d3cad7839f51b51c369a7f9b4..5a1bf3df11f832c3bbebe397cb46fe4f6cf63264 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -178,11 +178,18 @@ static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode, struct file *file) { mode_t mode = file->f_mode; + bool dump = false; + BUG_ON(!mutex_is_locked(&iint->mutex)); - if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) + if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { + if (unlikely(iint->readcount == 0)) + dump = true; iint->readcount--; + } if (mode & FMODE_WRITE) { + if (unlikely(iint->writecount == 0)) + dump = true; iint->writecount--; if (iint->writecount == 0) { if (iint->version != inode->i_version) @@ -190,10 +197,8 @@ static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode, } } - if (((iint->readcount < 0) || - (iint->writecount < 0)) && - !ima_limit_imbalance(file)) { - printk(KERN_INFO "%s: open/free imbalance (r:%ld w:%ld)\n", + if (dump && !ima_limit_imbalance(file)) { + printk(KERN_INFO "%s: open/free imbalance (r:%u w:%u)\n", __func__, iint->readcount, iint->writecount); dump_stack(); }