Return-Path: X-Original-To: krb5-send-pr-nospam1@krbdev.mit.edu Received: from pch.mit.edu (PCH.MIT.EDU [18.7.21.90]) by krbdev.mit.edu (Postfix) with ESMTP id F25595C248; Wed, 7 Jan 2009 21:05:53 +0000 (UTC) Received: from pch.mit.edu (pch.mit.edu [127.0.0.1]) by pch.mit.edu (8.13.6/8.12.8) with ESMTP id n07L5rnP015315; Wed, 7 Jan 2009 16:05:53 -0500 Received: from pacific-carrier-annex.mit.edu (PACIFIC-CARRIER-ANNEX.MIT.EDU [18.7.21.83]) by pch.mit.edu (8.13.6/8.12.8) with ESMTP id n07K9uT7004856 for ; Wed, 7 Jan 2009 15:09:58 -0500 Received: from mit.edu (W92-130-BARRACUDA-2.MIT.EDU [18.7.21.223]) by pacific-carrier-annex.mit.edu (8.13.6/8.9.2) with ESMTP id n07K9oAT026059 for ; Wed, 7 Jan 2009 15:09:50 -0500 (EST) Received: from arioch.imrryr.org (arioch.imrryr.org [38.117.134.205]) by mit.edu (Spam Firewall) with ESMTP id 119711190338 for ; Wed, 7 Jan 2009 15:09:25 -0500 (EST) Received: from imrryr.org (localhost [127.0.0.1]) by arioch.imrryr.org (Postfix) with ESMTP id 0F56637D93 for ; Wed, 7 Jan 2009 15:09:24 -0500 (EST) To: krb5-bugs@mit.edu Subject: select(2) if no fds < FD_SETSIZE are available. Organization: The Fall of Imrryr User-Agent: nmh-1.0.4 (NetBSD/alpha) X-Copyright: Copyright 2005, R. C. Dowdeswell. All Rights Reserved. X-Window-System: Release 6.3 Date: Wed, 07 Jan 2009 15:09:24 -0500 From: Roland Dowdeswell Message-ID: <20090107200924.0F56637D93@arioch.imrryr.org> X-Spam-Score: 0.12 X-Spam-Flag: NO X-Scanned-BY: MIMEDefang 2.42 X-Mailman-Approved-At: Wed, 07 Jan 2009 16:05:51 -0500 X-Beenthere: krb5-bugs-incoming@mailman.mit.edu X-Mailman-Version: 2.1.6 Precedence: list Sender: krb5-bugs-incoming-bounces@PCH.mit.edu Errors-To: krb5-bugs-incoming-bounces@PCH.mit.edu X-RT-Original-Encoding: iso-8859-1 Content-Length: 3111 sendto_kdc.c uses select(2) and does not check to see if the fds that it obtains are less than FD_SETSIZE. This can cause undefined behaviour as FD_SET() does not do bounds checking. Although, this limitation should probably be addressed by using Niels Provos' libevent, I provide a small patch which will: 1. return reasonable errors if the size is returned, and 2. increase the limit to DESIRED_FD_SETSIZE which I define to be 8192. I think that (1) or something like it should be applied. (2) on the other hand is quite inelegant. A better approach should be used, I just in case it is viewed to be a reasonable short term fix. I call the inability to obtain a socket < FD_SETSIZE a permanent error which we can also change. It seemed at the time best to simply fail quickly w/o core dumping. I also return EMFILE in this case so that the error message returned is slightly more descriptive than KRB5_KDC_UNREACH. You may very well be able to reach KDCs, if you just had a few more fds.. Index: sendto_kdc.c =================================================================== RCS file: /ms/dev/kerberos/mitkrb5/cvs-dirs/mitkrb5-1.4/mitkrb5/src/lib/krb5/os/sendto_kdc.c,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 sendto_kdc.c --- sendto_kdc.c 16 Aug 2005 19:52:03 -0000 1.1.1.2 +++ sendto_kdc.c 7 Jan 2009 17:21:02 -0000 @@ -28,6 +28,25 @@ * as necessary. */ +/* + * We start out by upping the size of FD_SETSIZE. On rational operating + * systems, this is simple. One simply #defines FD_SETSIZE before including + * anything else. Linux of course does not support this because they are + * better than that. So, we special case things... + */ + +#define DESIRED_FD_SETSIZE 8192 +#ifndef linux +#define FD_SETSIZE DESIRED_FD_SETSIZE +#else +#include +#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) +#include +#undef __FD_SETSIZE +#define __FD_SETSIZE DESIRED_FD_SETSIZE +#endif +#endif + #define NEED_SOCKETS #define NEED_LOWLEVEL_IO #include "fake-addrinfo.h" @@ -572,8 +591,16 @@ dprint("start_connection(@%p)\ngetting %s socket in family %d...", state, ai->ai_socktype == SOCK_STREAM ? "stream" : "dgram", ai->ai_family); fd = socket(ai->ai_family, ai->ai_socktype, 0); + if (fd >= FD_SETSIZE) { + close(fd); + state->err = EMFILE; + state->state = FAILED; /* XXXrcd: hmmm, is this permanent...? */ + dprint("socket: %m creating with af %d\n", state->err, ai->ai_family); + return -1; /* try other hosts */ + } if (fd == INVALID_SOCKET) { state->err = SOCKET_ERRNO; + state->state = FAILED; /* XXXrcd: hmmm, is this permanent...? */ dprint("socket: %m creating with af %d\n", state->err, ai->ai_family); return -1; /* try other hosts */ } @@ -1130,6 +1157,9 @@ if (sel_state->nfds == 0) { /* No addresses? */ retval = KRB5_KDC_UNREACH; + for (host = 0; host < n_conns; host++) + if (conns[host].err == EMFILE) + retval = EMFILE; goto egress; } if (e == 0 || winning_conn < 0) { -- Roland Dowdeswell http://www.Imrryr.ORG/~elric/