patch for 2.1.72 kernel/printk.c

Bill Hawes (whawes@star.net)
Thu, 18 Dec 1997 14:27:19 -0500


This is a multi-part message in MIME format.
--------------9E8A28F7316447357B86DB99
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

In reviewing the code for printk I found a small race that could result
in a buffer overrun on a call to sys_syslog with type == 3. A test is
made to limit the count to the value of logged_chars, but logged_chars
may change if an interrupt generates printk messages.

The patch disables interrupts while setting up the initial buffer index
so that consistent values are used.

Regards,
Bill
--------------9E8A28F7316447357B86DB99
Content-Type: text/plain; charset=us-ascii; name="printk_72-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="printk_72-patch"

--- kernel/printk.c.old Wed Dec 10 00:12:16 1997
+++ kernel/printk.c Thu Dec 18 15:12:21 1997
@@ -109,7 +109,7 @@
*/
asmlinkage int sys_syslog(int type, char * buf, int len)
{
- unsigned long i, j, count;
+ unsigned long i, j, count, flags;
int do_clear = 0;
char c;
int error = -EPERM;
@@ -170,12 +170,19 @@
error = verify_area(VERIFY_WRITE,buf,len);
if (error)
goto out;
+ /*
+ * The logged_chars, log_start, and log_size values may
+ * change from an interrupt, so we disable interrupts.
+ */
+ __save_flags(flags);
+ __cli();
count = len;
if (count > LOG_BUF_LEN)
count = LOG_BUF_LEN;
if (count > logged_chars)
count = logged_chars;
j = log_start + log_size - count;
+ __restore_flags(flags);
for (i = 0; i < count; i++) {
c = *((char *) log_buf+(j++ & (LOG_BUF_LEN-1)));
__put_user(c, buf++);

--------------9E8A28F7316447357B86DB99--