]> git.hungrycats.org Git - linux/commitdiff
ceph: just skip unrecognized info in ceph_reply_info_extra
authorJeff Layton <jlayton@kernel.org>
Thu, 26 Sep 2019 20:05:11 +0000 (16:05 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 29 Oct 2019 08:22:46 +0000 (09:22 +0100)
commit 1d3f87233e26362fc3d4e59f0f31a71b570f90b9 upstream.

In the future, we're going to want to extend the ceph_reply_info_extra
for create replies. Currently though, the kernel code doesn't accept an
extra blob that is larger than the expected data.

Change the code to skip over any unrecognized fields at the end of the
extra blob, rather than returning -EIO.

Cc: stable@vger.kernel.org
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/ceph/mds_client.c

index b11af7d8e8e936a112acd6f5914305a75d10787e..61282b77950f4641a41753a38608efaa8198ae09 100644 (file)
@@ -384,8 +384,8 @@ static int parse_reply_info_readdir(void **p, void *end,
        }
 
 done:
-       if (*p != end)
-               goto bad;
+       /* Skip over any unrecognized fields */
+       *p = end;
        return 0;
 
 bad:
@@ -406,12 +406,10 @@ static int parse_reply_info_filelock(void **p, void *end,
                goto bad;
 
        info->filelock_reply = *p;
-       *p += sizeof(*info->filelock_reply);
 
-       if (unlikely(*p != end))
-               goto bad;
+       /* Skip over any unrecognized fields */
+       *p = end;
        return 0;
-
 bad:
        return -EIO;
 }
@@ -425,18 +423,21 @@ static int parse_reply_info_create(void **p, void *end,
 {
        if (features == (u64)-1 ||
            (features & CEPH_FEATURE_REPLY_CREATE_INODE)) {
+               /* Malformed reply? */
                if (*p == end) {
                        info->has_create_ino = false;
                } else {
                        info->has_create_ino = true;
-                       info->ino = ceph_decode_64(p);
+                       ceph_decode_64_safe(p, end, info->ino, bad);
                }
+       } else {
+               if (*p != end)
+                       goto bad;
        }
 
-       if (unlikely(*p != end))
-               goto bad;
+       /* Skip over any unrecognized fields */
+       *p = end;
        return 0;
-
 bad:
        return -EIO;
 }