Whamcloud - gitweb
LU-14740 llite: avoid project quota overflow 39/43939/8
authorWang Shilong <wshilong@ddn.com>
Mon, 7 Jun 2021 15:40:22 +0000 (23:40 +0800)
committerOleg Drokin <green@whamcloud.com>
Tue, 27 Jul 2021 21:37:14 +0000 (21:37 +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.

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-on: https://review.whamcloud.com/43939
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/file.c
lustre/tests/sanity-quota.sh
lustre/utils/lfs.c

index 2e57c64..41af22a 100644 (file)
@@ -3414,8 +3414,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 9103aac..2fcf058 100755 (executable)
@@ -5044,6 +5044,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)) \
index fd9f0c7..c124188 100644 (file)
@@ -4577,6 +4577,7 @@ static int str2quotaid(__u32 *id, const char *arg)
        projid_tmp = strtoul(arg, &endptr, 10);
        if (*endptr != '\0')
                return -EINVAL;
+       /* UINT32_MAX is not allowed - see projid_valid()/INVALID_PROJID */
        if (projid_tmp >= UINT32_MAX)
                return -ERANGE;