Date: Fri, 31 Oct 2008 14:30:33 +0000 (UTC) From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r184507 - in stable/7/sys: . kern netinet sys Message-ID: <200810311430.m9VEUXax082891@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bz Date: Fri Oct 31 14:30:33 2008 New Revision: 184507 URL: http://svn.freebsd.org/changeset/base/184507 Log: MFC: r183982 Add cr_canseeinpcb() doing checks using the cached socket credentials from inp_cred which is also available after the socket is gone. Switch cr_canseesocket consumers to cr_canseeinpcb. This removes an extra acquisition of the socket lock. Approved by: re (rwatson) Modified: stable/7/sys/ (props changed) stable/7/sys/kern/kern_prot.c stable/7/sys/netinet/ip_divert.c stable/7/sys/netinet/raw_ip.c stable/7/sys/netinet/tcp_subr.c stable/7/sys/netinet/udp_usrreq.c stable/7/sys/sys/systm.h Modified: stable/7/sys/kern/kern_prot.c ============================================================================== --- stable/7/sys/kern/kern_prot.c Fri Oct 31 13:01:31 2008 (r184506) +++ stable/7/sys/kern/kern_prot.c Fri Oct 31 14:30:33 2008 (r184507) @@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$"); #include "opt_compat.h" +#include "opt_inet.h" +#include "opt_inet6.h" #include "opt_mac.h" #include <sys/param.h> @@ -68,6 +70,11 @@ __FBSDID("$FreeBSD$"); #include <sys/syscallsubr.h> #include <sys/sysctl.h> +#if defined(INET) || defined(INET6) +#include <netinet/in.h> +#include <netinet/in_pcb.h> +#endif + #include <security/audit/audit.h> #include <security/mac/mac_framework.h> @@ -1704,6 +1711,34 @@ cr_canseesocket(struct ucred *cred, stru return (0); } +#if defined(INET) || defined(INET6) +/*- + * Determine whether the subject represented by cred can "see" a socket. + * Returns: 0 for permitted, ENOENT otherwise. + */ +int +cr_canseeinpcb(struct ucred *cred, struct inpcb *inp) +{ + int error; + + error = prison_check(cred, inp->inp_cred); + if (error) + return (ENOENT); +#ifdef MAC + INP_LOCK_ASSERT(inp); + error = mac_check_inpcb_visible(cred, inp); + if (error) + return (error); +#endif + if (cr_seeotheruids(cred, inp->inp_cred)) + return (ENOENT); + if (cr_seeothergids(cred, inp->inp_cred)) + return (ENOENT); + + return (0); +} +#endif + /*- * Determine whether td can wait for the exit of p. * Returns: 0 for permitted, an errno value otherwise Modified: stable/7/sys/netinet/ip_divert.c ============================================================================== --- stable/7/sys/netinet/ip_divert.c Fri Oct 31 13:01:31 2008 (r184506) +++ stable/7/sys/netinet/ip_divert.c Fri Oct 31 14:30:33 2008 (r184507) @@ -616,7 +616,7 @@ div_pcblist(SYSCTL_HANDLER_ARGS) inp = LIST_NEXT(inp, inp_list)) { INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt && - cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) + cr_canseeinpcb(req->td->td_ucred, inp) == 0) inp_list[i++] = inp; INP_RUNLOCK(inp); } Modified: stable/7/sys/netinet/raw_ip.c ============================================================================== --- stable/7/sys/netinet/raw_ip.c Fri Oct 31 13:01:31 2008 (r184506) +++ stable/7/sys/netinet/raw_ip.c Fri Oct 31 14:30:33 2008 (r184507) @@ -926,7 +926,7 @@ rip_pcblist(SYSCTL_HANDLER_ARGS) inp = LIST_NEXT(inp, inp_list)) { INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt && - cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) { + cr_canseeinpcb(req->td->td_ucred, inp) == 0) { /* XXX held references? */ inp_list[i++] = inp; } Modified: stable/7/sys/netinet/tcp_subr.c ============================================================================== --- stable/7/sys/netinet/tcp_subr.c Fri Oct 31 13:01:31 2008 (r184506) +++ stable/7/sys/netinet/tcp_subr.c Fri Oct 31 14:30:33 2008 (r184507) @@ -956,8 +956,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS) else error = EINVAL; /* Skip this inp. */ } else - error = cr_canseesocket(req->td->td_ucred, - inp->inp_socket); + error = cr_canseeinpcb(req->td->td_ucred, inp); if (error == 0) inp_list[i++] = inp; } @@ -1044,8 +1043,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS) if (inp->inp_socket == NULL) error = ENOENT; if (error == 0) - error = cr_canseesocket(req->td->td_ucred, - inp->inp_socket); + error = cr_canseeinpcb(req->td->td_ucred, inp); if (error == 0) cru2x(inp->inp_cred, &xuc); INP_RUNLOCK(inp); @@ -1106,8 +1104,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS) if (inp->inp_socket == NULL) error = ENOENT; if (error == 0) - error = cr_canseesocket(req->td->td_ucred, - inp->inp_socket); + error = cr_canseeinpcb(req->td->td_ucred, inp); if (error == 0) cru2x(inp->inp_cred, &xuc); INP_RUNLOCK(inp); Modified: stable/7/sys/netinet/udp_usrreq.c ============================================================================== --- stable/7/sys/netinet/udp_usrreq.c Fri Oct 31 13:01:31 2008 (r184506) +++ stable/7/sys/netinet/udp_usrreq.c Fri Oct 31 14:30:33 2008 (r184507) @@ -696,7 +696,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS) inp = LIST_NEXT(inp, inp_list)) { INP_RLOCK(inp); if (inp->inp_gencnt <= gencnt && - cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) + cr_canseeinpcb(req->td->td_ucred, inp) == 0) inp_list[i++] = inp; INP_RUNLOCK(inp); } @@ -765,8 +765,7 @@ udp_getcred(SYSCTL_HANDLER_ARGS) if (inp->inp_socket == NULL) error = ENOENT; if (error == 0) - error = cr_canseesocket(req->td->td_ucred, - inp->inp_socket); + error = cr_canseeinpcb(req->td->td_ucred, inp); if (error == 0) cru2x(inp->inp_cred, &xuc); INP_RUNLOCK(inp); Modified: stable/7/sys/sys/systm.h ============================================================================== --- stable/7/sys/sys/systm.h Fri Oct 31 13:01:31 2008 (r184506) +++ stable/7/sys/sys/systm.h Fri Oct 31 14:30:33 2008 (r184507) @@ -116,6 +116,7 @@ extern char **kenvp; * General function declarations. */ +struct inpcb; struct lock_object; struct malloc_type; struct mtx; @@ -230,6 +231,7 @@ void cpu_stopprofclock(void); int cr_cansee(struct ucred *u1, struct ucred *u2); int cr_canseesocket(struct ucred *cred, struct socket *so); +int cr_canseeinpcb(struct ucred *cred, struct inpcb *inp); char *getenv(const char *name); void freeenv(char *env);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810311430.m9VEUXax082891>