pstore: inode: Convert mutex usage to guard(mutex)
authorKees Cook <keescook@chromium.org>
Tue, 5 Dec 2023 18:26:15 +0000 (10:26 -0800)
committerKees Cook <keescook@chromium.org>
Fri, 8 Dec 2023 22:15:44 +0000 (14:15 -0800)
Replace open-coded mutex handling with cleanup.h guard(mutex) and
scoped_guard(mutex, ...).

Cc: Guilherme G. Piccoli <gpiccoli@igalia.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: <linux-hardening@vger.kernel.org>
Link: https://lore.kernel.org/r/20231205182622.1329923-2-keescook@chromium.org
Signed-off-by: Kees Cook <keescook@chromium.org>
fs/pstore/inode.c

index 20f3452c8196022bc1a6b1f5e87c48589eed181e..0d89e0014b6f0453a770a1b4f17188d50a34c69a 100644 (file)
@@ -180,25 +180,21 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry)
 {
        struct pstore_private *p = d_inode(dentry)->i_private;
        struct pstore_record *record = p->record;
-       int rc = 0;
 
        if (!record->psi->erase)
                return -EPERM;
 
        /* Make sure we can't race while removing this file. */
-       mutex_lock(&records_list_lock);
-       if (!list_empty(&p->list))
-               list_del_init(&p->list);
-       else
-               rc = -ENOENT;
-       p->dentry = NULL;
-       mutex_unlock(&records_list_lock);
-       if (rc)
-               return rc;
-
-       mutex_lock(&record->psi->read_mutex);
-       record->psi->erase(record);
-       mutex_unlock(&record->psi->read_mutex);
+       scoped_guard(mutex, &records_list_lock) {
+               if (!list_empty(&p->list))
+                       list_del_init(&p->list);
+               else
+                       return -ENOENT;
+               p->dentry = NULL;
+       }
+
+       scoped_guard(mutex, &record->psi->read_mutex)
+               record->psi->erase(record);
 
        return simple_unlink(dir, dentry);
 }
@@ -290,19 +286,16 @@ static struct dentry *psinfo_lock_root(void)
 {
        struct dentry *root;
 
-       mutex_lock(&pstore_sb_lock);
+       guard(mutex)(&pstore_sb_lock);
        /*
         * Having no backend is fine -- no records appear.
         * Not being mounted is fine -- nothing to do.
         */
-       if (!psinfo || !pstore_sb) {
-               mutex_unlock(&pstore_sb_lock);
+       if (!psinfo || !pstore_sb)
                return NULL;
-       }
 
        root = pstore_sb->s_root;
        inode_lock(d_inode(root));
-       mutex_unlock(&pstore_sb_lock);
 
        return root;
 }
@@ -317,19 +310,19 @@ int pstore_put_backend_records(struct pstore_info *psi)
        if (!root)
                return 0;
 
-       mutex_lock(&records_list_lock);
-       list_for_each_entry_safe(pos, tmp, &records_list, list) {
-               if (pos->record->psi == psi) {
-                       list_del_init(&pos->list);
-                       rc = simple_unlink(d_inode(root), pos->dentry);
-                       if (WARN_ON(rc))
-                               break;
-                       d_drop(pos->dentry);
-                       dput(pos->dentry);
-                       pos->dentry = NULL;
+       scoped_guard(mutex, &records_list_lock) {
+               list_for_each_entry_safe(pos, tmp, &records_list, list) {
+                       if (pos->record->psi == psi) {
+                               list_del_init(&pos->list);
+                               rc = simple_unlink(d_inode(root), pos->dentry);
+                               if (WARN_ON(rc))
+                                       break;
+                               d_drop(pos->dentry);
+                               dput(pos->dentry);
+                               pos->dentry = NULL;
+                       }
                }
        }
-       mutex_unlock(&records_list_lock);
 
        inode_unlock(d_inode(root));
 
@@ -353,20 +346,20 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
        if (WARN_ON(!inode_is_locked(d_inode(root))))
                return -EINVAL;
 
-       rc = -EEXIST;
+       guard(mutex)(&records_list_lock);
+
        /* Skip records that are already present in the filesystem. */
-       mutex_lock(&records_list_lock);
        list_for_each_entry(pos, &records_list, list) {
                if (pos->record->type == record->type &&
                    pos->record->id == record->id &&
                    pos->record->psi == record->psi)
-                       goto fail;
+                       return -EEXIST;
        }
 
        rc = -ENOMEM;
        inode = pstore_get_inode(root->d_sb);
        if (!inode)
-               goto fail;
+               return -ENOMEM;
        inode->i_mode = S_IFREG | 0444;
        inode->i_fop = &pstore_file_operations;
        scnprintf(name, sizeof(name), "%s-%s-%llu%s",
@@ -394,7 +387,6 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record)
        d_add(dentry, inode);
 
        list_add(&private->list, &records_list);
-       mutex_unlock(&records_list_lock);
 
        return 0;
 
@@ -402,8 +394,6 @@ fail_private:
        free_pstore_private(private);
 fail_inode:
        iput(inode);
-fail:
-       mutex_unlock(&records_list_lock);
        return rc;
 }
 
@@ -449,9 +439,8 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent)
        if (!sb->s_root)
                return -ENOMEM;
 
-       mutex_lock(&pstore_sb_lock);
-       pstore_sb = sb;
-       mutex_unlock(&pstore_sb_lock);
+       scoped_guard(mutex, &pstore_sb_lock)
+               pstore_sb = sb;
 
        pstore_get_records(0);
 
@@ -466,17 +455,14 @@ static struct dentry *pstore_mount(struct file_system_type *fs_type,
 
 static void pstore_kill_sb(struct super_block *sb)
 {
-       mutex_lock(&pstore_sb_lock);
+       guard(mutex)(&pstore_sb_lock);
        WARN_ON(pstore_sb && pstore_sb != sb);
 
        kill_litter_super(sb);
        pstore_sb = NULL;
 
-       mutex_lock(&records_list_lock);
+       guard(mutex)(&records_list_lock);
        INIT_LIST_HEAD(&records_list);
-       mutex_unlock(&records_list_lock);
-
-       mutex_unlock(&pstore_sb_lock);
 }
 
 static struct file_system_type pstore_fs_type = {