Leon wrote:
On Mon, 2006-06-26 at 14:24 +0200, Marek Marcola wrote:
OK weirdness going on here. I've added the RAND_load_file() command to
the beginning of my program and it does not make a difference.
With a 1000 threads I get a call to RAND_poll() only with the first
connection and not with subsequent SSL_accept() calls. With 1500 threads
it segfaults inside that one RAND_poll call.

Sorry cant help as I dont know anything about the RAND_xxx() workaround.


I now know that I am overwriting some memory due to the FD_SETSIZE
limit. The best solution for me will be to increase the value and
recompile the kernel. I will keep you guys posted if it does not work.
This limit is per process?

I do not believe the kernel has any problem with super-large fd_set's being passed to it. I believe the kernel will use whatever size its given and attempt to access the memory based on the 'maxfd' argument to select. If the kernel attempts to access illegal memory from userspace context (which the select() syscall runs in) the select() will return EFAULT or SIGSEGV the application. So no "recompile the kernel" is needed.

The "ulimit -a" resources are set per process yes. This affect the allocation of new file descriptors within the kernel. The default for Fedora and its glibc build is 1024. In order for you to have descriptors above 1024 you must have already dealt with raising the ulimit. At that point you run into these sorts of problems with any auxiliary library your applications call that do IO with select(). So you may need to audit other things YMMV.



Its purely a userspace issue.

Maybe in rand/rand_unix.c you can replace 'fd_set' with 'my_fd_set', then at the top of the code put:

#include <sys/select.h>
#define I_WANT_FD_SETSIZE       2048

#ifndef _NFDBITS
 #define _NFDBITS 8
#endif
#ifdef __fd_mask
 /* probably not perfect for x86_64 */
 #define __fd_mask long int __fd_mask
#endif

struct my_fd_set_type {
        __fd_mask fds_bits[I_WANT_FD_SETSIZE / __NFDBITS];
};

typedef struct my_fd_set_type my_fd_set;



You need to replace:

fd_set fset;

with

my_fd_set fset;



You need to replace FD_ZERO(&fset) with:

memset(&my_fd_set, 0, sizeof(my_fd_set));


Since the default macro will only clear the bits covering the first 1024 fds.



The try as Marek suggests:

 FD_SET(fd, (fd_set *)&my_fd_set;

And with select use:
 select(aaa, (fd_set *)&my_fd_set, xxx, yyy, zzz);


It is only the userspace code that allocats storage for fd_set type and calls FD_ZERO() and FD_SET() that needs to be altered. From there you can pass around the address of 'my_fd_set' and ultimately use it on the select() call.

If the stock glibc FD_SET() do not work, you may need to implemnt your own version of them against your my_fd_set_type. But I dont think this is the case I think FD_SET() will work but FD_ZERO() wont. Just use memset() for FD_ZERO().


The above is pretty Linux / glibc specific. You dont need to recompile anything but the single file rand/rand_unix.c from OpenSSL. It is the only affected part within OpenSSL AFAIK.

Obviously you may need to audit your application code for the same requirements.


HTH

Darryl
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to