Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Jan 2005 16:11:24 GMT
From:      Eugene Stark <stark@cs.sunysb.edu>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/76207: Null pointer dereference in xl_detach()
Message-ID:  <200501131611.j0DGBOlv012072@www.freebsd.org>
Resent-Message-ID: <200501131620.j0DGK7Wj090391@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         76207
>Category:       kern
>Synopsis:       Null pointer dereference in xl_detach()
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jan 13 16:20:07 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Eugene Stark
>Release:        4.10-RELEASE
>Organization:
SUNY at Stony Brook
>Environment:
FreeBSD laptop.starkhome.cs.sunysb.edu 4.10-RELEASE-p4 FreeBSD 4.10-RELEASE-p4 #0: Thu Jan 13 10:47:59 EST 2005     gene@laptop.starkhome.cs.sunysb.edu:/A/src/sys/compile/LAPTOP  i386

>Description:
      My HP Omnibook 6000 uses the if_xl driver for the integrated
ethernet port.  Upon resuming from suspend-to-disk, sometimes the xl
driver reports "No memory for list buffers" and then crashes with a
null pointer dereference in generic_bzero() called from xl_detach+0x56.

      Tracing the problem shows that xl_attach() is called, but for
some reason allocation of the tx list buffers fails (this is the real
underlying problem, but I don't know why it occurs) and then xl_detach()
is called from the "fail" label in xl_attach().  The xl_detach()
function then attempts to bzero rx and tx list buffers without
checking whether they are NULL, and this causes the crash.

      At the very least, xl_detach() should check whether there are
any buffers before trying to bzero() them.  I have applied a patch that
does this as a workaround to keep the system from panicking when this
occurs.  As long as the system doesn't panic, one can do a suspend-to-memory and then unsuspend to recover from the problem and
get the xl driver working again.

       Various versions of this problem have been present for a number
of FreeBSD releases.  Between 4.8 and 4.10 there were some changes made
to the xl driver that seemed to address part of this, but they didn't
go far enough to avoid the null pointer dereferences and the problem still occurs.  I'd appreciate it if the workaround I mention below could
get in the tree so I don't have to keep applying this patch.



>How-To-Repeat:
      Get an HP Omnibook 6000, load the if_xl driver, suspend-to-disk,
then unsuspend and sometimes this will occur.

>Fix:
      I applied the following patch (diffs against 4.10-RELEASE) as a
workaround, pending identification of the real underlying problem.
It is probably not a bad idea to leave this patch in anyway as good
defensive programming.

      Well, OK, it says I'm not supposed to submit code here,
but whaddayawant?  Would be nice to provide an upload link so that
if I got a patch I can supply it.

Index: if_xl.c
===================================================================
RCS file: /A/cvs/src/sys/pci/if_xl.c,v
retrieving revision 1.72.2.29
diff -c -r1.72.2.29 if_xl.c
*** if_xl.c     19 Mar 2004 23:21:05 -0000      1.72.2.29
--- if_xl.c     13 Jan 2005 15:40:33 -0000
***************
*** 3274,3280 ****
                        sc->xl_cdata.xl_rx_chain[i].xl_mbuf = NULL;
                }
        }
!       bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
        /*
         * Free the TX list buffers.
         */
--- 3274,3285 ----
                        sc->xl_cdata.xl_rx_chain[i].xl_mbuf = NULL;
                }
        }
!       if(sc->xl_ldata.xl_rx_list != NULL)
!         bzero(sc->xl_ldata.xl_rx_list, XL_RX_LIST_SZ);
!       else
!         printf("xl%d: xl_ldata.xl_rx_list == NULL in xl_stop!\n",
!                sc->xl_unit);
! 
        /*
         * Free the TX list buffers.
         */
***************
*** 3288,3294 ****
                        sc->xl_cdata.xl_tx_chain[i].xl_mbuf = NULL;
                }
        }
!       bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
  
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
  
--- 3293,3303 ----
                        sc->xl_cdata.xl_tx_chain[i].xl_mbuf = NULL;
                }
        }
!       if(sc->xl_ldata.xl_tx_list != NULL)
!         bzero(sc->xl_ldata.xl_tx_list, XL_TX_LIST_SZ);
!       else
!         printf("xl%d: xl_ldata.xl_tx_list == NULL in xl_stop!\n",
!                sc->xl_unit);
  
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
  

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501131611.j0DGBOlv012072>