X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/4452a7af2eac33dbad800bcc91f2399d62c18f53..6601e61aa18bf4f09af135ff61fc7f4771d23b06:/bsd/netat/sys_glue.c diff --git a/bsd/netat/sys_glue.c b/bsd/netat/sys_glue.c index 597835330..47d47c496 100644 --- a/bsd/netat/sys_glue.c +++ b/bsd/netat/sys_glue.c @@ -1,29 +1,23 @@ /* * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * @APPLE_LICENSE_HEADER_START@ * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + * @APPLE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1995 Apple Computer, Inc. @@ -61,6 +55,7 @@ #include #include #include +#include #include extern struct atpcb ddp_head; @@ -97,6 +92,7 @@ SYSCTL_STRUCT(_net_appletalk, OID_AUTO, ddpstats, CTLFLAG_RD, static void ioccmd_t_32_to_64( ioccmd_t *from_p, user_ioccmd_t *to_p ); static void ioccmd_t_64_to_32( user_ioccmd_t *from_p, ioccmd_t *to_p ); +atlock_t refall_lock; caddr_t atp_free_cluster_list = 0; @@ -293,7 +289,7 @@ int _ATrw(fp, rw, uio, p) struct uio *uio; struct proc *p; { - int err, len, clen = 0, res; + int s, err, len, clen = 0, res; gref_t *gref; gbuf_t *m, *mhead, *mprev; @@ -305,6 +301,7 @@ int _ATrw(fp, rw, uio, p) if ((len = uio_resid(uio)) == 0) return 0; + ATDISABLE(s, gref->lock); if (rw == UIO_READ) { KERNEL_DEBUG(DBG_ADSP_ATRW, 0, gref, len, gref->rdhead, 0); @@ -312,18 +309,23 @@ int _ATrw(fp, rw, uio, p) gref->sevents |= POLLMSG; err = msleep(&gref->event, atalk_mutex, PSOCK | PCATCH, "AT read", 0); gref->sevents &= ~POLLMSG; - if (err != 0) + if (err != 0) { + ATENABLE(s, gref->lock); return err; + } KERNEL_DEBUG(DBG_ADSP_ATRW, 1, gref, gref->rdhead, mhead, gbuf_next(mhead)); } - if (gref->errno) + if (gref->errno) { + ATENABLE(s, gref->lock); return EPIPE; + } if ((gref->rdhead = gbuf_next(mhead)) == 0) gref->rdtail = 0; KERNEL_DEBUG(DBG_ADSP_ATRW, 2, gref, gref->rdhead, mhead, gbuf_next(mhead)); + ATENABLE(s, gref->lock); //##### LD TEST 08/05 // simple_lock(&gref->lock); @@ -355,10 +357,12 @@ int _ATrw(fp, rw, uio, p) gbuf_cont(mprev) = 0; else mhead = 0; + ATDISABLE(s, gref->lock); if (gref->rdhead == 0) gref->rdtail = m; gbuf_next(m) = gref->rdhead; gref->rdhead = m; + ATENABLE(s, gref->lock); } if (mhead) gbuf_freem(mhead); @@ -371,11 +375,14 @@ int _ATrw(fp, rw, uio, p) gref->sevents |= POLLSYNC; err = msleep(&gref->event, atalk_mutex, PSOCK | PCATCH, "AT write", 0); gref->sevents &= ~POLLSYNC; - if (err != 0) + if (err != 0) { + ATENABLE(s, gref->lock); return err; + } } } + ATENABLE(s, gref->lock); /* allocate a buffer to copy in the write data */ if ((m = gbuf_alloc(AT_WR_OFFSET+len, PRI_MED)) == 0) @@ -436,7 +443,7 @@ int _ATwrite(fp, uio, cred, flags, p) /* bms: update to be callable from kernel */ int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel) { - int err = 0, len; + int s, err = 0, len; u_int size; gbuf_t *m, *mdata; ioc_t *ioc; @@ -516,6 +523,7 @@ int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel) gref_wput(gref, m); /* wait for the ioc ack */ + ATDISABLE(s, gref->lock); while ((m = gref->ichead) == 0) { gref->sevents |= POLLPRI; #ifdef APPLETALK_DEBUG @@ -524,6 +532,7 @@ int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel) err = msleep(&gref->iocevent, atalk_mutex, PSOCK | PCATCH, "AT ioctl", 0); gref->sevents &= ~POLLPRI; if (err != 0) { + ATENABLE(s, gref->lock); #ifdef APPLETALK_DEBUG kprintf("at_ioctl: EINTR\n"); #endif @@ -537,6 +546,7 @@ int at_ioctl(gref_t *gref, u_long cmd, caddr_t arg, int fromKernel) gref->ichead = gbuf_next(m); + ATENABLE(s, gref->lock); #ifdef APPLETALK_DEBUG kprintf("at_ioctl: woke up from ioc sleep gref = 0x%x\n", @@ -623,7 +633,7 @@ int _ATselect(fp, which, wql, proc) void * wql; struct proc *proc; { - int err, rc = 0; + int s, err, rc = 0; gref_t *gref; /* Radar 4128949: Drop the proc_fd lock here to avoid lock inversion issues with the other AT calls @@ -641,6 +651,7 @@ int _ATselect(fp, which, wql, proc) if (err != 0) rc = 1; else { + ATDISABLE(s, gref->lock); if (which == FREAD) { if (gref->rdhead || (gref->readable && (*gref->readable)(gref))) rc = 1; @@ -660,6 +671,7 @@ int _ATselect(fp, which, wql, proc) } else rc = 1; } + ATENABLE(s, gref->lock); } return rc; @@ -677,7 +689,9 @@ void atalk_putnext(gref, m) gref_t *gref; gbuf_t *m; { + int s; + ATDISABLE(s, gref->lock); /* *** potential leak? *** */ gbuf_next(m) = 0; @@ -722,6 +736,7 @@ void atalk_putnext(gref, m) } } /* switch gbuf_type(m) */ + ATENABLE(s, gref->lock); } /* atalk_putnext */ void atalk_enablew(gref) @@ -734,7 +749,9 @@ void atalk_enablew(gref) void atalk_flush(gref) gref_t *gref; { + int s; + ATDISABLE(s, gref->lock); if (gref->rdhead) { gbuf_freel(gref->rdhead); gref->rdhead = 0; @@ -743,6 +760,7 @@ void atalk_flush(gref) gbuf_freel(gref->ichead); gref->ichead = 0; } + ATENABLE(s, gref->lock); } /* @@ -753,6 +771,8 @@ void atalk_notify(gref, errno) register gref_t *gref; int errno; { + int s; + ATDISABLE(s, gref->lock); if (gref->atpcb_socket) { /* For DDP -- @@ -783,29 +803,35 @@ void atalk_notify(gref, errno) } } } + ATENABLE(s, gref->lock); } /* atalk_notify */ void atalk_notify_sel(gref) gref_t *gref; { + int s; + ATDISABLE(s, gref->lock); if (gref->sevents & POLLIN) { gref->sevents &= ~POLLIN; selwakeup(&gref->si); } + ATENABLE(s, gref->lock); } int atalk_peek(gref, event) gref_t *gref; unsigned char *event; { - int rc; + int s, rc; + ATDISABLE(s, gref->lock); if (gref->rdhead) { *event = *gbuf_rptr(gref->rdhead); rc = 0; } else rc = -1; + ATENABLE(s, gref->lock); return rc; } @@ -851,13 +877,15 @@ int gref_alloc(grefp) gref_t **grefp; { extern gbuf_t *atp_resource_m; - int i; + int i, s; gbuf_t *m; gref_t *gref, *gref_array; *grefp = (gref_t *)NULL; + ATDISABLE(s, refall_lock); if (gref_free_list == 0) { + ATENABLE(s, refall_lock); #ifdef APPLETALK_DEBUG kprintf("gref_alloc: gbufalloc size=%d\n", GREF_PER_BLK*sizeof(gref_t)); #endif @@ -867,6 +895,7 @@ int gref_alloc(grefp) gref_array = (gref_t *)gbuf_rptr(m); for (i=0; i < GREF_PER_BLK-1; i++) gref_array[i].atpcb_next = (gref_t *)&gref_array[i+1]; + ATDISABLE(s, refall_lock); gbuf_cont(m) = atp_resource_m; atp_resource_m = m; gref_array[i].atpcb_next = gref_free_list; @@ -875,6 +904,10 @@ int gref_alloc(grefp) gref = gref_free_list; gref_free_list = gref->atpcb_next; + ATENABLE(s, refall_lock); + ATLOCKINIT(gref->lock); +//### LD Test 08/05/98 +// simple_lock_init(&gref->lock); ATEVENTINIT(gref->event); ATEVENTINIT(gref->iocevent); @@ -888,7 +921,7 @@ int gref_alloc(grefp) /* bms: make gref_close callable from kernel */ int gref_close(gref_t *gref) { - int rc; + int s, rc; switch (gref->proto) { @@ -916,9 +949,11 @@ int gref_close(gref_t *gref) selthreadclear(&gref->si); /* from original gref_free() */ + ATDISABLE(s, refall_lock); bzero((char *)gref, sizeof(gref_t)); gref->atpcb_next = gref_free_list; gref_free_list = gref; + ATENABLE(s, refall_lock); } return rc; @@ -955,7 +990,7 @@ struct mbuf *m_clattach(extbuf, extfree, extsize, extarg, wait) m->m_ext.ext_size = extsize; m->m_ext.ext_arg = extarg; m->m_ext.ext_refs.forward = - m->m_ext.ext_refs.backward = &m->m_ext.ext_refs; + m->m_ext.ext_refs.backward = &m->m_ext.ext_refs; m->m_data = extbuf; m->m_flags |= M_EXT; @@ -1032,8 +1067,17 @@ struct mbuf *m_lgbuf_alloc(size, wait) struct mbuf *m; if (atp_free_cluster_list) - atp_delete_free_clusters(); /* delete any free clusters on the free list */ - + atp_delete_free_clusters(NULL); /* delete any free clusters on the free list */ + + /* Radar 5423399 + * check that the passed size is within admissible boundaries + * The max data size being ASP of 4576 (8 * ATP_DATA_SIZE), + * allow for extra space for control data + */ + + if (size < 0 || size > (ATP_DATA_SIZE * 10)) + return(NULL); + /* If size is too large, allocate a cluster, otherwise, use the standard mbuf allocation routines.*/ if (size > MCLBYTES) {