]> Zhao Yanbai Git Server - minix.git/commitdiff
TTY: fix crash obtaining kernel messages
authorDavid van Moolenbroek <david@minix3.org>
Mon, 5 Nov 2012 23:11:16 +0000 (00:11 +0100)
committerDavid van Moolenbroek <david@minix3.org>
Mon, 5 Nov 2012 23:17:44 +0000 (00:17 +0100)
Also fix a case of potential message loss in TTY and LOG.

drivers/log/diag.c
drivers/tty/tty.c

index ac7841ba4e9ebec89c3e3bdeb7879ef035678043..28eb1e7e4aa6bd739b23b1f57441fdcf6aa5a62a 100644 (file)
@@ -21,8 +21,7 @@ void do_new_kmess(void)
 /* Notification for a new kernel message. */
   static struct kmessages *kmess;              /* entire kmess structure */
   static char print_buf[_KMESS_BUF_SIZE];      /* copy new message here */
-  int bytes;
-  int i, r;
+  int i, r, next, bytes;
   static int prev_next = 0;
 
   assert(_minix_kerninfo);
@@ -31,12 +30,13 @@ void do_new_kmess(void)
   /* Print only the new part. Determine how many new bytes there are with 
    * help of the current and previous 'next' index. Note that the kernel
    * buffer is circular. This works fine if less than KMESS_BUF_SIZE bytes
-   * are new data; else we miss % KMESS_BUF_SIZE here.  
+   * are new data; else we miss % KMESS_BUF_SIZE here. Obtain 'next' only
+   * once, since we are operating on shared memory here.
    * Check for size being positive, the buffer might as well be emptied!
    */
-  if (kmess->km_size > 0) {
-      bytes = ((kmess->km_next + _KMESS_BUF_SIZE) - prev_next) %
-       _KMESS_BUF_SIZE;
+  next = kmess->km_next;
+  bytes = ((next + _KMESS_BUF_SIZE) - prev_next) % _KMESS_BUF_SIZE;
+  if (bytes > 0) {
       r= prev_next;                            /* start at previous old */ 
       i=0;
       while (bytes > 0) {                      
@@ -53,5 +53,5 @@ void do_new_kmess(void)
   /* Almost done, store 'next' so that we can determine what part of the
    * kernel messages buffer to print next time a notification arrives.
    */
-  prev_next = kmess->km_next;
+  prev_next = next;
 }
index 29d65a054a175220a361b37ea0d806df0c4875f7..c1dc41a02ef552cc106dba28f485d7d1bbcc58f3 100644 (file)
@@ -456,9 +456,9 @@ do_new_kmess(void)
 {
 /* Kernel wants to print a new message */
        struct kmessages *kmess_ptr;    /* kmessages structure */
-       char kernel_buf_copy[2*_KMESS_BUF_SIZE];
+       char kernel_buf_copy[_KMESS_BUF_SIZE];
        static int prev_next = 0;
-       int bytes, copy, restore = 0;
+       int next, bytes, copy, restore = 0;
        tty_t *tp, rtp;
        message print_kmsg;
 
@@ -468,14 +468,15 @@ do_new_kmess(void)
        /* The kernel buffer is circular; print only the new part. Determine
         * how many new bytes there are with the help of current and
         * previous 'next' index. This works fine if less than _KMESS_BUF_SIZE
-        * bytes is new data; else we miss % _KMESS_BUF_SIZE here.
+        * bytes is new data; else we miss % _KMESS_BUF_SIZE here. Obtain
+        * 'next' only once, since we are operating on shared memory here.
         * Check for size being positive; the buffer might as well be emptied!
         */
-       if (kmess_ptr->km_size > 0) {
-               bytes = ((kmess_ptr->km_next + _KMESS_BUF_SIZE) - prev_next) %
-                                                               _KMESS_BUF_SIZE;
-               /* Copy from current position to end of buffer */
-               copy = (prev_next + bytes) % _KMESS_BUF_SIZE;
+       next = kmess_ptr->km_next;
+       bytes = ((next + _KMESS_BUF_SIZE) - prev_next) % _KMESS_BUF_SIZE;
+       if (bytes > 0) {
+               /* Copy from current position toward end of buffer */
+               copy = MIN(_KMESS_BUF_SIZE - prev_next, bytes);
                memcpy(kernel_buf_copy, &kmess_ptr->km_buf[prev_next], copy);
 
                /* Copy remainder from start of buffer */
@@ -510,7 +511,7 @@ do_new_kmess(void)
        /* Store 'next' pointer so that we can determine what part of the
         * kernel messages buffer to print next time a notification arrives.
         */
-       prev_next = kmess_ptr->km_next;
+       prev_next = next;
 }
 
 /*===========================================================================*