From 4b48bfe2bb8471be547a0503aa516a5248277bac Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sun, 29 Sep 2013 22:12:21 +0100 Subject: [PATCH] Prevent read_openpgp_stream from returning empty packets If read_openpgp_stream got an invalid packet that had a semi valid header it could potentially return an empty package, which would confuse splitkeys. Cleanup the final package returned if it turns out we didn't have valid data for it. Fixes Debian bug #716350 --- parsekey.c | 18 ++++++++++++++---- splitkeys.c | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/parsekey.c b/parsekey.c index aedbd14..b8bb5b0 100644 --- a/parsekey.c +++ b/parsekey.c @@ -191,7 +191,7 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, int maxnum) { unsigned char curchar = 0; - struct openpgp_packet_list *curpacket = NULL; + struct openpgp_packet_list *curpacket = NULL, **packetend = NULL; onak_status_t rc = ONAK_E_OK; int keys = 0; bool inpacket = false; @@ -216,10 +216,12 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, inpacket = true; if (curpacket != NULL) { curpacket->next = malloc(sizeof (*curpacket)); + packetend = &curpacket->next; curpacket = curpacket->next; } else { *packets = curpacket = malloc(sizeof (*curpacket)); + packetend = packets; } memset(curpacket, 0, sizeof(*curpacket)); curpacket->packet = @@ -245,7 +247,9 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, curpacket->packet->length += 192; } else if (curpacket->packet->length > 223 && curpacket->packet->length < 255) { - return ONAK_E_UNSUPPORTED_FEATURE; + free(curpacket->packet); + curpacket->packet = NULL; + rc = ONAK_E_UNSUPPORTED_FEATURE; } else if (curpacket->packet->length == 255) { /* * 5 byte length; ie 255 followed by 3 @@ -292,8 +296,8 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, break; case 3: rc = ONAK_E_UNSUPPORTED_FEATURE; - curpacket->packet->length = 0; - curpacket->packet->data = NULL; + free(curpacket->packet); + curpacket->packet = NULL; break; } } @@ -320,6 +324,12 @@ onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count, } } + /* Trim the last packet if it doesn't actually exist */ + if (packetend != NULL && (*packetend)->packet == NULL) { + free(*packetend); + *packetend = NULL; + } + return (rc); } diff --git a/splitkeys.c b/splitkeys.c index 2d3c58c..2a91d2f 100644 --- a/splitkeys.c +++ b/splitkeys.c @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) tmp->next = NULL; } } - if (tmp->next != NULL) { + if (tmp != NULL && tmp->next != NULL) { list_end = NULL; } -- 2.30.2