Remove some usage of "priv" and "privileged" variables and instead pass

around credentials. Also push down kauth(9) calls closer to where the
operation is done.

Mailing list reference:

	http://mail-index.netbsd.org/tech-net/2009/04/30/msg001270.html
This commit is contained in:
elad 2009-05-06 21:41:59 +00:00
parent 6c4dd62a45
commit 4188b89914
7 changed files with 66 additions and 86 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_output.c,v 1.201 2009/03/18 16:00:22 cegger Exp $ */
/* $NetBSD: ip_output.c,v 1.202 2009/05/06 21:41:59 elad Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.201 2009/03/18 16:00:22 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.202 2009/05/06 21:41:59 elad Exp $");
#include "opt_pfil_hooks.h"
#include "opt_inet.h"
@ -1296,20 +1296,8 @@ ip_ctloutput(int op, struct socket *so, struct sockopt *sopt)
#if defined(IPSEC) || defined(FAST_IPSEC)
case IP_IPSEC_POLICY:
{
int priv = 0;
#ifdef __NetBSD__
if (l == 0 || kauth_authorize_generic(l->l_cred,
KAUTH_GENERIC_ISSUSER, NULL))
priv = 0;
else
priv = 1;
#else
priv = (in6p->in6p_socket->so_state & SS_PRIV);
#endif
error = ipsec4_set_policy(inp, sopt->sopt_name,
sopt->sopt_data, sopt->sopt_size, priv);
sopt->sopt_data, sopt->sopt_size, l->l_cred);
break;
}
#endif /*IPSEC*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_output.c,v 1.137 2009/04/18 12:40:52 drochner Exp $ */
/* $NetBSD: ip6_output.c,v 1.138 2009/05/06 21:41:59 elad Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.137 2009/04/18 12:40:52 drochner Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.138 2009/05/06 21:41:59 elad Exp $");
#include "opt_inet.h"
#include "opt_inet6.h"
@ -128,9 +128,9 @@ struct ip6_exthdrs {
};
static int ip6_pcbopt(int, u_char *, int, struct ip6_pktopts **,
int, int);
kauth_cred_t, int);
static int ip6_getpcbopt(struct ip6_pktopts *, int, struct sockopt *);
static int ip6_setpktopt(int, u_char *, int, struct ip6_pktopts *, int,
static int ip6_setpktopt(int, u_char *, int, struct ip6_pktopts *, kauth_cred_t,
int, int, int);
static int ip6_setmoptions(const struct sockopt *, struct ip6_moptions **);
static int ip6_getmoptions(struct sockopt *, struct ip6_moptions *);
@ -1466,11 +1466,10 @@ ip6_getpmtu(struct route *ro_pmtu, struct route *ro, struct ifnet *ifp,
int
ip6_ctloutput(int op, struct socket *so, struct sockopt *sopt)
{
int privileged, optdatalen, uproto;
int optdatalen, uproto;
void *optdata;
struct in6pcb *in6p = sotoin6pcb(so);
int error, optval;
struct lwp *l = curlwp; /* XXX */
int level, optname;
KASSERT(sopt != NULL);
@ -1479,8 +1478,6 @@ ip6_ctloutput(int op, struct socket *so, struct sockopt *sopt)
optname = sopt->sopt_name;
error = optval = 0;
privileged = (l == 0 || kauth_authorize_generic(l->l_cred,
KAUTH_GENERIC_ISSUSER, NULL)) ? 0 : 1;
uproto = (int)so->so_proto->pr_protocol;
if (level != IPPROTO_IPV6) {
@ -1511,10 +1508,10 @@ ip6_ctloutput(int op, struct socket *so, struct sockopt *sopt)
case IPV6_RECVHOPOPTS:
case IPV6_RECVDSTOPTS:
case IPV6_RECVRTHDRDSTOPTS:
if (!privileged) {
error = EPERM;
error = kauth_authorize_generic(kauth_cred_get(),
KAUTH_GENERIC_ISSUSER, NULL);
if (error)
break;
}
/* FALLTHROUGH */
case IPV6_UNICAST_HOPS:
case IPV6_HOPLIMIT:
@ -1586,7 +1583,7 @@ else \
(u_char *)&optval,
sizeof(optval),
optp,
privileged, uproto);
kauth_cred_get(), uproto);
break;
}
@ -1705,7 +1702,7 @@ else \
(u_char *)&tclass,
sizeof(tclass),
optp,
privileged, uproto);
kauth_cred_get(), uproto);
break;
}
@ -1722,7 +1719,7 @@ else \
(u_char *)&optval,
sizeof(optval),
optp,
privileged, uproto);
kauth_cred_get(), uproto);
break;
}
@ -1749,13 +1746,19 @@ else \
* Check super-user privilege.
* See comments for IPV6_RECVHOPOPTS.
*/
if (!privileged)
return (EPERM);
error =
kauth_authorize_generic(kauth_cred_get(),
KAUTH_GENERIC_ISSUSER, NULL);
if (error)
return (error);
OPTSET2292(IN6P_HOPOPTS);
break;
case IPV6_2292DSTOPTS:
if (!privileged)
return (EPERM);
error =
kauth_authorize_generic(kauth_cred_get(),
KAUTH_GENERIC_ISSUSER, NULL);
if (error)
return (error);
OPTSET2292(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS); /* XXX */
break;
case IPV6_2292RTHDR:
@ -1793,7 +1796,7 @@ else \
sockopt_get(sopt, optbuf, optbuflen);
optp = &in6p->in6p_outputopts;
error = ip6_pcbopt(optname, optbuf, optbuflen,
optp, privileged, uproto);
optp, kauth_cred_get(), uproto);
break;
}
#undef OPTSET
@ -1837,7 +1840,7 @@ else \
#if defined(IPSEC) || defined(FAST_IPSEC)
case IPV6_IPSEC_POLICY:
error = ipsec6_set_policy(in6p, optname,
sopt->sopt_data, sopt->sopt_size, privileged);
sopt->sopt_data, sopt->sopt_size, kauth_cred_get());
break;
#endif /* IPSEC */
@ -2120,8 +2123,6 @@ ip6_pcbopts(struct ip6_pktopts **pktopt, struct socket *so,
struct ip6_pktopts *opt = *pktopt;
struct mbuf *m;
int error = 0;
struct lwp *l = curlwp; /* XXX */
int priv = 0;
/* turn off any old options. */
if (opt) {
@ -2149,17 +2150,14 @@ ip6_pcbopts(struct ip6_pktopts **pktopt, struct socket *so,
}
/* set options specified by user. */
if (l && !kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
NULL))
priv = 1;
m = sockopt_getmbuf(sopt);
if (m == NULL) {
free(opt, M_IP6OPT);
return (ENOBUFS);
}
error = ip6_setpktopts(m, opt, NULL, priv, so->so_proto->pr_protocol);
error = ip6_setpktopts(m, opt, NULL, kauth_cred_get(),
so->so_proto->pr_protocol);
m_freem(m);
if (error != 0) {
ip6_clearpktopts(opt, -1); /* XXX: discard all options */
@ -2188,7 +2186,7 @@ ip6_initpktopts(struct ip6_pktopts *opt)
#define sin6tosa(sin6) ((struct sockaddr *)(sin6)) /* XXX */
static int
ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt,
int priv, int uproto)
kauth_cred_t cred, int uproto)
{
struct ip6_pktopts *opt;
@ -2202,7 +2200,7 @@ ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt,
}
opt = *pktopt;
return (ip6_setpktopt(optname, buf, len, opt, priv, 1, 0, uproto));
return (ip6_setpktopt(optname, buf, len, opt, cred, 1, 0, uproto));
}
static int
@ -2778,7 +2776,7 @@ ip6_freemoptions(struct ip6_moptions *im6o)
*/
int
ip6_setpktopts(struct mbuf *control, struct ip6_pktopts *opt,
struct ip6_pktopts *stickyopt, int priv, int uproto)
struct ip6_pktopts *stickyopt, kauth_cred_t cred, int uproto)
{
struct cmsghdr *cm = 0;
@ -2824,7 +2822,7 @@ ip6_setpktopts(struct mbuf *control, struct ip6_pktopts *opt,
continue;
error = ip6_setpktopt(cm->cmsg_type, CMSG_DATA(cm),
cm->cmsg_len - CMSG_LEN(0), opt, priv, 0, 1, uproto);
cm->cmsg_len - CMSG_LEN(0), opt, cred, 0, 1, uproto);
if (error)
return (error);
}
@ -2843,9 +2841,13 @@ ip6_setpktopts(struct mbuf *control, struct ip6_pktopts *opt,
*/
static int
ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt,
int priv, int sticky, int cmsg, int uproto)
kauth_cred_t cred, int sticky, int cmsg, int uproto)
{
int minmtupolicy;
int priv = 0;
if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) == 0)
priv = 1;
if (!sticky && !cmsg) {
#ifdef DIAGNOSTIC

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_var.h,v 1.52 2009/03/23 18:43:20 liamjfoy Exp $ */
/* $NetBSD: ip6_var.h,v 1.53 2009/05/06 21:41:59 elad Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@ -346,7 +346,7 @@ int ip6_ctloutput(int, struct socket *, struct sockopt *);
int ip6_raw_ctloutput(int, struct socket *, struct sockopt *);
void ip6_initpktopts(struct ip6_pktopts *);
int ip6_setpktopts(struct mbuf *, struct ip6_pktopts *,
struct ip6_pktopts *, int, int);
struct ip6_pktopts *, kauth_cred_t, int);
void ip6_clearpktopts(struct ip6_pktopts *, int);
struct ip6_pktopts *ip6_copypktopts(struct ip6_pktopts *, int);
int ip6_optlen(struct in6pcb *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipsec.c,v 1.140 2009/04/18 14:58:05 tsutsui Exp $ */
/* $NetBSD: ipsec.c,v 1.141 2009/05/06 21:41:59 elad Exp $ */
/* $KAME: ipsec.c,v 1.136 2002/05/19 00:36:39 itojun Exp $ */
/*
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.140 2009/04/18 14:58:05 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.141 2009/05/06 21:41:59 elad Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -55,6 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.140 2009/04/18 14:58:05 tsutsui Exp $");
#include <sys/sysctl.h>
#include <sys/once.h>
#include <sys/uidinfo.h>
#include <sys/kauth.h>
#include <net/if.h>
#include <net/route.h>
@ -150,7 +151,7 @@ static int ipsec_deepcopy_pcbpolicy(struct inpcbpolicy *);
#endif
static struct secpolicy *ipsec_deepcopy_policy(struct secpolicy *);
static int ipsec_set_policy
(struct secpolicy **, int, void *, size_t, int);
(struct secpolicy **, int, void *, size_t, kauth_cred_t);
static int ipsec_get_policy(struct secpolicy *, struct mbuf **);
static void vshiftl(unsigned char *, int, int);
static int ipsec_in_reject(struct secpolicy *, struct mbuf *);
@ -1371,11 +1372,12 @@ fail:
/* set policy and ipsec request if present. */
static int
ipsec_set_policy(struct secpolicy **spp, int optname, void *request,
size_t len, int priv)
size_t len, kauth_cred_t cred)
{
struct sadb_x_policy *xpl;
struct secpolicy *newsp = NULL;
int error;
int priv = 0;
/* sanity check. */
if (spp == NULL || *spp == NULL || request == NULL)
@ -1394,6 +1396,9 @@ ipsec_set_policy(struct secpolicy **spp, int optname, void *request,
xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
return EINVAL;
if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) == 0)
priv = 1;
/* check privileged socket */
if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
return EACCES;
@ -1438,7 +1443,7 @@ ipsec_get_policy(struct secpolicy *sp, struct mbuf **mp)
int
ipsec4_set_policy(struct inpcb *inp, int optname, void *request,
size_t len, int priv)
size_t len, kauth_cred_t cred)
{
struct sadb_x_policy *xpl;
struct secpolicy **spp;
@ -1465,7 +1470,7 @@ ipsec4_set_policy(struct inpcb *inp, int optname, void *request,
}
ipsec_invalpcbcache(inp->inp_sp, IPSEC_DIR_ANY);
return ipsec_set_policy(spp, optname, request, len, priv);
return ipsec_set_policy(spp, optname, request, len, cred);
}
int
@ -1533,7 +1538,7 @@ ipsec4_delete_pcbpolicy(struct inpcb *inp)
#ifdef INET6
int
ipsec6_set_policy(struct in6pcb *in6p, int optname, void *request,
size_t len, int priv)
size_t len, kauth_cred_t cred)
{
struct sadb_x_policy *xpl;
struct secpolicy **spp;
@ -1560,7 +1565,7 @@ ipsec6_set_policy(struct in6pcb *in6p, int optname, void *request,
}
ipsec_invalpcbcache(in6p->in6p_sp, IPSEC_DIR_ANY);
return ipsec_set_policy(spp, optname, request, len, priv);
return ipsec_set_policy(spp, optname, request, len, cred);
}
int

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipsec.h,v 1.50 2009/03/14 14:46:10 dsl Exp $ */
/* $NetBSD: ipsec.h,v 1.51 2009/05/06 21:41:59 elad Exp $ */
/* $KAME: ipsec.h,v 1.51 2001/08/05 04:52:58 itojun Exp $ */
/*
@ -377,7 +377,7 @@ extern int ipsec_copy_pcbpolicy
(struct inpcbpolicy *, struct inpcbpolicy *);
extern u_int ipsec_get_reqlevel(struct ipsecrequest *, int);
extern int ipsec4_set_policy(struct inpcb *, int, void *, size_t, int);
extern int ipsec4_set_policy(struct inpcb *, int, void *, size_t, kauth_cred_t);
extern int ipsec4_get_policy(struct inpcb *, void *, size_t,
struct mbuf **);
extern int ipsec4_delete_pcbpolicy(struct inpcb *);
@ -387,7 +387,8 @@ extern int ipsec4_in_reject(struct mbuf *, struct inpcb *);
#ifdef INET6
extern int ipsec6_in_reject_so(struct mbuf *, struct socket *);
extern int ipsec6_delete_pcbpolicy(struct in6pcb *);
extern int ipsec6_set_policy(struct in6pcb *, int, void *, size_t, int);
extern int ipsec6_set_policy(struct in6pcb *, int, void *, size_t,
kauth_cred_t);
extern int ipsec6_get_policy(struct in6pcb *, void *, size_t,
struct mbuf **);
extern int ipsec6_in_reject(struct mbuf *, struct in6pcb *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: raw_ip6.c,v 1.103 2009/03/15 21:26:09 cegger Exp $ */
/* $NetBSD: raw_ip6.c,v 1.104 2009/05/06 21:41:59 elad Exp $ */
/* $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.103 2009/03/15 21:26:09 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.104 2009/05/06 21:41:59 elad Exp $");
#include "opt_ipsec.h"
@ -404,22 +404,16 @@ rip6_output(struct mbuf *m, struct socket *so, struct sockaddr_in6 *dstsock,
struct ip6_pktopts opt, *optp = NULL;
struct ifnet *oifp = NULL;
int type, code; /* for ICMPv6 output statistics only */
int priv = 0;
int scope_ambiguous = 0;
struct in6_addr *in6a;
in6p = sotoin6pcb(so);
priv = 0;
if (curlwp && !kauth_authorize_generic(curlwp->l_cred,
KAUTH_GENERIC_ISSUSER, NULL))
priv = 1;
dst = &dstsock->sin6_addr;
if (control) {
if ((error = ip6_setpktopts(control, &opt,
in6p->in6p_outputopts,
priv, so->so_proto->pr_protocol)) != 0) {
kauth_cred_get(), so->so_proto->pr_protocol)) != 0) {
goto bad;
}
optp = &opt;
@ -619,12 +613,6 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m,
struct in6pcb *in6p = sotoin6pcb(so);
int s;
int error = 0;
int priv;
priv = 0;
if (l && !kauth_authorize_generic(l->l_cred,
KAUTH_GENERIC_ISSUSER, NULL))
priv++;
if (req == PRU_CONTROL)
return in6_control(so, (u_long)m, (void *)nam,
@ -641,11 +629,13 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m,
switch (req) {
case PRU_ATTACH:
error = kauth_authorize_network(l->l_cred,
KAUTH_NETWORK_SOCKET, KAUTH_REQ_NETWORK_SOCKET_RAWSOCK,
NULL, NULL, NULL);
sosetlock(so);
if (in6p != NULL)
panic("rip6_attach");
if (!priv) {
error = EACCES;
if (error) {
break;
}
s = splsoftnet();

View File

@ -1,4 +1,4 @@
/* $NetBSD: udp6_output.c,v 1.38 2009/04/30 18:18:34 elad Exp $ */
/* $NetBSD: udp6_output.c,v 1.39 2009/05/06 21:41:59 elad Exp $ */
/* $KAME: udp6_output.c,v 1.43 2001/10/15 09:19:52 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: udp6_output.c,v 1.38 2009/04/30 18:18:34 elad Exp $");
__KERNEL_RCSID(0, "$NetBSD: udp6_output.c,v 1.39 2009/05/06 21:41:59 elad Exp $");
#include "opt_inet.h"
@ -128,7 +128,6 @@ udp6_output(struct in6pcb *in6p, struct mbuf *m, struct mbuf *addr6,
u_int16_t fport;
int error = 0;
struct ip6_pktopts *optp, opt;
int priv;
int af = AF_INET6, hlen = sizeof(struct ip6_hdr);
#ifdef INET
struct ip *ip;
@ -137,11 +136,6 @@ udp6_output(struct in6pcb *in6p, struct mbuf *m, struct mbuf *addr6,
#endif
struct sockaddr_in6 tmp;
priv = 0;
if (l && !kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
NULL))
priv = 1;
if (addr6) {
if (addr6->m_len != sizeof(*sin6)) {
error = EINVAL;
@ -173,7 +167,7 @@ udp6_output(struct in6pcb *in6p, struct mbuf *m, struct mbuf *addr6,
if (control) {
if ((error = ip6_setpktopts(control, &opt,
in6p->in6p_outputopts, priv, IPPROTO_UDP)) != 0)
in6p->in6p_outputopts, l->l_cred, IPPROTO_UDP)) != 0)
goto release;
optp = &opt;
} else