Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nanopb/nanopb.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2020-02-01 22:08:30 +0300
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2020-02-01 22:08:30 +0300
commite382ea5c2bb38179e4a8a57464cd97a04653b1df (patch)
tree3ea631146a6fa64e4882f0a2c85b856ae3f7961a /pb_decode.c
parent982655a7c9efabd3dd42faae03057203ddd070d8 (diff)
Avoid overflows in allocation for packed fields.
This will only occur with unlimited length streams, so it's kind-of low impact. Such streams allow denial of service anyway.
Diffstat (limited to 'pb_decode.c')
-rw-r--r--pb_decode.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/pb_decode.c b/pb_decode.c
index f16837b..f936412 100644
--- a/pb_decode.c
+++ b/pb_decode.c
@@ -670,12 +670,25 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_
while (substream.bytes_left)
{
+ if (*size == PB_SIZE_MAX)
+ {
+#ifndef PB_NO_ERRMSG
+ stream->errmsg = "too many array entries";
+#endif
+ status = false;
+ break;
+ }
+
if ((size_t)*size + 1 > allocated_size)
{
/* Allocate more storage. This tries to guess the
* number of remaining entries. Round the division
* upwards. */
- allocated_size += (substream.bytes_left - 1) / field->data_size + 1;
+ size_t remain = (substream.bytes_left - 1) / field->data_size + 1;
+ if (remain < PB_SIZE_MAX - allocated_size)
+ allocated_size += remain;
+ else
+ allocated_size += 1;
if (!allocate_field(&substream, field->pField, field->data_size, allocated_size))
{
@@ -693,15 +706,6 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_
break;
}
- if (*size == PB_SIZE_MAX)
- {
-#ifndef PB_NO_ERRMSG
- stream->errmsg = "too many array entries";
-#endif
- status = false;
- break;
- }
-
(*size)++;
}
if (!pb_close_string_substream(stream, &substream))