X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Faf_inet.c;h=8d450fb04a3dce3df5c3fa54d4f080c81a0263f7;hb=2ab7e6fcc578694936be605151227a660d2f1b95;hp=edf45709017806f8f847f652a15706eb2346d912;hpb=86090fcac5e27b630656fe3d963a6b80e26dac44;p=linux-2.6.git diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index edf457090..8d450fb04 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -158,6 +158,9 @@ void inet_sock_destruct(struct sock *sk) if (inet->opt) kfree(inet->opt); + + BUG_ON(sk->sk_nx_info); + BUG_ON(sk->sk_vx_info); dst_release(sk->sk_dst_cache); #ifdef INET_REFCNT_DEBUG atomic_dec(&inet_sock_nr); @@ -216,7 +219,7 @@ void inet_sock_release(struct sock *sk) * Set socket options on an inet socket. */ int inet_setsockopt(struct socket *sock, int level, int optname, - char *optval, int optlen) + char __user *optval, int optlen) { struct sock *sk = sock->sk; @@ -232,7 +235,7 @@ int inet_setsockopt(struct socket *sock, int level, int optname, */ int inet_getsockopt(struct socket *sock, int level, int optname, - char *optval, int *optlen) + char __user *optval, int __user *optlen) { struct sock *sk = sock->sk; @@ -397,6 +400,11 @@ static int inet_create(struct socket *sock, int protocol) sk->sk_family = PF_INET; sk->sk_protocol = protocol; sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv; + + set_vx_info(&sk->sk_vx_info, current->vx_info); + sk->sk_xid = vx_current_xid(); + set_nx_info(&sk->sk_nx_info, current->nx_info); + sk->sk_nid = nx_current_nid(); inet->uc_ttl = -1; inet->mc_loop = 1; @@ -421,8 +429,13 @@ static int inet_create(struct socket *sock, int protocol) if (sk->sk_prot->init) { err = sk->sk_prot->init(sk); - if (err) - inet_sock_release(sk); + if (err) { +/* sk->sk_vx_info = NULL; + put_vx_info(current->vx_info); + sk->sk_nx_info = NULL; + put_nx_info(current->nx_info); +*/ inet_sock_release(sk); + } } out: return err; @@ -460,6 +473,8 @@ int inet_release(struct socket *sock) !(current->flags & PF_EXITING)) timeout = sk->sk_lingertime; sock->sk = NULL; + clr_vx_info(&sk->sk_vx_info); + clr_nx_info(&sk->sk_nx_info); sk->sk_prot->close(sk, timeout); } return 0; @@ -476,6 +491,10 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) unsigned short snum; int chk_addr_ret; int err; + __u32 s_addr; /* Address used for validation */ + __u32 s_addr1; + __u32 s_addr2 = 0xffffffffl; /* Optional address of the socket */ + struct nx_info *nxi = sk->sk_nx_info; /* If the socket has its own bind function then use it. (RAW) */ if (sk->sk_prot->bind) { @@ -486,7 +505,36 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (addr_len < sizeof(struct sockaddr_in)) goto out; - chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); + s_addr = s_addr1 = addr->sin_addr.s_addr; + nxdprintk("inet_bind(%p) %p,%p;%lx\n", + sk, nx_info, sk->sk_socket, + (sk->sk_socket?sk->sk_socket->flags:0)); + if (nxi) { + __u32 v4_bcast = nxi->v4_bcast; + __u32 ipv4root = nxi->ipv4[0]; + int nbipv4 = nxi->nbipv4; + if (s_addr == 0) { + s_addr = ipv4root; + if (nbipv4 > 1) + s_addr1 = 0; + else { + s_addr1 = ipv4root; + } + s_addr2 = v4_bcast; + } else if (s_addr == 0x0100007f) { + s_addr = s_addr1 = ipv4root; + } else if (s_addr != v4_bcast) { + int i; + for (i=0; iipv4[i]) + break; + } + if (i == nbipv4) { + return -EADDRNOTAVAIL; + } + } + } + chk_addr_ret = inet_addr_type(s_addr); /* Not specified by any standard per-se, however it breaks too * many applications when removed. It is unfortunate since @@ -498,7 +546,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) err = -EADDRNOTAVAIL; if (!sysctl_ip_nonlocal_bind && !inet->freebind && - addr->sin_addr.s_addr != INADDR_ANY && + s_addr != INADDR_ANY && chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) @@ -523,7 +571,8 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (sk->sk_state != TCP_CLOSE || inet->num) goto out_release_sock; - inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr; + inet->rcv_saddr = inet->saddr = s_addr1; + inet->rcv_saddr2 = s_addr2; if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) inet->saddr = 0; /* Use device */ @@ -843,7 +892,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) switch (cmd) { case SIOCGSTAMP: - err = sock_get_timestamp(sk, (struct timeval *)arg); + err = sock_get_timestamp(sk, (struct timeval __user *)arg); break; case SIOCADDRT: case SIOCDELRT: @@ -853,7 +902,7 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCDARP: case SIOCGARP: case SIOCSARP: - err = arp_ioctl(cmd, (void *)arg); + err = arp_ioctl(cmd, (void __user *)arg); break; case SIOCGIFADDR: case SIOCSIFADDR: @@ -866,13 +915,13 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCSIFPFLAGS: case SIOCGIFPFLAGS: case SIOCSIFFLAGS: - err = devinet_ioctl(cmd, (void *)arg); + err = devinet_ioctl(cmd, (void __user *)arg); break; default: if (!sk->sk_prot->ioctl || (err = sk->sk_prot->ioctl(sk, cmd, arg)) == -ENOIOCTLCMD) - err = dev_ioctl(cmd, (void *)arg); + err = dev_ioctl(cmd, (void __user *)arg); break; } return err; @@ -978,7 +1027,7 @@ void inet_register_protosw(struct inet_protosw *p) spin_lock_bh(&inetsw_lock); - if (p->type > SOCK_MAX) + if (p->type >= SOCK_MAX) goto out_illegal; /* If we are trying to override a permanent protocol, bail. */