The information has been provided by iDefense Labs Security Advisories.
The original article can be found at: http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=600
* Linux Kernel version 184.108.40.206
* Linux Kernel version 220.127.116.11
The problem lies within the handling of multiple reads from the "/proc/driver/snd-page-alloc" file. The kernel side function that handles the read system call, "snd_mem_proc_read", is defined in sound/core/memalloc.c as shown below.
484 static int snd_mem_proc_read(char *page, char **start, off_t off,
485 int count, int *eof, void *data)
487 int len = 0;
494 len += snprintf(page + len, count - len,
495 "pages : %li bytes (%li pages per %likB)\n",
496 pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
508 return len;
On line 494, snprintf is called to generate the output for the proc file system entry. By supplying a count value of 1, snprintf will only write a single byte to the destination buffer. However, the function will return the number of bytes that would have been written if enough space were available. The "*eof" value is never set, and the "*ppos" value is never used.
This function is called from "proc_file_read" function, which is defined in fs/proc/generic.c.
51 static ssize_t
52 proc_file_read(struct file *file, char __user *buf, size_t nbytes,
53 loff_t *ppos)
136 n = dp->read_proc(page, &start, *ppos,
137 count, &eof, dp->data);
155 n -= *ppos;
156 if (n <= 0)
158 if (n > count)
159 n = count;
160 start = page + *ppos;
186 n -= copy_to_user(buf, start < page ? page : start, n);
193 *ppos += start < page ? (unsigned long)start : n;
The value "n" is returned from the call to the snd_proc_mem_read function on line 136. Since the value returned, approximately 41 in single device scenarios, is greater than the requested read size (1), the value "n" is set to "count" on line 158. Later, "*ppos" is incremented and "n" bytes are copied to user-land from "start" (which is calculated as "page" + *ppos).
In subsequent user-land read operations, when "*ppos" is greater than zero, the proc_file_read function will copy from beyond the part of the page that snd_mem_proc_read wrote. This results in the disclosure of kernel memory.
Exploitation of this vulnerability allows attackers to obtain sensitive information from kernel memory.
In order to exploit this vulnerability, an attacker would need access to open the /proc/driver/snd-page-alloc file. It is important to note that this file does not exist unless an audio device is present.
Additionally, the Linux kernel must be built with ALSA support as well as support for the proc file system. The kernels for the majority of common Linux distributions are built with these options.
Since memory is only disclosed from the beginning of an uninitialized page, it may not be possible to obtain certain types of information. However, the ability to obtain the password hash for the root accountwas confirmed during iDefense Labs testing.
The following workarounds will prevent exploitation of thisvulnerability.
* If the ALSA drivers have been built as modules, unload the snd_page_alloc module.
* Restrict access to the /proc file system by modifying the mount parameters within /etc/fstab
The Linux Kernel maintainers have addressed this vulnerability within version 18.104.22.168. More information can be found from the URLs shown below.
09/12/2007 - Initial vendor notification
09/12/2007 - Initial vendor response
09/25/2007 - Coordinated public disclosure