From a473aaaa43e34705bb730b05350d6b733890e542 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 1 Aug 2018 20:38:54 +0200 Subject: Fix NIF stack recursion bug and enforce a limit Fix recursion bug when decoding Constructed value within another value - here the allowed buffer for the recursed decode shall only be the size of the enclosing value, not the whole buffer. Return ASN1_ERROR if BER decode recurses more than about 8 kWords. --- lib/asn1/c_src/asn1_erl_nif.c | 10 ++++++++-- lib/asn1/test/asn1_SUITE.erl | 45 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/lib/asn1/c_src/asn1_erl_nif.c b/lib/asn1/c_src/asn1_erl_nif.c index d5aaadb89b..797be6d4f8 100644 --- a/lib/asn1/c_src/asn1_erl_nif.c +++ b/lib/asn1/c_src/asn1_erl_nif.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2002-2017. All Rights Reserved. + * Copyright Ericsson AB 2002-2018. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -949,6 +949,12 @@ static int ber_decode_value(ErlNifEnv* env, ERL_NIF_TERM *value, unsigned char * unsigned char *tmp_out_buff; ERL_NIF_TERM term = 0, curr_head = 0; + /* Recursion depth limitation, borrow a signed int: maybe_ret */ + maybe_ret = (int) (ErlNifSInt) ((char *)value - (char *)ib_index); + maybe_ret = maybe_ret < 0 ? -maybe_ret : maybe_ret; + if (maybe_ret >= sizeof(void *) * 8192) /* 8 k pointer words */ + return ASN1_ERROR; + if (((in_buf[*ib_index]) & 0x80) == ASN1_SHORT_DEFINITE_LENGTH) { len = in_buf[*ib_index]; } else if (in_buf[*ib_index] == ASN1_INDEFINITE_LENGTH) { @@ -993,7 +999,7 @@ static int ber_decode_value(ErlNifEnv* env, ERL_NIF_TERM *value, unsigned char * while (*ib_index < end_index) { if ((maybe_ret = ber_decode(env, &term, in_buf, ib_index, - in_buf_len)) <= ASN1_ERROR + *ib_index + len)) <= ASN1_ERROR ) return maybe_ret; curr_head = enif_make_list_cell(env, term, curr_head); diff --git a/lib/asn1/test/asn1_SUITE.erl b/lib/asn1/test/asn1_SUITE.erl index bfeffa969f..31b41a4ba6 100644 --- a/lib/asn1/test/asn1_SUITE.erl +++ b/lib/asn1/test/asn1_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2017. All Rights Reserved. +%% Copyright Ericsson AB 2001-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -132,7 +132,8 @@ groups() -> testSeq2738, % Uses 'Constructed' {group, [], [constructed, - ber_decode_error]}, + ber_decode_error, + otp_14440]}, testSeqSetIndefinite, testChoiceIndefinite, per_open_type, @@ -737,6 +738,36 @@ ber_decode_error(Config, Rule, Opts) -> asn1_test_lib:compile("Constructed", Config, [Rule|Opts]), ber_decode_error:run(Opts). +otp_14440(_Config) -> + Args = " -pa \"" ++ filename:dirname(code:which(?MODULE)) ++ "\"", + {ok,N} = slave:start(hostname(), otp_14440, Args), + Result = rpc:call(N, ?MODULE, otp_14440_decode, []), + io:format("Decode result = ~p~n", [Result]), + case Result of + {exit,{error,{asn1,{invalid_value,5}}}} -> + ok = slave:stop(N); + %% We get this if stack depth limit kicks in: + {exit,{error,{asn1,{unknown,_}}}} -> + ok = slave:stop(N); + _ -> + _ = slave:stop(N), + ?t:fail(Result) + end. +%% +otp_14440_decode() -> + Data = + iolist_to_binary( + lists:duplicate( + 32, list_to_binary(lists:duplicate(1024, 16#7f)))), + try asn1rt_nif:decode_ber_tlv(Data) of + Result -> + {unexpected_return,Result} + catch + Class:Reason -> + {Class,Reason} + end. + + h323test(Config) -> test(Config, fun h323test/3). h323test(Config, Rule, Opts) -> Files = ["H235-SECURITY-MESSAGES", "H323-MESSAGES", @@ -1351,7 +1382,7 @@ xref_export_all(_Config) -> {ok,_} = xref:q(S, Def), {ok,Unused} = xref:q(S, "X - Called - range (closure E | Called)"), xref:stop(S), - case Unused of + case Unused -- [{?MODULE,otp_14440_decode,0}] of [] -> ok; [_|_] -> @@ -1386,3 +1417,11 @@ all_called_1([F|T]) when is_atom(F) -> L ++ all_called_1(T); all_called_1([]) -> []. + +hostname() -> + hostname(atom_to_list(node())). + +hostname([$@ | Hostname]) -> + list_to_atom(Hostname); +hostname([_C | Cs]) -> + hostname(Cs). -- cgit v1.2.3 From d2d4ffbb113860305116af32f5588fe10d625cf1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Thu, 2 Aug 2018 10:04:10 +0200 Subject: Prepare release --- lib/asn1/doc/src/notes.xml | 22 ++++++++++++++++++++++ lib/asn1/vsn.mk | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml index bb15c9ff5f..40f1812dff 100644 --- a/lib/asn1/doc/src/notes.xml +++ b/lib/asn1/doc/src/notes.xml @@ -32,6 +32,28 @@

This document describes the changes made to the asn1 application.

+
Asn1 5.0.5.1 + +
Known Bugs and Problems + + +

A bug in ASN.1 BER decoding has been fixed. When + decoding a recursively enclosed term the length was not + propagated to that term decoding, so if the length of the + enclosed term was longer than the enclosing that error + was not dectected

A hard coded C stack limitation + for decoding recursive ASN.1 terms has been introduced. + This is currently set to 8 kWords giving a nesting depth + of about 1000 levels. Deeper terms can not be decoded, + which should not be much of a real world limitation.

+

+ Own Id: OTP-14440 Aux Id: ERIERL-220

+
+
+
+ +
+
Asn1 5.0.5
Fixed Bugs and Malfunctions diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk index 39dfe8f4fb..b7936a347a 100644 --- a/lib/asn1/vsn.mk +++ b/lib/asn1/vsn.mk @@ -1 +1 @@ -ASN1_VSN = 5.0.5 +ASN1_VSN = 5.0.5.1 -- cgit v1.2.3 From 757057b32f60fc1626af9593b49975f40fcceefd Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Thu, 2 Aug 2018 10:04:12 +0200 Subject: Updated OTP version --- OTP_VERSION | 2 +- otp_versions.table | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/OTP_VERSION b/OTP_VERSION index 308ec5d54a..d2be43cced 100644 --- a/OTP_VERSION +++ b/OTP_VERSION @@ -1 +1 @@ -20.3.8.3 +20.3.8.4 diff --git a/otp_versions.table b/otp_versions.table index 5082c962d4..3216c7d43f 100644 --- a/otp_versions.table +++ b/otp_versions.table @@ -1,3 +1,4 @@ +OTP-20.3.8.4 : asn1-5.0.5.1 # common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 erl_interface-3.10.2.1 erts-9.3.3.2 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4.2 inets-6.5.2.2 jinterface-1.8.1 kernel-5.4.3.2 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11 ssh-4.6.9.1 ssl-8.2.6.1 stdlib-3.4.5 syntax_tools-2.1.4.1 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : OTP-20.3.8.3 : erts-9.3.3.2 ic-4.4.4.2 inets-6.5.2.2 kernel-5.4.3.2 ssl-8.2.6.1 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 erl_interface-3.10.2.1 et-1.6.1 eunit-2.3.5 hipe-3.17.1 jinterface-1.8.1 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11 ssh-4.6.9.1 stdlib-3.4.5 syntax_tools-2.1.4.1 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : OTP-20.3.8.2 : erl_interface-3.10.2.1 erts-9.3.3.1 ic-4.4.4.1 kernel-5.4.3.1 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 et-1.6.1 eunit-2.3.5 hipe-3.17.1 inets-6.5.2.1 jinterface-1.8.1 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11 ssh-4.6.9.1 ssl-8.2.6 stdlib-3.4.5 syntax_tools-2.1.4.1 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : OTP-20.3.8.1 : inets-6.5.2.1 ssh-4.6.9.1 syntax_tools-2.1.4.1 # asn1-5.0.5 common_test-1.15.4 compiler-7.1.5 cosEvent-2.2.2 cosEventDomain-1.2.2 cosFileTransfer-1.2.2 cosNotification-1.2.3 cosProperty-1.2.3 cosTime-1.2.3 cosTransactions-1.3.3 crypto-4.2.2 debugger-4.2.4 dialyzer-3.2.4 diameter-2.1.4 edoc-0.9.2 eldap-1.2.3 erl_docgen-0.7.3 erl_interface-3.10.2 erts-9.3.3 et-1.6.1 eunit-2.3.5 hipe-3.17.1 ic-4.4.4 jinterface-1.8.1 kernel-5.4.3 megaco-3.18.3 mnesia-4.15.3 observer-2.7 odbc-2.12.1 orber-3.8.4 os_mon-2.4.4 otp_mibs-1.1.2 parsetools-2.1.6 public_key-1.5.2 reltool-0.7.5 runtime_tools-1.12.5 sasl-3.1.2 snmp-5.2.11 ssl-8.2.6 stdlib-3.4.5 tools-2.11.2 wx-1.8.3 xmerl-1.3.16 : -- cgit v1.2.3