pev: fix crash with -D_FORTIFY_SOURCE=2

While we're at it, correct plugins dir, license, and fix musl build.

Fix: #22604
This commit is contained in:
Đoàn Trần Công Danh 2020-06-06 13:04:49 +07:00 committed by Enno Boland
parent 3de75b3c25
commit c289bc2767
13 changed files with 417 additions and 5 deletions

View file

@ -0,0 +1,26 @@
From d27d76f7a52c154f809847d2b7d30cab2d7d31ed Mon Sep 17 00:00:00 2001
From: Jakub Wilk <jwilk@jwilk.net>
Date: Mon, 17 Jul 2017 12:10:31 +0200
Subject: [PATCH 01/12] Fix buffer underwrite in imphash()
---
src/pehash.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git src/pehash.c src/pehash.c
index e03a0a9..ffb4fdd 100644
--- src/pehash.c
+++ src/pehash.c
@@ -483,7 +483,8 @@ static void imphash(pe_ctx_t *ctx, int flavor)
free(elt);
imphash_string_size = strlen(imphash_string);
- imphash_string[imphash_string_size-1] = '\0'; // remove the last comma sign
+ if (imphash_string_size)
+ imphash_string[imphash_string_size-1] = '\0'; // remove the last comma sign
//puts(imphash_string); // DEBUG
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,27 @@
From 061612666eaa831feed897f52125f7c7812a51d0 Mon Sep 17 00:00:00 2001
From: Jakub Wilk <jwilk@jwilk.net>
Date: Sun, 16 Jul 2017 20:25:04 +0200
Subject: [PATCH 02/12] Remove const qualifier from parent_scope
If parent_scope is declared as const, the compiler may emit code that
assumes the value doesn't change, i.e. dereferencing the null pointer.
---
src/output.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git src/output.c src/output.c
index b825ca2..ed2e48e 100644
--- src/output.c
+++ src/output.c
@@ -288,7 +288,7 @@ void output_open_scope(const char *scope_name, output_scope_type_e scope_type) {
scope->depth = scope_depth + 1;
if (scope_depth > 0) {
- output_scope_t * const parent_scope = NULL;
+ output_scope_t * parent_scope = NULL;
STACK_PEEK(g_scope_stack, (void *)&parent_scope);
scope->parent_type = parent_scope->type;
}
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,26 @@
From ee0ec66ac2da159c0d215c9dbbe0ccc8333f51cc Mon Sep 17 00:00:00 2001
From: Jakub Wilk <jwilk@jwilk.net>
Date: Mon, 17 Jul 2017 11:04:25 +0200
Subject: [PATCH 03/12] Fix off-by-one buffer overflow in imphash()
The extra byte is needed for the terminating null byte.
---
src/pehash.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git src/pehash.c src/pehash.c
index ffb4fdd..59e15b0 100644
--- src/pehash.c
+++ src/pehash.c
@@ -488,7 +488,7 @@ static void imphash(pe_ctx_t *ctx, int flavor)
//puts(imphash_string); // DEBUG
- char imphash[32];
+ char imphash[33];
calc_hash("md5", (unsigned char *)imphash_string, strlen(imphash_string), imphash);
free(imphash_string);
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,26 @@
From 180db22b5b51ef2a00eae9a25ca94d859d348a93 Mon Sep 17 00:00:00 2001
From: Jakub Wilk <jwilk@jwilk.net>
Date: Mon, 17 Jul 2017 14:10:42 +0200
Subject: [PATCH 04/12] Fix imphash_string buffer size calculation
Fixes buffer overflow in imphash().
---
src/pehash.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git src/pehash.c src/pehash.c
index 59e15b0..db1735a 100644
--- src/pehash.c
+++ src/pehash.c
@@ -470,7 +470,7 @@ static void imphash(pe_ctx_t *ctx, int flavor)
LL_COUNT(head, elt, count);
//printf("%d number of elements in list outside\n", count);
- size_t imphash_string_size = sizeof(char) * count * MAX_DLL_NAME + MAX_FUNCTION_NAME;
+ size_t imphash_string_size = sizeof(char) * count * (MAX_DLL_NAME + MAX_FUNCTION_NAME) + 1;
char *imphash_string = (char *) malloc_s(imphash_string_size);
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,27 @@
From f3f66090a0a8bdcdb98984322169c73be89892b6 Mon Sep 17 00:00:00 2001
From: Jakub Wilk <jwilk@jwilk.net>
Date: Mon, 17 Jul 2017 11:58:29 +0200
Subject: [PATCH 05/12] Fix misuse of sprintf() in imphash()
The results are undefined if source and destination buffers overlap when
calling sprintf().
---
src/pehash.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git src/pehash.c src/pehash.c
index db1735a..e49f0c1 100644
--- src/pehash.c
+++ src/pehash.c
@@ -477,7 +477,7 @@ static void imphash(pe_ctx_t *ctx, int flavor)
memset(imphash_string, 0, imphash_string_size);
LL_FOREACH_SAFE(head, elt, tmp) \
- sprintf(imphash_string, "%s%s.%s,", imphash_string, elt->dll_name, elt->function_name); \
+ sprintf(imphash_string + strlen(imphash_string), "%s.%s,", elt->dll_name, elt->function_name); \
LL_DELETE(head, elt);
free(elt);
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,51 @@
From 97a05b57c3e86a96ff0ca2c4771cf74ff5b05061 Mon Sep 17 00:00:00 2001
From: Jardel Weyrich <jweyrich@gmail.com>
Date: Mon, 17 Jul 2017 11:55:15 -0300
Subject: [PATCH 06/12] Fixes #116. Thanks to Jakub Wilk!
print_basic_hash() declares the output buffer as:
char hash_value[EVP_MAX_MD_SIZE * 2 + 1];
With the current OpenSSL versions, EVP_MAX_MD_SIZE * 2 + 1 is 129.
However, fuzzy_hash_buf() requires an output buffer of size
FUZZY_MAX_RESULT, which is 148.
---
src/pehash.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git src/pehash.c src/pehash.c
index e49f0c1..f1e6b4c 100644
--- src/pehash.c
+++ src/pehash.c
@@ -229,16 +229,24 @@ static void calc_hash(const char *alg_name, const unsigned char *data, size_t si
static void print_basic_hash(const unsigned char *data, size_t size)
{
- char *basic_hashes[] = { "md5", "sha1", "sha256", "ssdeep" };
- char hash_value[EVP_MAX_MD_SIZE * 2 + 1];
-
if (!data || !size)
return;
+ const size_t openssl_hash_maxsize = EVP_MAX_MD_SIZE * 2 + 1;
+ const size_t ssdeep_hash_maxsize = FUZZY_MAX_RESULT;
+ // Since standard C lacks max(), we do it manually.
+ const size_t hash_maxsize = openssl_hash_maxsize > ssdeep_hash_maxsize
+ ? openssl_hash_maxsize
+ : ssdeep_hash_maxsize;
+ const char *basic_hashes[] = { "md5", "sha1", "sha256", "ssdeep" };
+ char *hash_value = malloc_s(hash_maxsize);
+
for (unsigned i=0; i < sizeof(basic_hashes) / sizeof(char *); i++) {
calc_hash(basic_hashes[i], data, size, hash_value);
output(basic_hashes[i], hash_value);
}
+
+ free(hash_value);
}
typedef struct element {
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,25 @@
From e1ba6dba2d88f004587ea9f987bd3218b7079ace Mon Sep 17 00:00:00 2001
From: Jardel Weyrich <jweyrich@gmail.com>
Date: Tue, 18 Jul 2017 11:45:41 -0300
Subject: [PATCH 07/12] Fix memory leak related to scope stack.
---
src/output.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git src/output.c src/output.c
index ed2e48e..8c23e92 100644
--- src/output.c
+++ src/output.c
@@ -144,7 +144,7 @@ void output_term(void) {
// TODO(jweyrich): Should we loop to pop + close + output every scope?
if (g_scope_stack != NULL)
- free(g_scope_stack);
+ STACK_DEALLOC(g_scope_stack);
_unregister_all_formats();
}
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,28 @@
From ddf689e4543171c066d728a8d1b5ebd26c7dfdff Mon Sep 17 00:00:00 2001
From: Jardel Weyrich <jweyrich@gmail.com>
Date: Tue, 18 Jul 2017 11:46:15 -0300
Subject: [PATCH 08/12] Fix memory leak caused during digital signature
validation.
---
src/pesec.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git src/pesec.c src/pesec.c
index 470af17..c36c5e0 100644
--- src/pesec.c
+++ src/pesec.c
@@ -274,7 +274,9 @@ static int parse_pkcs7_data(const options_t *options, const CRYPT_DATA_BLOB *blo
if (numcerts > 0) {
X509 *subject = sk_X509_value(certs, 0);
X509 *issuer = sk_X509_value(certs, numcerts - 1);
- int valid_sig = X509_verify(subject, X509_get_pubkey(issuer));
+ EVP_PKEY *issuer_pubkey = X509_get_pubkey(issuer);
+ int valid_sig = X509_verify(subject, issuer_pubkey);
+ EVP_PKEY_free(issuer_pubkey);
output("Signature", valid_sig == 1 ? "valid" : "invalid");
}
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,47 @@
From 72c95ff9a6aadf787d798deb47ec125e6a2ed8cc Mon Sep 17 00:00:00 2001
From: Jardel Weyrich <jweyrich@gmail.com>
Date: Tue, 18 Jul 2017 15:23:24 -0300
Subject: [PATCH 09/12] Fix memory leak during output scope unwinding.
---
include/output.h | 2 +-
src/output.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git include/output.h include/output.h
index 48e843e..7877454 100644
--- include/output.h
+++ include/output.h
@@ -59,7 +59,7 @@ typedef enum {
} output_scope_type_e;
typedef struct {
- const char *name;
+ char *name;
output_scope_type_e type;
uint16_t depth;
output_scope_type_e parent_type;
diff --git src/output.c src/output.c
index 8c23e92..8ac837f 100644
--- src/output.c
+++ src/output.c
@@ -305,7 +305,7 @@ void output_open_scope(const char *scope_name, output_scope_type_e scope_type) {
void output_close_scope(void) {
assert(g_format != NULL);
- output_scope_t * const scope = NULL;
+ output_scope_t *scope = NULL;
int ret = STACK_POP(g_scope_stack, (void *)&scope);
if (ret < 0) {
fprintf(stderr, "output: cannot close a scope that has not been opened.\n");
@@ -320,6 +320,7 @@ void output_close_scope(void) {
if (g_format != NULL)
g_format->output_fn(g_format, type, scope, key, value);
+ free(scope->name);
free(scope);
}
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,33 @@
From 9173ec91ab3c82833ad2ac691e7421607c5edbc3 Mon Sep 17 00:00:00 2001
From: root <root@localhost.localdomain>
Date: Fri, 11 Aug 2017 18:13:07 +0800
Subject: [PATCH 10/12] fix readdir bug
---
src/plugins.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git src/plugins.c src/plugins.c
index 7488043..3885e01 100644
--- src/plugins.c
+++ src/plugins.c
@@ -159,10 +159,16 @@ int plugins_load_all_from_directory(const char *path) {
// MORE: http://womble.decadent.org.uk/readdir_r-advisory.html
// NOTE: readdir is not thread-safe.
while ((dir_entry = readdir(dir)) != NULL) {
+
switch (dir_entry->d_type) {
default: // Unhandled
break;
+
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+ case DT_UNKNOWN:
+#else
case DT_REG: // Regular file
+#endif
{
const char *filename = dir_entry->d_name;
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,29 @@
From c4974983f1a6b6590a91a961b8e1a38d6622ef38 Mon Sep 17 00:00:00 2001
From: Jardel Weyrich <jweyrich@users.noreply.github.com>
Date: Thu, 14 Dec 2017 11:24:51 -0200
Subject: [PATCH 11/12] We don't want to ignore DT_REG if, for instance, Linux
reports it.
See https://github.com/merces/pev/pull/121#issuecomment-323853185
---
src/plugins.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git src/plugins.c src/plugins.c
index 3885e01..646b4af 100644
--- src/plugins.c
+++ src/plugins.c
@@ -166,9 +166,8 @@ int plugins_load_all_from_directory(const char *path) {
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
case DT_UNKNOWN:
-#else
- case DT_REG: // Regular file
#endif
+ case DT_REG: // Regular file
{
const char *filename = dir_entry->d_name;
--
2.26.2.672.g232c24e857

View file

@ -0,0 +1,32 @@
From be991e88c2605fb6013cd24d876acbacf37f6c33 Mon Sep 17 00:00:00 2001
From: Jardel Weyrich <jweyrich@gmail.com>
Date: Tue, 30 Jul 2019 16:01:57 -0300
Subject: [PATCH 12/12] peres: Fix unitialized memory issues. Fixes #122.
---
src/peres.c | 2 ++
1 file changed, 2 insertions(+)
diff --git src/peres.c src/peres.c
index 47fdaf4..249521c 100644
--- src/peres.c
+++ src/peres.c
@@ -315,6 +315,7 @@ static NODE_PERES * createNode(NODE_PERES *currentNode, NODE_TYPE_PERES typeOfNe
{
assert(currentNode != NULL);
NODE_PERES *newNode = malloc_s(sizeof(NODE_PERES));
+ memset(newNode, 0, sizeof(*newNode));
newNode->lastNode = currentNode;
newNode->nextNode = NULL;
newNode->nodeType = typeOfNextNode;
@@ -634,6 +635,7 @@ static NODE_PERES * discoveryNodesPeres(pe_ctx_t *ctx)
}
NODE_PERES *node = malloc_s(sizeof(NODE_PERES));
+ memset(node, 0, sizeof(*node));
node->lastNode = NULL; // root
node->nodeType = RDT_RESOURCE_DIRECTORY;
node->nodeLevel = RDT_LEVEL1;
--
2.26.2.672.g232c24e857

View file

@ -1,17 +1,52 @@
# Template file for 'pev'
pkgname=pev
version=0.80
revision=7
revision=8
wrksrc=${pkgname}
build_style=gnu-makefile
make_build_args="prefix=/usr"
make_install_args="prefix=/usr"
make_build_args="prefix=/usr sysconfdir=/etc"
make_install_args="prefix=/usr sysconfdir=/etc"
makedepends="libressl-devel pcre-devel"
short_desc="The PE file analysis toolkit"
# We don't need python for check, only their PE binary is needed
checkdepends="which python3"
short_desc="PE file analysis toolkit"
maintainer="Diogo Leal <diogo@diogoleal.com>"
license="GPL-3"
# executable is GPL-2.0-or-later, libpe is LGPL-3.0-or-later
license="GPL-2.0-or-later, MIT, LGPL-3.0-or-later, BSD-2-Clause"
homepage="http://pev.sourceforge.net/"
#distfiles="${SOURCEFORGE_SITE}/project/${pkgname}/${pkgname}-${version}/${pkgname}-${version}.tar.gz"
# Temporarily use a Debian mirror
distfiles="http://http.debian.net/debian/pool/main/p/pev/pev_${version}.orig.tar.gz"
checksum=f68c8596f16d221d9a742812f6f728bcc739be90957bc1b00fbaa5943ffc5cfa
if [ "$XBPS_TARGET_LIBC" = musl ]; then
makedepends+=" musl-legacy-compat"
fi
post_patch() {
# BSD-2-Clause
sed -ne '/Copyright/,/SUCH DAMAGE[.]/s/ *[*]* *//p; /[*]\//q' \
lib/libudis86/udis86.h >libudis86.LICENSE
# include/stack.h and src/dylib.c is MIT by same author.
sed -ne '/The MIT License/,/THE SOFTWARE[.]$/s/[[:space:]]*//p; /[*]\//q' \
include/stack.h >stack-dylib.LICENSE
vsed -i -e 's,/usr/local/lib/pev/plugins,/usr/lib/pev/plugins,' \
src/config.c
}
_real_check() {
for f in /usr/lib/python$py3_ver/distutils/command/*.exe; do
tests/run.sh pe32 "$f"
done
}
do_check() {
export LD_LIBRARY_PATH=$(pwd)/src/build
ln -sf ../../lib/libpe/libpe.so src/build/libpe.so.1
! _real_check | tee /dev/stderr | grep -q 'NOK$'
}
post_install() {
vlicense libudis86.LICENSE
vlicense stack-dylib.LICENSE
}