version 1.160.2.2, 2009/05/04 08:13:49 |
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 555 fsocreate(int domain, struct socket **so |
|
Line 615 fsocreate(int domain, struct socket **so |
|
} |
} |
|
|
int |
int |
|
sofamily(const struct socket *so) |
|
{ |
|
const struct protosw *pr; |
|
const struct domain *dom; |
|
|
|
if ((pr = so->so_proto) == NULL) |
|
return AF_UNSPEC; |
|
if ((dom = pr->pr_domain) == NULL) |
|
return AF_UNSPEC; |
|
return dom->dom_family; |
|
} |
|
|
|
int |
sobind(struct socket *so, struct mbuf *nam, struct lwp *l) |
sobind(struct socket *so, struct mbuf *nam, struct lwp *l) |
{ |
{ |
int error; |
int error; |
Line 696 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 828 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 902 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 1082 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 1196 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 1340 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 1472 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 1481 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 1547 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 |