From 114f984d932b1f6810293178a80279f30cd2bd27 Mon Sep 17 00:00:00 2001 From: "Thordur I. Bjornsson" Date: Fri, 23 May 2008 15:51:13 +0000 Subject: Deal with the situation when TCP nfs mounts timeout and processes get hung in nfs_reconnect() because they do not have the proper privilages to bind to a socket, by adding a struct proc * argument to sobind() (and the *_usrreq() routines, and finally in{6}_pcbbind) and do the sobind() with proc0 in nfs_connect. OK markus@, blambert@. "go ahead" deraadt@. Fixes an issue reported by bernd@ (Tested by bernd@). Fixes PR5135 too. --- sys/netinet/in_pcb.c | 10 +++++----- sys/netinet/in_pcb.h | 6 +++--- sys/netinet/ip_var.h | 4 ++-- sys/netinet/raw_ip.c | 4 ++-- sys/netinet/tcp_usrreq.c | 19 ++++++++++--------- sys/netinet/tcp_var.h | 4 ++-- sys/netinet/udp_usrreq.c | 11 ++++++----- sys/netinet/udp_var.h | 4 ++-- 8 files changed, 32 insertions(+), 30 deletions(-) (limited to 'sys/netinet') diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index ad69036f1c5..64584522347 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.98 2008/05/15 19:40:38 markus Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.99 2008/05/23 15:51:12 thib Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -232,23 +232,23 @@ in_pcballoc(so, v) } int -in_pcbbind(v, nam) +in_pcbbind(v, nam, p) void *v; struct mbuf *nam; + struct proc *p; { struct inpcb *inp = v; struct socket *so = inp->inp_socket; struct inpcbtable *table = inp->inp_table; u_int16_t *lastport = &inp->inp_table->inpt_lastport; struct sockaddr_in *sin; - struct proc *p = curproc; /* XXX */ u_int16_t lport = 0; int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); int error; #ifdef INET6 if (sotopf(so) == PF_INET6) - return in6_pcbbind(inp, nam); + return in6_pcbbind(inp, nam, p); #endif /* INET6 */ if (TAILQ_EMPTY(&in_ifaddr)) @@ -434,7 +434,7 @@ in_pcbconnect(v, nam) return (EADDRINUSE); if (inp->inp_laddr.s_addr == INADDR_ANY) { if (inp->inp_lport == 0 && - in_pcbbind(inp, (struct mbuf *)0) == EADDRNOTAVAIL) + in_pcbbind(inp, NULL, curproc) == EADDRNOTAVAIL) return (EADDRNOTAVAIL); inp->inp_laddr = ifaddr->sin_addr; } diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index cebbdba4172..194f23585da 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.h,v 1.62 2008/05/15 19:40:38 markus Exp $ */ +/* $OpenBSD: in_pcb.h,v 1.63 2008/05/23 15:51:12 thib Exp $ */ /* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */ /* @@ -240,7 +240,7 @@ struct baddynamicports { void in_losing(struct inpcb *); int in_pcballoc(struct socket *, void *); -int in_pcbbind(void *, struct mbuf *); +int in_pcbbind(void *, struct mbuf *, struct proc *); int in_pcbconnect(void *, struct mbuf *); void in_pcbdetach(void *); void in_pcbdisconnect(void *); @@ -257,7 +257,7 @@ struct inpcb * struct inpcb * in6_pcblookup_listen(struct inpcbtable *, struct in6_addr *, u_int, int, struct mbuf *); -int in6_pcbbind(struct inpcb *, struct mbuf *); +int in6_pcbbind(struct inpcb *, struct mbuf *, struct proc *); int in6_pcbconnect(struct inpcb *, struct mbuf *); int in6_setsockaddr(struct inpcb *, struct mbuf *); int in6_setpeeraddr(struct inpcb *, struct mbuf *); diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index b6ea372229f..bc72a08ff57 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_var.h,v 1.37 2007/09/18 18:56:02 markus Exp $ */ +/* $OpenBSD: ip_var.h,v 1.38 2008/05/23 15:51:12 thib Exp $ */ /* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */ /* @@ -192,6 +192,6 @@ void rip_init(void); void rip_input(struct mbuf *, ...); int rip_output(struct mbuf *, ...); int rip_usrreq(struct socket *, - int, struct mbuf *, struct mbuf *, struct mbuf *); + int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); #endif /* _KERNEL */ #endif /* _NETINET_IP_VAR_H_ */ diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 1b45549be3c..051d260c51d 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip.c,v 1.43 2008/05/09 02:52:15 markus Exp $ */ +/* $OpenBSD: raw_ip.c,v 1.44 2008/05/23 15:51:12 thib Exp $ */ /* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */ /* @@ -345,7 +345,7 @@ u_long rip_recvspace = RIPRCVQ; /*ARGSUSED*/ int rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, - struct mbuf *control) + struct mbuf *control, struct proc *p) { int error = 0; struct inpcb *inp = sotoinpcb(so); diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 9752c57b043..c0918876e48 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_usrreq.c,v 1.97 2008/05/15 19:40:38 markus Exp $ */ +/* $OpenBSD: tcp_usrreq.c,v 1.98 2008/05/23 15:51:12 thib Exp $ */ /* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */ /* @@ -134,7 +134,7 @@ tcp6_usrreq(so, req, m, nam, control, p) struct proc *p; { - return tcp_usrreq(so, req, m, nam, control); + return tcp_usrreq(so, req, m, nam, control, p); } #endif @@ -145,10 +145,11 @@ tcp6_usrreq(so, req, m, nam, control, p) */ /*ARGSUSED*/ int -tcp_usrreq(so, req, m, nam, control) +tcp_usrreq(so, req, m, nam, control, p) struct socket *so; int req; struct mbuf *m, *nam, *control; + struct proc *p; { struct sockaddr_in *sin; struct inpcb *inp; @@ -239,10 +240,10 @@ tcp_usrreq(so, req, m, nam, control) case PRU_BIND: #ifdef INET6 if (inp->inp_flags & INP_IPV6) - error = in6_pcbbind(inp, nam); + error = in6_pcbbind(inp, nam, p); else #endif - error = in_pcbbind(inp, nam); + error = in_pcbbind(inp, nam, p); if (error) break; break; @@ -254,10 +255,10 @@ tcp_usrreq(so, req, m, nam, control) if (inp->inp_lport == 0) { #ifdef INET6 if (inp->inp_flags & INP_IPV6) - error = in6_pcbbind(inp, NULL); + error = in6_pcbbind(inp, NULL, p); else #endif - error = in_pcbbind(inp, NULL); + error = in_pcbbind(inp, NULL, p); } /* If the in_pcbbind() above is called, the tp->pf should still be whatever it was before. */ @@ -291,7 +292,7 @@ tcp_usrreq(so, req, m, nam, control) } if (inp->inp_lport == 0) { - error = in6_pcbbind(inp, NULL); + error = in6_pcbbind(inp, NULL, p); if (error) break; } @@ -307,7 +308,7 @@ tcp_usrreq(so, req, m, nam, control) } if (inp->inp_lport == 0) { - error = in_pcbbind(inp, NULL); + error = in_pcbbind(inp, NULL, p); if (error) break; } diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 51cf640a800..c707e1499bd 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_var.h,v 1.87 2008/05/06 08:47:36 markus Exp $ */ +/* $OpenBSD: tcp_var.h,v 1.88 2008/05/23 15:51:12 thib Exp $ */ /* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */ /* @@ -600,7 +600,7 @@ int tcp6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); #endif int tcp_usrreq(struct socket *, - int, struct mbuf *, struct mbuf *, struct mbuf *); + int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); void tcp_xmit_timer(struct tcpcb *, int); void tcpdropoldhalfopen(struct tcpcb *, u_int16_t); #ifdef TCP_SACK diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 1bcd75bbe20..088d9d50e3f 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_usrreq.c,v 1.119 2008/05/15 19:40:38 markus Exp $ */ +/* $OpenBSD: udp_usrreq.c,v 1.120 2008/05/23 15:51:12 thib Exp $ */ /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ /* @@ -1011,16 +1011,17 @@ udp6_usrreq(so, req, m, addr, control, p) struct proc *p; { - return udp_usrreq(so, req, m, addr, control); + return udp_usrreq(so, req, m, addr, control, p); } #endif /*ARGSUSED*/ int -udp_usrreq(so, req, m, addr, control) +udp_usrreq(so, req, m, addr, control, p) struct socket *so; int req; struct mbuf *m, *addr, *control; + struct proc *p; { struct inpcb *inp = sotoinpcb(so); int error = 0; @@ -1076,10 +1077,10 @@ udp_usrreq(so, req, m, addr, control) s = splsoftnet(); #ifdef INET6 if (inp->inp_flags & INP_IPV6) - error = in6_pcbbind(inp, addr); + error = in6_pcbbind(inp, addr, p); else #endif - error = in_pcbbind(inp, addr); + error = in_pcbbind(inp, addr, p); splx(s); break; diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index 943711bf1e6..eaba606ca7f 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_var.h,v 1.17 2007/12/13 20:00:53 reyk Exp $ */ +/* $OpenBSD: udp_var.h,v 1.18 2008/05/23 15:51:12 thib Exp $ */ /* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */ /* @@ -118,6 +118,6 @@ int udp6_output(struct inpcb *, struct mbuf *, struct mbuf *, int udp_output(struct mbuf *, ...); int udp_sysctl(int *, u_int, void *, size_t *, void *, size_t); int udp_usrreq(struct socket *, - int, struct mbuf *, struct mbuf *, struct mbuf *); + int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); #endif /* _KERNEL */ #endif /* _NETINET_UDP_VAR_H_ */ -- cgit v1.2.3