Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Apr 2000 23:44:11 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Alfred Perlstein <bright@wintelcom.net>
Cc:        Hellmuth Michaelis <hm@hcs.de>, garyj@muc.de, freebsd-current@FreeBSD.ORG
Subject:   Re: MLEN and crashes
Message-ID:  <Pine.BSF.4.21.0004032319210.409-100000@alphplex.bde.org>
In-Reply-To: <20000403023858.F21029@fw.wintelcom.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 3 Apr 2000, Alfred Perlstein wrote:

> * Hellmuth Michaelis <hm@hcs.de> [000403 02:12] wrote:
> > >From the keyboard of Bruce Evans:
> > 
> > > It's just a bug to allocate big structs on the kernel stack.
> > 
> > Please specify "big"! :-)
> 
> have a look at src/sys/nfs/nfs_vnops.c:
> 
> line ~2787:
> #ifndef NFS_COMMITBVECSIZ
> #define NFS_COMMITBVECSIZ	20
> #endif
> 	struct buf *bvec_on_stack[NFS_COMMITBVECSIZ];
> 	int bvecsize = 0, bveccount;
> 
> I guess 80 bytes is pushing it, some routines are worse, but 2k
> is totally out of line.

This case is an array of pointers.  Big arrays are just as bad as big
structs, of course.

Having a parameterized array size makes it hard to prove that the size
is small enough.

> If you're worried about such things happening then you can use
> the pre-processor to catch things that may make your structures
> too large.

This won't work for dynamic arrays.  E.g., vm_pageout_flush() uses
"int pageout_status[count];".  It is not immediately obvious that
count < vm_pageout_page_count where vm_pageout_page_count is either
8 or VM_PAGEOUT_PAGE_COUNT = 16.  Using a constant array size of
VM_PAGEOUT_PAGE_COUNT would be simpler, faster, and wouldn't break
K&R support.

objdump(1) can be used to find struct sizes.  E.g.,
"objdump --stabs kernel.debug | grep cstate" gives:

18052  LCSYM  0      120    c02b7a00 208921 escstate:V(0,1)
129365 LSYM   0      0      00000000 1929789 cstate:T(55,1)=s244cs_next:(55,2)=*(55,1),0,32;cs_hlen:(7,8),32,16;cs_id:(7,1),48,8;cs_filler:(7,1),56,8;slcs_u:(55,3)=u236csu_hdr:(35,14),0,1888;csu_ip:(54,1),0,160;;,64,1888;;

This shows that the last struct member has size 64 bits and offset 1888 bits.
The struct size is usually the sum of the last member offset and size.

Bruce



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0004032319210.409-100000>