Commit 69e324b3 authored by Hideaki Yoshifuji's avatar Hideaki Yoshifuji Committed by David S. Miller

[IPV6]: Fix several errors in udpv6_connect().

- Pointer within an automatic storage class variable fl was illegally
  cached using ip6_dst_store()
- uninitialized saddr was copied to fl.fl6_src
- dont cache if ipv6_saddr_get() failed.

Based upon patch from Ville Nuorvala (vnuorval@tcs.hut.fi)
parent 8d473232
...@@ -254,7 +254,6 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -254,7 +254,6 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
struct inet_opt *inet = inet_sk(sk); struct inet_opt *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct in6_addr *daddr; struct in6_addr *daddr;
struct in6_addr saddr;
struct dst_entry *dst; struct dst_entry *dst;
struct flowi fl; struct flowi fl;
struct ip6_flowlabel *flowlabel = NULL; struct ip6_flowlabel *flowlabel = NULL;
...@@ -355,7 +354,7 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -355,7 +354,7 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
fl.proto = IPPROTO_UDP; fl.proto = IPPROTO_UDP;
ipv6_addr_copy(&fl.fl6_dst, &np->daddr); ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
ipv6_addr_copy(&fl.fl6_src, &saddr); ipv6_addr_copy(&fl.fl6_src, &np->saddr);
fl.oif = sk->bound_dev_if; fl.oif = sk->bound_dev_if;
fl.fl_ip_dport = inet->dport; fl.fl_ip_dport = inet->dport;
fl.fl_ip_sport = inet->sport; fl.fl_ip_sport = inet->sport;
...@@ -381,20 +380,23 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -381,20 +380,23 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
return err; return err;
} }
ip6_dst_store(sk, dst, &fl.fl6_dst);
/* get the source address used in the appropriate device */ /* get the source address used in the appropriate device */
err = ipv6_get_saddr(dst, daddr, &saddr); err = ipv6_get_saddr(dst, daddr, &fl.fl6_src);
if (err == 0) { if (err == 0) {
if (ipv6_addr_any(&np->saddr)) if (ipv6_addr_any(&np->saddr))
ipv6_addr_copy(&np->saddr, &saddr); ipv6_addr_copy(&np->saddr, &fl.fl6_src);
if (ipv6_addr_any(&np->rcv_saddr)) { if (ipv6_addr_any(&np->rcv_saddr)) {
ipv6_addr_copy(&np->rcv_saddr, &saddr); ipv6_addr_copy(&np->rcv_saddr, &fl.fl6_src);
inet->rcv_saddr = LOOPBACK4_IPV6; inet->rcv_saddr = LOOPBACK4_IPV6;
} }
ip6_dst_store(sk, dst,
!ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
&np->daddr : NULL);
sk->state = TCP_ESTABLISHED; sk->state = TCP_ESTABLISHED;
} }
fl6_sock_release(flowlabel); fl6_sock_release(flowlabel);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment