| From 677e806da4d916052585301785d847c3b3e6186a Mon Sep 17 00:00:00 2001 |
| From: Andy Whitcroft <apw@canonical.com> |
| Date: Wed, 22 Mar 2017 07:29:31 +0000 |
| Subject: xfrm_user: validate XFRM_MSG_NEWAE XFRMA_REPLAY_ESN_VAL replay_window |
| |
| From: Andy Whitcroft <apw@canonical.com> |
| |
| commit 677e806da4d916052585301785d847c3b3e6186a upstream. |
| |
| When a new xfrm state is created during an XFRM_MSG_NEWSA call we |
| validate the user supplied replay_esn to ensure that the size is valid |
| and to ensure that the replay_window size is within the allocated |
| buffer. However later it is possible to update this replay_esn via a |
| XFRM_MSG_NEWAE call. There we again validate the size of the supplied |
| buffer matches the existing state and if so inject the contents. We do |
| not at this point check that the replay_window is within the allocated |
| memory. This leads to out-of-bounds reads and writes triggered by |
| netlink packets. This leads to memory corruption and the potential for |
| priviledge escalation. |
| |
| We already attempt to validate the incoming replay information in |
| xfrm_new_ae() via xfrm_replay_verify_len(). This confirms that the user |
| is not trying to change the size of the replay state buffer which |
| includes the replay_esn. It however does not check the replay_window |
| remains within that buffer. Add validation of the contained |
| replay_window. |
| |
| CVE-2017-7184 |
| Signed-off-by: Andy Whitcroft <apw@canonical.com> |
| Acked-by: Steffen Klassert <steffen.klassert@secunet.com> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| net/xfrm/xfrm_user.c | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/net/xfrm/xfrm_user.c |
| +++ b/net/xfrm/xfrm_user.c |
| @@ -393,6 +393,9 @@ static inline int xfrm_replay_verify_len |
| replay_esn->bmp_len != up->bmp_len) |
| return -EINVAL; |
| |
| + if (up->replay_window > up->bmp_len * sizeof(__u32) * 8) |
| + return -EINVAL; |
| + |
| return 0; |
| } |
| |