Skip to content

Commit c4c22b8

Browse files
committed
libceph: reject preamble if control segment is empty
While head_onwire_len() has a branch to handle ctrl_len == 0 case, prepare_read_control() always sets up a kvec for the CRC meaning that a non-empty control segment is effectively assumed. All frames that clients deal with meet that assumption, so let's make it official and treat the preamble with an empty control segment as malformed. Cc: [email protected] Signed-off-by: Ilya Dryomov <[email protected]> Reviewed-by: Alex Markuze <[email protected]>
1 parent a5a3737 commit c4c22b8

1 file changed

Lines changed: 8 additions & 9 deletions

File tree

net/ceph/messenger_v2.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ static int head_onwire_len(int ctrl_len, bool secure)
392392
int head_len;
393393
int rem_len;
394394

395-
BUG_ON(ctrl_len < 0 || ctrl_len > CEPH_MSG_MAX_CONTROL_LEN);
395+
BUG_ON(ctrl_len < 1 || ctrl_len > CEPH_MSG_MAX_CONTROL_LEN);
396396

397397
if (secure) {
398398
head_len = CEPH_PREAMBLE_SECURE_LEN;
@@ -401,9 +401,7 @@ static int head_onwire_len(int ctrl_len, bool secure)
401401
head_len += padded_len(rem_len) + CEPH_GCM_TAG_LEN;
402402
}
403403
} else {
404-
head_len = CEPH_PREAMBLE_PLAIN_LEN;
405-
if (ctrl_len)
406-
head_len += ctrl_len + CEPH_CRC_LEN;
404+
head_len = CEPH_PREAMBLE_PLAIN_LEN + ctrl_len + CEPH_CRC_LEN;
407405
}
408406
return head_len;
409407
}
@@ -528,11 +526,16 @@ static int decode_preamble(void *p, struct ceph_frame_desc *desc)
528526
desc->fd_aligns[i] = ceph_decode_16(&p);
529527
}
530528

531-
if (desc->fd_lens[0] < 0 ||
529+
/*
530+
* This would fire for FRAME_TAG_WAIT (it has one empty
531+
* segment), but we should never get it as client.
532+
*/
533+
if (desc->fd_lens[0] < 1 ||
532534
desc->fd_lens[0] > CEPH_MSG_MAX_CONTROL_LEN) {
533535
pr_err("bad control segment length %d\n", desc->fd_lens[0]);
534536
return -EINVAL;
535537
}
538+
536539
if (desc->fd_lens[1] < 0 ||
537540
desc->fd_lens[1] > CEPH_MSG_MAX_FRONT_LEN) {
538541
pr_err("bad front segment length %d\n", desc->fd_lens[1]);
@@ -549,10 +552,6 @@ static int decode_preamble(void *p, struct ceph_frame_desc *desc)
549552
return -EINVAL;
550553
}
551554

552-
/*
553-
* This would fire for FRAME_TAG_WAIT (it has one empty
554-
* segment), but we should never get it as client.
555-
*/
556555
if (!desc->fd_lens[desc->fd_seg_cnt - 1]) {
557556
pr_err("last segment empty, segment count %d\n",
558557
desc->fd_seg_cnt);

0 commit comments

Comments
 (0)