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
This commit is contained in:
Bjoern A. Zeeb 2008-02-02 14:11:31 +00:00
parent a4afe9200c
commit c26fe973a3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=175892
5 changed files with 30 additions and 59 deletions

View File

@ -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;
}

View File

@ -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:

View File

@ -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 @@ ipsec_deepcopy_policy(src)
/* 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

View File

@ -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 *));

View File

@ -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 *));