Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
asn1c
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
asn1c
Commits
9d1b45f8
Commit
9d1b45f8
authored
Oct 01, 2017
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix UPER string decoding constrained only by lower bound > 0
parent
ce6b0a66
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
130 additions
and
105 deletions
+130
-105
ChangeLog
ChangeLog
+2
-0
skeletons/ANY.c
skeletons/ANY.c
+1
-1
skeletons/INTEGER.c
skeletons/INTEGER.c
+1
-1
skeletons/OCTET_STRING.c
skeletons/OCTET_STRING.c
+97
-79
skeletons/constr_SET_OF.c
skeletons/constr_SET_OF.c
+1
-2
skeletons/file-dependencies
skeletons/file-dependencies
+3
-3
skeletons/per_opentype.c
skeletons/per_opentype.c
+2
-2
skeletons/per_support.c
skeletons/per_support.c
+19
-14
skeletons/per_support.h
skeletons/per_support.h
+4
-3
No files found.
ChangeLog
View file @
9d1b45f8
...
...
@@ -10,6 +10,8 @@
(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)
0.9.28: 2017-03-26
* PER decoding: avoid memory leak on error. By github.com/simo5
...
...
skeletons/ANY.c
View file @
9d1b45f8
...
...
@@ -216,7 +216,7 @@ ANY_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
int
ret
;
/* Get the PER length */
raw_len
=
uper_get_length
(
pd
,
-
1
,
&
repeat
);
raw_len
=
uper_get_length
(
pd
,
-
1
,
0
,
&
repeat
);
if
(
raw_len
<
0
)
RETURN
(
RC_WMORE
);
ASN_DEBUG
(
"Got PER length len %zu, %s (%s)"
,
raw_len
,
...
...
skeletons/INTEGER.c
View file @
9d1b45f8
...
...
@@ -656,7 +656,7 @@ INTEGER_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t
int
ret
=
0
;
/* Get the PER length */
len
=
uper_get_length
(
pd
,
-
1
,
&
repeat
);
len
=
uper_get_length
(
pd
,
-
1
,
0
,
&
repeat
);
if
(
len
<
0
)
ASN__DECODE_STARVED
;
p
=
REALLOC
(
st
->
buf
,
st
->
size
+
len
+
1
);
...
...
skeletons/OCTET_STRING.c
View file @
9d1b45f8
...
...
@@ -1424,7 +1424,6 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
if
(
inext
<
0
)
RETURN
(
RC_WMORE
);
if
(
inext
)
{
csiz
=
&
asn_DEF_OCTET_STRING_constraints
.
size
;
cval
=
&
asn_DEF_OCTET_STRING_constraints
.
value
;
unit_bits
=
canonical_unit_bits
;
}
}
...
...
@@ -1477,9 +1476,9 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
int
ret
;
/* Get the PER length */
raw_len
=
uper_get_length
(
pd
,
csiz
->
effective_bits
,
&
repeat
);
raw_len
=
uper_get_length
(
pd
,
csiz
->
effective_bits
,
csiz
->
lower_bound
,
&
repeat
);
if
(
raw_len
<
0
)
RETURN
(
RC_WMORE
);
raw_len
+=
csiz
->
lower_bound
;
ASN_DEBUG
(
"Got PER length eb %ld, len %ld, %s (%s)"
,
(
long
)
csiz
->
effective_bits
,
(
long
)
raw_len
,
...
...
@@ -1531,7 +1530,7 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
int
inext
=
0
;
/* Lies not within extension root */
unsigned
int
unit_bits
;
unsigned
int
canonical_unit_bits
;
unsigned
int
sizein
units
;
size_t
size_in_
units
;
const
uint8_t
*
buf
;
int
ret
;
enum
{
...
...
@@ -1561,23 +1560,23 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
case
ASN_OSUBV_BIT
:
canonical_unit_bits
=
unit_bits
=
1
;
bpc
=
OS__BPC_BIT
;
size
in
units
=
st
->
size
*
8
-
(
st
->
bits_unused
&
0x07
);
ASN_DEBUG
(
"BIT STRING of %
d
bytes, %d bits unused"
,
size
in
units
,
st
->
bits_unused
);
size
_in_
units
=
st
->
size
*
8
-
(
st
->
bits_unused
&
0x07
);
ASN_DEBUG
(
"BIT STRING of %
zu
bytes, %d bits unused"
,
size
_in_
units
,
st
->
bits_unused
);
break
;
case
ASN_OSUBV_STR
:
canonical_unit_bits
=
unit_bits
=
8
;
if
(
cval
->
flags
&
APC_CONSTRAINED
)
unit_bits
=
cval
->
range_bits
;
bpc
=
OS__BPC_CHAR
;
size
in
units
=
st
->
size
;
size
_in_
units
=
st
->
size
;
break
;
case
ASN_OSUBV_U16
:
canonical_unit_bits
=
unit_bits
=
16
;
if
(
cval
->
flags
&
APC_CONSTRAINED
)
unit_bits
=
cval
->
range_bits
;
bpc
=
OS__BPC_U16
;
size
in
units
=
st
->
size
>>
1
;
size
_in_
units
=
st
->
size
>>
1
;
if
(
st
->
size
&
1
)
{
ASN_DEBUG
(
"%s string size is not modulo 2"
,
td
->
name
);
ASN__ENCODE_FAILED
;
...
...
@@ -1588,7 +1587,7 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
if
(
cval
->
flags
&
APC_CONSTRAINED
)
unit_bits
=
cval
->
range_bits
;
bpc
=
OS__BPC_U32
;
size
in
units
=
st
->
size
>>
2
;
size
_in_
units
=
st
->
size
>>
2
;
if
(
st
->
size
&
3
)
{
ASN_DEBUG
(
"%s string size is not modulo 4"
,
td
->
name
);
ASN__ENCODE_FAILED
;
...
...
@@ -1596,92 +1595,85 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
break
;
}
ASN_DEBUG
(
"Encoding %s into %
d
units of %d bits"
ASN_DEBUG
(
"Encoding %s into %
zu
units of %d bits"
" (%ld..%ld, effective %d)%s"
,
td
->
name
,
size
in
units
,
unit_bits
,
td
->
name
,
size
_in_
units
,
unit_bits
,
csiz
->
lower_bound
,
csiz
->
upper_bound
,
csiz
->
effective_bits
,
ct_extensible
?
" EXT"
:
""
);
/* Figure out whether size lies within PER visible constraint */
if
(
csiz
->
effective_bits
>=
0
)
{
if
((
int
)
sizeinunits
<
csiz
->
lower_bound
||
(
int
)
sizeinunits
>
csiz
->
upper_bound
)
{
if
(
ct_extensible
)
{
cval
=
&
asn_DEF_OCTET_STRING_constraints
.
value
;
csiz
=
&
asn_DEF_OCTET_STRING_constraints
.
size
;
unit_bits
=
canonical_unit_bits
;
inext
=
1
;
}
else
{
ASN__ENCODE_FAILED
;
}
}
}
else
{
inext
=
0
;
}
if
(
csiz
->
effective_bits
>=
0
)
{
if
((
ssize_t
)
size_in_units
<
csiz
->
lower_bound
||
(
ssize_t
)
size_in_units
>
csiz
->
upper_bound
)
{
if
(
ct_extensible
)
{
csiz
=
&
asn_DEF_OCTET_STRING_constraints
.
size
;
unit_bits
=
canonical_unit_bits
;
inext
=
1
;
}
else
{
ASN__ENCODE_FAILED
;
}
}
}
else
{
inext
=
0
;
}
if
(
ct_extensible
)
{
if
(
ct_extensible
)
{
/* Declare whether length is [not] within extension root */
if
(
per_put_few_bits
(
po
,
inext
,
1
))
ASN__ENCODE_FAILED
;
}
/* X.691, #16.5: zero-length encoding */
/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
if
(
csiz
->
effective_bits
>=
0
)
{
ASN_DEBUG
(
"Encoding %zu bytes (%ld), length in %d bits"
,
st
->
size
,
sizeinunits
-
csiz
->
lower_bound
,
csiz
->
effective_bits
);
ret
=
per_put_few_bits
(
po
,
sizeinunits
-
csiz
->
lower_bound
,
csiz
->
effective_bits
);
if
(
ret
)
ASN__ENCODE_FAILED
;
if
(
bpc
)
{
ret
=
OCTET_STRING_per_put_characters
(
po
,
st
->
buf
,
sizeinunits
,
bpc
,
unit_bits
,
cval
->
lower_bound
,
cval
->
upper_bound
,
pc
);
}
else
{
ret
=
per_put_many_bits
(
po
,
st
->
buf
,
sizeinunits
*
unit_bits
);
}
if
(
ret
)
ASN__ENCODE_FAILED
;
ASN__ENCODED_OK
(
er
);
}
if
(
csiz
->
effective_bits
>=
0
&&
!
inext
)
{
ASN_DEBUG
(
"Encoding %zu bytes (%ld), length in %d bits"
,
st
->
size
,
size_in_units
-
csiz
->
lower_bound
,
csiz
->
effective_bits
);
ret
=
per_put_few_bits
(
po
,
size_in_units
-
csiz
->
lower_bound
,
csiz
->
effective_bits
);
if
(
ret
)
ASN__ENCODE_FAILED
;
if
(
bpc
)
{
ret
=
OCTET_STRING_per_put_characters
(
po
,
st
->
buf
,
size_in_units
,
bpc
,
unit_bits
,
cval
->
lower_bound
,
cval
->
upper_bound
,
pc
);
}
else
{
assert
(
unit_bits
==
1
);
ret
=
per_put_many_bits
(
po
,
st
->
buf
,
size_in_units
);
}
if
(
ret
)
ASN__ENCODE_FAILED
;
ASN__ENCODED_OK
(
er
);
}
ASN_DEBUG
(
"Encoding %zu bytes"
,
st
->
size
);
ASN_DEBUG
(
"Encoding %zu bytes"
,
st
->
size
);
if
(
sizeinunits
==
0
)
{
if
(
uper_put_length
(
po
,
0
))
ASN__ENCODE_FAILED
;
ASN__ENCODED_OK
(
er
);
}
if
(
size_in_units
==
0
)
{
if
(
uper_put_length
(
po
,
0
))
ASN__ENCODE_FAILED
;
ASN__ENCODED_OK
(
er
);
}
buf
=
st
->
buf
;
while
(
sizein
units
)
{
ssize_t
maySave
=
uper_put_length
(
po
,
sizein
units
);
if
(
maySave
<
0
)
ASN__ENCODE_FAILED
;
buf
=
st
->
buf
;
while
(
size_in_
units
)
{
ssize_t
maySave
=
uper_put_length
(
po
,
size_in_
units
);
if
(
maySave
<
0
)
ASN__ENCODE_FAILED
;
ASN_DEBUG
(
"Encoding %ld of %ld"
,
(
long
)
maySave
,
(
long
)
sizeinunits
);
ASN_DEBUG
(
"Encoding %ld of %ld"
,
(
long
)
maySave
,
(
long
)
sizeinunits
);
if
(
bpc
)
{
ret
=
OCTET_STRING_per_put_characters
(
po
,
buf
,
maySave
,
bpc
,
unit_bits
,
cval
->
lower_bound
,
cval
->
upper_bound
,
pc
);
}
else
{
ret
=
per_put_many_bits
(
po
,
buf
,
maySave
*
unit_bits
);
}
if
(
ret
)
ASN__ENCODE_FAILED
;
if
(
bpc
)
buf
+=
maySave
*
bpc
;
else
buf
+=
maySave
>>
3
;
sizein
units
-=
maySave
;
assert
(
!
(
maySave
&
0x07
)
||
!
sizein
units
);
}
if
(
bpc
)
{
ret
=
OCTET_STRING_per_put_characters
(
po
,
buf
,
maySave
,
bpc
,
unit_bits
,
cval
->
lower_bound
,
cval
->
upper_bound
,
pc
);
}
else
{
ret
=
per_put_many_bits
(
po
,
buf
,
maySave
);
}
if
(
ret
)
ASN__ENCODE_FAILED
;
if
(
bpc
)
buf
+=
maySave
*
bpc
;
else
buf
+=
maySave
>>
3
;
size_in_
units
-=
maySave
;
assert
(
!
(
maySave
&
0x07
)
||
!
size_in_
units
);
}
ASN__ENCODED_OK
(
er
);
ASN__ENCODED_OK
(
er
);
}
#endif
/* ASN_DISABLE_PER_SUPPORT */
...
...
@@ -1987,10 +1979,36 @@ OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
const
asn_per_constraint_t
*
pc
=
&
td
->
encoding_constraints
.
per_constraints
->
size
;
if
(
pc
->
flags
&
APC_CONSTRAINED
)
{
long
suggested_upper_bound
=
pc
->
upper_bound
<
max_length
?
pc
->
upper_bound
:
max_length
;
if
(
max_length
<
(
size_t
)
pc
->
lower_bound
)
{
return
result_skipped
;
}
rnd_len
=
asn_random_between
(
pc
->
lower_bound
,
pc
->
upper_bound
);
if
(
pc
->
flags
&
APC_EXTENSIBLE
)
{
switch
(
asn_random_between
(
0
,
5
))
{
case
0
:
if
(
pc
->
lower_bound
>
0
)
{
rnd_len
=
pc
->
lower_bound
-
1
;
break
;
}
/* Fall through */
case
1
:
rnd_len
=
pc
->
upper_bound
+
1
;
break
;
case
2
:
/* Keep rnd_len from the table */
if
(
rnd_len
<
max_length
)
{
break
;
}
/* Fall through */
default:
rnd_len
=
asn_random_between
(
pc
->
lower_bound
,
suggested_upper_bound
);
}
}
else
{
rnd_len
=
asn_random_between
(
pc
->
lower_bound
,
suggested_upper_bound
);
}
}
else
{
rnd_len
=
asn_random_between
(
0
,
max_length
-
1
);
}
...
...
skeletons/constr_SET_OF.c
View file @
9d1b45f8
...
...
@@ -910,8 +910,7 @@ SET_OF_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *
do
{
int
i
;
if
(
nelems
<
0
)
{
nelems
=
uper_get_length
(
pd
,
ct
?
ct
->
effective_bits
:
-
1
,
&
repeat
);
nelems
=
uper_get_length
(
pd
,
-
1
,
0
,
&
repeat
);
ASN_DEBUG
(
"Got to decode %d elements (eff %d)"
,
(
int
)
nelems
,
(
int
)(
ct
?
ct
->
effective_bits
:
-
1
));
if
(
nelems
<
0
)
ASN__DECODE_STARVED
;
...
...
skeletons/file-dependencies
View file @
9d1b45f8
...
...
@@ -73,10 +73,10 @@ oer_decoder.h oer_decoder.c OPEN_TYPE.h # OER decoding support
oer_encoder.h oer_encoder.c # OER encoding support
oer_support.h oer_support.c # OER support
OPEN_TYPE.h OPEN_TYPE_oer.c constr_CHOICE.h
INTEGER_oer.c
INTEGER_oer.c
INTEGER.h
OCTET_STRING_oer.c
NativeInteger_oer.c
NativeEnumerated_oer.c
NativeInteger_oer.c
NativeInteger.h
NativeEnumerated_oer.c
NativeEnumerated.h
constr_SEQUENCE_oer.c constr_SEQUENCE.h
constr_CHOICE_oer.c
constr_SET_OF_oer.c constr_SET_OF.h asn_SET_OF.h asn_SET_OF.c
...
...
skeletons/per_opentype.c
View file @
9d1b45f8
...
...
@@ -73,7 +73,7 @@ uper_open_type_get_simple(const asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
ASN_DEBUG
(
"Getting open type %s..."
,
td
->
name
);
do
{
chunk_bytes
=
uper_get_length
(
pd
,
-
1
,
&
repeat
);
chunk_bytes
=
uper_get_length
(
pd
,
-
1
,
0
,
&
repeat
);
if
(
chunk_bytes
<
0
)
{
FREEMEM
(
buf
);
ASN__DECODE_STARVED
;
...
...
@@ -329,7 +329,7 @@ uper_ugot_refill(asn_per_data_t *pd) {
return
-
1
;
}
next_chunk_bytes
=
uper_get_length
(
oldpd
,
-
1
,
&
arg
->
repeat
);
next_chunk_bytes
=
uper_get_length
(
oldpd
,
-
1
,
0
,
&
arg
->
repeat
);
ASN_DEBUG
(
"Open type LENGTH %ld bytes at off %ld, repeat %ld"
,
(
long
)
next_chunk_bytes
,
(
long
)
oldpd
->
moved
,
(
long
)
arg
->
repeat
);
if
(
next_chunk_bytes
<
0
)
return
-
1
;
...
...
skeletons/per_support.c
View file @
9d1b45f8
...
...
@@ -12,14 +12,17 @@
* Get the optionally constrained length "n" from the stream.
*/
ssize_t
uper_get_length
(
asn_per_data_t
*
pd
,
int
ebits
,
int
*
repeat
)
{
uper_get_length
(
asn_per_data_t
*
pd
,
int
ebits
,
size_t
lower_bound
,
int
*
repeat
)
{
ssize_t
value
;
*
repeat
=
0
;
/* #11.9.4.1 Encoding if constrained (according to effective bits) */
if
(
ebits
>=
0
&&
ebits
<=
16
)
{
return
per_get_few_bits
(
pd
,
ebits
);
value
=
per_get_few_bits
(
pd
,
ebits
);
if
(
value
>=
0
)
value
+=
lower_bound
;
return
value
;
}
value
=
per_get_few_bits
(
pd
,
8
);
...
...
@@ -58,7 +61,7 @@ uper_get_nslength(asn_per_data_t *pd) {
return
length
;
}
else
{
int
repeat
;
length
=
uper_get_length
(
pd
,
-
1
,
&
repeat
);
length
=
uper_get_length
(
pd
,
-
1
,
0
,
&
repeat
);
if
(
length
>=
0
&&
!
repeat
)
return
length
;
return
-
1
;
/* Error, or do not support >16K extensions */
}
...
...
@@ -170,23 +173,25 @@ int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int
}
/*
* X.691 (08/2015) #11.9 "General rules for encoding a length determinant"
* Put the length "n" (or part of it) into the stream.
*/
ssize_t
uper_put_length
(
asn_per_outp_t
*
po
,
size_t
length
)
{
if
(
length
<=
127
)
/* #10
.9.3.6 */
return
per_put_few_bits
(
po
,
length
,
8
)
?
-
1
:
(
ssize_t
)
length
;
else
if
(
length
<
16384
)
/* #10.9.3.7 */
return
per_put_few_bits
(
po
,
length
|
0x8000
,
16
)
?
-
1
:
(
ssize_t
)
length
;
if
(
length
<=
127
)
/* #11
.9.3.6 */
return
per_put_few_bits
(
po
,
length
,
8
)
?
-
1
:
(
ssize_t
)
length
;
else
if
(
length
<
16384
)
/* #10.9.3.7 */
return
per_put_few_bits
(
po
,
length
|
0x8000
,
16
)
?
-
1
:
(
ssize_t
)
length
;
length
>>=
14
;
if
(
length
>
4
)
length
=
4
;
length
>>=
14
;
if
(
length
>
4
)
length
=
4
;
return
per_put_few_bits
(
po
,
0xC0
|
length
,
8
)
?
-
1
:
(
ssize_t
)(
length
<<
14
);
return
per_put_few_bits
(
po
,
0xC0
|
length
,
8
)
?
-
1
:
(
ssize_t
)(
length
<<
14
);
}
...
...
@@ -199,7 +204,7 @@ int
uper_put_nslength
(
asn_per_outp_t
*
po
,
size_t
length
)
{
if
(
length
<=
64
)
{
/* #1
0
.9.3.4 */
/* #1
1
.9.3.4 */
if
(
length
==
0
)
return
-
1
;
return
per_put_few_bits
(
po
,
length
-
1
,
7
)
?
-
1
:
0
;
}
else
{
...
...
skeletons/per_support.h
View file @
9d1b45f8
...
...
@@ -43,11 +43,11 @@ typedef struct asn_bit_data_s asn_per_data_t;
asn_get_many_bits(data, dst, align, bits)
/*
* X.691 (08/2015) #11.9 "General rules for encoding a length determinant"
* Get the length "n" from the Unaligned PER stream.
*/
ssize_t
uper_get_length
(
asn_per_data_t
*
pd
,
int
effective_bound_bits
,
int
*
repeat
);
ssize_t
uper_get_length
(
asn_per_data_t
*
pd
,
int
effective_bound_bits
,
size_t
lower_bound
,
int
*
repeat
);
/*
* Get the normally small length "n".
...
...
@@ -74,6 +74,7 @@ int uper_put_constrained_whole_number_s(asn_per_outp_t *po, long v, int nbits);
int
uper_put_constrained_whole_number_u
(
asn_per_outp_t
*
po
,
unsigned
long
v
,
int
nbits
);
/*
* X.691 (08/2015) #11.9 "General rules for encoding a length determinant"
* Put the length "n" to the Unaligned PER stream.
* This function returns the number of units which may be flushed
* in the next units saving iteration.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment