Unverified Commit a5fbd258 authored by Mouse's avatar Mouse Committed by GitHub

Merge pull request #42 from vlm/master

Merging minor security fix (#318)
parents 5b314f76 f8b6e73a
......@@ -34,8 +34,11 @@ stamp-h*
# /asn1c/
/asn1c/asn1c
/asn1c/unber
/asn1c/enber
# /asn1c-tools
/asn1-tools/enber/enber
/asn1-tools/unber/unber
/asn1-tools/unber/check_unber
# /skeletons
/skeletons/check-*
......
......@@ -4,8 +4,10 @@ Bartosz Marcinkiewicz <bma@megawatt.com.pl>
Bent Nicolaisen <BN@JAI.com>
Bi-Ruei, Chiu <biruei.chiu@gmail.com>
Daniele Varrazzo <daniele.varrazzo@gmail.com>
Dave Cridland <dave@cridland.net>
Denis Filatov (DanyaFilatov @ github)
daa @ github
Eric Sesterhenn <eric.sesterhenn@x41-dsec.de>
Erika Thorsen (akire @ github)
gareins @ github
johvik @ github
......
......@@ -24,18 +24,22 @@
* uper_encode() API got new argument (breaks API compatibility).
* asn1c -gen-XXX flags are deprecated. Use -no-gen-XXX to disable codecs.
FIXES:
* CVE-2017-12966 verified not present.
* Fix incomplete (failed) CHOICE XER decoding memory leak.
(Severity: medium; Security impact: medium)
* Fix REAL type overwrite conversion memory leak.
(Severity: low; Security impact: medium)
* Fix UPER string decoding constrained only by lower bound > 0
(Severity: low; Security impact: none)
* Fix UPER decoding of large [bit-]strings of size a multiple of 16K
(Severity: low; Security impact: none)
* Fix XER decoder crash on maliciously constructed ENUMERATED input.
(Severity: medium; Security impact: medium)
FIXES IN COMPILER-GENERATED OUTPUT:
* Fix incomplete (failed) CHOICE XER decoding memory leak.
(Severity: medium; Security impact: medium)
* Fix REAL type overwrite conversion memory leak.
(Severity: low; Security impact: medium)
* Fix UPER string decoding constrained only by lower bound > 0
(Severity: low; Security impact: none)
* Fix UPER decoding of large [bit-]strings of size a multiple of 16K
(Severity: low; Security impact: none)
* Fix XER decoder crash on maliciously constructed ENUMERATED input.
(Severity: medium; Security impact: medium)
FIXES IN TOOLING:
* CVE-2017-12966 verified not present.
* Fix `unber` buffer overrun. Reported by Eric Sesterhenn.
(Severity: low; Security impact: high)
0.9.28: 2017-03-26
* PER decoding: avoid memory leak on error. By github.com/simo5
......
......@@ -8,8 +8,8 @@ SUBDIRS = \
libasn1common libasn1parser \
libasn1fix libasn1print \
libasn1compiler \
asn1c skeletons tests \
examples doc
asn1-tools asn1c skeletons \
tests examples doc
docsdir = $(datadir)/doc/asn1c
......
@CODE_COVERAGE_RULES@
SUBDIRS=unber enber
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = -I${top_srcdir}/skeletons
dist_check_SCRIPTS = check-xxber.sh
TESTS_ENVIRONMENT= builddir=${builddir}
TESTS = $(dist_check_SCRIPTS)
CLEANFILES = .check-xxber.*.tmp
unber - The ASN.1 BER Decoder
enber - Reverse unber(1) output back into BER
......@@ -3,6 +3,10 @@
ORIG="./.check-xxber.orig.$$.tmp"
TEST="./.check-xxber.test.$$.tmp"
builddir=${builddir:-.}
ENBER=${builddir}/enber/enber
UNBER=${builddir}/unber/unber
# Test diff(1) capabilities
diff -a . . 2>/dev/null && diffArgs="-a" # Assume text files
diff -u . . 2>/dev/null && diffArgs="$diffArgs -u" # Unified diff output
......@@ -23,7 +27,7 @@ cat<<EOM > $ORIG
</I O="32" T="[UNIVERSAL 0]" TL="2" L="4">
EOM
./enber $ORIG | ./unber -p -i 0 - > $TEST 2>&1
${ENBER} $ORIG | ${UNBER} -p -i 0 - > $TEST 2>&1
diff $diffArgs "$ORIG" "$TEST" >/dev/null 2>&1
diffExitCode=$?
......@@ -36,7 +40,7 @@ fi
echo '</I O="34" T="[UNIVERSAL 0]" TL="2" L="36">' >> $ORIG
# Try trancoding again
./enber $ORIG | ./unber -p -i 0 - > $TEST 2>&1
${ENBER} $ORIG | ${UNBER} -p -i 0 - > $TEST 2>&1
diff $diffArgs "$ORIG" "$TEST"
diffExitCode=$?
......
@CODE_COVERAGE_RULES@
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = \
-I${top_srcdir}/libasn1common \
-I${top_srcdir}/libasn1parser \
-I${top_srcdir}/skeletons
bin_PROGRAMS = enber
/*-
/*
* Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -22,9 +22,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
#include "sys-common.h"
#include "asn1_common.h"
#include <asn1parser.h> /* For static string tables */
......
@CODE_COVERAGE_RULES@
AM_CFLAGS = @ADD_CFLAGS@
AM_CPPFLAGS = \
-I${top_srcdir}/libasn1common \
-I${top_srcdir}/libasn1parser \
-I${top_srcdir}/skeletons
noinst_LTLIBRARIES = libasn1-unber-tool.la
libasn1_unber_tool_la_SOURCES = \
libasn1_unber_tool.c libasn1_unber_tool.h
bin_PROGRAMS = unber
unber_LDADD = libasn1-unber-tool.la \
$(top_builddir)/libasn1common/libasn1common.la
check_PROGRAMS = check_unber
check_unber_CFLAGS = $(TESTSUITE_CFLAGS) $(LIBFUZZER_CFLAGS)
check_unber_LDADD = libasn1-unber-tool.la \
$(top_builddir)/libasn1common/libasn1common.la
dist_check_SCRIPTS=check_unber.sh
# This jump through the shell is needed to run ./check_unber binary with
# proper fuzzing options.
TESTS_ENVIRONMENT= \
ASAN_ENV_FLAGS="@ASAN_ENV_FLAGS@" \
builddir=${builddir}
TESTS= check_unber.sh
#include "asn1_common.h"
#include "libasn1_unber_tool.h"
// An abstraction for getting data from the in-memory buffer.
struct memory_buffer_stream {
input_stream_t istream;
const uint8_t *data;
size_t size;
size_t offset;
};
static int memory_buffer_stream_nextChar(input_stream_t *ibs) {
struct memory_buffer_stream *bs = (struct memory_buffer_stream *)ibs;
if(bs->offset < bs->size) {
return bs->data[bs->offset++];
} else {
return -1;
}
}
static off_t memory_buffer_stream_bytesRead(input_stream_t *ibs) {
struct memory_buffer_stream *bs = (struct memory_buffer_stream *)ibs;
return (off_t)bs->offset;
}
static int
ignore_vprintf(output_stream_t *os, const char *fmt, va_list ap) {
(void)os;
(void)fmt;
(void)ap;
// Ignore all output.
return 0;
}
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
int
LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
// Read from a memory buffer.
struct memory_buffer_stream mbs;
mbs.istream.nextChar = memory_buffer_stream_nextChar;
mbs.istream.bytesRead = memory_buffer_stream_bytesRead;
mbs.data = Data;
mbs.size = Size;
mbs.offset = 0;
// Do not print anywhere.
struct output_stream nullstream;
nullstream.vprintf = ignore_vprintf;
nullstream.vprintfError = ignore_vprintf;
(void)unber_stream("<fuzzed-input>", &mbs.istream, &nullstream);
return 0;
}
#ifndef ENABLE_LIBFUZZER
int main() {
printf("libfuzzer is not compiled-in, pretend the test went OK.\n");
return 0;
}
#endif
#!/bin/sh
FUZZ_TIME=${FUZZ_TIME:-10}
builddir=${builddir:-.}
env ${ASAN_ENV_FLAGS:-} ${builddir}/check_unber \
-timeout=3 \
-max_total_time=${FUZZ_TIME} \
-max_len=500
/*
* Copyright (c) 2004-2019 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/* Set global options. */
void set_minimalistic_output(int v);
void set_single_type_decoding(int v);
void set_pretty_printing(int v);
int set_skip_bytes(long v);
int set_indent_size(int indent_size);
/*
* Convert BER-encoded file into the low level non-standard XML-like structure.
* Primarily used for manual debugging.
*/
int unber_file(const char *fname);
typedef struct input_stream {
/*
* Return the next character as if it were an unsigned int converted to
* an int. Returns -1 on EOF or error.
*/
int (*nextChar)(struct input_stream *);
/*
* Return the number of bytes consumed from the stream so far.
*/
off_t (*bytesRead)(struct input_stream *);
} input_stream_t;
typedef struct output_stream {
/*
* Return the next character as if it were an unsigned int converted to
* an int. Returns -1 on EOF or error.
*/
int (*vprintf)(struct output_stream *, const char *fmt, va_list);
int (*vprintfError)(struct output_stream *, const char *fmt, va_list);
} output_stream_t;
/*
* Lower level converter.
*/
int unber_stream(const char *fname, input_stream_t *, output_stream_t *);
/*
* Decode the TLV given by the given string.
*/
int decode_tlv_from_hex_string(const char *datastring);
/*
* Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include "asn1_common.h"
#include "libasn1_unber_tool.h"
#undef COPYRIGHT
#define COPYRIGHT "Copyright (c) 2004-2019 Lev Walkin <vlm@lionet.info>\n"
static void usage(const char *av0); /* Print the Usage screen and exit */
int
main(int ac, char **av) {
int ch; /* Command line character */
/*
* Process command-line options.
*/
while((ch = getopt(ac, av, "1hi:mps:t:v")) != -1) {
switch(ch) {
case '1':
set_single_type_decoding(1);
break;
case 'i':
if(set_indent_size(atoi(optarg)) != 0) {
fprintf(stderr, "-i %s: Invalid indent value\n", optarg);
exit(EX_USAGE);
}
break;
case 'm':
set_minimalistic_output(1);
break;
case 'p':
set_pretty_printing(0);
break;
case 's':
if(set_skip_bytes(atol(optarg)) != 0) {
fprintf(stderr, "-s %s: positive value expected\n", optarg);
exit(EX_USAGE);
}
break;
case 't':
if(decode_tlv_from_hex_string(optarg)) exit(EX_DATAERR);
exit(0);
case 'v':
fprintf(stderr, "ASN.1 BER Decoder, v" VERSION "\n" COPYRIGHT);
exit(0);
break;
case 'h':
default:
usage(av[0]);
}
}
/*
* Ensure that there are some input files present.
*/
if(ac > optind) {
ac -= optind;
av += optind;
} else {
fprintf(stderr, "%s: No input files specified\n", av[0]);
exit(1);
}
setvbuf(stdout, 0, _IOLBF, 0);
/*
* Iterate over input files and parse each.
* All syntax trees from all files will be bundled together.
*/
for(int i = 0; i < ac; i++) {
if(unber_file(av[i])) exit(EX_DATAERR);
}
return 0;
}
/*
* Print the usage screen and exit(EX_USAGE).
*/
static void
usage(const char *av0) {
/* clang-format off */
fprintf(stderr,
"ASN.1 BER Decoder, v" VERSION "\n" COPYRIGHT
"Usage: %s [options] [-] [file ...]\n"
"Options:\n"
" -1 Decode only the first BER structure (otherwise, until EOF)\n"
" -i <indent> Amount of spaces for output indentation (default is 4)\n"
" -m Minimalistic mode: print as little as possible\n"
" -p Do not attempt pretty-printing of known ASN.1 types\n"
" -s <skip> Ignore first <skip> bytes of input\n"
" -t <hex-string> Decode the given tag[/length] sequence (e.g. -t \"bf20\")\n"
"\n"
"The XML opening tag format is as follows:\n"
" <tform O=\"off\" T=\"tag\" TL=\"tl_len\" V=\"{Indefinite|v_len}\" [A=\"type\"] [F]>\n"
"Where:\n"
" tform Which form the value is in: constructed (\"C\", \"I\") or primitive (\"P\")\n"
" off Offset of the encoded element in the unber input stream\n"
" tag The tag class and value in human readable form\n"
" tl_len The length of the TL (BER Tag and Length) encoding\n"
" v_len The length of the value (V, encoded by the L), may be \"Indefinite\"\n"
" type Likely name of the underlying ASN.1 type (for [UNIVERSAL n] tags)\n"
" [F] Indicates that the value was reformatted (pretty-printed)\n"
"See the manual page for details\n"
, av0);
/* clang-format on */
exit(EX_USAGE);
}
......@@ -17,14 +17,4 @@ asn1c_LDADD = \
$(top_builddir)/libasn1fix/libasn1fix.la \
$(top_builddir)/libasn1compiler/libasn1compiler.la
unber_LDADD = \
$(top_builddir)/libasn1common/libasn1common.la
bin_PROGRAMS = asn1c unber enber
noinst_HEADERS = sys-common.h
dist_check_SCRIPTS = check-xxber.sh
TESTS_ENVIRONMENT= top_srcdir=${top_srcdir}
TESTS = $(dist_check_SCRIPTS)
CLEANFILES = .check-xxber.*.tmp
bin_PROGRAMS = asn1c
asn1c - The ASN.1 Compiler
unber - The ASN.1 BER Decoder
enber - Reverse unber(1) output back into BER
......@@ -23,13 +23,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
/*
* This is the program that connects the libasn1* libraries together.
* It uses them in turn to parse, fix and then compile or print the ASN.1 tree.
*/
#include "sys-common.h"
#include "asn1_common.h"
#undef COPYRIGHT
#define COPYRIGHT "Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info> and contributors.\n"
......
......@@ -292,6 +292,9 @@ tests/tests-asn1c-smoke/Makefile \
tests/tests-randomized/Makefile \
tests/tests-c-compiler/Makefile \
tests/tests-skeletons/Makefile \
asn1-tools/enber/Makefile \
asn1-tools/unber/Makefile \
asn1-tools/Makefile \
libasn1compiler/Makefile \
libasn1common/Makefile \
libasn1parser/Makefile \
......
......@@ -5,7 +5,7 @@ AM_CFLAGS = @ADD_CFLAGS@
noinst_LTLIBRARIES = libasn1common.la
libasn1common_la_SOURCES = \
asn1_ref.c asn1_ref.h \
asn1_common.h asn1_ref.c asn1_ref.h \
asn1_buffer.c asn1_buffer.h \
asn1_namespace.c asn1_namespace.h \
genhash.c genhash.h
......
......@@ -4,15 +4,17 @@
diff -a . . 2>/dev/null && diffArgs="-a" # Assume text files
diff -u . . 2>/dev/null && diffArgs="$diffArgs -u" # Unified diff output
ec=0
finalExitCode=0
if [ "$1" != "regenerate" ]; then
set -e
fi
PROCESSING=""
LAST_FAILED=""
print_status() {
echo "Error while processing $PROCESSING"
if [ -n "${LAST_FAILED}" ]; then
echo "Error while processing $LAST_FAILED"
fi
}
trap print_status EXIT
......@@ -29,20 +31,20 @@ for ref in ${top_srcdir}/tests/tests-asn1c-compiler/*.asn1.-*; do
template=.tmp.check-parsing.$$
oldversion=${template}.old
newversion=${template}.new
PROCESSING="$ref (from $src)"
LANG=C sed -e 's/^found in .*/found in .../' < "$ref" > "$oldversion"
ec=0
(${top_builddir}/asn1c/asn1c -S ${top_srcdir}/skeletons -no-gen-OER -no-gen-PER "-$flags" "$src" | LANG=C sed -e 's/^found in .*/found in .../' > "$newversion") || ec=$?
if [ $? = 0 ]; then
diff $diffArgs "$oldversion" "$newversion" || ec=$?
fi
if [ $ec != 0 ]; then
LAST_FAILED="$ref (from $src)"
finalExitCode=$ec
fi
rm -f $oldversion $newversion
if [ "$1" = "regenerate" ]; then
${top_builddir}/asn1c/asn1c -S ${top_srcdir}/skeletons -no-gen-OER -no-gen-PER "-$flags" "$src" > "$ref"
fi
done
if [ $ec = 0 ]; then
trap '' EXIT
fi
exit $ec
exit $finalExitCode
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment