From be49b5ec22ddd845d78eca7e7c2176c9d4c0aae3 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 7 Jan 2009 09:30:00 -0500 Subject: Check size of incoming packets. This should fix a buffer overflow waiting to be exploited :/ --- server/nss/nsssrv.c | 3 ++- server/nss/nsssrv.h | 2 ++ server/nss/nsssrv_packet.c | 16 +++++++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) (limited to 'server') diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c index bd9202bdc..32ab43db1 100644 --- a/server/nss/nsssrv.c +++ b/server/nss/nsssrv.c @@ -112,7 +112,8 @@ static void client_recv(struct event_context *ev, struct cli_ctx *cctx) } if (!cctx->creq->in) { - ret = nss_packet_new(cctx->creq, 0, 0, &cctx->creq->in); + ret = nss_packet_new(cctx->creq, NSS_PACKET_MAX_RECV_SIZE, + 0, &cctx->creq->in); if (ret != EOK) { DEBUG(0, ("Failed to alloc request, aborting client!\n")); talloc_free(cctx); diff --git a/server/nss/nsssrv.h b/server/nss/nsssrv.h index 223066f3d..90dda15ed 100644 --- a/server/nss/nsssrv.h +++ b/server/nss/nsssrv.h @@ -32,6 +32,8 @@ #define NSS_SBUS_SERVICE_VERSION 0x0001 #define NSS_SBUS_SERVICE_NAME "nss" +#define NSS_PACKET_MAX_RECV_SIZE 1024 + struct nss_ldb_ctx; struct getent_ctx; diff --git a/server/nss/nsssrv_packet.c b/server/nss/nsssrv_packet.c index c15f5c764..07cc2ff8a 100644 --- a/server/nss/nsssrv_packet.c +++ b/server/nss/nsssrv_packet.c @@ -50,9 +50,6 @@ struct nss_packet { * * - if size is defined use it otherwise the default packet will be * NSSSRV_PACKET_MEM_SIZE bytes. - * - if buf is provided also give back the pointer to the base of - * the buffer (the header), so that a packet can be written into - * firecgtly from the wire */ int nss_packet_new(TALLOC_CTX *mem_ctx, size_t size, enum sss_nss_command cmd, @@ -142,8 +139,13 @@ int nss_packet_recv(struct nss_packet *packet, int fd) void *buf; buf = packet->buffer + packet->iop; - if (packet->iop > 4) len = *packet->len; - else len = packet->memsize; + if (packet->iop > 4) len = *packet->len - packet->iop; + else len = packet->memsize - packet->iop; + + /* check for wrapping */ + if (len > packet->memsize) { + return EINVAL; + } errno = 0; rb = recv(fd, buf, len, 0); @@ -156,6 +158,10 @@ int nss_packet_recv(struct nss_packet *packet, int fd) return EIO; } + if (packet->len > packet->memsize) { + return EINVAL; + } + packet->iop += rb; if (packet->iop < 4) { return EAGAIN; -- cgit