From 164049133457364ba9acb832cea392e1545ed8eb Mon Sep 17 00:00:00 2001 From: Jan Vcelak <jan.vcelak@nic.cz> Date: Sun, 15 Nov 2015 00:11:54 +0100 Subject: [PATCH] knot_naptr_header_size: fix buffer boundary checks found by LibFuzzer --- src/Makefile.am | 1 + src/libknot/rrset.c | 1 + src/libknot/rrtype/naptr.c | 48 ++++++++++++++++++++++++++++++++++++++ src/libknot/rrtype/naptr.h | 35 +-------------------------- 4 files changed, 51 insertions(+), 34 deletions(-) create mode 100644 src/libknot/rrtype/naptr.c diff --git a/src/Makefile.am b/src/Makefile.am index e570beb811..341401bf56 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,6 +113,7 @@ libknot_la_SOURCES = \ libknot/rdataset.c \ libknot/rrset-dump.c \ libknot/rrset.c \ + libknot/rrtype/naptr.c \ libknot/rrtype/nsec3.c \ libknot/rrtype/nsec3param.c \ libknot/rrtype/opt.c \ diff --git a/src/libknot/rrset.c b/src/libknot/rrset.c index 4c6184b285..212accb09d 100644 --- a/src/libknot/rrset.c +++ b/src/libknot/rrset.c @@ -22,6 +22,7 @@ #include "libknot/consts.h" #include "libknot/descriptor.h" #include "libknot/dname.h" +#include "libknot/errcode.h" #include "libknot/rrtype/naptr.h" #include "libknot/internal/mempattern.h" #include "libknot/internal/macros.h" diff --git a/src/libknot/rrtype/naptr.c b/src/libknot/rrtype/naptr.c new file mode 100644 index 0000000000..b423e28628 --- /dev/null +++ b/src/libknot/rrtype/naptr.c @@ -0,0 +1,48 @@ +/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <assert.h> +#include <stdint.h> + +#include "libknot/errcode.h" +#include "libknot/internal/macros.h" +#include "libknot/internal/wire_ctx.h" +#include "libknot/rrtype/naptr.h" + +_public_ +int knot_naptr_header_size(const uint8_t *naptr, const uint8_t *maxp) +{ + if (!naptr || !maxp || naptr > maxp) { + return KNOT_EINVAL; + } + + wire_ctx_t wire = wire_ctx_init_const(naptr, maxp - naptr); + + /* Fixed fields size (order, preference) */ + wire_ctx_skip(&wire, 2 * sizeof(uint16_t)); + + /* Variable fields size (flags, services, regexp) */ + for (int i = 0; i < 3; i++) { + uint8_t size = wire_ctx_read_u8(&wire); + wire_ctx_skip(&wire, size); + } + + if (wire.error != KNOT_EOK) { + return KNOT_EMALF; + } + + return wire_ctx_offset(&wire); +} diff --git a/src/libknot/rrtype/naptr.h b/src/libknot/rrtype/naptr.h index b6bd36869f..f0a9ea0db1 100644 --- a/src/libknot/rrtype/naptr.h +++ b/src/libknot/rrtype/naptr.h @@ -13,24 +13,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/*! - * \file naptr.h - * - * \author Lubos Slovak <lubos.slovak@nic.cz> - * - * \brief Functions for manipulation of NAPTR RDATA. - * - * \addtogroup libknot - * @{ - */ #pragma once -#include <stdbool.h> #include <stdint.h> -#include <string.h> - -#include "libknot/errcode.h" /*! * \brief Counts the size of the NAPTR RDATA before the Replacement domain name. @@ -43,23 +29,4 @@ * \retval KNOT_EMALF if the record is malformed. * \retval Size of the RDATA before the Replacement domain name. */ -static inline int knot_naptr_header_size(const uint8_t *naptr, const uint8_t *maxp) -{ - int size = 0; - - /* Fixed fields size (order, preference) */ - size += 2 * sizeof(uint16_t); - - /* Variable fields size (flags, services, regexp) */ - for (int i = 0; i < 3; i++) { - const uint8_t *len_ptr = naptr + size; - if (len_ptr >= maxp) { - return KNOT_EMALF; - } - size += 1 + *len_ptr; - } - - return size; -} - -/*! @} */ +int knot_naptr_header_size(const uint8_t *naptr, const uint8_t *maxp); -- GitLab