? lib/libkern/ssp.c Index: conf/Makefile.kern.inc =================================================================== RCS file: /cvsroot/src/sys/conf/Makefile.kern.inc,v retrieving revision 1.91 diff -u -u -r1.91 Makefile.kern.inc --- conf/Makefile.kern.inc 30 Oct 2006 17:56:30 -0000 1.91 +++ conf/Makefile.kern.inc 5 Nov 2006 14:17:42 -0000 @@ -89,6 +89,11 @@ CFLAGS+= -fno-strict-aliasing .endif +.if ${USE_SSP} == "yes" +CFLAGS+=-fstack-protector-all -Wstack-protector +LDFLAGS+=-fstack-protector-all -Wstack-protector +.endif + # If we want the bpendtsleep: label in kern_synch.c, we need to use # -fno-reorder-blocks. Don't make this a config(1) defflag without # making sure this fragment remains valid. Index: dev/cgd.c =================================================================== RCS file: /cvsroot/src/sys/dev/cgd.c,v retrieving revision 1.39 diff -u -u -r1.39 cgd.c --- dev/cgd.c 12 Oct 2006 06:57:27 -0000 1.39 +++ dev/cgd.c 5 Nov 2006 14:17:43 -0000 @@ -542,6 +542,12 @@ if (ret) goto bail; + if (ci->ci_blocksize > 4096) { + printf("cgd: large blocksize %zu\n", ci->ci_blocksize); + ret = ENOMEM; + goto bail; + } + cs->sc_cdata.cf_blocksize = ci->ci_blocksize; cs->sc_cdata.cf_mode = CGD_CIPHER_CBC_ENCBLKNO; cs->sc_cdata.cf_priv = cs->sc_cfuncs->cf_init(ci->ci_keylen, inbuf, @@ -727,9 +733,9 @@ struct iovec dstiov[2]; struct iovec srciov[2]; int blocksize = cs->sc_cdata.cf_blocksize; - char sink[blocksize]; - char zero_iv[blocksize]; - char blkno_buf[blocksize]; + char *sink; + char *zero_iv; + char *blkno_buf; DPRINTF_FOLLOW(("cgd_cipher() dir=%d\n", dir)); @@ -740,7 +746,9 @@ DIAGCONDPANIC(sizeof(daddr_t) > blocksize, ("cgd_cipher: sizeof(daddr_t) > blocksize")); - memset(zero_iv, 0x0, sizeof(zero_iv)); + zero_iv = malloc(blocksize, M_TEMP, M_WAITOK|M_ZERO); + sink = malloc(blocksize, M_TEMP, M_WAITOK); + blkno_buf = malloc(blocksize, M_TEMP, M_WAITOK); dstuio.uio_iov = dstiov; dstuio.uio_iovcnt = 2; @@ -783,6 +791,9 @@ src += secsize; blkno++; } + free(zero_iv, M_TEMP); + free(sink, M_TEMP); + free(blkno_buf, M_TEMP); } #ifdef DEBUG Index: kern/uipc_socket.c =================================================================== RCS file: /cvsroot/src/sys/kern/uipc_socket.c,v retrieving revision 1.129 diff -u -u -r1.129 uipc_socket.c --- kern/uipc_socket.c 1 Nov 2006 10:17:59 -0000 1.129 +++ kern/uipc_socket.c 5 Nov 2006 14:17:47 -0000 @@ -261,6 +261,7 @@ vsize_t len; paddr_t pa; int i, npgs; + struct vm_page **apgs = NULL; eva = round_page((vaddr_t) buf + size); sva = trunc_page((vaddr_t) buf); @@ -268,7 +269,7 @@ npgs = len >> PAGE_SHIFT; if (__predict_false(pgs == NULL)) { - pgs = alloca(npgs * sizeof(*pgs)); + apgs = pgs = malloc(npgs * sizeof(*pgs), M_TEMP, M_WAITOK); for (i = 0, va = sva; va < eva; i++, va += PAGE_SIZE) { if (pmap_extract(pmap_kernel(), va, &pa) == FALSE) @@ -280,6 +281,8 @@ pmap_kremove(sva, len); pmap_update(pmap_kernel()); uvm_unloan(pgs, npgs, UVM_LOAN_TOPAGE); + if (apgs != NULL) + free(apgs, M_TEMP); sokvafree(sva, len); } Index: lib/libkern/Makefile =================================================================== RCS file: /cvsroot/src/sys/lib/libkern/Makefile,v retrieving revision 1.83 diff -u -u -r1.83 Makefile --- lib/libkern/Makefile 27 Oct 2006 21:20:48 -0000 1.83 +++ lib/libkern/Makefile 5 Nov 2006 14:17:47 -0000 @@ -55,6 +55,8 @@ SRCS+= xlat_mbr_fstype.c +SRCS+= ssp.c + # Files to clean up CLEANFILES+= lib${LIB}.o lib${LIB}.po Index: miscfs/genfs/genfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/genfs/genfs_vnops.c,v retrieving revision 1.137 diff -u -u -r1.137 genfs_vnops.c --- miscfs/genfs/genfs_vnops.c 20 Oct 2006 18:58:12 -0000 1.137 +++ miscfs/genfs/genfs_vnops.c 5 Nov 2006 14:17:49 -0000 @@ -1062,7 +1062,7 @@ off_t off; int flags = ap->a_flags; /* Even for strange MAXPHYS, the shift rounds down to a page */ - const int maxpages = MAXPHYS >> PAGE_SHIFT; +#define maxpages (MAXPHYS >> PAGE_SHIFT) int i, s, error, npages, nback; int freeflag; struct vm_page *pgs[maxpages], *pg, *nextpg, *tpg, curmp, endmp; Index: nfs/nfs_bio.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_bio.c,v retrieving revision 1.145 diff -u -u -r1.145 nfs_bio.c --- nfs/nfs_bio.c 23 Jul 2006 22:06:14 -0000 1.145 +++ nfs/nfs_bio.c 5 Nov 2006 14:17:51 -0000 @@ -1027,7 +1027,7 @@ int iomode; boolean_t stalewriteverf = FALSE; int i, npages = (bp->b_bcount + PAGE_SIZE - 1) >> PAGE_SHIFT; - struct vm_page *pgs[npages]; + struct vm_page **pgs; #ifndef NFS_V2_ONLY boolean_t needcommit = TRUE; /* need only COMMIT RPC */ #else @@ -1049,6 +1049,7 @@ #endif lockmgr(&nmp->nm_writeverflock, LK_SHARED, NULL); + pgs = malloc(npages * sizeof(*pgs), M_TEMP, M_WAITOK); for (i = 0; i < npages; i++) { pgs[i] = uvm_pageratop((vaddr_t)bp->b_data + (i << PAGE_SHIFT)); if (pgs[i]->uobject == uobj && @@ -1223,6 +1224,7 @@ if (stalewriteverf) { nfs_clearcommit(vp->v_mount); } + free(pgs, M_TEMP); return error; } @@ -1325,13 +1327,14 @@ struct uvm_object *uobj = &vp->v_uobj; struct nfsnode *np = VTONFS(vp); const int npages = *ap->a_count; - struct vm_page *pg, **pgs, *opgs[npages]; + struct vm_page *pg, **pgs, **opgs; off_t origoffset, len; int i, error; boolean_t v3 = NFS_ISV3(vp); boolean_t write = (ap->a_access_type & VM_PROT_WRITE) != 0; boolean_t locked = (ap->a_flags & PGO_LOCKED) != 0; + opgs = malloc(npages * sizeof(*opgs), M_TEMP, M_WAITOK); /* * call the genfs code to get the pages. `pgs' may be NULL * when doing read-ahead. @@ -1353,9 +1356,8 @@ memcpy(opgs, pgs, npages * sizeof(struct vm_pages *)); } error = genfs_getpages(v); - if (error) { - return (error); - } + if (error) + goto out; /* * for read faults where the nfs node is not yet marked NMODIFIED, @@ -1380,7 +1382,7 @@ } } if (!write) { - return (0); + goto out; } /* @@ -1409,7 +1411,7 @@ *ap->a_count = 0; memcpy(pgs, opgs, npages * sizeof(struct vm_pages *)); - return (error); + goto out; } nfs_del_committed_range(vp, origoffset, len); nfs_del_tobecommitted_range(vp, origoffset, len); @@ -1431,5 +1433,7 @@ if (v3) { lockmgr(&np->n_commitlock, LK_RELEASE, NULL); } - return (0); +out: + free(opgs, M_TEMP); + return error; } Index: ufs/ufs/ufs_inode.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_inode.c,v retrieving revision 1.61 diff -u -u -r1.61 ufs_inode.c --- ufs/ufs/ufs_inode.c 14 Oct 2006 09:17:26 -0000 1.61 +++ ufs/ufs/ufs_inode.c 5 Nov 2006 14:17:53 -0000 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -211,7 +212,7 @@ int bshift = vp->v_mount->mnt_fs_bshift; int bsize = 1 << bshift; int ppb = MAX(bsize >> PAGE_SHIFT, 1); - struct vm_page *pgs[ppb]; + struct vm_page **pgs; UVMHIST_FUNC("ufs_balloc_range"); UVMHIST_CALLED(ubchist); UVMHIST_LOG(ubchist, "vp %p off 0x%x len 0x%x u_size 0x%x", vp, off, len, vp->v_size); @@ -221,6 +222,7 @@ error = 0; uobj = &vp->v_uobj; + pgs = malloc(ppb * sizeof(*pgs), M_TEMP, M_WAITOK); pgs[0] = NULL; /* @@ -237,9 +239,8 @@ error = VOP_GETPAGES(vp, pagestart, pgs, &npages, 0, VM_PROT_WRITE, 0, PGO_SYNCIO|PGO_PASTEOF|PGO_NOBLOCKALLOC|PGO_NOTIMESTAMP); - if (error) { - return error; - } + if (error) + goto out; simple_lock(&uobj->vmobjlock); uvm_lock_pageq(); for (i = 0; i < npages; i++) { @@ -290,5 +291,7 @@ uvm_page_unbusy(pgs, npages); } simple_unlock(&uobj->vmobjlock); +out: + free(pgs, M_TEMP); return error; } Index: ufs/ufs/ufs_lookup.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_lookup.c,v retrieving revision 1.79 diff -u -u -r1.79 ufs_lookup.c --- ufs/ufs/ufs_lookup.c 23 Jul 2006 22:06:15 -0000 1.79 +++ ufs/ufs/ufs_lookup.c 5 Nov 2006 14:17:54 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -1331,14 +1332,16 @@ daddr_t lbn; int error; const int dirrablks = ufs_dirrablks; - daddr_t blks[1 + dirrablks]; - int blksizes[1 + dirrablks]; + daddr_t *blks; + int *blksizes; int run; struct mount *mp = vp->v_mount; const int bshift = mp->mnt_fs_bshift; const int bsize = 1 << bshift; off_t eof; + blks = malloc((1 + dirrablks) * sizeof(*blks), M_TEMP, M_WAITOK); + blksizes = malloc((1 + dirrablks) * sizeof(*blksizes), M_TEMP, M_WAITOK); ip = VTOI(vp); KASSERT(vp->v_size == ip->i_size); GOP_SIZE(vp, vp->v_size, &eof, 0); @@ -1371,5 +1374,7 @@ *res = (char *)bp->b_data + (offset & (bsize - 1)); } *bpp = bp; + free(blks, M_TEMP); + free(blksizes, M_TEMP); return 0; } Index: uvm/uvm_bio.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_bio.c,v retrieving revision 1.54 diff -u -u -r1.54 uvm_bio.c --- uvm/uvm_bio.c 1 Nov 2006 10:18:27 -0000 1.54 +++ uvm/uvm_bio.c 5 Nov 2006 14:17:54 -0000 @@ -226,10 +226,14 @@ struct ubc_map *umap; vaddr_t va, eva, ubc_offset, slot_offset; int i, error, npages; - struct vm_page *pgs[ubc_winsize >> PAGE_SHIFT], *pg; + struct vm_page **pgs, *pg; vm_prot_t prot; UVMHIST_FUNC("ubc_fault"); UVMHIST_CALLED(ubchist); + pgs = malloc((ubc_winsize >> PAGE_SHIFT) * sizeof(*pgs), M_TEMP, + M_NOWAIT); + if (pgs == NULL) + return ENOMEM; /* * no need to try with PGO_LOCKED... * we don't need to have the map locked since we know that @@ -302,9 +306,8 @@ tsleep(&lbolt, PVM, "ubc_fault", 0); goto again; } - if (error) { - return error; - } + if (error) + goto out; va = ufi->orig_rvaddr; eva = ufi->orig_rvaddr + (npages << PAGE_SHIFT); @@ -399,7 +402,9 @@ } } pmap_update(ufi->orig_map->pmap); - return 0; +out: + free(pgs, M_TEMP); + return error; } /* @@ -506,7 +511,11 @@ if (flags & UBC_FAULTBUSY) { int npages = (*lenp + PAGE_SIZE - 1) >> PAGE_SHIFT; - struct vm_page *pgs[npages]; + struct vm_page **pgs; + pgs = malloc((ubc_winsize >> PAGE_SHIFT) * sizeof(*pgs), M_TEMP, + M_NOWAIT); + if (pgs == NULL) + panic("can't allocate pgs"); int gpflags = PGO_SYNCIO|PGO_OVERWRITE|PGO_PASTEOF|PGO_NOBLOCKALLOC| PGO_NOTIMESTAMP; @@ -532,6 +541,7 @@ } pmap_update(pmap_kernel()); umap->flags |= UMAP_PAGES_LOCKED; + free(pgs, M_TEMP); } out: @@ -563,7 +573,7 @@ int zerolen = round_page(endoff) - endoff; int npages = (int)(round_page(umap->writeoff + umap->writelen) - trunc_page(umap->writeoff)) >> PAGE_SHIFT; - struct vm_page *pgs[npages]; + struct vm_page **pgs; paddr_t pa; int i; boolean_t rv; @@ -573,6 +583,10 @@ } umap->flags &= ~UMAP_PAGES_LOCKED; uvm_lock_pageq(); + pgs = malloc((ubc_winsize >> PAGE_SHIFT) * sizeof(*pgs), M_TEMP, + M_NOWAIT); + if (pgs == NULL) + panic("can't allocate pgs"); for (i = 0; i < npages; i++) { rv = pmap_extract(pmap_kernel(), umapva + slot_offset + (i << PAGE_SHIFT), &pa); @@ -582,6 +596,7 @@ KASSERT(pgs[i]->loan_count == 0); uvm_pageactivate(pgs[i]); } + free(pgs, M_TEMP); uvm_unlock_pageq(); pmap_kremove(umapva, ubc_winsize); pmap_update(pmap_kernel()); Index: uvm/uvm_pager.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_pager.c,v retrieving revision 1.78 diff -u -u -r1.78 uvm_pager.c --- uvm/uvm_pager.c 15 Sep 2006 15:51:13 -0000 1.78 +++ uvm/uvm_pager.c 5 Nov 2006 14:17:54 -0000 @@ -290,7 +290,7 @@ uvm_aio_aiodone(struct buf *bp) { int npages = bp->b_bufsize >> PAGE_SHIFT; - struct vm_page *pg, *pgs[npages]; + struct vm_page *pg, **pgs; struct uvm_object *uobj; struct simplelock *slock; int s, i, error, swslot; @@ -306,6 +306,7 @@ } uobj = NULL; + pgs = malloc(npages * sizeof(*pgs), M_TEMP, M_WAITOK); for (i = 0; i < npages; i++) { pgs[i] = uvm_pageratop((vaddr_t)bp->b_data + (i << PAGE_SHIFT)); UVMHIST_LOG(ubchist, "pgs[%d] = %p", i, pgs[i],0,0); @@ -450,6 +451,7 @@ } #endif /* defined(VMSWAP) */ } + free(pgs, M_TEMP); if (!swap) { uvm_page_unbusy(pgs, npages); uvm_unlock_pageq(); --- /dev/null 2006-11-05 09:18:00.000000000 -0500 +++ lib/libkern/ssp.c 2006-11-05 09:10:37.000000000 -0500 @@ -0,0 +1,60 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2006 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static void __guard_setup(void) __attribute__((__constructor__, __used__)); +void __stack_chk_fail(void); + +/*LINTED used*/ +static void +__guard_setup(void) +{ + if (__stack_chk_guard[0] != 0) + return; + + arc4randbytes(__stack_chk_guard, sizeof(__stack_chk_guard)); +} + +void +__stack_chk_fail(void) +{ + panic("stack overflow detected; terminated"); +}