forked from acouzens/open5gs
[ASN.1] Fix buffer overflow (mouse07410/asn1c#134) (#2742)
This commit is contained in:
parent
d2f2fa0402
commit
9479f29f3d
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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$ \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue