summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2008-02-02 14:11:31 +0000
committerbz <bz@FreeBSD.org>2008-02-02 14:11:31 +0000
commitcfb85f0c07e631c309f5158c6aeebac935619b92 (patch)
treedbf75dec875afa39ded965d6896a91bf2171580d
parentddf9fd25a8b759fac39499e04a7624ae5c938dd0 (diff)
downloadFreeBSD-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.c25
-rw-r--r--sys/netinet6/ip6_output.c35
-rw-r--r--sys/netipsec/ipsec.c25
-rw-r--r--sys/netipsec/ipsec.h2
-rw-r--r--sys/netipsec/ipsec6.h2
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 *));
OpenPOWER on IntegriCloud