ceph: use correct index when encoding client supported features
authorLuís Henriques <lhenriques@suse.de>
Tue, 24 May 2022 16:06:27 +0000 (17:06 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Tue, 2 Aug 2022 22:54:12 +0000 (00:54 +0200)
Feature bits have to be encoded into the correct locations.  This hasn't
been an issue so far because the only hole in the feature bits was in bit
10 (CEPHFS_FEATURE_RECLAIM_CLIENT), which is located in the 2nd byte.  When
adding more bits that go beyond the this 2nd byte, the bug will show up.

[xiubli: remove incorrect comment for CEPHFS_FEATURES_CLIENT_SUPPORTED]

Fixes: 9ba1e224538a ("ceph: allocate the correct amount of extra bytes for the session features")
Signed-off-by: Luís Henriques <lhenriques@suse.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/mds_client.c
fs/ceph/mds_client.h

index 33f517d..0aded10 100644 (file)
@@ -1220,14 +1220,17 @@ static int encode_supported_features(void **p, void *end)
        if (count > 0) {
                size_t i;
                size_t size = FEATURE_BYTES(count);
+               unsigned long bit;
 
                if (WARN_ON_ONCE(*p + 4 + size > end))
                        return -ERANGE;
 
                ceph_encode_32(p, size);
                memset(*p, 0, size);
-               for (i = 0; i < count; i++)
-                       ((unsigned char*)(*p))[i / 8] |= BIT(feature_bits[i] % 8);
+               for (i = 0; i < count; i++) {
+                       bit = feature_bits[i];
+                       ((unsigned char *)(*p))[bit / 8] |= BIT(bit % 8);
+               }
                *p += size;
        } else {
                if (WARN_ON_ONCE(*p + 4 > end))
index 1140aec..2a49e33 100644 (file)
@@ -33,10 +33,6 @@ enum ceph_feature_type {
        CEPHFS_FEATURE_MAX = CEPHFS_FEATURE_METRIC_COLLECT,
 };
 
-/*
- * This will always have the highest feature bit value
- * as the last element of the array.
- */
 #define CEPHFS_FEATURES_CLIENT_SUPPORTED {     \
        0, 1, 2, 3, 4, 5, 6, 7,                 \
        CEPHFS_FEATURE_MIMIC,                   \
@@ -45,8 +41,6 @@ enum ceph_feature_type {
        CEPHFS_FEATURE_MULTI_RECONNECT,         \
        CEPHFS_FEATURE_DELEG_INO,               \
        CEPHFS_FEATURE_METRIC_COLLECT,          \
-                                               \
-       CEPHFS_FEATURE_MAX,                     \
 }
 #define CEPHFS_FEATURES_CLIENT_REQUIRED {}