From: Simon Ruggier Date: Sat, 15 Dec 2018 04:32:22 +0000 (-0500) Subject: Objecter::calc_op_budget: Fix invalid access to extent union member X-Git-Tag: v13.2.5~94^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F26066%2Fhead;p=ceph.git Objecter::calc_op_budget: Fix invalid access to extent union member Previously, the function was checking the extent length for any operation with the CEPH_OSD_OP_MODE_RD and CEPH_OSD_OP_TYPE_DATA bits set, but some operation types that have these bits set use a different interpretation of the ceph_osd_op union. This leads to a type safety problem where another field, such as the object version, is interpreted as an extent length and added to the budget. In addition to producing an incorrectly high budget for the operation, this also triggers an assertion failure if the value is large enough to overflow a signed 32-bit integer, as described in bug #9592 and bug #37932. This change uses the ceph_osd_op_uses_extent function to prevent invalid access to the union, instead of ceph_osd_op_type_data. Fixes: http://tracker.ceph.com/issues/37932 Signed-off-by: Simon Ruggier (cherry picked from commit 1cb91c2cdfa7556b23b9800c8d10033d0c815b4e) --- diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index 50014a516ff5..dabef6bd7dcd 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -3308,11 +3308,11 @@ int Objecter::calc_op_budget(const vector& ops) if (i->op.op & CEPH_OSD_OP_MODE_WR) { op_budget += i->indata.length(); } else if (ceph_osd_op_mode_read(i->op.op)) { - if (ceph_osd_op_type_data(i->op.op)) { - if ((int64_t)i->op.extent.length > 0) - op_budget += (int64_t)i->op.extent.length; + if (ceph_osd_op_uses_extent(i->op.op)) { + if ((int64_t)i->op.extent.length > 0) + op_budget += (int64_t)i->op.extent.length; } else if (ceph_osd_op_type_attr(i->op.op)) { - op_budget += i->op.xattr.name_len + i->op.xattr.value_len; + op_budget += i->op.xattr.name_len + i->op.xattr.value_len; } } }