From: ws@tools.de (Wolfgang Solfrank)
Newsgroups: comp.unix.bsd
Subject: Bug in mbuf allocation
Date: 31 Aug 92 13:32:39
Organization: TooLs GmbH, Bonn, Germany
NNTP-Posting-Host: kurt.tools.de

BUG FINDER INFORMATION

NAME:	Wolfgang Solfrank
FIRM:	TooLs GmbH
ADDRESS: Adolfstr. 5, D-W5300 Bonn 1
COUNTRY: Germany
PHONE:	+49 228 985800
FAX:	+49 228 697543
EMAIL:	ws@tools.de

There is a bug in the mbuf allocation code.

While the flags in sys/mbuf.h define M_DONTWAIT and M_WAIT in terms of
M_NOWAIT and M_WAITOK, these flags are only used for the kernel malloc.
But the actual code in kern/uipc_mbuf.h uses kmem_malloc, which has
only a parameter canwait. To stick with Murphy's law :-) this parameter
has just the opposite meaning from the flag values above.
This may result in occasional hangs of the system (if mbuf allocation
with M_DONTWAIT is called which may result in a wait) or panics or other
nasty things (if called with M_WAIT which may return a NULL pointer
that is not expected and as such not tested by the calling code).

For the moment I have fixed the relevant parts in uipc_mbuf.c (fix
included below), but the real fix would probably require a change
in the last parameter to kmem_malloc to get in line with the
parameter to malloc.
--
ws@tools.de     (Wolfgang Solfrank, TooLs GmbH) +49-228-985800

--------------- cut --------------- cut --------------- cut ---------------
*** uipc_mbuf.c	Sat Jul 18 18:29:56 1992
--- /home/kurt/bsd/bsd/sys/kern/uipc_mbuf.c	Mon Aug 31 13:18:39 1992
***************
*** 71,78 ****
   * and place on cluster free list.
   * Must be called at splimp.
   */
! /* ARGSUSED */
! m_clalloc(ncl, canwait)
  	register int ncl;
  {
  	int npg, mbx;
--- 71,77 ----
   * and place on cluster free list.
   * Must be called at splimp.
   */
! m_clalloc(ncl, how)
  	register int ncl;
  {
  	int npg, mbx;
***************
*** 81,87 ****
  	static int logged;
  
  	npg = ncl * CLSIZE;
! 	p = (caddr_t)kmem_malloc(mb_map, ctob(npg), canwait);
  	if (p == NULL) {
  		if (logged == 0) {
  			logged++;
--- 80,86 ----
  	static int logged;
  
  	npg = ncl * CLSIZE;
! 	p = (caddr_t)kmem_malloc(mb_map, ctob(npg), !(how&M_DONTWAIT));
  	if (p == NULL) {
  		if (logged == 0) {
  			logged++;
***************
*** 153,184 ****
   * for critical paths.
   */
  struct mbuf *
! m_get(canwait, type)
! 	int canwait, type;
  {
  	register struct mbuf *m;
  
! 	MGET(m, canwait, type);
  	return (m);
  }
  
  struct mbuf *
! m_gethdr(canwait, type)
! 	int canwait, type;
  {
  	register struct mbuf *m;
  
! 	MGETHDR(m, canwait, type);
  	return (m);
  }
  
  struct mbuf *
! m_getclr(canwait, type)
! 	int canwait, type;
  {
  	register struct mbuf *m;
  
! 	MGET(m, canwait, type);
  	if (m == 0)
  		return (0);
  	bzero(mtod(m, caddr_t), MLEN);
--- 152,183 ----
   * for critical paths.
   */
  struct mbuf *
! m_get(how, type)
! 	int how, type;
  {
  	register struct mbuf *m;
  
! 	MGET(m, how, type);
  	return (m);
  }
  
  struct mbuf *
! m_gethdr(how, type)
! 	int how, type;
  {
  	register struct mbuf *m;
  
! 	MGETHDR(m, how, type);
  	return (m);
  }
  
  struct mbuf *
! m_getclr(how, type)
! 	int how, type;
  {
  	register struct mbuf *m;
  
! 	MGET(m, how, type);
  	if (m == 0)
  		return (0);
  	bzero(mtod(m, caddr_t), MLEN);
--------------- cut --------------- cut --------------- cut ---------------
--
ws@tools.de     (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
Newsgroups: comp.unix.bsd