From f74da371592dbe1e09495f48e79e77ec170a2c46 Mon Sep 17 00:00:00 2001 From: mvs Date: Wed, 12 May 2021 08:09:33 +0000 Subject: [PATCH] Use local copy of `ps_rtableid' in ip{,6}_ctloutput() and mark `ps_rtableid' as atomic. This allows us to unlock setrtable(2). ok claudio@ mpi@ --- sys/netinet/ip_output.c | 9 +++++---- sys/netinet6/ip6_output.c | 9 +++++---- sys/sys/proc.h | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index e9e41517e7b..396caa3ea13 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -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 */ diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 28ed1c4aef2..e11ac43961b 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -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 */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 80585795c28..75ae18c541c 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -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 */ -- 2.20.1