CVE-2011-3209: Medium severity linux kernel vulnerability
Description of Problem: The call trace is as follows:
crash> bt PID: 16963 TASK: f7415aa0 CPU: 0 COMMAND: "1-2.run-test" #0 [eb1c4e20] crashkexec at c04434bd #1 [eb1c4e64] die at c04064d3 #2 [eb1c4e94] dodivideerror at c0406ac5 #3 [eb1c4f44] errorcode (via divideerror) at c0405abb EAX: 5e3c58c2 EBX: 3b9aca00 ECX: fffffe4c EDX: fffffe4c EBP: eb1c4000 DS: 007b ESI: eb1c4fac ES: 007b EDI: eb1c4fac CS: 0060 EIP: c04374cd ERR: ffffffff EFLAGS: 00210246 #4 [eb1c4f78] sampletotimespec at c04374cd #5 [eb1c4f8c] posixcpuclockget at c0438744 #6 [eb1c4fa8] sysclockgettime at c04367f3 #7 [eb1c4fb8] systemcall at c0404f44 EAX: ffffffda EBX: fffffff2 ECX: bfe85f78 EDX: 00967ff4 DS: 007b ESI: fffffff2 ES: 007b EDI: 00000000 SS: 007b ESP: bfe85f3c EBP: bfe85f58 CS: 0073 EIP: 00963e75 ERR: 00000109 EFLAGS: 00200246
Here is [customer's] analysis of the problem.
Processing clockgettime system call reached Divide Error Fault as described below:
1) clockgettime system call is called with 0xfffffff2, which is clock ID of the init process whose process ID is 1. The clock ID is got from clockgetcpuclockid(1,&clockid). 2) posixcpuclockget() sets cputimecount->sched to taskstruct->schedtime of PID#1 and calls sampletotimespec(). 3) sampletotimespec() divides cputimecount->sched by NSECPERSEC using divlonglongrem(). 4) The result of the division becomes bigger than 0xffffffff. 5) Divide Error Fault occurs.
The reason why Divide Error Fault occurs is the huge taskstruct->schedtime of PDI#1. When sysclockgettime() was called, taskstruct->schedtime of PID#1 was 0xfffffe4c5e3c58c2.
The taskstruct->schedtime is increased by updatecpuclock() while handling local timer interrupts as follows.
--- static inline void updatecpuclock(struct taskstruct p, struct rq rq, unsigned long long now) { p->schedtime += now - max(p->timestamp, rq->timestamplasttick); } ---
The 'now' argument is got from TSC and if it is nearly zero, p->schedtime becomes very large. It can happen while system booting on which TSC is initialized to zero as follows.
--- init() "init/main.c" -> smppreparecpus(maxcpus) -> synchronizetscbp() -> writetsc() => TSC is initialized to 0 ---
So the summary of the problem is as follows:
1) TSC is initialized to zero during system booting. 2) updatecpuclock() is called just after 1) then taskstruct->schedtime of PID#1 becomes very large. 3) sysclockgettime() is called for clock ID of PID#1. 4) Divide Error Fault occurs.
Other sources
The divlonglongrem implementation in include/asm-x86/div64.h in the Linux kernel before 2.6.26 on the x86 platform allows local users to cause a denial of service (Divide Error Fault and panic) via a clockgettime system call.
— Launchpad
Affected Software
Remediation
Patch Available
Event History
Frequently Asked Questions
What is the severity of CVE-2011-3209?
CVE-2011-3209 has been rated as high severity due to its potential to cause system crashes and compromise stability.
How do I fix CVE-2011-3209?
To mitigate CVE-2011-3209, update the Linux kernel to version 2.6.26 or later.
Which systems are affected by CVE-2011-3209?
CVE-2011-3209 affects all versions of the Linux kernel up to and including 2.6.25.20.
What type of vulnerability is CVE-2011-3209?
CVE-2011-3209 is a divide error vulnerability that can lead to crashes under specific conditions.
Is there any known exploit for CVE-2011-3209?
As of now, there are no public exploits specifically targeting CVE-2011-3209, but it poses significant risk due to its nature.