api change uper_encode()

This commit is contained in:
Lev Walkin 2017-10-24 00:47:03 -07:00
parent cb59ce69a8
commit 5615304c9a
12 changed files with 54 additions and 61 deletions

View File

@ -17,6 +17,7 @@
https://medium.com/@levwalkin/compile-llvm-clang-libfuzzer-b61e82718430
then ensure the new clang is in the way:
CC=clang CXX=clang++ ./configure --enable-Werror --enable-test-fuzzer
* uper_encode() API got new argument (breaks API compatibility).
FIXES:
* CVE-2017-12966 verified not present.

View File

@ -248,7 +248,7 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
/* Fall through. */
case ATS_UNALIGNED_CANONICAL_PER:
if(td->op->uper_encoder) {
er = uper_encode(td, sptr, callback, callback_key);
er = uper_encode(td, 0, sptr, callback, callback_key);
if(er.encoded == -1) {
if(er.failed_type && er.failed_type->op->uper_encoder) {
errno = EBADF; /* Structure has incorrect form. */

View File

@ -2,16 +2,41 @@
#include <asn_internal.h>
#include <per_encoder.h>
static asn_enc_rval_t uper_encode_internal(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *,
const void *sptr,
asn_app_consume_bytes_f *cb,
void *app_key);
static int _uper_encode_flush_outp(asn_per_outp_t *po);
asn_enc_rval_t
uper_encode(const asn_TYPE_descriptor_t *td, const void *sptr,
uper_encode(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *constraints, const void *sptr,
asn_app_consume_bytes_f *cb, void *app_key) {
return uper_encode_internal(td, 0, sptr, cb, app_key);
asn_per_outp_t po;
asn_enc_rval_t er;
/*
* Invoke type-specific encoder.
*/
if(!td || !td->op->uper_encoder)
ASN__ENCODE_FAILED; /* PER is not compiled in */
po.buffer = po.tmpspace;
po.nboff = 0;
po.nbits = 8 * sizeof(po.tmpspace);
po.output = cb;
po.op_key = app_key;
po.flushed_bytes = 0;
er = td->op->uper_encoder(td, constraints, sptr, &po);
if(er.encoded != -1) {
size_t bits_to_flush;
bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
/* Set number of bits encoded to a firm value */
er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
if(_uper_encode_flush_outp(&po)) ASN__ENCODE_FAILED;
}
return er;
}
/*
@ -35,16 +60,17 @@ static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
}
asn_enc_rval_t
uper_encode_to_buffer(const asn_TYPE_descriptor_t *td, const void *sptr,
void *buffer, size_t buffer_size) {
uper_encode_to_buffer(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *constraints,
const void *sptr, void *buffer, size_t buffer_size) {
enc_to_buf_arg key;
key.buffer = buffer;
key.left = buffer_size;
key.buffer = buffer;
key.left = buffer_size;
if(td) ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
if(td) ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key);
return uper_encode(td, constraints, sptr, encode_to_buffer_cb, &key);
}
typedef struct enc_dyn_arg {
@ -79,7 +105,7 @@ uper_encode_to_new_buffer(const asn_TYPE_descriptor_t *td,
memset(&key, 0, sizeof(key));
er = uper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key);
er = uper_encode(td, constraints, sptr, encode_dyn_cb, &key);
switch(er.encoded) {
case -1:
FREEMEM(key.buffer);
@ -123,39 +149,3 @@ _uper_encode_flush_outp(asn_per_outp_t *po) {
return po->output(po->tmpspace, buf - po->tmpspace, po->op_key);
}
static asn_enc_rval_t
uper_encode_internal(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *constraints, const void *sptr,
asn_app_consume_bytes_f *cb, void *app_key) {
asn_per_outp_t po;
asn_enc_rval_t er;
/*
* Invoke type-specific encoder.
*/
if(!td || !td->op->uper_encoder)
ASN__ENCODE_FAILED; /* PER is not compiled in */
po.buffer = po.tmpspace;
po.nboff = 0;
po.nbits = 8 * sizeof(po.tmpspace);
po.output = cb;
po.op_key = app_key;
po.flushed_bytes = 0;
er = td->op->uper_encoder(td, constraints, sptr, &po);
if(er.encoded != -1) {
size_t bits_to_flush;
bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
/* Set number of bits encoded to a firm value */
er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
if(_uper_encode_flush_outp(&po))
ASN__ENCODE_FAILED;
}
return er;
}

View File

@ -22,6 +22,7 @@ struct asn_TYPE_descriptor_s; /* Forward declaration */
*/
asn_enc_rval_t uper_encode(
const struct asn_TYPE_descriptor_s *type_descriptor,
const asn_per_constraints_t *constraints,
const void *struct_ptr, /* Structure to be encoded */
asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
void *app_key /* Arbitrary callback argument */
@ -34,6 +35,7 @@ asn_enc_rval_t uper_encode(
*/
asn_enc_rval_t uper_encode_to_buffer(
const struct asn_TYPE_descriptor_s *type_descriptor,
const asn_per_constraints_t *constraints,
const void *struct_ptr, /* Structure to be encoded */
void *buffer, /* Pre-allocated buffer */
size_t buffer_size /* Initial buffer size (max) */

View File

@ -77,7 +77,7 @@ save_object_as(PDU_t *st, enum expectation exp, enum enctype how) {
*/
switch(how) {
case AS_PER:
rval = uper_encode(&asn_DEF_PDU, st,
rval = uper_encode(&asn_DEF_PDU, 0, st,
_buf_writer, 0);
if(exp == EXP_PER_NOCOMP)
assert(rval.encoded == -1);

View File

@ -77,7 +77,7 @@ save_object_as(PDU_t *st, enum expectation exp, enum enctype how) {
*/
switch(how) {
case AS_PER:
rval = uper_encode(&asn_DEF_PDU, st,
rval = uper_encode(&asn_DEF_PDU, 0, st,
_buf_writer, 0);
if(exp == EXP_PER_NOCOMP)
assert(rval.encoded == -1);

View File

@ -66,7 +66,7 @@ save_object_as(PDU_t *st, enum enctype how) {
*/
switch(how) {
case AS_PER:
rval = uper_encode(&asn_DEF_PDU, st, _buf_writer, 0);
rval = uper_encode(&asn_DEF_PDU, 0, st, _buf_writer, 0);
assert(rval.encoded > 0);
fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset);
return;

View File

@ -20,7 +20,7 @@ verify(int testNo, T_t *ti) {
ti->small32range, ti->full32range,
ti->unsigned32, ti->unsplit32);
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
assert(er.encoded == 8 * sizeof(buf));
rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0);

View File

@ -16,7 +16,7 @@ verify(int testNo, T_t *ti) {
unsigned char buf[2];
T_t *to = 0;
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
fprintf(stderr, "%d IN: %d => %zd\n", testNo, ti->present, er.encoded);
assert(er.encoded >= 1 && er.encoded <= (ssize_t)(8 * sizeof(buf)));

View File

@ -16,7 +16,7 @@ verify(int testNo, T_t *ti) {
unsigned char buf[8];
T_t *to = 0;
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
fprintf(stderr, "%d IN: %d => %zd\n", testNo, ti->present, er.encoded);
assert(er.encoded >= 1);
assert(er.encoded <= (ssize_t)(8 * sizeof(buf)));

View File

@ -48,7 +48,7 @@ verify(int testNo, T_t *ti) {
i2l(&ti->signed33), i2l(&ti->signed33ext)
);
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
assert(er.encoded >= 33 + 42 + 33 + 1 + 33);
rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0);
@ -83,7 +83,7 @@ NO_encode(int testNo, T_t *ti) {
i2l(&ti->signed33), i2l(&ti->signed33ext)
);
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
assert(er.encoded == -1);
}

View File

@ -22,7 +22,7 @@ check_encode_failed(asn_TYPE_descriptor_t *td, const char *buf, size_t buflen) {
fprintf(stderr, "%s\n", error_buf);
/* Second signal that something is wrong with the length */
asn_enc_rval_t enc = uper_encode_to_buffer(td, st_in, uper_output_buffer,
asn_enc_rval_t enc = uper_encode_to_buffer(td, 0, st_in, uper_output_buffer,
sizeof(uper_output_buffer));
assert(enc.encoded == -1);
@ -42,7 +42,7 @@ check_round_trip_OK(asn_TYPE_descriptor_t *td, const char *buf, size_t buflen) {
int st_in_ct = asn_check_constraints(td, st_in, NULL, NULL);
assert(st_in_ct == 0);
asn_enc_rval_t enc =
uper_encode_to_buffer(td, st_in,
uper_encode_to_buffer(td, 0, st_in,
uper_output_buffer, sizeof(uper_output_buffer));
assert(enc.encoded > 0);