Whamcloud - gitweb
LU-14740 llite: avoid project quota overflow
authorWang Shilong <wshilong@ddn.com>
Wed, 28 Jul 2021 02:31:17 +0000 (10:31 +0800)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 23 Sep 2021 03:55:06 +0000 (03:55 +0000)
Currently, project ID is stored as u32, max possible
value for it is 4294967295.

However, VFS reserve max value for special usage, see
following function:

  static inline bool
  qid_has_mapping(struct user_namespace *ns, struct kqid qid)
  {
          return from_kqid(ns, qid) != (qid_t) -1;
  }

So qid_has_mapping() could return 0 for id 4294967295.
A further try on chown test:

  $ chown 4294967295:4294967295 c.sh
  chown: invalid user: "4294967295:4294967295"
  $ chown 4294967294:4294967294 c.sh

Fix to check max possible value for project ID in the
client kernel side, and add a test case for this.

Lustre-change: https://review.whamcloud.com/43939
Lustre-commit: 3ffa5d680f0092ae51ffa84bd94a9983f9a8c99e

Test-Parameters: trivial testlist=sanity-quota
Fixes: 7b5c1f1404c3 ("LU-13845 utils: Quota id 0xFFFFFFFF is invalid")
Signed-off-by: Wang Shilong <wshilong@ddn.com>
Change-Id: Ide8b9cc79d9b7f2a8b9860a0c0f683ec903b8f91
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/44938
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/llite/file.c
lustre/tests/sanity-quota.sh

index 6e30ef0..8b3e96b 100644 (file)
@@ -3380,8 +3380,17 @@ int ll_ioctl_check_project(struct inode *inode, __u32 xflags,
         * namespace. Enforce that restriction only if we are trying to change
         * the quota ID state. Everything else is allowed in user namespaces.
         */
-       if (current_user_ns() == &init_user_ns)
+       if (current_user_ns() == &init_user_ns) {
+               /*
+                * Caller is allowed to change the project ID. if it is being
+                * changed, make sure that the new value is valid.
+                */
+               if (ll_i2info(inode)->lli_projid != projid &&
+                    !projid_valid(make_kprojid(&init_user_ns, projid)))
+                       return -EINVAL;
+
                return 0;
+       }
 
        if (ll_i2info(inode)->lli_projid != projid)
                return -EINVAL;
index ecfa9b4..62f6810 100755 (executable)
@@ -4908,6 +4908,23 @@ test_75()
 }
 run_test 75 "nodemap squashed root respects quota enforcement"
 
+test_76() {
+       ! is_project_quota_supported &&
+               skip "skip project quota unsupported"
+
+       setup_quota_test || error "setup quota failed with $?"
+       quota_init
+
+       local testfile="$DIR/$tdir/$tfile-0"
+
+       touch $testfile
+       $LFS project -p 4294967295 $testfile &&
+               error "set project ID should fail"
+
+       cleanup_quota_test
+}
+run_test 76 "project ID 4294967295 should be not allowed"
+
 quota_fini()
 {
        do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota"