Source: oss4 Version: 4.2-build2006-2 Severity: normal Tags: security patch
The Linux implementation of oss_cmn_err() uses a fixed-size temporary buffer and does not protect against overflow. Although this is not obviously exploitable, it could well become exploitable in future. The argument counting and copying is also unportable and generally incorrect. Ben. -- System Information: Debian Release: wheezy/sid APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'proposed-updates'), (500, 'unstable'), (500, 'stable'), (1, 'experimental') Architecture: i386 (x86_64) Foreign Architectures: amd64 Kernel: Linux 3.2.0-4-amd64 (SMP w/2 CPU cores) Locale: LANG=en_GB.utf8, LC_CTYPE=en_GB.utf8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash
From: Ben Hutchings <b...@decadent.org.uk> Subject: Linux error logging fixes The Linux implementation of oss_cmn_err() uses a fixed-size temporary buffer and does not protect against overflow. Although this is not obviously exploitable, it could well become exploitable in future. The argument counting and copying is also unportable and generally incorrect. Therefore: - If we are not going to edit the log line in any way, just call vprintk() and don't bother with the temporary buffer. - If we need to edit the log line or call panic() instead of printk(), use vsnprintf() instead of printf(). --- --- a/setup/Linux/oss/build/osscore.c +++ b/setup/Linux/oss/build/osscore.c @@ -633,43 +633,24 @@ oss_create_uio (uio_t * uio, char *buf, void oss_cmn_err (int level, const char *s, ...) { - char tmp[1024], *a[6]; + char tmp[1024]; va_list ap; - int i, n = 0; va_start (ap, s); - for (i = 0; i < strlen (s); i++) - if (s[i] == '%') - n++; - - for (i = 0; i < n && i < 6; i++) - a[i] = va_arg (ap, char *); - - for (i = n; i < 6; i++) - a[i] = NULL; - if (level == CE_CONT) { - sprintf (tmp, s, a[0], a[1], a[2], a[3], a[4], a[5], NULL, - NULL, NULL, NULL); - printk ("%s", tmp); + vprintk (s, ap); } else { strcpy (tmp, "osscore: "); - sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5], - NULL, NULL, NULL, NULL); + vsnprintf (tmp + strlen (tmp), sizeof(tmp) - strlen(tmp), s, ap); if (level == CE_PANIC) panic (tmp); printk (KERN_ALERT "%s", tmp); } -#if 0 - /* This may cause a crash under SMP */ - if (sound_started) - store_msg (tmp); -#endif va_end (ap); }