aide/backport-CVE-2021-45417-Precalculate-buffer-size-in-base64-functions.patch

147 lines
3.9 KiB
Diff
Raw Normal View History

2022-02-08 16:07:03 +08:00
From 9c3cc43f55f6b2935250932109eb23c60aaf1035 Mon Sep 17 00:00:00 2001
From: Hannes von Haugwitz <hannes@vonhaugwitz.com>
Date: Sat, 15 Jan 2022 17:16:51 +0100
Subject: [PATCH] Precalculate buffer size in base64 functions
Aide uses a fixed size (16k bytes) for the return buffer in
encode_base64/decode_base64 functions. This results in a segfault if
aide processes a file with too large extended attribute value or ACL.
Fix this issue by precalculating the size of the return buffer depending on
the input in the encode_base64/decode_base64 functions.
This addresses CVE-2021-45417. Thanks to David Bouman for reporting this
vulnerability and reviewing this patch.
---
include/base64.h | 1 -
src/base64.c | 35 +++++++++++++++++------------------
src/db.c | 6 ++++--
3 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/include/base64.h b/include/base64.h
index a446812..d9cbfd2 100644
--- a/include/base64.h
+++ b/include/base64.h
@@ -35,7 +35,6 @@
#include <assert.h>
#include "types.h"
-#define B64_BUF 16384
#define FAIL -1
#define SKIP -2
diff --git a/src/base64.c b/src/base64.c
index e01c0f5..09098db 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -85,11 +85,9 @@ FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL
};
/* Returns NULL on error */
-/* FIXME Possible buffer overflow on outputs larger than B64_BUF */
char* encode_base64(byte* src,size_t ssize)
{
char* outbuf;
- char* retbuf;
int pos;
int i, l, left;
unsigned long triple;
@@ -100,7 +98,10 @@ char* encode_base64(byte* src,size_t ssize)
log_msg(LOG_LEVEL_DEBUG,"encode base64: empty string");
return NULL;
}
- outbuf = (char *)checked_malloc(sizeof(char)*B64_BUF);
+
+ /* length of encoded base64 string (padded) */
+ size_t length = sizeof(char)* ((ssize + 2) / 3) * 4;
+ outbuf = (char *)checked_malloc(length + 1);
/* Initialize working pointers */
inb = src;
@@ -161,20 +162,14 @@ char* encode_base64(byte* src,size_t ssize)
inb++;
}
- /* outbuf is not completely used so we use retbuf */
- retbuf=(char*)checked_malloc(sizeof(char)*(pos+1));
- memcpy(retbuf,outbuf,pos);
- retbuf[pos]='\0';
- free(outbuf);
+ outbuf[pos]='\0';
- return retbuf;
+ return outbuf;
}
-/* FIXME Possible buffer overflow on outputs larger than B64_BUF */
byte* decode_base64(char* src,size_t ssize, size_t *ret_len)
{
byte* outbuf;
- byte* retbuf;
char* inb;
int i;
int l;
@@ -188,10 +183,18 @@ byte* decode_base64(char* src,size_t ssize, size_t *ret_len)
return NULL;
}
+ /* exit on unpadded input */
+ if (ssize % 4) {
+ log_msg(LOG_LEVEL_WARNING, "decode_base64: '%s' has invalid length (missing padding characters?)", src);
+ return NULL;
+ }
+
+ /* calculate length of decoded string, substract padding chars if any (ssize is >= 4) */
+ size_t length = sizeof(byte) * ((ssize / 4) * 3)- (src[ssize-1] == '=') - (src[ssize-2] == '=');
/* Initialize working pointers */
inb = src;
- outbuf = (byte *)checked_malloc(sizeof(byte)*B64_BUF);
+ outbuf = (byte *)checked_malloc(length + 1);
l = 0;
triple = 0;
@@ -242,15 +245,11 @@ byte* decode_base64(char* src,size_t ssize, size_t *ret_len)
inb++;
}
- retbuf=(byte*)checked_malloc(sizeof(byte)*(pos+1));
- memcpy(retbuf,outbuf,pos);
- retbuf[pos]='\0';
-
- free(outbuf);
+ outbuf[pos]='\0';
if (ret_len) *ret_len = pos;
- return retbuf;
+ return outbuf;
}
size_t length_base64(char* src,size_t ssize)
diff --git a/src/db.c b/src/db.c
index d8b23a2..ac55f0a 100644
--- a/src/db.c
+++ b/src/db.c
@@ -428,13 +428,15 @@ db_line* db_char2line(char** ss, database* db){
time_t base64totime_t(char* s, database* db, const char* field_name){
+ if(strcmp(s,"0")==0){
+ return 0;
+ }
byte* b=decode_base64(s,strlen(s),NULL);
char* endp;
- if (b==NULL||strcmp(s,"0")==0) {
+ if (b==NULL) {
/* Should we print error here? */
- free(b);
return 0;
} else {
--
1.8.3.1