[ASN.1] Fix buffer overflow (mouse07410/asn1c#134) (#2742)

This commit is contained in:
Sukchan Lee 2023-11-20 21:16:35 +09:00 committed by GitHub
parent d2f2fa0402
commit 9479f29f3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 115 additions and 44 deletions

View File

@ -6,21 +6,15 @@
#include <asn_internal.h>
#include <BIT_STRING.h>
static const char *_bit_pattern[16] = {
"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
};
asn_enc_rval_t
BIT_STRING_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
int ilevel, enum jer_encoder_flags_e flags,
asn_app_consume_bytes_f *cb, void *app_key) {
asn_enc_rval_t er = {0, 0, 0};
char scratch[128];
const char * const h2c = "0123456789ABCDEF";
char scratch[16 * 3 + 4];
char *p = scratch;
char *scend = scratch + (sizeof(scratch) - 10);
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
int xcan = 0;
uint8_t *buf;
uint8_t *end;
@ -33,36 +27,32 @@ BIT_STRING_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
end = buf + st->size - 1; /* Last byte is special */
/*
* Binary dump
* Hex dump
*/
for(; buf < end; buf++) {
int v = *buf;
int nline = xcan?0:(((buf - st->buf) % 8) == 0);
if(p >= scend || nline) {
ASN__CALLBACK(scratch, p - scratch);
*p++ = '"';
for(int i = 0; buf < end; buf++, i++) {
if(!(i % 16) && (i || st->size > 16)) {
ASN__CALLBACK(scratch, p-scratch);
p = scratch;
if(nline) ASN__TEXT_INDENT(1, ilevel);
}
memcpy(p + 0, _bit_pattern[v >> 4], 4);
memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
p += 8;
*p++ = h2c[*buf >> 4];
*p++ = h2c[*buf & 0x0F];
}
if(!xcan && ((buf - st->buf) % 8) == 0)
ASN__TEXT_INDENT(1, ilevel);
ASN__CALLBACK(scratch, p - scratch);
p = scratch;
if(buf == end) {
int v = *buf;
int ubits = st->bits_unused;
int i;
for(i = 7; i >= ubits; i--)
*p++ = (v & (1 << i)) ? 0x31 : 0x30;
uint8_t v = *buf & (0xff << ubits);
*p++ = h2c[v >> 4];
*p++ = h2c[v & 0x0F];
ASN__CALLBACK(scratch, p - scratch);
p = scratch;
}
if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
*p++ = '"';
ASN__CALLBACK(scratch, p - scratch);
ASN__TEXT_INDENT(1, ilevel - 1);
ASN__ENCODED_OK(er);
cb_failed:

View File

@ -30,22 +30,19 @@ OCTET_STRING_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
*/
buf = st->buf;
end = buf + st->size;
ASN__CALLBACK("\"", 1);
for(i = 0; buf < end; buf++, i++) {
if(!(i % 16) && (i || st->size > 16)) {
ASN__CALLBACK(scratch, p-scratch);
p = scratch;
ASN__TEXT_INDENT(1, ilevel);
}
*p++ = h2c[(*buf >> 4) & 0x0F];
*p++ = h2c[*buf & 0x0F];
*p++ = 0x20;
}
if(p - scratch) {
p--; /* Remove the tail space */
ASN__CALLBACK3("\"", 1, scratch, p-scratch, "\"", 1); /* Dump the rest */
if(st->size > 16)
ASN__TEXT_INDENT(1, ilevel-1);
ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */
}
ASN__CALLBACK("\"", 1);
ASN__ENCODED_OK(er);
cb_failed:

View File

@ -179,8 +179,25 @@ asn__format_to_callback(
/*
* Check stack against overflow, if limit is set.
*/
/* Since GCC 13, AddressSanitizer started defaulting to
* ASAN_OPTIONS="detect_stack_use_after_return=1", which makes this check
* fail due to apparently jumping stack pointers.
* Hence, disable this check if building with ASan, as documented in:
* GCC: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
* Clang: https://clang.llvm.org/docs/AddressSanitizer.html#conditional-compilation-with-has-feature-address-sanitizer
*/
#if defined(__SANITIZE_ADDRESS__)
#define ASN__SANITIZE_ENABLED 1
#elif defined(__has_feature)
#if __has_feature(address_sanitizer)
#define ASN__SANITIZE_ENABLED 1
#endif
#endif
#define ASN__DEFAULT_STACK_MAX (30000)
#ifdef ASN_DISABLE_STACK_OVERFLOW_CHECK
#if defined(ASN__SANITIZE_ENABLED) || defined(ASN_DISABLE_STACK_OVERFLOW_CHECK)
static int CC_NOTUSED
ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx) {
(void)ctx;

View File

@ -42,17 +42,22 @@ asn_random_between(intmax_t lb, intmax_t rb) {
uintmax_t range = asn__intmax_range(lb, rb);
uintmax_t value = 0;
uintmax_t got_entropy = 0;
(void)intmax_max;
assert(RAND_MAX > 0xffffff); /* Seen 7ffffffd! */
int max = 0xffffff;
#ifdef __WIN32__
max = RAND_MAX-1;
#endif
assert(RAND_MAX > max); /* Seen 7ffffffd! */
assert(range < intmax_max);
for(; got_entropy < range;) {
got_entropy = (got_entropy << 24) | 0xffffff;
got_entropy = (got_entropy << 24) | max;
#ifdef HAVE_RANDOM
value = (value << 24) | (random() % 0xffffff);
value = (value << 24) | (random() % max);
#else
value = (value << 24) | (rand() % 0xffffff);
value = (value << 24) | (rand() % max);
#endif
}

View File

@ -40,6 +40,8 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
value = per_get_few_bits(pd, 1);
if(value < 0) ASN__DECODE_STARVED;
if(value) ct = 0; /* Not restricted */
if((unsigned)value >= td->elements_count)
ASN__DECODE_FAILED;
}
if(ct && ct->range_bits >= 0) {
@ -53,8 +55,8 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
if(specs->ext_start == -1)
ASN__DECODE_FAILED;
if (ct && ct->upper_bound >= ct->lower_bound) {
value = aper_get_nsnnwn(pd, ct->upper_bound - ct->lower_bound + 1);
if(specs && specs->tag2el_count > specs->ext_start) {
value = aper_get_nsnnwn(pd, specs->tag2el_count - specs->ext_start); /* extension elements range */
if(value < 0) ASN__DECODE_STARVED;
value += specs->ext_start;
if((unsigned)value >= td->elements_count)

View File

@ -1,10 +1,19 @@
Use mounse07410(vlm_master) git's fork for asn1c
commit ebed802c88b3049cfe67326e4df780cefc6da49e (HEAD -> vlm_master, origin/vlm_master, origin/HEAD)
Author: Leith Bade <leith@swiftnav.com>
Date: Mon Nov 14 20:28:25 2022 +1100
commit 3e6592bd840b42a2e16cc6286449f286b118ae8b (HEAD, origin/vlm_master, origin/HEAD, vlm_master)
Merge: 29ef59bb 4e28be09
Author: Mouse <mouse07410@users.noreply.github.com>
Date: Mon Nov 13 21:08:35 2023 -0500
Check SEQUENCE field constraint check result instead of returning
Merge pull request #140 from velichkov/mouse07410_issues134
commit 4e28be09549f3ad6ee4fd5e84996899671591a36
Author: Vasil Velichkov <vvvelichkov@gmail.com>
Date: Mon Nov 13 21:42:39 2023 +0200
aper: Check CHOICE present value is not greater than elements count
Fixes mouse07410/asn1c#134
===========================================
user@host ~/Documents/git/my$ \

View File

@ -604,6 +604,55 @@ static void test6_func(abts_case *tc, void *data)
ogs_pkbuf_free(s1apbuf);
}
static void test7_func(abts_case *tc, void *data)
{
const char *payload =
"0026406300000a00 7a400f2004d222a6 4500bf48f328170b b75b007a40020000"
"007a40020000007a 4004f5023d4d007a 50020000007a4003 00015a007a400b20"
"00008fc5f89e4556 4a667a0b400c2001 cc00acc4e7380083 bd93007a40030001"
"83007a40020000";
ogs_s1ap_message_t message;
ogs_pkbuf_t *enb_pkbuf;
int result;
char hexbuf[OGS_HUGE_LEN];
enb_pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
ogs_assert(enb_pkbuf);
ogs_pkbuf_put_data(enb_pkbuf,
ogs_hex_from_string(payload, hexbuf, sizeof(hexbuf)), 103);
result = ogs_s1ap_decode(&message, enb_pkbuf);
ABTS_INT_EQUAL(tc, -1, result);
ogs_s1ap_free(&message);
ogs_pkbuf_free(enb_pkbuf);
}
static void test8_func(abts_case *tc, void *data)
{
const char *payload =
"0025405a00000a00 79400b2000001f64 1125bd6050210079 4002000000794006"
"0004680e99090079 4002000000794002 00000079400f2004 248c28ab0035cd56"
"ea3daf3f75007940 02000000794003ff 01f60079400200ea 007940020000";
ogs_s1ap_message_t message;
ogs_pkbuf_t *enb_pkbuf;
int result;
char hexbuf[OGS_HUGE_LEN];
enb_pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
ogs_assert(enb_pkbuf);
ogs_pkbuf_put_data(enb_pkbuf,
ogs_hex_from_string(payload, hexbuf, sizeof(hexbuf)), 94);
result = ogs_s1ap_decode(&message, enb_pkbuf);
ABTS_INT_EQUAL(tc, -1, result);
ogs_s1ap_free(&message);
ogs_pkbuf_free(enb_pkbuf);
}
abts_suite *test_crash(abts_suite *suite)
{
suite = ADD_SUITE(suite)
@ -614,6 +663,8 @@ abts_suite *test_crash(abts_suite *suite)
abts_run_test(suite, test4_func, NULL);
abts_run_test(suite, test5_func, NULL);
abts_run_test(suite, test6_func, NULL);
abts_run_test(suite, test7_func, NULL);
abts_run_test(suite, test8_func, NULL);
return suite;
}