diff options
author | Xi Wang <xi.wang@gmail.com> | 2012-02-16 17:55:48 +0100 |
---|---|---|
committer | Alex Elder <elder@dreamhost.com> | 2012-03-22 16:47:45 +0100 |
commit | 64486697771cbe219fffcb5c8e2ed9ca4fdf086c (patch) | |
tree | a623eebb8105ae8e7585c7faaf171729a9cbadbb /net/ceph/osdmap.c | |
parent | ceph: avoid panic with mismatched symlink sizes in fill_inode() (diff) | |
download | linux-64486697771cbe219fffcb5c8e2ed9ca4fdf086c.tar.xz linux-64486697771cbe219fffcb5c8e2ed9ca4fdf086c.zip |
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 <xi.wang@gmail.com>
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'net/ceph/osdmap.c')
-rw-r--r-- | net/ceph/osdmap.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index fd863fe76934..29ad46ec9dcf 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -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) + |