Date: Mon, 07 Nov 2016 21:50:25 +0000 From: bugzilla-noreply@freebsd.org To: freebsd-amd64@FreeBSD.org Subject: [Bug 214300] Integer truncation issues lead to out-of-bounds kernel reads and panics in clock_settime(). Message-ID: <bug-214300-6@https.bugs.freebsd.org/bugzilla/>
next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D214300 Bug ID: 214300 Summary: Integer truncation issues lead to out-of-bounds kernel reads and panics in clock_settime(). Product: Base System Version: 10.3-RELEASE Hardware: amd64 OS: Any Status: New Severity: Affects Some People Priority: --- Component: kern Assignee: freebsd-bugs@FreeBSD.org Reporter: tim.newsham@nccgroup.trust CC: freebsd-amd64@FreeBSD.org CC: freebsd-amd64@FreeBSD.org Created attachment 176751 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=3D176751&action= =3Dedit reproduction program Integer truncation issues in clock_ts_to_ct() result in out-of-bounds results. These results are trusted by atrtc_settime() which calls bin2bcd(ct.day). bin2bcd is implemented with a table lookup, and when ct.day is out-of-bounds, it results in an out-of-bounds read to the bin2bcd_data[] table. This can lead to a page fault in the kernel and a panic. To trigger this issue you must have the PRIV_CLOCK_SETTIME privilege. Specifically when ts->tv_sec is large or negative on 64-bit platforms, the clock_ts_to_ct function calculations: days =3D secs / SECDAY; can result in an incorrect value that is negative. This can later result in several incorrect calculations in the result including ct->dow =3D day_of_week(days); which performs a modulus operation on a negative value, an integer overflow in ct->year, and an out-of-range value in ct->day, ct->hour =3D rsec / 3600; rsec =3D rsec % 3600; ct->min =3D rsec / 60; rsec =3D rsec % 60; ct->sec =3D rsec; and out-of-range values for ct->min and ct->sec (due to modulus operations on negative values). Verified on FreeBSD 10.3-RELEASE kernel on amd64 platform with QEMU "hardware". Recommendation: The "years" and "days" variables in clock_ts_to_ct() should be "long" and not "int". This function should not be called when the input "ts.tv_sec" field is negative, or it should return an error, or the function should be updated to properly handle negative second values. It should be carefully written to avoid signed-overflows=20 and signed-modulus operations in this case. Reproduction: # cc -Wall crash_clock_settime.c -o crash_clock_settime # ./crash_clock_settime Fatal trap 12: page fault while in kernel mode cpuid =3D 0; apic id =3D 00 fault virtual address =3D 0xffffffff7eab4242 fault code =3D supervisor read data, page not present instruction pointer =3D 0x20:0xffffffff80e6e6c8 stack pointer =3D 0x28:0xfffffe00002169d0 frame pointer =3D 0x28:0xfffffe0000216a10 code segment =3D base 0x0, limit 0xfffff, type 0x1b =3D DPL 0, pres 1, long 1, def32 0, gran 1 processor eflags =3D interrupt enabled, IOPL =3D 0 current process =3D 22 (a.out) trap number =3D 12 panic: page fault cpuid =3D 0 KDB: stack backtrace: #0 0xffffffff8098e390 at kdb_backtrace+0x60 #1 0xffffffff80951066 at vpanic+0x126 #2 0xffffffff80950f33 at panic+0x43 #3 0xffffffff80d55f7b at trap_fatal+0x36b #4 0xffffffff80d5627d at trap_pfault+0x2ed #5 0xffffffff80d558fa at trap+0x47a #6 0xffffffff80d3b8d2 at calltrap+0x8 #7 0xffffffff809993f1 at resettodr+0xc1 #8 0xffffffff80963ea0 at settime+0x180 #9 0xffffffff80963c96 at sys_clock_settime+0x86 #10 0xffffffff80d5694f at amd64_syscall+0x40f #11 0xffffffff80d3bbbb at Xfast_syscall+0xfb --=20 You are receiving this mail because: You are on the CC list for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-214300-6>