Use local copy of `ps_rtableid' in ip{,6}_ctloutput() and mark
authormvs <mvs@openbsd.org>
Wed, 12 May 2021 08:09:33 +0000 (08:09 +0000)
committermvs <mvs@openbsd.org>
Wed, 12 May 2021 08:09:33 +0000 (08:09 +0000)
`ps_rtableid' as atomic. This allows us to unlock setrtable(2).

ok claudio@ mpi@

sys/netinet/ip_output.c
sys/netinet6/ip6_output.c
sys/sys/proc.h

index e9e4151..396caa3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip_output.c,v 1.370 2021/03/30 08:37:11 sashan Exp $  */
+/*     $OpenBSD: ip_output.c,v 1.371 2021/05/12 08:09:33 mvs Exp $     */
 /*     $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $  */
 
 /*
@@ -856,11 +856,13 @@ ip_ctloutput(int op, struct socket *so, int level, int optname,
        int optval = 0;
        struct proc *p = curproc; /* XXX */
        int error = 0;
-       u_int rtid = 0;
+       u_int rtableid, rtid = 0;
 
        if (level != IPPROTO_IP)
                return (EINVAL);
 
+       rtableid = p->p_p->ps_rtableid;
+
        switch (op) {
        case PRCO_SETOPT:
                switch (optname) {
@@ -1050,8 +1052,7 @@ ip_ctloutput(int op, struct socket *so, int level, int optname,
                        if (inp->inp_rtableid == rtid)
                                break;
                        /* needs privileges to switch when already set */
-                       if (p->p_p->ps_rtableid != rtid &&
-                           p->p_p->ps_rtableid != 0 &&
+                       if (rtableid != rtid && rtableid != 0 &&
                            (error = suser(p)) != 0)
                                break;
                        /* table must exist */
index 28ed1c4..e11ac43 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip6_output.c,v 1.256 2021/03/10 10:21:49 jsg Exp $    */
+/*     $OpenBSD: ip6_output.c,v 1.257 2021/05/12 08:09:33 mvs Exp $    */
 /*     $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $    */
 
 /*
@@ -1059,7 +1059,7 @@ ip6_ctloutput(int op, struct socket *so, int level, int optname,
        struct inpcb *inp = sotoinpcb(so);
        int error, optval;
        struct proc *p = curproc; /* For IPsec and rdomain */
-       u_int rtid = 0;
+       u_int rtableid, rtid = 0;
 
        error = optval = 0;
 
@@ -1069,6 +1069,8 @@ ip6_ctloutput(int op, struct socket *so, int level, int optname,
        if (level != IPPROTO_IPV6)
                return (EINVAL);
 
+       rtableid = p->p_p->ps_rtableid;
+
        switch (op) {
        case PRCO_SETOPT:
                switch (optname) {
@@ -1363,8 +1365,7 @@ do { \
                        if (inp->inp_rtableid == rtid)
                                break;
                        /* needs privileges to switch when already set */
-                       if (p->p_p->ps_rtableid != rtid &&
-                           p->p_p->ps_rtableid != 0 &&
+                       if (rtableid != rtid && rtableid != 0 &&
                            (error = suser(p)) != 0)
                                break;
                        /* table must exist */
index 8058579..75ae18c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: proc.h,v 1.311 2021/03/17 14:06:54 visa Exp $ */
+/*     $OpenBSD: proc.h,v 1.312 2021/05/12 08:09:33 mvs Exp $  */
 /*     $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $       */
 
 /*-
@@ -251,7 +251,7 @@ struct process {
        vaddr_t ps_sigcode;             /* User pointer to the signal code */
        vaddr_t ps_sigcoderet;          /* User pointer to sigreturn retPC */
        u_long  ps_sigcookie;
-       u_int   ps_rtableid;            /* Process routing table/domain. */
+       u_int   ps_rtableid;            /* [a] Process routing table/domain. */
        char    ps_nice;                /* Process "nice" value. */
 
        struct uprof {                  /* profile arguments */