tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Pushing down kauth(9) calls in netinet{,6}



Hi,

Attached diff pushes down some kauth(9) calls closer to where their
return value is used.

I've changed some curlwp->l_cred to kauth_cred_get(), functions now
pass credentials instead of a variable that says if the caller is
privileged or not, etc.

Please review.

Thanks,

-e.
Index: netinet/ip_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_output.c,v
retrieving revision 1.201
diff -u -p -r1.201 ip_output.c
--- netinet/ip_output.c 18 Mar 2009 16:00:22 -0000      1.201
+++ netinet/ip_output.c 30 Apr 2009 22:29:11 -0000
@@ -1296,20 +1296,8 @@ ip_ctloutput(int op, struct socket *so, 
 #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*/
Index: netinet6/ip6_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.136
diff -u -p -r1.136 ip6_output.c
--- netinet6/ip6_output.c       18 Mar 2009 16:00:23 -0000      1.136
+++ netinet6/ip6_output.c       30 Apr 2009 22:29:13 -0000
@@ -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, struc
 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,
        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,
                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 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,
        }
 
        /*  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
        }
        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 *im
  */
 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;
 
@@ -2823,7 +2821,7 @@ ip6_setpktopts(struct mbuf *control, str
                        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);
        }
@@ -2842,9 +2840,13 @@ ip6_setpktopts(struct mbuf *control, str
  */
 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
Index: netinet6/ip6_var.h
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_var.h,v
retrieving revision 1.52
diff -u -p -r1.52 ip6_var.h
--- netinet6/ip6_var.h  23 Mar 2009 18:43:20 -0000      1.52
+++ netinet6/ip6_var.h  30 Apr 2009 22:29:13 -0000
@@ -346,7 +346,7 @@ int ip6_ctloutput(int, struct socket *, 
 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 *);
Index: netinet6/ipsec.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ipsec.c,v
retrieving revision 1.139
diff -u -p -r1.139 ipsec.c
--- netinet6/ipsec.c    19 Mar 2009 08:31:03 -0000      1.139
+++ netinet6/ipsec.c    30 Apr 2009 22:29:14 -0000
@@ -55,6 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.
 #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(stru
 #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,
            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, s
 
 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
        }
 
        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 *in
 #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, i
        }
 
        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
Index: netinet6/ipsec.h
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ipsec.h,v
retrieving revision 1.50
diff -u -p -r1.50 ipsec.h
--- netinet6/ipsec.h    14 Mar 2009 14:46:10 -0000      1.50
+++ netinet6/ipsec.h    30 Apr 2009 22:29:14 -0000
@@ -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 
 #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 *);
Index: netinet6/raw_ip6.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.103
diff -u -p -r1.103 raw_ip6.c
--- netinet6/raw_ip6.c  15 Mar 2009 21:26:09 -0000      1.103
+++ netinet6/raw_ip6.c  30 Apr 2009 22:29:15 -0000
@@ -404,22 +404,16 @@ rip6_output(struct mbuf *m, struct socke
        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 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, 
 
        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();
Index: netinet6/udp6_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/udp6_output.c,v
retrieving revision 1.38
diff -u -p -r1.38 udp6_output.c
--- netinet6/udp6_output.c      30 Apr 2009 18:18:34 -0000      1.38
+++ netinet6/udp6_output.c      30 Apr 2009 22:29:15 -0000
@@ -128,7 +128,6 @@ udp6_output(struct in6pcb *in6p, struct 
        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 
 #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 
 
        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


Home | Main Index | Thread Index | Old Index