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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Aug 2022 09:40:13 +0000 (11:40 +0200)
commit fea013e020e6ecc7be75bea0d61697b7e916b44d upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/ceph/mds_client.c
fs/ceph/mds_client.h

index 912903de4de4289951ff76eaa7c26c504aa97dbd..78d052dc17987a0ee1f68c41e47fc8d432016ff2 100644 (file)
@@ -1196,14 +1196,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 97c7f7bfa55f39ba67ae1f733791148142406241..2667350eb72cf083dfc7c60ca1fd953412aec88a 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 {}