Whamcloud - gitweb
LU-13587 quota: protect qpi in proc
authorSergey Cheremencev <sergey.cheremencev@hpe.com>
Thu, 15 Apr 2021 14:14:51 +0000 (17:14 +0300)
committerAndreas Dilger <adilger@whamcloud.com>
Mon, 21 Mar 2022 19:09:21 +0000 (19:09 +0000)
Access to pool info only when pool is fully inited.
This patch protects from following panic:

    BUG: unable to handle kernel NULL pointer dereference at (null)
    IP: [<ffffffffc0e55e46>] qpi_state_seq_show+0x86/0xe0 [lquota]
    ...
    Call Trace:
    [<ffffffffbbc68b50>] seq_read+0x130/0x440
    [<ffffffffbbcb8380>] proc_reg_read+0x40/0x80
    [<ffffffffbbc4118f>] vfs_read+0x9f/0x170
    [<ffffffffbbc4204f>] SyS_read+0x7f/0xf0
    [<ffffffffbc176ddb>] system_call_fastpath+0x22/0x27

Add test 79 to sanity-quota to check that race between
access to /proc/.../dt-pool_name/info of non-existed pool
with this pool creating doesn't cause a panic.

Lustre-change: https://review.whamcloud.com/43987
Lustre-commit: a11168f46cf01c45a431a804da01cf67e18ecca9

HPE-bug-id: LUS-9938
Change-Id: I8eff846c6c3881a8431a98efb54e660ecb9155bf
Signed-off-by: Sergey Cheremencev <sergey.cheremencev@hpe.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/46658
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
lustre/quota/qmt_internal.h
lustre/quota/qmt_pool.c

index 919876c..286edb1 100644 (file)
@@ -100,6 +100,7 @@ enum {
 enum {
        /* set while recalc_thread is working */
        QPI_FLAG_RECALC_OFFSET,
+       QPI_FLAG_STATE_INITED,
 };
 
 /*
index 37034eb..e31787c 100644 (file)
@@ -79,6 +79,8 @@ static int qpi_state_seq_show(struct seq_file *m, void *data)
        int                      type;
 
        LASSERT(pool != NULL);
+       if (unlikely(!test_bit(QPI_FLAG_STATE_INITED, &pool->qpi_flags)))
+               return -ENOENT;
 
        seq_printf(m, "pool:\n"
                   "    id: %u\n"
@@ -106,6 +108,8 @@ static int qpi_soft_least_qunit_seq_show(struct seq_file *m, void *data)
 {
        struct qmt_pool_info    *pool = m->private;
        LASSERT(pool != NULL);
+       if (unlikely(!test_bit(QPI_FLAG_STATE_INITED, &pool->qpi_flags)))
+               return -ENOENT;
 
        seq_printf(m, "%lu\n", pool->qpi_soft_least_qunit);
        return 0;
@@ -121,6 +125,8 @@ qpi_soft_least_qunit_seq_write(struct file *file, const char __user *buffer,
        int rc;
 
        LASSERT(pool != NULL);
+       if (unlikely(!test_bit(QPI_FLAG_STATE_INITED, &pool->qpi_flags)))
+               return -ENOENT;
 
        /* Not tuneable for inode limit */
        if (pool->qpi_rtype != LQUOTA_RES_DT)
@@ -177,6 +183,7 @@ static int qmt_pool_alloc(const struct lu_env *env, struct qmt_device *qmt,
        init_rwsem(&pool->qpi_recalc_sem);
 
        pool->qpi_rtype = pool_type;
+       pool->qpi_flags = 0;
 
        /* initialize refcount to 1, hash table will then grab an additional
         * reference */
@@ -670,6 +677,7 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
                                      qmt->qmt_svname, PFID(&qti->qti_fid), rc);
 #endif
                }
+               set_bit(QPI_FLAG_STATE_INITED, &pool->qpi_flags);
                if (name)
                        break;
        }