[PATCH v2] libceph: Assign requests to homeless osd if calculated osd exceeds max_osd
Raphael Zimmer <[email protected]>
| Newsgroups | org.kernel.vger.ceph-devel |
|---|---|
| Message-ID | <[email protected]> |
A corrupted osdmap received from a Ceph monitor or OSD may contain
placement groups with osd indices that don't exist, i.e., that are
greater than max_osd or smaller than CEPH_HOMELESS_OSD (-1).
Subsequently, this may lead to calc_target() returning such an index as
target osd for a (linger) request. Because the osd_state, osd_weight,
and osd_addr arrays only contain max_osd entries (with indices 0 to
max_osd -1), this leads to out-of-bounds accesses when trying to read
values from these arrays.
This patch fixes the issue by adding a check to calc_target() assigning
the request to the homeless osd if the target osd index read from the
osdmap falls outside the valid osd index range.
Fixes: 63244fa123a7 ("libceph: introduce ceph_osd_request_target, calc_target()")
Signed-off-by: Raphael Zimmer <[email protected]>
---
net/ceph/osd_client.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index a4d3cbfd27a3..3d13226a5d1f 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -1707,6 +1707,12 @@ static enum calc_target_result calc_target(struct ceph_osd_client *osdc,
}
}
+ if (t->osd != CEPH_HOMELESS_OSD && (u32)t->osd >= osdc->osdmap->max_osd) {
+ t->osd = CEPH_HOMELESS_OSD;
+ ct_res = CALC_TARGET_NEED_RESEND;
+ goto out;
+ }
+
if (unpaused || legacy_change || force_resend || split)
ct_res = CALC_TARGET_NEED_RESEND;
else
--
2.47.3