aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorRygebin <kaankulahli@gmail.com>2017-06-20 14:29:27 +0000
committerRygebin <kaankulahli@gmail.com>2017-06-20 14:29:27 +0000
commitafa9ad70f02491fbe10df2203f8f2fa42f956228 (patch)
treeb6dce4ed04f62fd443721a94ac3e7f81427e0ad1 /net
parent582eb92a1e8bf6c0e743774c1fb550e630715433 (diff)
parent08d1ec9238c605a9a5cf1229fd60961efcd21ff1 (diff)
Merge https://github.com/OneDeveloperOrganization/android_kernel_google_shamrock into n7.1HEADn7.1
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/udp.c6
-rw-r--r--net/ipv6/udp.c6
-rw-r--r--net/xfrm/xfrm_user.c9
3 files changed, 16 insertions, 5 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index dd535e3d97d..3d166535002 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1215,6 +1215,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
int peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
+ bool checksum_valid = false;
bool slow;
if (flags & MSG_ERRQUEUE)
@@ -1240,11 +1241,12 @@ try_again:
*/
if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
- if (udp_lib_checksum_complete(skb))
+ checksum_valid = !udp_lib_checksum_complete(skb);
+ if (!checksum_valid)
goto csum_copy_err;
}
- if (skb_csum_unnecessary(skb))
+ if (checksum_valid || skb_csum_unnecessary(skb))
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied);
else {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 25f3babd59d..0f22ad1e847 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -370,6 +370,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
int peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
+ bool checksum_valid = false;
int is_udp4;
bool slow;
@@ -401,11 +402,12 @@ try_again:
*/
if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
- if (udp_lib_checksum_complete(skb))
+ checksum_valid = !udp_lib_checksum_complete(skb);
+ if (!checksum_valid)
goto csum_copy_err;
}
- if (skb_csum_unnecessary(skb))
+ if (checksum_valid || skb_csum_unnecessary(skb))
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied);
else {
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 7a70a5a5671..91a6a2903e8 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -390,7 +390,14 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es
up = nla_data(rp);
ulen = xfrm_replay_state_esn_len(up);
- if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen)
+ /* Check the overall length and the internal bitmap length to avoid
+ * potential overflow. */
+ if (nla_len(rp) < ulen ||
+ xfrm_replay_state_esn_len(replay_esn) != ulen ||
+ replay_esn->bmp_len != up->bmp_len)
+ return -EINVAL;
+
+ if (up->replay_window > up->bmp_len * sizeof(__u32) * 8)
return -EINVAL;
return 0;