libceph: fix overflow check in crush_decode()
PATCH 1/1 libceph: fix overflow check in crush_decode()
The existing overflow check (n > ULONG_MAX / b) didn't work, because n = ULONG_MAX / b would both bypass the check and still overflow the allocation size a + n * b.
The correct check should be (n > (ULONG_MAX - a) / b).
Signed-off-by Xi Wang <[email protected]>
--- net/ceph/osdmap.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
net/ceph/osdmap.c +2 -1
@@ -283,7 +283,8 @@ static struct crush_map *crush_decode(void *pbyval, void *end)ceph_decode_32_safe (p, end, yes, bad);#if BITS_PER_LONG ==32 err = -EINVAL ; -if (yes >ULONG_MAX /sizeof (struct crush_rule_step )) +if (yes > (ULONG_MAX -sizeof (*r)) + /sizeof (struct crush_rule_step )) goto bad;#endif r = c->rules[i] = kmalloc(sizeof(*r) +
Signature · 1 line
1.7.5.4
Sage Weil
AppliedApplied these both, thanks!
sage
Quoted 34 lines · Xi Wang
The existing overflow check (n >
ULONG_MAX/ b) didn't work, because n =ULONG_MAX/ b would both bypass the check and still overflow the allocation size a + n * b.The correct check should be (n > (
ULONG_MAX- a) / b).Signed-off-by Xi Wang <[email protected]>--- net/ceph/osdmap.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)net/ceph/osdmap.c +2
-1@@ -283,7 +283,8 @@ static struct crush_map *crush_decode(void *pbyval, void *end)ceph_decode_32_safe (p, end, yes, bad);#if BITS_PER_LONG ==32 err = -EINVAL ; -if (yes >ULONG_MAX /sizeof (struct crush_rule_step )) +if (yes > (ULONG_MAX -sizeof (*r)) + /sizeof (struct crush_rule_step )) goto bad;#endif r = c->rules[i] = kmalloc(sizeof(*r) +Signature · 6 lines
1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html