Commit 69fb5d91 authored by Ilya Dryomov's avatar Ilya Dryomov
Browse files

libceph: prevent potential out-of-bounds reads in process_message_header()



If the message frame is (maliciously) corrupted in a way that the
length of the control segment ends up being less than the size of the
message header or a different frame is made to look like a message
frame, out-of-bounds reads may ensue in process_message_header().

Perform an explicit bounds check before decoding the message header.

Cc: stable@vger.kernel.org
Reported-by: default avatarRaphael Zimmer <raphael.zimmer@tu-ilmenau.de>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
Reviewed-by: default avatarAlex Markuze <amarkuze@redhat.com>
Reviewed-by: default avatarViacheslav Dubeyko <Slava.Dubeyko@ibm.com>
parent 081a0b78
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -2833,12 +2833,15 @@ static int process_message_header(struct ceph_connection *con,
				  void *p, void *end)
{
	struct ceph_frame_desc *desc = &con->v2.in_desc;
	struct ceph_msg_header2 *hdr2 = p;
	struct ceph_msg_header2 *hdr2;
	struct ceph_msg_header hdr;
	int skip;
	int ret;
	u64 seq;

	ceph_decode_need(&p, end, sizeof(*hdr2), bad);
	hdr2 = p;

	/* verify seq# */
	seq = le64_to_cpu(hdr2->seq);
	if ((s64)seq - (s64)con->in_seq < 1) {
@@ -2869,6 +2872,10 @@ static int process_message_header(struct ceph_connection *con,
	WARN_ON(!con->in_msg);
	WARN_ON(con->in_msg->con != con);
	return 1;

bad:
	pr_err("failed to decode message header\n");
	return -EINVAL;
}

static int process_message(struct ceph_connection *con)