summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2009-01-07 09:30:00 -0500
committerSimo Sorce <idra@samba.org>2009-01-07 09:30:00 -0500
commitbe49b5ec22ddd845d78eca7e7c2176c9d4c0aae3 (patch)
tree3dc7c2f0a714738f3a31e6b0c646b357e5e36e72 /server
parent054321c995958ecc7f8e5a92f8d35c6a6bd6e809 (diff)
downloadsssd-be49b5ec22ddd845d78eca7e7c2176c9d4c0aae3.tar.gz
sssd-be49b5ec22ddd845d78eca7e7c2176c9d4c0aae3.tar.bz2
sssd-be49b5ec22ddd845d78eca7e7c2176c9d4c0aae3.zip
Check size of incoming packets.
This should fix a buffer overflow waiting to be exploited :/
Diffstat (limited to 'server')
-rw-r--r--server/nss/nsssrv.c3
-rw-r--r--server/nss/nsssrv.h2
-rw-r--r--server/nss/nsssrv_packet.c16
3 files changed, 15 insertions, 6 deletions
diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c
index bd9202bd..32ab43db 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 223066f3..90dda15e 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 c15f5c76..07cc2ff8 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;