Project

General

Profile

Actions

Bug #9749

closed

kcephfs: kernel divide-by-zero crash in __validate_layout (fs/ceph/ioctl.c)

Added by David Ramos over 9 years ago. Updated over 9 years ago.

Status:
Resolved
Priority:
Urgent
Assignee:
Category:
-
Target version:
-
% Done:

0%

Source:
other
Tags:
Backport:
Regression:
Severity:
3 - minor
Reviewed:
Affected Versions:
ceph-qa-suite:
Crash signature (v1):
Crash signature (v2):

Description

Our UC-KLEE tool discovered a Linux kernel divide-by-zero crash in the Ceph
client driver. I found the bug on kernel 3.16.3, but it appears to date back to
commit 8f4e91dee2a245e4be6942f4a8d83a769e13a47d (2009-10-06).

The bug occurs in the ioctl code for CEPH_IOC_SET_LAYOUT and
CEPH_IOC_SET_LAYOUT_POLICY, which improperly checks the userspace input before
using it as the divisor in a modulus (%) operation.

This bug appears to be exploitable by a non-privileged user issuing an offending
ioctl.

The backtraces reported by our tool are:

__validate_layout () at fs/ceph/ioctl.c:42
ceph_ioctl_set_layout () at fs/ceph/ioctl.c:102
ceph_ioctl () at fs/ceph/ioctl.c:279
__validate_layout () at fs/ceph/ioctl.c:42
ceph_ioctl_set_layout_policy () at fs/ceph/ioctl.c:147
ceph_ioctl () at fs/ceph/ioctl.c:282

The offending code in fs/ceph/ioctl.c is as follows:

42 if ((l->object_size & ~PAGE_MASK) ||
43 (l->stripe_unit & ~PAGE_MASK) ||
44 (l->stripe_unit != 0 &&
45 ((unsigned)l->object_size % (unsigned)l->stripe_unit)))
46 return -EINVAL;

The 'stripe_unit' field is 64 bits, so a value such as 0xff00000000000000 will
pass the "stripe_unit != 0" test but result in a zero divisor once cast to
32 bits on line 45.

Actions #1

Updated by Ilya Dryomov over 9 years ago

  • Status changed from New to 12
  • Assignee set to Ilya Dryomov
Actions #2

Updated by Zheng Yan over 9 years ago

  • Status changed from 12 to Resolved

fixed by "ceph: fix divide-by-zero in __validate_layout()" in the testing branch

Actions #3

Updated by David Ramos over 9 years ago

This bug appears to be exploitable by unprivileged local users and will cause a machine-wide DoS. Is there some reason a CVE number isn't being assigned?

Actions #4

Updated by Ilya Dryomov over 9 years ago

I guess we are just not used to doing it - I think we haven't filed any CVEs for ceph kernel bits (and kcephfs in particular) ever and we haven't been backporting kcephfs fixes to stable kernels either (although krbd fixes are being backported pretty rigorously). That's all changing now, but we aren't there just yet.

Actions

Also available in: Atom PDF