Commit ec3797f0 authored by ziming zhang's avatar ziming zhang Committed by Ilya Dryomov
Browse files

libceph: replace BUG_ON with bounds check for map->max_osd



OSD indexes come from untrusted network packets. Boundary checks are
added to validate these against map->max_osd.

[ idryomov: drop BUG_ON in ceph_get_primary_affinity(), minor cosmetic
  edits ]

Cc: stable@vger.kernel.org
Signed-off-by: default avatarziming zhang <ezrakiez@gmail.com>
Reviewed-by: default avatarIlya Dryomov <idryomov@gmail.com>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 43962db4
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -1504,8 +1504,6 @@ static int decode_new_primary_temp(void **p, void *end,

u32 ceph_get_primary_affinity(struct ceph_osdmap *map, int osd)
{
	BUG_ON(osd >= map->max_osd);

	if (!map->osd_primary_affinity)
		return CEPH_OSD_DEFAULT_PRIMARY_AFFINITY;

@@ -1514,8 +1512,6 @@ u32 ceph_get_primary_affinity(struct ceph_osdmap *map, int osd)

static int set_primary_affinity(struct ceph_osdmap *map, int osd, u32 aff)
{
	BUG_ON(osd >= map->max_osd);

	if (!map->osd_primary_affinity) {
		int i;

@@ -1577,6 +1573,8 @@ static int decode_new_primary_affinity(void **p, void *end,

		ceph_decode_32_safe(p, end, osd, e_inval);
		ceph_decode_32_safe(p, end, aff, e_inval);
		if (osd >= map->max_osd)
			goto e_inval;

		ret = set_primary_affinity(map, osd, aff);
		if (ret)
@@ -1879,7 +1877,9 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v,
		ceph_decode_need(p, end, 2*sizeof(u32), e_inval);
		osd = ceph_decode_32(p);
		w = ceph_decode_32(p);
		BUG_ON(osd >= map->max_osd);
		if (osd >= map->max_osd)
			goto e_inval;

		osdmap_info(map, "osd%d weight 0x%x %s\n", osd, w,
			    w == CEPH_OSD_IN ? "(in)" :
			    (w == CEPH_OSD_OUT ? "(out)" : ""));
@@ -1905,13 +1905,15 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v,
		u32 xorstate;

		osd = ceph_decode_32(p);
		if (osd >= map->max_osd)
			goto e_inval;

		if (struct_v >= 5)
			xorstate = ceph_decode_32(p);
		else
			xorstate = ceph_decode_8(p);
		if (xorstate == 0)
			xorstate = CEPH_OSD_UP;
		BUG_ON(osd >= map->max_osd);
		if ((map->osd_state[osd] & CEPH_OSD_UP) &&
		    (xorstate & CEPH_OSD_UP))
			osdmap_info(map, "osd%d down\n", osd);
@@ -1937,7 +1939,9 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v,
		struct ceph_entity_addr addr;

		osd = ceph_decode_32(p);
		BUG_ON(osd >= map->max_osd);
		if (osd >= map->max_osd)
			goto e_inval;

		if (struct_v >= 7)
			ret = ceph_decode_entity_addrvec(p, end, msgr2, &addr);
		else