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
69f73478
Commit
69f73478
authored
Aug 11, 2019
by
Mouse
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/master' into vlm_master
parents
3631169e
6495ca55
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
241 additions
and
96 deletions
+241
-96
ChangeLog
ChangeLog
+5
-0
skeletons/INTEGER.c
skeletons/INTEGER.c
+110
-96
tests/tests-skeletons/check-INTEGER.c
tests/tests-skeletons/check-INTEGER.c
+126
-0
No files found.
ChangeLog
View file @
69f73478
...
...
@@ -35,6 +35,11 @@
(Severity: low; Security impact: none)
* Fix XER decoder crash on maliciously constructed ENUMERATED input.
(Severity: medium; Security impact: medium)
* Fix XER decoder of INTEGER, OBJECT IDENTIFIER, and RELATIVE-OID.
In some cases an INTEGER overflow during parsing is not detected
and incorrect value is returned to the decoder instead of an error.
Reported by Nika Pona <npona@digamma.ai>.
(Severity: low; Security impact: medium).
FIXES IN TOOLING:
* CVE-2017-12966 verified not present.
...
...
skeletons/INTEGER.c
View file @
69f73478
/*
-
* Copyright (c) 2003-201
4
Lev Walkin <vlm@lionet.info>.
/*
* Copyright (c) 2003-201
9
Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
...
...
@@ -1428,64 +1428,71 @@ asn_int642INTEGER(INTEGER_t *st, int64_t value) {
*/
enum
asn_strtox_result_e
asn_strtoimax_lim
(
const
char
*
str
,
const
char
**
end
,
intmax_t
*
intp
)
{
int
sign
=
1
;
intmax_t
value
;
int
sign
=
1
;
intmax_t
value
;
#define ASN1_INTMAX_MAX ((~(uintmax_t)0) >> 1)
const
intmax_t
upper_boundary
=
ASN1_INTMAX_MAX
/
10
;
intmax_t
last_digit_max
=
ASN1_INTMAX_MAX
%
10
;
#undef ASN1_INTMAX_MAX
const
intmax_t
asn1_intmax_max
=
((
~
(
uintmax_t
)
0
)
>>
1
);
const
intmax_t
upper_boundary
=
asn1_intmax_max
/
10
;
intmax_t
last_digit_max
=
asn1_intmax_max
%
10
;
if
(
str
>=
*
end
)
return
ASN_STRTOX_ERROR_INVAL
;
if
(
str
>=
*
end
)
return
ASN_STRTOX_ERROR_INVAL
;
switch
(
*
str
)
{
case
'-'
:
last_digit_max
++
;
sign
=
-
1
;
/* FALL THROUGH */
case
'+'
:
str
++
;
if
(
str
>=
*
end
)
{
*
end
=
str
;
return
ASN_STRTOX_EXPECT_MORE
;
}
}
switch
(
*
str
)
{
case
'-'
:
last_digit_max
++
;
sign
=
-
1
;
/* FALL THROUGH */
case
'+'
:
str
++
;
if
(
str
>=
*
end
)
{
*
end
=
str
;
return
ASN_STRTOX_EXPECT_MORE
;
}
}
for
(
value
=
0
;
str
<
(
*
end
);
str
++
)
{
switch
(
*
str
)
{
case
0x30
:
case
0x31
:
case
0x32
:
case
0x33
:
case
0x34
:
case
0x35
:
case
0x36
:
case
0x37
:
case
0x38
:
case
0x39
:
{
int
d
=
*
str
-
'0'
;
if
(
value
<
upper_boundary
)
{
value
=
value
*
10
+
d
;
}
else
if
(
value
==
upper_boundary
)
{
if
(
d
<=
last_digit_max
)
{
if
(
sign
>
0
)
{
value
=
value
*
10
+
d
;
}
else
{
sign
=
1
;
value
=
-
value
*
10
-
d
;
}
}
else
{
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
else
{
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
continue
;
default:
*
end
=
str
;
*
intp
=
sign
*
value
;
return
ASN_STRTOX_EXTRA_DATA
;
}
}
for
(
value
=
0
;
str
<
(
*
end
);
str
++
)
{
if
(
*
str
>=
0x30
&&
*
str
<=
0x39
)
{
int
d
=
*
str
-
'0'
;
if
(
value
<
upper_boundary
)
{
value
=
value
*
10
+
d
;
}
else
if
(
value
==
upper_boundary
)
{
if
(
d
<=
last_digit_max
)
{
if
(
sign
>
0
)
{
value
=
value
*
10
+
d
;
}
else
{
sign
=
1
;
value
=
-
value
*
10
-
d
;
}
str
+=
1
;
if
(
str
<
*
end
)
{
// If digits continue, we're guaranteed out of range.
*
end
=
str
;
if
(
*
str
>=
0x30
&&
*
str
<=
0x39
)
{
return
ASN_STRTOX_ERROR_RANGE
;
}
else
{
*
intp
=
sign
*
value
;
return
ASN_STRTOX_EXTRA_DATA
;
}
}
break
;
}
else
{
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
else
{
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
else
{
*
end
=
str
;
*
intp
=
sign
*
value
;
return
ASN_STRTOX_EXTRA_DATA
;
}
}
*
end
=
str
;
*
intp
=
sign
*
value
;
return
ASN_STRTOX_OK
;
*
end
=
str
;
*
intp
=
sign
*
value
;
return
ASN_STRTOX_OK
;
}
/*
...
...
@@ -1496,56 +1503,63 @@ asn_strtoimax_lim(const char *str, const char **end, intmax_t *intp) {
*/
enum
asn_strtox_result_e
asn_strtoumax_lim
(
const
char
*
str
,
const
char
**
end
,
uintmax_t
*
uintp
)
{
uintmax_t
value
;
uintmax_t
value
;
#define ASN1_UINTMAX_MAX ((~(uintmax_t)0))
const
uintmax_t
upper_boundary
=
ASN1_UINTMAX_MAX
/
10
;
uintmax_t
last_digit_max
=
ASN1_UINTMAX_MAX
%
10
;
#undef ASN1_UINTMAX_MAX
const
uintmax_t
asn1_uintmax_max
=
((
~
(
uintmax_t
)
0
));
const
uintmax_t
upper_boundary
=
asn1_uintmax_max
/
10
;
uintmax_t
last_digit_max
=
asn1_uintmax_max
%
10
;
if
(
str
>=
*
end
)
return
ASN_STRTOX_ERROR_INVAL
;
switch
(
*
str
)
{
case
'-'
:
switch
(
*
str
)
{
case
'-'
:
return
ASN_STRTOX_ERROR_INVAL
;
case
'+'
:
str
++
;
if
(
str
>=
*
end
)
{
*
end
=
str
;
return
ASN_STRTOX_EXPECT_MORE
;
}
}
case
'+'
:
str
++
;
if
(
str
>=
*
end
)
{
*
end
=
str
;
return
ASN_STRTOX_EXPECT_MORE
;
}
}
for
(
value
=
0
;
str
<
(
*
end
);
str
++
)
{
switch
(
*
str
)
{
case
0x30
:
case
0x31
:
case
0x32
:
case
0x33
:
case
0x34
:
case
0x35
:
case
0x36
:
case
0x37
:
case
0x38
:
case
0x39
:
{
unsigned
int
d
=
*
str
-
'0'
;
if
(
value
<
upper_boundary
)
{
value
=
value
*
10
+
d
;
}
else
if
(
value
==
upper_boundary
)
{
if
(
d
<=
last_digit_max
)
{
for
(
value
=
0
;
str
<
(
*
end
);
str
++
)
{
if
(
*
str
>=
0x30
&&
*
str
<=
0x39
)
{
unsigned
int
d
=
*
str
-
'0'
;
if
(
value
<
upper_boundary
)
{
value
=
value
*
10
+
d
;
}
else
if
(
value
==
upper_boundary
)
{
if
(
d
<=
last_digit_max
)
{
value
=
value
*
10
+
d
;
str
+=
1
;
if
(
str
<
*
end
)
{
// If digits continue, we're guaranteed out of range.
*
end
=
str
;
if
(
*
str
>=
0x30
&&
*
str
<=
0x39
)
{
return
ASN_STRTOX_ERROR_RANGE
;
}
else
{
*
uintp
=
value
;
return
ASN_STRTOX_EXTRA_DATA
;
}
}
break
;
}
else
{
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
else
{
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
continue
;
default:
*
end
=
str
;
*
uintp
=
value
;
return
ASN_STRTOX_EXTRA_DATA
;
}
}
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
else
{
*
end
=
str
;
return
ASN_STRTOX_ERROR_RANGE
;
}
}
else
{
*
end
=
str
;
*
uintp
=
value
;
return
ASN_STRTOX_EXTRA_DATA
;
}
}
*
end
=
str
;
*
uintp
=
value
;
return
ASN_STRTOX_OK
;
*
end
=
str
;
*
uintp
=
value
;
return
ASN_STRTOX_OK
;
}
enum
asn_strtox_result_e
...
...
tests/tests-skeletons/check-INTEGER.c
View file @
69f73478
...
...
@@ -178,6 +178,129 @@ check_xer(int lineno, int tofail, char *xmldata, long orig_value) {
ASN_STRUCT_FREE
(
asn_DEF_INTEGER
,
st
);
}
static
void
check_strtoimax
()
{
const
intmax_t
intmax_max
=
((
~
(
uintmax_t
)
0
)
>>
1
);
const
intmax_t
intmax_min
=
-
((
intmax_t
)
intmax_max
)
-
1
;
char
positive_max
[
32
];
char
negative_min
[
32
];
const
int
len_pmax
=
snprintf
(
positive_max
,
sizeof
(
positive_max
),
"+%"
ASN_PRIdMAX
,
intmax_max
);
const
int
len_nmin
=
snprintf
(
negative_min
,
sizeof
(
negative_min
),
"%"
ASN_PRIdMAX
,
intmax_min
);
assert
(
len_pmax
<
(
int
)
sizeof
(
positive_max
));
assert
(
len_nmin
<
(
int
)
sizeof
(
negative_min
));
enum
asn_strtox_result_e
result
;
intmax_t
value
;
/*
* Test edge values first.
*/
// Positive.
const
char
*
last_pmax
=
&
positive_max
[
len_pmax
];
result
=
asn_strtoimax_lim
(
positive_max
,
&
last_pmax
,
&
value
);
assert
(
result
==
ASN_STRTOX_OK
);
assert
(
last_pmax
==
&
positive_max
[
len_pmax
]);
assert
(
value
==
intmax_max
);
// Negative.
const
char
*
last_nmin
=
&
negative_min
[
len_nmin
];
result
=
asn_strtoimax_lim
(
negative_min
,
&
last_nmin
,
&
value
);
assert
(
result
==
ASN_STRTOX_OK
);
assert
(
last_nmin
==
&
negative_min
[
len_nmin
]);
assert
(
value
==
intmax_min
);
/*
* Test one smaller than edge evalues.
*/
positive_max
[
len_pmax
-
1
]
--
;
negative_min
[
len_nmin
-
1
]
--
;
// Positive.
result
=
asn_strtoimax_lim
(
positive_max
,
&
last_pmax
,
&
value
);
assert
(
result
==
ASN_STRTOX_OK
);
assert
(
last_pmax
==
&
positive_max
[
len_pmax
]);
assert
(
value
==
intmax_max
-
1
);
// Negative.
result
=
asn_strtoimax_lim
(
negative_min
,
&
last_nmin
,
&
value
);
assert
(
result
==
ASN_STRTOX_OK
);
assert
(
last_nmin
==
&
negative_min
[
len_nmin
]);
assert
(
value
==
intmax_min
+
1
);
/*
* Test one bigger than edge evalues.
*/
positive_max
[
len_pmax
-
1
]
+=
2
;
negative_min
[
len_nmin
-
1
]
+=
2
;
// Positive.
value
=
42
;
result
=
asn_strtoimax_lim
(
positive_max
,
&
last_pmax
,
&
value
);
assert
(
result
==
ASN_STRTOX_ERROR_RANGE
);
assert
(
last_pmax
==
&
positive_max
[
len_pmax
-
1
]);
assert
(
value
==
42
);
// Negative.
value
=
42
;
result
=
asn_strtoimax_lim
(
negative_min
,
&
last_nmin
,
&
value
);
assert
(
result
==
ASN_STRTOX_ERROR_RANGE
);
assert
(
last_nmin
==
&
negative_min
[
len_nmin
-
1
]);
assert
(
value
==
42
);
/*
* Get back to the edge.
* Append an extra digit at the end.
*/
positive_max
[
len_pmax
-
1
]
--
;
negative_min
[
len_nmin
-
1
]
--
;
assert
(
len_pmax
<
(
int
)
sizeof
(
positive_max
)
-
1
);
assert
(
len_nmin
<
(
int
)
sizeof
(
negative_min
)
-
1
);
strcat
(
positive_max
,
"0"
);
strcat
(
negative_min
,
"0"
);
last_pmax
++
;
last_nmin
++
;
value
=
42
;
result
=
asn_strtoimax_lim
(
positive_max
,
&
last_pmax
,
&
value
);
assert
(
result
==
ASN_STRTOX_OK
);
assert
(
value
==
intmax_max
);
result
=
asn_strtoimax_lim
(
negative_min
,
&
last_nmin
,
&
value
);
assert
(
result
==
ASN_STRTOX_OK
);
assert
(
value
==
intmax_min
);
}
/*
* Check that asn_strtoimax_lim() always reaches the end of the numeric
* sequence, even if it can't fit into the range.
*/
static
void
check_strtoimax_span
()
{
const
intmax_t
intmax_max
=
((
~
(
uintmax_t
)
0
)
>>
1
);
const
intmax_t
almost_min
=
-
((
intmax_t
)(
intmax_max
-
10
));
char
buf
[
64
];
intmax_t
value
=
42
;
enum
asn_strtox_result_e
result
;
// Check a particular way to integer overflow.
// Check that we scan until the very end.
int
len
=
snprintf
(
buf
,
sizeof
(
buf
),
"%"
PRIdMAX
"0</end>"
,
almost_min
);
assert
(
len
<
(
int
)
sizeof
(
buf
));
const
char
*
nmlast
=
&
buf
[
len
];
result
=
asn_strtoimax_lim
(
buf
,
&
nmlast
,
&
value
);
assert
(
*
nmlast
==
'0'
);
assert
((
ptrdiff_t
)(
nmlast
-
buf
)
==
(
ptrdiff_t
)(
len
-
strlen
(
"0</end>"
)));
assert
(
result
==
ASN_STRTOX_ERROR_RANGE
);
assert
(
value
==
42
);
// Check a particular way to integer overflow.
// Check that we scan until the very end.
len
=
snprintf
(
buf
,
sizeof
(
buf
),
"%"
PRIdMAX
"</end>"
,
almost_min
);
assert
(
len
<
(
int
)
sizeof
(
buf
));
nmlast
=
&
buf
[
len
];
result
=
asn_strtoimax_lim
(
buf
,
&
nmlast
,
&
value
);
assert
(
*
nmlast
==
'<'
);
assert
((
ptrdiff_t
)(
nmlast
-
buf
)
==
(
ptrdiff_t
)(
len
-
strlen
(
"</end>"
)));
assert
(
result
==
ASN_STRTOX_EXTRA_DATA
);
assert
(
value
==
almost_min
);
}
int
main
()
{
uint8_t
buf1
[]
=
{
1
};
...
...
@@ -298,5 +421,8 @@ main() {
}
#endif
check_strtoimax
();
check_strtoimax_span
();
return
0
;
}
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