| version 1.160.2.3, 2009/09/16 13:38:01 |
version 1.160.2.4, 2010/03/11 15:04:20 |
| Line 151 int somaxkva = SOMAXKVA; |
|
| Line 151 int somaxkva = SOMAXKVA; |
|
| static int socurkva; |
static int socurkva; |
| static kcondvar_t socurkva_cv; |
static kcondvar_t socurkva_cv; |
| |
|
| |
static kauth_listener_t socket_listener; |
| |
|
| #define SOCK_LOAN_CHUNK 65536 |
#define SOCK_LOAN_CHUNK 65536 |
| |
|
| static size_t sodopendfree(void); |
static size_t sodopendfree(void); |
| Line 384 sosend_loan(struct socket *so, struct ui |
|
| Line 386 sosend_loan(struct socket *so, struct ui |
|
| |
|
| for (i = 0, va = lva; i < npgs; i++, va += PAGE_SIZE) |
for (i = 0, va = lva; i < npgs; i++, va += PAGE_SIZE) |
| pmap_kenter_pa(va, VM_PAGE_TO_PHYS(m->m_ext.ext_pgs[i]), |
pmap_kenter_pa(va, VM_PAGE_TO_PHYS(m->m_ext.ext_pgs[i]), |
| VM_PROT_READ); |
VM_PROT_READ, 0); |
| pmap_update(pmap_kernel()); |
pmap_update(pmap_kernel()); |
| |
|
| lva += (vaddr_t) iov->iov_base & PAGE_MASK; |
lva += (vaddr_t) iov->iov_base & PAGE_MASK; |
| Line 428 getsombuf(struct socket *so, int type) |
|
| Line 430 getsombuf(struct socket *so, int type) |
|
| return m; |
return m; |
| } |
} |
| |
|
| |
static int |
| |
socket_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, |
| |
void *arg0, void *arg1, void *arg2, void *arg3) |
| |
{ |
| |
int result; |
| |
enum kauth_network_req req; |
| |
|
| |
result = KAUTH_RESULT_DEFER; |
| |
req = (enum kauth_network_req)arg0; |
| |
|
| |
if ((action != KAUTH_NETWORK_SOCKET) && |
| |
(action != KAUTH_NETWORK_BIND)) |
| |
return result; |
| |
|
| |
switch (req) { |
| |
case KAUTH_REQ_NETWORK_BIND_PORT: |
| |
result = KAUTH_RESULT_ALLOW; |
| |
break; |
| |
|
| |
case KAUTH_REQ_NETWORK_SOCKET_DROP: { |
| |
/* Normal users can only drop their own connections. */ |
| |
struct socket *so = (struct socket *)arg1; |
| |
|
| |
if (proc_uidmatch(cred, so->so_cred)) |
| |
result = KAUTH_RESULT_ALLOW; |
| |
|
| |
break; |
| |
} |
| |
|
| |
case KAUTH_REQ_NETWORK_SOCKET_OPEN: |
| |
/* We allow "raw" routing/bluetooth sockets to anyone. */ |
| |
if ((u_long)arg1 == PF_ROUTE || (u_long)arg1 == PF_BLUETOOTH) |
| |
result = KAUTH_RESULT_ALLOW; |
| |
else { |
| |
/* Privileged, let secmodel handle this. */ |
| |
if ((u_long)arg2 == SOCK_RAW) |
| |
break; |
| |
} |
| |
|
| |
result = KAUTH_RESULT_ALLOW; |
| |
|
| |
break; |
| |
|
| |
case KAUTH_REQ_NETWORK_SOCKET_CANSEE: |
| |
result = KAUTH_RESULT_ALLOW; |
| |
|
| |
break; |
| |
|
| |
default: |
| |
break; |
| |
} |
| |
|
| |
return result; |
| |
} |
| |
|
| void |
void |
| soinit(void) |
soinit(void) |
| { |
{ |
|
|
| |
|
| callback_register(&vm_map_to_kernel(kernel_map)->vmk_reclaim_callback, |
callback_register(&vm_map_to_kernel(kernel_map)->vmk_reclaim_callback, |
| &sokva_reclaimerentry, NULL, sokva_reclaim_callback); |
&sokva_reclaimerentry, NULL, sokva_reclaim_callback); |
| |
|
| |
socket_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK, |
| |
socket_listener_cb, NULL); |
| } |
} |
| |
|
| /* |
/* |
| Line 501 socreate(int dom, struct socket **aso, i |
|
| Line 561 socreate(int dom, struct socket **aso, i |
|
| #endif |
#endif |
| uid = kauth_cred_geteuid(l->l_cred); |
uid = kauth_cred_geteuid(l->l_cred); |
| so->so_uidinfo = uid_find(uid); |
so->so_uidinfo = uid_find(uid); |
| so->so_egid = kauth_cred_getegid(l->l_cred); |
|
| so->so_cpid = l->l_proc->p_pid; |
so->so_cpid = l->l_proc->p_pid; |
| if (lockso != NULL) { |
if (lockso != NULL) { |
| /* Caller wants us to share a lock. */ |
/* Caller wants us to share a lock. */ |
| Line 520 socreate(int dom, struct socket **aso, i |
|
| Line 579 socreate(int dom, struct socket **aso, i |
|
| sofree(so); |
sofree(so); |
| return error; |
return error; |
| } |
} |
| |
so->so_cred = kauth_cred_dup(l->l_cred); |
| sounlock(so); |
sounlock(so); |
| *aso = so; |
*aso = so; |
| return 0; |
return 0; |
| Line 709 soclose(struct socket *so) |
|
| Line 769 soclose(struct socket *so) |
|
| discard: |
discard: |
| if (so->so_state & SS_NOFDREF) |
if (so->so_state & SS_NOFDREF) |
| panic("soclose: NOFDREF"); |
panic("soclose: NOFDREF"); |
| |
kauth_cred_free(so->so_cred); |
| so->so_state |= SS_NOFDREF; |
so->so_state |= SS_NOFDREF; |
| sofree(so); |
sofree(so); |
| return (error); |
return (error); |
| Line 841 sosend(struct socket *so, struct mbuf *a |
|
| Line 902 sosend(struct socket *so, struct mbuf *a |
|
| struct proc *p; |
struct proc *p; |
| long space, len, resid, clen, mlen; |
long space, len, resid, clen, mlen; |
| int error, s, dontroute, atomic; |
int error, s, dontroute, atomic; |
| |
short wakeup_state = 0; |
| |
|
| p = l->l_proc; |
p = l->l_proc; |
| sodopendfree(); |
sodopendfree(); |
| Line 915 sosend(struct socket *so, struct mbuf *a |
|
| Line 977 sosend(struct socket *so, struct mbuf *a |
|
| goto release; |
goto release; |
| } |
} |
| sbunlock(&so->so_snd); |
sbunlock(&so->so_snd); |
| |
if (wakeup_state & SS_RESTARTSYS) { |
| |
error = ERESTART; |
| |
goto out; |
| |
} |
| error = sbwait(&so->so_snd); |
error = sbwait(&so->so_snd); |
| if (error) |
if (error) |
| goto out; |
goto out; |
| |
wakeup_state = so->so_state; |
| goto restart; |
goto restart; |
| } |
} |
| |
wakeup_state = 0; |
| mp = ⊤ |
mp = ⊤ |
| space -= clen; |
space -= clen; |
| do { |
do { |
| Line 1095 soreceive(struct socket *so, struct mbuf |
|
| Line 1163 soreceive(struct socket *so, struct mbuf |
|
| struct mbuf *nextrecord; |
struct mbuf *nextrecord; |
| int mbuf_removed = 0; |
int mbuf_removed = 0; |
| const struct domain *dom; |
const struct domain *dom; |
| |
short wakeup_state = 0; |
| |
|
| pr = so->so_proto; |
pr = so->so_proto; |
| atomic = pr->pr_flags & PR_ATOMIC; |
atomic = pr->pr_flags & PR_ATOMIC; |
| Line 1209 soreceive(struct socket *so, struct mbuf |
|
| Line 1278 soreceive(struct socket *so, struct mbuf |
|
| SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 1"); |
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 1"); |
| SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1"); |
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1"); |
| sbunlock(&so->so_rcv); |
sbunlock(&so->so_rcv); |
| error = sbwait(&so->so_rcv); |
if (wakeup_state & SS_RESTARTSYS) |
| |
error = ERESTART; |
| |
else |
| |
error = sbwait(&so->so_rcv); |
| if (error != 0) { |
if (error != 0) { |
| sounlock(so); |
sounlock(so); |
| splx(s); |
splx(s); |
| return error; |
return error; |
| } |
} |
| |
wakeup_state = so->so_state; |
| goto restart; |
goto restart; |
| } |
} |
| dontblock: |
dontblock: |
| Line 1353 soreceive(struct socket *so, struct mbuf |
|
| Line 1426 soreceive(struct socket *so, struct mbuf |
|
| panic("receive 3"); |
panic("receive 3"); |
| #endif |
#endif |
| so->so_state &= ~SS_RCVATMARK; |
so->so_state &= ~SS_RCVATMARK; |
| |
wakeup_state = 0; |
| len = uio->uio_resid; |
len = uio->uio_resid; |
| if (so->so_oobmark && len > so->so_oobmark - offset) |
if (so->so_oobmark && len > so->so_oobmark - offset) |
| len = so->so_oobmark - offset; |
len = so->so_oobmark - offset; |
| Line 1485 soreceive(struct socket *so, struct mbuf |
|
| Line 1559 soreceive(struct socket *so, struct mbuf |
|
| NULL, (struct mbuf *)(long)flags, NULL, l); |
NULL, (struct mbuf *)(long)flags, NULL, l); |
| SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2"); |
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2"); |
| SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2"); |
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2"); |
| error = sbwait(&so->so_rcv); |
if (wakeup_state & SS_RESTARTSYS) |
| |
error = ERESTART; |
| |
else |
| |
error = sbwait(&so->so_rcv); |
| if (error != 0) { |
if (error != 0) { |
| sbunlock(&so->so_rcv); |
sbunlock(&so->so_rcv); |
| sounlock(so); |
sounlock(so); |
| Line 1494 soreceive(struct socket *so, struct mbuf |
|
| Line 1571 soreceive(struct socket *so, struct mbuf |
|
| } |
} |
| if ((m = so->so_rcv.sb_mb) != NULL) |
if ((m = so->so_rcv.sb_mb) != NULL) |
| nextrecord = m->m_nextpkt; |
nextrecord = m->m_nextpkt; |
| |
wakeup_state = so->so_state; |
| } |
} |
| } |
} |
| |
|
| Line 1560 soshutdown(struct socket *so, int how) |
|
| Line 1638 soshutdown(struct socket *so, int how) |
|
| return error; |
return error; |
| } |
} |
| |
|
| int |
void |
| sodrain(struct socket *so) |
sorestart(struct socket *so) |
| { |
{ |
| int error; |
/* |
| |
* An application has called close() on an fd on which another |
| |
* of its threads has called a socket system call. |
| |
* Mark this and wake everyone up, and code that would block again |
| |
* instead returns ERESTART. |
| |
* On system call re-entry the fd is validated and EBADF returned. |
| |
* Any other fd will block again on the 2nd syscall. |
| |
*/ |
| solock(so); |
solock(so); |
| so->so_state |= SS_ISDRAINING; |
so->so_state |= SS_RESTARTSYS; |
| cv_broadcast(&so->so_cv); |
cv_broadcast(&so->so_cv); |
| error = soshutdown(so, SHUT_RDWR); |
cv_broadcast(&so->so_snd.sb_cv); |
| |
cv_broadcast(&so->so_rcv.sb_cv); |
| sounlock(so); |
sounlock(so); |
| |
|
| return error; |
|
| } |
} |
| |
|
| void |
void |