[Kernel-packages] [Bug 1510213] Re: Regression: Stable kernel update to 3.13.0-66 breaks UDP sockets
*** This bug is a duplicate of bug 1508510 *** https://bugs.launchpad.net/bugs/1508510 Thank you, this seems to be a duplicate of bug #1508510 which has been fixed already in -proposed. ** This bug has been marked a duplicate of bug 1508510 Something in the Kernel crashes when I try to mount via NFS -- You received this bug notification because you are a member of Kernel Packages, which is subscribed to linux in Ubuntu. https://bugs.launchpad.net/bugs/1510213 Title: Regression: Stable kernel update to 3.13.0-66 breaks UDP sockets Status in linux package in Ubuntu: Confirmed Bug description: I am running the 3.13 series kernel on Ubuntu 14.04 LTS (Trusty Tahr). A change introduced in version 3.13.0-66.108 of this kernel breaks UDP sockets under certain circumstances. The effect is that the recvfrom operation returns with an error, setting errno to EFAULT, even though the pointers passed to recvfrom are okay. Using bisection, I could track down this problem to a single change: 2dde51aa53393a531b493e3a8194e4d467e194a3 is the first bad commit commit 2dde51aa53393a531b493e3a8194e4d467e194a3 Author: Herbert XuDate: Mon Jul 13 20:01:42 2015 +0800 net: Fix skb csum races when peeking BugLink: http://bugs.launchpad.net/bugs/1500810 [ Upstream commit 89c22d8c3b278212eef6a8cc66b570bc840a6f5a ] When we calculate the checksum on the recv path, we store the result in the skb as an optimisation in case we need the checksum again down the line. This is in fact bogus for the MSG_PEEK case as this is done without any locking. So multiple threads can peek and then store the result to the same skb, potentially resulting in bogus skb states. This patch fixes this by only storing the result if the skb is not shared. This preserves the optimisations for the few cases where it can be done safely due to locking or other reasons, e.g., SIOCINQ. Signed-off-by: Herbert Xu Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Kamal Mostafa Signed-off-by: Luis Henriques :04 04 423debc59ddbc7424283e647e609289fd40dc494 2511e80df4c30a7309737f6b3cee0260269a0ef7 M net Steps to reproduce the problem: Install freeradius, and have a radius client connect to the RADIUS server. After a short amount of time, freeradius spins at 100% CPU, alternating between a select and recvfrom call. The recvfrom call fails every time with error EFAULT. As an alternative to freeradius, you can use the following minimal program that I wrote that also exhibits this problem: #include #include #include #include #include #include #include #include #include int prepare_socket(int port) { int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { printf("Could not create socket.\n"); return -1; } int opt = 1; if (setsockopt(sock, SOL_IP, IP_PKTINFO, , sizeof(opt)) < 0) { printf("setsockopt failed.\n"); return -1; } struct sockaddr_in bind_addr; bind_addr.sin_family = AF_INET; bind_addr.sin_port = htons(port); bind_addr.sin_addr.s_addr = INADDR_ANY; int rc = bind(sock, (struct sockaddr *) _addr, sizeof(bind_addr)); if (rc < 0) { printf("Could not bind socket.\n"); return -1; } return sock; } int main(int argc, char **argv) { int sock = prepare_socket(1812); if (sock < 0) { return 1; } for (;;) { unsigned char buffer[4]; struct sockaddr src; socklen_t src_len = sizeof(src); ssize_t received_len = recvfrom(sock, buffer, sizeof(buffer), MSG_PEEK, , _len); if (received_len < 0) { if (errno == EAGAIN) { printf("EAGAIN\n"); continue; } printf("recvfrom failed.\n"); perror(NULL); return 1; } if (received_len == 4) { src_len = sizeof(src); received_len = recvfrom(sock, buffer, sizeof(buffer), 0, , _len); if (received_len != 4) { printf("Strange received length.\n"); return 1; } } } /* Never reached */ return 0; } However, I did not find out how to craft the traffic that triggers the bug. However, the traffic from a RADIUS client (a WiFi AP in my case) reliably triggers the bug after a few seconds. As this is perfectly legal code and the problem only appears with the change introduced earlier, I think that this is a regression and the change in question should be removed from the stable kernel tree. ProblemType: Bug DistroRelease: Ubuntu 14.04 Package: linux-image-3.13.0-66-generic 3.13.0-66.108 ProcVersionSignature: Ubuntu 3.13.0-66.108-generic
[Kernel-packages] [Bug 1510213] Re: Regression: Stable kernel update to 3.13.0-66 breaks UDP sockets
*** This bug is a duplicate of bug 1508510 *** https://bugs.launchpad.net/bugs/1508510 I can confirm that this bug is a duplicate of bug #1508510 and that the kernel from -proposed fixes the problem. -- You received this bug notification because you are a member of Kernel Packages, which is subscribed to linux in Ubuntu. https://bugs.launchpad.net/bugs/1510213 Title: Regression: Stable kernel update to 3.13.0-66 breaks UDP sockets Status in linux package in Ubuntu: Confirmed Bug description: I am running the 3.13 series kernel on Ubuntu 14.04 LTS (Trusty Tahr). A change introduced in version 3.13.0-66.108 of this kernel breaks UDP sockets under certain circumstances. The effect is that the recvfrom operation returns with an error, setting errno to EFAULT, even though the pointers passed to recvfrom are okay. Using bisection, I could track down this problem to a single change: 2dde51aa53393a531b493e3a8194e4d467e194a3 is the first bad commit commit 2dde51aa53393a531b493e3a8194e4d467e194a3 Author: Herbert XuDate: Mon Jul 13 20:01:42 2015 +0800 net: Fix skb csum races when peeking BugLink: http://bugs.launchpad.net/bugs/1500810 [ Upstream commit 89c22d8c3b278212eef6a8cc66b570bc840a6f5a ] When we calculate the checksum on the recv path, we store the result in the skb as an optimisation in case we need the checksum again down the line. This is in fact bogus for the MSG_PEEK case as this is done without any locking. So multiple threads can peek and then store the result to the same skb, potentially resulting in bogus skb states. This patch fixes this by only storing the result if the skb is not shared. This preserves the optimisations for the few cases where it can be done safely due to locking or other reasons, e.g., SIOCINQ. Signed-off-by: Herbert Xu Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Kamal Mostafa Signed-off-by: Luis Henriques :04 04 423debc59ddbc7424283e647e609289fd40dc494 2511e80df4c30a7309737f6b3cee0260269a0ef7 M net Steps to reproduce the problem: Install freeradius, and have a radius client connect to the RADIUS server. After a short amount of time, freeradius spins at 100% CPU, alternating between a select and recvfrom call. The recvfrom call fails every time with error EFAULT. As an alternative to freeradius, you can use the following minimal program that I wrote that also exhibits this problem: #include #include #include #include #include #include #include #include #include int prepare_socket(int port) { int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { printf("Could not create socket.\n"); return -1; } int opt = 1; if (setsockopt(sock, SOL_IP, IP_PKTINFO, , sizeof(opt)) < 0) { printf("setsockopt failed.\n"); return -1; } struct sockaddr_in bind_addr; bind_addr.sin_family = AF_INET; bind_addr.sin_port = htons(port); bind_addr.sin_addr.s_addr = INADDR_ANY; int rc = bind(sock, (struct sockaddr *) _addr, sizeof(bind_addr)); if (rc < 0) { printf("Could not bind socket.\n"); return -1; } return sock; } int main(int argc, char **argv) { int sock = prepare_socket(1812); if (sock < 0) { return 1; } for (;;) { unsigned char buffer[4]; struct sockaddr src; socklen_t src_len = sizeof(src); ssize_t received_len = recvfrom(sock, buffer, sizeof(buffer), MSG_PEEK, , _len); if (received_len < 0) { if (errno == EAGAIN) { printf("EAGAIN\n"); continue; } printf("recvfrom failed.\n"); perror(NULL); return 1; } if (received_len == 4) { src_len = sizeof(src); received_len = recvfrom(sock, buffer, sizeof(buffer), 0, , _len); if (received_len != 4) { printf("Strange received length.\n"); return 1; } } } /* Never reached */ return 0; } However, I did not find out how to craft the traffic that triggers the bug. However, the traffic from a RADIUS client (a WiFi AP in my case) reliably triggers the bug after a few seconds. As this is perfectly legal code and the problem only appears with the change introduced earlier, I think that this is a regression and the change in question should be removed from the stable kernel tree. ProblemType: Bug DistroRelease: Ubuntu 14.04 Package: linux-image-3.13.0-66-generic 3.13.0-66.108 ProcVersionSignature: Ubuntu 3.13.0-66.108-generic 3.13.11-ckt27 Uname: Linux 3.13.0-66-generic x86_64 AlsaDevices: total 0 crw-rw 1 root audio