From 4395e552e2eb08e6dc53ccf82bfcc4040c59bda6 Mon Sep 17 00:00:00 2001 From: green Date: Sun, 19 Sep 1999 02:17:02 +0000 Subject: [PATCH] Change so_cred's type to a ucred, not a pcred. THis makes more sense, actually. Make a sonewconn3() which takes an extra argument (proc) so new sockets created with sonewconn() from a user's system call get the correct credentials, not just the parent's credentials. --- sys/kern/uipc_sockbuf.c | 23 ++++++++++++++++------- sys/kern/uipc_socket.c | 12 ++++-------- sys/kern/uipc_socket2.c | 23 ++++++++++++++++------- sys/kern/uipc_usrreq.c | 2 +- sys/netinet/in_pcb.c | 7 +++---- sys/netinet/ip_fw.c | 12 ++++++------ sys/netinet/tcp_subr.c | 6 ++---- sys/netinet/tcp_timewait.c | 6 ++---- sys/netinet/udp_usrreq.c | 6 ++---- sys/sys/socketvar.h | 4 +++- 10 files changed, 55 insertions(+), 46 deletions(-) diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index f6115a97186e..a51f98379cd6 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -203,6 +204,16 @@ sonewconn(head, connstatus) register struct socket *head; int connstatus; { + + return (sonewconn3(head, connstatus, NULL)); +} + +struct socket * +sonewconn3(head, connstatus, p) + register struct socket *head; + int connstatus; + struct proc *p; +{ register struct socket *so; if (head->so_qlen > 3 * head->so_qlimit / 2) @@ -217,12 +228,10 @@ sonewconn(head, connstatus) so->so_state = head->so_state | SS_NOFDREF; so->so_proto = head->so_proto; so->so_timeo = head->so_timeo; - so->so_cred = head->so_cred; - if (so->so_cred) - so->so_cred->p_refcnt++; - (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat); - - if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) { + so->so_cred = p ? p->p_ucred : head->so_cred; + crhold(so->so_cred); + if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat) || + (*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) { sodealloc(so); return ((struct socket *)0); } @@ -921,7 +930,7 @@ sotoxsocket(struct socket *so, struct xsocket *xso) xso->so_oobmark = so->so_oobmark; sbtoxsockbuf(&so->so_snd, &xso->so_snd); sbtoxsockbuf(&so->so_rcv, &xso->so_rcv); - xso->so_uid = so->so_cred ? so->so_cred->pc_ucred->cr_uid : -1; + xso->so_uid = so->so_cred->cr_uid; } /* diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 0cf3c048d793..9719b79e985e 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -125,10 +125,8 @@ socreate(dom, aso, type, proto, p) TAILQ_INIT(&so->so_incomp); TAILQ_INIT(&so->so_comp); so->so_type = type; - if (p) { - so->so_cred = p->p_cred; - so->so_cred->p_refcnt++; - } else so->so_cred = NULL; + so->so_cred = p->p_ucred; + crhold(so->so_cred); so->so_proto = prp; error = (*prp->pr_usrreqs->pru_attach)(so, proto, p); if (error) { @@ -158,11 +156,9 @@ void sodealloc(so) struct socket *so; { + so->so_gencnt = ++so_gencnt; - if (so->so_cred && --so->so_cred->p_refcnt == 0) { - crfree(so->so_cred->pc_ucred); - FREE(so->so_cred, M_SUBPROC); - } + crfree(so->so_cred); zfreei(so->so_zone, so); } diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index f6115a97186e..a51f98379cd6 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -203,6 +204,16 @@ sonewconn(head, connstatus) register struct socket *head; int connstatus; { + + return (sonewconn3(head, connstatus, NULL)); +} + +struct socket * +sonewconn3(head, connstatus, p) + register struct socket *head; + int connstatus; + struct proc *p; +{ register struct socket *so; if (head->so_qlen > 3 * head->so_qlimit / 2) @@ -217,12 +228,10 @@ sonewconn(head, connstatus) so->so_state = head->so_state | SS_NOFDREF; so->so_proto = head->so_proto; so->so_timeo = head->so_timeo; - so->so_cred = head->so_cred; - if (so->so_cred) - so->so_cred->p_refcnt++; - (void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat); - - if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) { + so->so_cred = p ? p->p_ucred : head->so_cred; + crhold(so->so_cred); + if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat) || + (*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL)) { sodealloc(so); return ((struct socket *)0); } @@ -921,7 +930,7 @@ sotoxsocket(struct socket *so, struct xsocket *xso) xso->so_oobmark = so->so_oobmark; sbtoxsockbuf(&so->so_snd, &xso->so_snd); sbtoxsockbuf(&so->so_rcv, &xso->so_rcv); - xso->so_uid = so->so_cred ? so->so_cred->pc_ucred->cr_uid : -1; + xso->so_uid = so->so_cred->cr_uid; } /* diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index a48e7db0c5d1..66352aa85959 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -623,7 +623,7 @@ unp_connect(so, nam, p) } if (so->so_proto->pr_flags & PR_CONNREQUIRED) { if ((so2->so_options & SO_ACCEPTCONN) == 0 || - (so3 = sonewconn(so2, 0)) == 0) { + (so3 = sonewconn3(so2, 0, p)) == 0) { error = ECONNREFUSED; goto bad; } diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 162eaa392256..018a040302b8 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -202,7 +202,7 @@ in_pcbbind(inp, nam, p) return (EACCES); if (p && p->p_prison) prison = 1; - if (so->so_cred && so->so_cred->p_ruid != 0 && + if (so->so_cred->cr_uid != 0 && !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { t = in_pcblookup_local(inp->inp_pcbinfo, sin->sin_addr, lport, @@ -212,9 +212,8 @@ in_pcbbind(inp, nam, p) ntohl(t->inp_laddr.s_addr) != INADDR_ANY || (t->inp_socket->so_options & SO_REUSEPORT) == 0) && - (t->inp_socket->so_cred) && - (so->so_cred->p_ruid != - t->inp_socket->so_cred->p_ruid)) + (so->so_cred->cr_uid != + t->inp_socket->so_cred->cr_uid)) return (EADDRINUSE); } t = in_pcblookup_local(pcbinfo, sin->sin_addr, diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c index fadb7104f947..46c7d5403b76 100644 --- a/sys/netinet/ip_fw.c +++ b/sys/netinet/ip_fw.c @@ -698,13 +698,13 @@ again: P = in_pcblookup_hash(&tcbinfo, ip->ip_src, tcp->th_sport, ip->ip_dst, tcp->th_dport, 0); - if (P && P->inp_socket && P->inp_socket->so_cred) { + if (P && P->inp_socket) { if (f->fw_flg & IP_FW_F_UID) { - if (P->inp_socket->so_cred->p_ruid != + if (P->inp_socket->so_cred->cr_uid != f->fw_uid) continue; } else if (!groupmember(f->fw_gid, - P->inp_socket->so_cred->pc_ucred)) + P->inp_socket->so_cred)) continue; } else continue; @@ -729,13 +729,13 @@ again: P = in_pcblookup_hash(&udbinfo, ip->ip_src, udp->uh_sport, ip->ip_dst, udp->uh_dport, 1); - if (P && P->inp_socket && P->inp_socket->so_cred) { + if (P && P->inp_socket) { if (f->fw_flg & IP_FW_F_UID) { - if (P->inp_socket->so_cred->p_ruid != + if (P->inp_socket->so_cred->cr_uid != f->fw_uid) continue; } else if (!groupmember(f->fw_gid, - P->inp_socket->so_cred->pc_ucred)) + P->inp_socket->so_cred)) continue; } else continue; diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index a6a52704d29e..07da9545535a 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -641,13 +641,11 @@ tcp_getcred SYSCTL_HANDLER_ARGS s = splnet(); inp = in_pcblookup_hash(&tcbinfo, addrs[1].sin_addr, addrs[1].sin_port, addrs[0].sin_addr, addrs[0].sin_port, 0); - if (inp == NULL || inp->inp_socket == NULL || - inp->inp_socket->so_cred == NULL) { + if (inp == NULL || inp->inp_socket == NULL) { error = ENOENT; goto out; } - error = SYSCTL_OUT(req, inp->inp_socket->so_cred->pc_ucred, - sizeof(struct ucred)); + error = SYSCTL_OUT(req, inp->inp_socket->so_cred, sizeof(struct ucred)); out: splx(s); return (error); diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index a6a52704d29e..07da9545535a 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -641,13 +641,11 @@ tcp_getcred SYSCTL_HANDLER_ARGS s = splnet(); inp = in_pcblookup_hash(&tcbinfo, addrs[1].sin_addr, addrs[1].sin_port, addrs[0].sin_addr, addrs[0].sin_port, 0); - if (inp == NULL || inp->inp_socket == NULL || - inp->inp_socket->so_cred == NULL) { + if (inp == NULL || inp->inp_socket == NULL) { error = ENOENT; goto out; } - error = SYSCTL_OUT(req, inp->inp_socket->so_cred->pc_ucred, - sizeof(struct ucred)); + error = SYSCTL_OUT(req, inp->inp_socket->so_cred, sizeof(struct ucred)); out: splx(s); return (error); diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 337e796ad07a..44ff6eedec03 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -473,13 +473,11 @@ udp_getcred SYSCTL_HANDLER_ARGS s = splnet(); inp = in_pcblookup_hash(&udbinfo, addrs[1].sin_addr, addrs[1].sin_port, addrs[0].sin_addr, addrs[0].sin_port, 1); - if (inp == NULL || inp->inp_socket == NULL || - inp->inp_socket->so_cred == NULL) { + if (inp == NULL || inp->inp_socket == NULL) { error = ENOENT; goto out; } - error = SYSCTL_OUT(req, inp->inp_socket->so_cred->pc_ucred, - sizeof(struct ucred)); + error = SYSCTL_OUT(req, inp->inp_socket->so_cred, sizeof(struct ucred)); out: splx(s); return (error); diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index fb1542582c8b..25123fba055b 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -105,7 +105,7 @@ struct socket { void (*so_upcall) __P((struct socket *, void *, int)); void *so_upcallarg; - struct pcred *so_cred; /* user credentials */ + struct ucred *so_cred; /* user credentials */ /* NB: generation count must not be first; easiest to make it last. */ so_gen_t so_gencnt; /* generation count */ void *so_emuldata; /* private data for emulators */ @@ -349,6 +349,8 @@ struct socket * sodropablereq __P((struct socket *head)); struct socket * sonewconn __P((struct socket *head, int connstatus)); +struct socket * + sonewconn3 __P((struct socket *head, int connstatus, struct proc *p)); int sooptcopyin __P((struct sockopt *sopt, void *buf, size_t len, size_t minlen)); int sooptcopyout __P((struct sockopt *sopt, void *buf, size_t len));