[Forensics-changes] [yara] 57/192: Don't unmask signals when setting up exception handler (Unix) (#546)
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:31:46 UTC 2017
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to annotated tag v3.6.0
in repository yara.
commit 8b2b6b8f82b8a8a8830bae122474b39ac2814fc6
Author: Hilko Bengen <hillu at users.noreply.github.com>
Date: Mon Oct 31 09:40:38 2016 +0100
Don't unmask signals when setting up exception handler (Unix) (#546)
* YR_TRYCATCH: Remove duplicate initialization of oldmask
* Add test for handling exceptions
With
#define YR_TRYCATCH(_try_clause_, _catch_clause_) {_try_clause_}
this will cause a bus error on Linux -- as it should.
* tests: Add assert_*_rule_blob_size, make count_matches usable from test code
* test-exception: Block and send SIGUSR1 before 2nd yr_rules_scan_mem call
This seems to reproduce something similar to the symptom described in
$ ./test-exception
Scanning for "aaaa"...
err = 4, matches = 0
Sending blocked SIGUSR1 to ourselves...
Scanning for {00 00 00 00}...
User defined signal 1
* exception (UNIX): Remove unneeded pthread_sigmask() calls
sigsetjmp() already saves the signal mask for us.
Also, setting the signal mask using the (empty) act.sa_mask was wrong
and led to the behavior described in #544.
We still want delivery of all signals to be blocked during execution of
the signal handler.
* Document test-exception
---
Makefile.am | 4 +-
libyara/exception.h | 7 +---
tests/test-exception.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++
tests/util.c | 2 +-
tests/util.h | 20 +++++++--
5 files changed, 129 insertions(+), 12 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 8c1652a..8f5ab59 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,7 +15,7 @@ yarac_SOURCES = args.c args.h yarac.c
yarac_LDADD = libyara/.libs/libyara.a
TESTS = $(check_PROGRAMS)
-check_PROGRAMS = test-alignment test-rules test-pe test-elf
+check_PROGRAMS = test-alignment test-rules test-pe test-elf test-exception
test_alignment_SOURCES = tests/test-alignment.c
test_rules_SOURCES = tests/test-rules.c tests/util.c
test_rules_LDADD = libyara/.libs/libyara.a
@@ -23,6 +23,8 @@ test_pe_SOURCES = tests/test-pe.c tests/util.c
test_pe_LDADD = libyara/.libs/libyara.a
test_elf_SOURCES = tests/test-elf.c tests/util.c
test_elf_LDADD = libyara/.libs/libyara.a
+test_exception_SOURCES = tests/test-exception.c tests/util.c
+test_exception_LDADD = libyara/.libs/libyara.a
# man pages
man1_MANS = yara.man yarac.man
diff --git a/libyara/exception.h b/libyara/exception.h
index 436d006..c70ae63 100644
--- a/libyara/exception.h
+++ b/libyara/exception.h
@@ -99,13 +99,9 @@ typedef struct sigaction sa;
{ \
struct sigaction oldact; \
struct sigaction act; \
- sigset_t oldmask; \
act.sa_handler = exception_handler; \
act.sa_flags = 0; /* SA_ONSTACK? */ \
- sigemptyset(&oldmask); \
- sigemptyset(&act.sa_mask); \
- sigemptyset(&oldmask); \
- pthread_sigmask(SIG_SETMASK, &act.sa_mask, &oldmask); \
+ sigfillset(&act.sa_mask); \
sigaction(SIGBUS, &act, &oldact); \
int tidx = yr_get_tidx(); \
assert(tidx != -1); \
@@ -117,7 +113,6 @@ typedef struct sigaction sa;
{ _catch_clause_ } \
exc_jmp_buf[tidx] = NULL; \
sigaction(SIGBUS, &oldact, NULL); \
- pthread_sigmask(SIG_SETMASK, &oldmask, NULL); \
} while (0)
#endif
diff --git a/tests/test-exception.c b/tests/test-exception.c
new file mode 100644
index 0000000..19dc911
--- /dev/null
+++ b/tests/test-exception.c
@@ -0,0 +1,108 @@
+/*
+Copyright (c) 2016. The YARA Authors. All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <signal.h>
+
+#include <yara.h>
+#include "util.h"
+
+int main(int argc, char **argv)
+{
+ char* filename = strdup("yara-testblob.XXXXXX");
+ int fd = mkstemp(filename);
+ char wbuf[4096];
+ int i;
+
+ if (fd <= 0)
+ {
+ perror("Create temp file");
+ return 77;
+ }
+ unlink(filename);
+
+ memset(wbuf, 'a', sizeof(wbuf));
+ for (i=0; i<=3; i++)
+ write(fd, wbuf, sizeof(wbuf));
+
+ uint8_t* mapped_region = mmap(NULL, 4*sizeof(wbuf), PROT_READ, MAP_SHARED, fd, 0);
+ ftruncate(fd, 2*sizeof(wbuf));
+ /*
+ mapped_region is now only partially backed by the open file
+ referred to by fd. Accessing the memory beyond
+
+ mapped_region + 2*sizeof(wbuf)
+
+ causes SIGBUS to be raised.
+ */
+
+ yr_initialize();
+
+ YR_RULES* rules_a = compile_rule("rule test { strings: $a = \"aaaa\" condition: all of them }");
+ YR_RULES* rules_0 = compile_rule("rule test { strings: $a = { 00 00 00 00 } condition: all of them }");
+
+ puts("Scanning for \"aaaa\"...");
+ int matches = 0;
+
+ /*
+ If YR_TRYCATCH is redefined like this
+
+ #define YR_TRYCATCH(_try_clause_,_catch_clause_) {_try_clause_}
+
+ yr_rules_scan_mem() will terminate the process.
+ */
+ int rc = yr_rules_scan_mem(rules_a, mapped_region, 4*sizeof(wbuf), 0, count_matches, &matches, 0);
+ printf("err = %d, matches = %d\n", rc, matches);
+ if (rc == ERROR_SUCCESS || matches != 0)
+ return 1;
+
+ puts("Sending blocked SIGUSR1 to ourselves...");
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGUSR1);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+ kill(getpid(), SIGUSR1);
+
+ puts("Scanning for {00 00 00 00}...");
+ matches = 0;
+
+ /*
+ This tests that SIGUSR1 is not delivered when setting up SIGBUS
+ signal handling -- or during SIGBUS signal handling
+ */
+ rc = yr_rules_scan_mem(rules_0, mapped_region, 4*sizeof(wbuf), 0, count_matches, &matches, 0);
+ printf("err = %d, matches = %d\n", rc, matches);
+ if (rc == ERROR_SUCCESS || matches != 0)
+ return 1;
+
+ return 0;
+}
diff --git a/tests/util.c b/tests/util.c
index 5597c98..59105dd 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -82,7 +82,7 @@ _exit:
}
-static int count_matches(
+int count_matches(
int message,
void* message_data,
void* user_data)
diff --git a/tests/util.h b/tests/util.h
index 89b245b..835115f 100644
--- a/tests/util.h
+++ b/tests/util.h
@@ -36,6 +36,12 @@ YR_RULES* compile_rule(
char* string);
+int count_matches(
+ int message,
+ void* message_data,
+ void* user_data);
+
+
int matches_blob(
char* rule,
uint8_t* blob,
@@ -66,15 +72,18 @@ int read_file(
} \
} while (0);
-#define assert_true_rule_blob(rule, blob) \
+#define assert_true_rule_blob_size(rule, blob, size) \
do { \
- if (!matches_blob(rule, (uint8_t*) (blob), sizeof(blob))) { \
+ if (!matches_blob(rule, (uint8_t*) (blob), size)) { \
fprintf(stderr, "%s:%d: rule does not match (but should)\n", \
__FILE__, __LINE__ ); \
exit(EXIT_FAILURE); \
} \
} while (0);
+#define assert_true_rule_blob(rule, blob) \
+ assert_true_rule_blob_size(rule, blob, sizeof(blob))
+
#define assert_true_rule_file(rule, filename) \
do { \
char* buf; \
@@ -102,15 +111,18 @@ int read_file(
} \
} while (0);
-#define assert_false_rule_blob(rule, blob) \
+#define assert_false_rule_blob_size(rule, blob, size) \
do { \
- if (matches_blob(rule, (uint8_t*) (blob), sizeof(blob))) { \
+ if (matches_blob(rule, (uint8_t*) (blob), size)) { \
fprintf(stderr, "%s:%d: rule matches (but shouldn't)\n", \
__FILE__, __LINE__ ); \
exit(EXIT_FAILURE); \
} \
} while (0);
+#define assert_false_rule_blob(rule, blob) \
+ assert_false_rule_blob_size(rule, blob, sizeof(blob))
+
#define assert_false_rule_file(rule, filename) \
do { \
char* buf; \
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git
More information about the forensics-changes
mailing list