-
Notifications
You must be signed in to change notification settings - Fork 839
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix buffer overflow when encoding bytes with size set to 65535 (#547)
On platforms where size_t equals pb_size_t, for example AVR where both are 16-bit, or x86 and ARM when PB_FIELD_32BIT is defined, the buffer size checks in pb_write() and pb_enc_submessage can overflow if a bytes field has size close to maximum size value. This causes read and write out of bounds. This issue can cause a security vulnerability if the size of a bytes field in the structure given to pb_encode() is untrusted. Note that pb_decode() has correct bounds checking and will reject too large values.
- Loading branch information
1 parent
0bf6bef
commit 7b44235
Showing
4 changed files
with
64 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Regression test for issue #547: | ||
| # Buffer overflow when encoding bytes with size set to 65535 | ||
|
|
||
| Import("env") | ||
|
|
||
| env.NanopbProto("test.proto") | ||
|
|
||
| # Define the compilation options | ||
| opts = env.Clone() | ||
| opts.Append(CPPDEFINES = {'PB_FIELD_32BIT': 1}) | ||
|
|
||
| # Build new version of core | ||
| strict = opts.Clone() | ||
| strict.Append(CFLAGS = strict['CORECFLAGS']) | ||
| strict.Object("pb_encode_fields32.o", "$NANOPB/pb_encode.c") | ||
| strict.Object("pb_common_fields32.o", "$NANOPB/pb_common.c") | ||
|
|
||
| # Build and run test | ||
| test = opts.Program(["test.c", "test.pb.c", "pb_encode_fields32.o", "pb_common_fields32.o"]) | ||
|
|
||
| env.RunTest(test) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| #include <string.h> | ||
| #include <pb_encode.h> | ||
| #include <unittests.h> | ||
| #include "test.pb.h" | ||
|
|
||
| int main() | ||
| { | ||
| pb_byte_t buf[512]; | ||
| MyMessage msg = MyMessage_init_zero; | ||
| pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf)); | ||
|
|
||
| msg.mybytes.size = 0xFFFFFFFF; | ||
|
|
||
| if (pb_encode(&stream, MyMessage_fields, &msg)) | ||
| { | ||
| fprintf(stderr, "Failure: expected pb_encode() to fail.\n"); | ||
| return 1; | ||
| } | ||
| else if (strcmp(PB_GET_ERROR(&stream), "bytes size exceeded") != 0) | ||
| { | ||
| fprintf(stderr, "Unexpected encoding error: %s\n", PB_GET_ERROR(&stream)); | ||
| return 2; | ||
| } | ||
| else | ||
| { | ||
| return 0; | ||
| } | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| syntax = "proto2"; | ||
|
|
||
| import "nanopb.proto"; | ||
|
|
||
| message MyMessage { | ||
| required bytes mybytes = 1 [(nanopb).max_size = 512]; | ||
| } |