diff options
author | bz <bz@FreeBSD.org> | 2008-02-02 14:11:31 +0000 |
---|---|---|
committer | bz <bz@FreeBSD.org> | 2008-02-02 14:11:31 +0000 |
commit | cfb85f0c07e631c309f5158c6aeebac935619b92 (patch) | |
tree | dbf75dec875afa39ded965d6896a91bf2171580d | |
parent | ddf9fd25a8b759fac39499e04a7624ae5c938dd0 (diff) | |
download | FreeBSD-src-cfb85f0c07e631c309f5158c6aeebac935619b92.zip FreeBSD-src-cfb85f0c07e631c309f5158c6aeebac935619b92.tar.gz |
Rather than passing around a cached 'priv', pass in an ucred to
ipsec*_set_policy and do the privilege check only if needed.
Try to assimilate both ip*_ctloutput code blocks calling ipsec*_set_policy.
Reviewed by: rwatson
-rw-r--r-- | sys/netinet/ip_output.c | 25 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 35 | ||||
-rw-r--r-- | sys/netipsec/ipsec.c | 25 | ||||
-rw-r--r-- | sys/netipsec/ipsec.h | 2 | ||||
-rw-r--r-- | sys/netipsec/ipsec6.h | 2 |
5 files changed, 30 insertions, 59 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 4105fe4..2cdf1a6 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -43,10 +43,12 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/priv.h> +#include <sys/proc.h> #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/sysctl.h> +#include <sys/ucred.h> #include <net/if.h> #include <net/netisr.h> @@ -972,33 +974,16 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) case IP_IPSEC_POLICY: { caddr_t req; - size_t len = 0; - int priv; struct mbuf *m; - int optname; if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */ break; if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */ break; - if (sopt->sopt_td != NULL) { - /* - * XXXRW: Would be more desirable to do this - * one layer down so that we only exercise - * privilege if it is needed. - */ - error = priv_check(sopt->sopt_td, - PRIV_NETINET_IPSEC); - if (error) - priv = 0; - else - priv = 1; - } else - priv = 1; req = mtod(m, caddr_t); - len = m->m_len; - optname = sopt->sopt_name; - error = ipsec4_set_policy(inp, optname, req, len, priv); + error = ipsec4_set_policy(inp, sopt->sopt_name, req, + m->m_len, (sopt->sopt_td != NULL) ? + sopt->sopt_td->td_ucred : NULL); m_freem(m); break; } diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 4b6c52e..8f7caa5 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -68,15 +68,16 @@ __FBSDID("$FreeBSD$"); #include "opt_ipsec.h" #include <sys/param.h> +#include <sys/kernel.h> #include <sys/malloc.h> #include <sys/mbuf.h> -#include <sys/proc.h> #include <sys/errno.h> #include <sys/priv.h> +#include <sys/proc.h> #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> -#include <sys/kernel.h> +#include <sys/ucred.h> #include <net/if.h> #include <net/netisr.h> @@ -1767,39 +1768,21 @@ do { \ #ifdef IPSEC case IPV6_IPSEC_POLICY: - { - caddr_t req = NULL; - size_t len = 0; + { + caddr_t req; struct mbuf *m; - int priv = 0; if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */ break; if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */ break; - if (m) { - req = mtod(m, caddr_t); - len = m->m_len; - } - if (sopt->sopt_td != NULL) { - /* - * XXXRW/XXX-BZ: Would be more desirable to do - * this one layer down so that we only exercise - * privilege if it is needed. - */ - error = priv_check(sopt->sopt_td, - PRIV_NETINET_IPSEC); - if (error) - priv = 0; - else - priv = 1; - } else - priv = 1; + req = mtod(m, caddr_t); error = ipsec6_set_policy(in6p, optname, req, - len, priv); + m->m_len, (sopt->sopt_td != NULL) ? + sopt->sopt_td->td_ucred : NULL); m_freem(m); - } break; + } #endif /* IPSEC */ default: diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index 354157b..a99759b 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -219,7 +219,7 @@ static int ipsec6_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *)); static void ipsec_delpcbpolicy __P((struct inpcbpolicy *)); static struct secpolicy *ipsec_deepcopy_policy __P((struct secpolicy *src)); static int ipsec_set_policy __P((struct secpolicy **pcb_sp, - int optname, caddr_t request, size_t len, int priv)); + int optname, caddr_t request, size_t len, struct ucred *cred)); static int ipsec_get_policy __P((struct secpolicy *pcb_sp, struct mbuf **mp)); static void vshiftl __P((unsigned char *, int, int)); static size_t ipsec_hdrsiz __P((struct secpolicy *)); @@ -1005,12 +1005,12 @@ fail: /* set policy and ipsec request if present. */ static int -ipsec_set_policy(pcb_sp, optname, request, len, priv) +ipsec_set_policy(pcb_sp, optname, request, len, cred) struct secpolicy **pcb_sp; int optname; caddr_t request; size_t len; - int priv; + struct ucred *cred; { struct sadb_x_policy *xpl; struct secpolicy *newsp = NULL; @@ -1034,8 +1034,11 @@ ipsec_set_policy(pcb_sp, optname, request, len, priv) return EINVAL; /* check privileged socket */ - if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS) - return EACCES; + if (cred != NULL && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS) { + error = priv_check_cred(cred, PRIV_NETINET_IPSEC, 0); + if (error) + return EACCES; + } /* allocation new SP entry */ if ((newsp = key_msg2sp(xpl, len, &error)) == NULL) @@ -1077,12 +1080,12 @@ ipsec_get_policy(pcb_sp, mp) } int -ipsec4_set_policy(inp, optname, request, len, priv) +ipsec4_set_policy(inp, optname, request, len, cred) struct inpcb *inp; int optname; caddr_t request; size_t len; - int priv; + struct ucred *cred; { struct sadb_x_policy *xpl; struct secpolicy **pcb_sp; @@ -1108,7 +1111,7 @@ ipsec4_set_policy(inp, optname, request, len, priv) return EINVAL; } - return ipsec_set_policy(pcb_sp, optname, request, len, priv); + return ipsec_set_policy(pcb_sp, optname, request, len, cred); } int @@ -1170,12 +1173,12 @@ ipsec4_delete_pcbpolicy(inp) #ifdef INET6 int -ipsec6_set_policy(in6p, optname, request, len, priv) +ipsec6_set_policy(in6p, optname, request, len, cred) struct in6pcb *in6p; int optname; caddr_t request; size_t len; - int priv; + struct ucred *cred; { struct sadb_x_policy *xpl; struct secpolicy **pcb_sp; @@ -1201,7 +1204,7 @@ ipsec6_set_policy(in6p, optname, request, len, priv) return EINVAL; } - return ipsec_set_policy(pcb_sp, optname, request, len, priv); + return ipsec_set_policy(pcb_sp, optname, request, len, cred); } int diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h index 6efacc6..d49aefd 100644 --- a/sys/netipsec/ipsec.h +++ b/sys/netipsec/ipsec.h @@ -370,7 +370,7 @@ extern u_int ipsec_get_reqlevel __P((struct ipsecrequest *)); extern int ipsec_in_reject __P((struct secpolicy *, struct mbuf *)); extern int ipsec4_set_policy __P((struct inpcb *inp, int optname, - caddr_t request, size_t len, int priv)); + caddr_t request, size_t len, struct ucred *cred)); extern int ipsec4_get_policy __P((struct inpcb *inpcb, caddr_t request, size_t len, struct mbuf **mp)); extern int ipsec4_delete_pcbpolicy __P((struct inpcb *)); diff --git a/sys/netipsec/ipsec6.h b/sys/netipsec/ipsec6.h index 32b2b83..1d31d6c 100644 --- a/sys/netipsec/ipsec6.h +++ b/sys/netipsec/ipsec6.h @@ -53,7 +53,7 @@ struct inpcb; extern int ipsec6_delete_pcbpolicy __P((struct inpcb *)); extern int ipsec6_set_policy __P((struct inpcb *inp, int optname, - caddr_t request, size_t len, int priv)); + caddr_t request, size_t len, struct ucred *cred)); extern int ipsec6_get_policy __P((struct inpcb *inp, caddr_t request, size_t len, struct mbuf **mp)); extern int ipsec6_in_reject __P((struct mbuf *, struct inpcb *)); |