| From dfaef61d75a2fe7f1c1a4e505e6e0c5f539c4a63 Mon Sep 17 00:00:00 2001 |
| From: Maxime Jayat <maxime.jayat@mobile-devices.fr> |
| Date: Tue, 21 Feb 2017 18:35:51 +0100 |
| Subject: [PATCH] net: socket: fix recvmmsg not returning error from sock_error |
| |
| commit e623a9e9dec29ae811d11f83d0074ba254aba374 upstream. |
| |
| Commit 34b88a68f26a ("net: Fix use after free in the recvmmsg exit path"), |
| changed the exit path of recvmmsg to always return the datagrams |
| variable and modified the error paths to set the variable to the error |
| code returned by recvmsg if necessary. |
| |
| However in the case sock_error returned an error, the error code was |
| then ignored, and recvmmsg returned 0. |
| |
| Change the error path of recvmmsg to correctly return the error code |
| of sock_error. |
| |
| The bug was triggered by using recvmmsg on a CAN interface which was |
| not up. Linux 4.6 and later return 0 in this case while earlier |
| releases returned -ENETDOWN. |
| |
| Fixes: 34b88a68f26a ("net: Fix use after free in the recvmmsg exit path") |
| Signed-off-by: Maxime Jayat <maxime.jayat@mobile-devices.fr> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/net/socket.c b/net/socket.c |
| index 03bc2c289c94..caf3ae902d2b 100644 |
| --- a/net/socket.c |
| +++ b/net/socket.c |
| @@ -2185,8 +2185,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
| return err; |
| |
| err = sock_error(sock->sk); |
| - if (err) |
| + if (err) { |
| + datagrams = err; |
| goto out_put; |
| + } |
| |
| entry = mmsg; |
| compat_entry = (struct compat_mmsghdr __user *)mmsg; |
| -- |
| 2.12.0 |
| |