summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hanselmann <public@hansmi.ch>2021-08-22 21:34:13 +0200
committerMichael Hanselmann <public@hansmi.ch>2021-08-23 21:03:34 +0200
commit060d7914ea137e48739f0edf28d42b8ac6f00be7 (patch)
treea27f2cd39724b6883170474641075805bf8ed7b6
parente37d86c260d95eae53326b14d496ffa85e9e5934 (diff)
Update write buffer count during deserialization
At commit 8490a7ac the following `fuzzing/usbredirparserfuzz` input causes an integer underflow on write_buf_count as it's not updated during deserialization: ``` $ base64 -d <<'EOF' | gunzip -c > testcase6250181968920576 H4sIAMChImECAzNkwA0YgZgTxPiPBGCSAkgK07b9YgPRLDA+EBvNYoPLuzDg A3Cj3/xHBTc5IPJgFQz/vwNJznSGBIYQIBtJPxN29n842xbhaohtaXA7GX4z fHsPFNVmYHiI4S8jBiKAADbfAEMOaEkCMEDArv6fBpX4gzMM/6OoxxHOWMMO YjYiIFleosvhsxcD/IYofY/dW0AD/xPy1nWc3kpDTUsEnYPD+UQEPzHuxB78 qWDwn0pgP8k6UvGDq0Alu7Foe0+0BYygEDBg+LwtAZhdAUAa2Kf/AwAA EOF ``` Signed-off-by: Michael Hanselmann <public@hansmi.ch>
-rw-r--r--usbredirparser/usbredirparser.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/usbredirparser/usbredirparser.c b/usbredirparser/usbredirparser.c
index 054a3d8..67aa6f5 100644
--- a/usbredirparser/usbredirparser.c
+++ b/usbredirparser/usbredirparser.c
@@ -20,6 +20,7 @@
*/
#include "config.h"
+#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
@@ -1100,6 +1101,8 @@ int usbredirparser_do_write(struct usbredirparser *parser_pub)
int w, ret = 0;
LOCK(parser);
+ assert((parser->write_buf_count != 0) ^ (parser->write_buf == NULL));
+
for (;;) {
wbuf = parser->write_buf;
if (!wbuf)
@@ -1838,6 +1841,7 @@ int usbredirparser_unserialize(struct usbredirparser *parser_pub,
if (unserialize_data(parser, &state, &remain, &parser->data, &i, "data"))
return -1;
parser->data_read = i;
+ parser->write_buf_count = 0;
/* Get the write buffer count and the write buffers */
if (unserialize_int(parser, &state, &remain, &i, "write_buf_count"))
@@ -1867,6 +1871,7 @@ int usbredirparser_unserialize(struct usbredirparser *parser_pub,
wbuf->len = l;
*next = wbuf;
next = &wbuf->next;
+ parser->write_buf_count++;
i--;
}