diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 30 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 6 |
2 files changed, 31 insertions, 5 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3883b4036a74..43b3c9f89c12 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1916,8 +1916,32 @@ ok: | |||
1916 | update_lft = 1; | 1916 | update_lft = 1; |
1917 | else if (stored_lft <= MIN_VALID_LIFETIME) { | 1917 | else if (stored_lft <= MIN_VALID_LIFETIME) { |
1918 | /* valid_lft <= stored_lft is always true */ | 1918 | /* valid_lft <= stored_lft is always true */ |
1919 | /* XXX: IPsec */ | 1919 | /* |
1920 | update_lft = 0; | 1920 | * RFC 4862 Section 5.5.3e: |
1921 | * "Note that the preferred lifetime of | ||
1922 | * the corresponding address is always | ||
1923 | * reset to the Preferred Lifetime in | ||
1924 | * the received Prefix Information | ||
1925 | * option, regardless of whether the | ||
1926 | * valid lifetime is also reset or | ||
1927 | * ignored." | ||
1928 | * | ||
1929 | * So if the preferred lifetime in | ||
1930 | * this advertisement is different | ||
1931 | * than what we have stored, but the | ||
1932 | * valid lifetime is invalid, just | ||
1933 | * reset prefered_lft. | ||
1934 | * | ||
1935 | * We must set the valid lifetime | ||
1936 | * to the stored lifetime since we'll | ||
1937 | * be updating the timestamp below, | ||
1938 | * else we'll set it back to the | ||
1939 | * minumum. | ||
1940 | */ | ||
1941 | if (prefered_lft != ifp->prefered_lft) { | ||
1942 | valid_lft = stored_lft; | ||
1943 | update_lft = 1; | ||
1944 | } | ||
1921 | } else { | 1945 | } else { |
1922 | valid_lft = MIN_VALID_LIFETIME; | 1946 | valid_lft = MIN_VALID_LIFETIME; |
1923 | if (valid_lft < prefered_lft) | 1947 | if (valid_lft < prefered_lft) |
@@ -3085,7 +3109,7 @@ restart: | |||
3085 | spin_unlock(&ifp->lock); | 3109 | spin_unlock(&ifp->lock); |
3086 | continue; | 3110 | continue; |
3087 | } else if (age >= ifp->prefered_lft) { | 3111 | } else if (age >= ifp->prefered_lft) { |
3088 | /* jiffies - ifp->tsamp > age >= ifp->prefered_lft */ | 3112 | /* jiffies - ifp->tstamp > age >= ifp->prefered_lft */ |
3089 | int deprecate = 0; | 3113 | int deprecate = 0; |
3090 | 3114 | ||
3091 | if (!(ifp->flags&IFA_F_DEPRECATED)) { | 3115 | if (!(ifp->flags&IFA_F_DEPRECATED)) { |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index b4b16a43f277..3a3c677bc0f2 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -157,7 +157,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
157 | ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr); | 157 | ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr); |
158 | ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr); | 158 | ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr); |
159 | 159 | ||
160 | while (pskb_may_pull(skb, nh + offset + 1 - skb->data)) { | 160 | while (nh + offset + 1 < skb->data || |
161 | pskb_may_pull(skb, nh + offset + 1 - skb->data)) { | ||
161 | nh = skb_network_header(skb); | 162 | nh = skb_network_header(skb); |
162 | exthdr = (struct ipv6_opt_hdr *)(nh + offset); | 163 | exthdr = (struct ipv6_opt_hdr *)(nh + offset); |
163 | 164 | ||
@@ -177,7 +178,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
177 | case IPPROTO_TCP: | 178 | case IPPROTO_TCP: |
178 | case IPPROTO_SCTP: | 179 | case IPPROTO_SCTP: |
179 | case IPPROTO_DCCP: | 180 | case IPPROTO_DCCP: |
180 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 4 - skb->data)) { | 181 | if (!onlyproto && (nh + offset + 4 < skb->data || |
182 | pskb_may_pull(skb, nh + offset + 4 - skb->data))) { | ||
181 | __be16 *ports = (__be16 *)exthdr; | 183 | __be16 *ports = (__be16 *)exthdr; |
182 | 184 | ||
183 | fl->fl_ip_sport = ports[!!reverse]; | 185 | fl->fl_ip_sport = ports[!!reverse]; |