[compiler-rt] d9b3691 - [DFSAN] Add support for strncat
Andrew Browne via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 21 14:21:32 PDT 2023
Author: Tomasz Kuchta
Date: 2023-06-21T21:21:13Z
New Revision: d9b3691166f1cf60c2c6746fd6ed777787740c84
URL: https://github.com/llvm/llvm-project/commit/d9b3691166f1cf60c2c6746fd6ed777787740c84
DIFF: https://github.com/llvm/llvm-project/commit/d9b3691166f1cf60c2c6746fd6ed777787740c84.diff
LOG: [DFSAN] Add support for strncat
This patch adds a support for the libc strncat() function in DFSAN
Reviewed by: browneee
Differential Revision: https://reviews.llvm.org/D152196
Added:
Modified:
compiler-rt/lib/dfsan/dfsan_custom.cpp
compiler-rt/lib/dfsan/done_abilist.txt
compiler-rt/test/dfsan/custom.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/dfsan/dfsan_custom.cpp b/compiler-rt/lib/dfsan/dfsan_custom.cpp
index e63e68084fa32..f41dd50617fbc 100644
--- a/compiler-rt/lib/dfsan/dfsan_custom.cpp
+++ b/compiler-rt/lib/dfsan/dfsan_custom.cpp
@@ -682,6 +682,37 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat(
return ret;
}
+SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strncat(
+ char *dest, const char *src, size_t num, dfsan_label dest_label,
+ dfsan_label src_label, dfsan_label num_label, dfsan_label *ret_label) {
+ size_t src_len = strlen(src);
+ src_len = src_len < num ? src_len : num;
+ size_t dest_len = strlen(dest);
+
+ char *ret = strncat(dest, src, num);
+ dfsan_mem_shadow_transfer(dest + dest_len, src, src_len);
+ *ret_label = dest_label;
+ return ret;
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncat(
+ char *dest, const char *src, size_t num, dfsan_label dest_label,
+ dfsan_label src_label, dfsan_label num_label, dfsan_label *ret_label,
+ dfsan_origin dest_origin, dfsan_origin src_origin, dfsan_origin num_origin,
+ dfsan_origin *ret_origin) {
+ size_t src_len = strlen(src);
+ src_len = src_len < num ? src_len : num;
+ size_t dest_len = strlen(dest);
+
+ char *ret = strncat(dest, src, num);
+
+ dfsan_mem_origin_transfer(dest + dest_len, src, src_len);
+ dfsan_mem_shadow_transfer(dest + dest_len, src, src_len);
+ *ret_label = dest_label;
+ *ret_origin = dest_origin;
+ return ret;
+}
+
SANITIZER_INTERFACE_ATTRIBUTE char *
__dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
size_t len = strlen(s);
diff --git a/compiler-rt/lib/dfsan/done_abilist.txt b/compiler-rt/lib/dfsan/done_abilist.txt
index cc3578b95cd49..df5eedcafeb86 100644
--- a/compiler-rt/lib/dfsan/done_abilist.txt
+++ b/compiler-rt/lib/dfsan/done_abilist.txt
@@ -268,6 +268,7 @@ fun:strtoll=custom
fun:strtoul=custom
fun:strtoull=custom
fun:strcat=custom
+fun:strncat=custom
# Functions that produce an output that is computed from the input, but is not
# necessarily data dependent.
diff --git a/compiler-rt/test/dfsan/custom.cpp b/compiler-rt/test/dfsan/custom.cpp
index 62483c1ed96f2..c67602d4538e6 100644
--- a/compiler-rt/test/dfsan/custom.cpp
+++ b/compiler-rt/test/dfsan/custom.cpp
@@ -340,6 +340,7 @@ void test_strcat() {
dfsan_origin dst_o = dfsan_get_origin((long)dst[0]);
(void)dst_o;
char *ret = strcat(p, src);
+
ASSERT_LABEL(ret, k_label);
ASSERT_EQ_ORIGIN(ret, p);
assert(ret == dst);
@@ -367,6 +368,56 @@ void test_strcat() {
ASSERT_LABEL(dst[11], j_label);
}
+void test_strncat(int n) {
+ char src[] = "world";
+ int volatile x = 0; // buffer to ensure src and dst do not share origins
+ (void)x;
+ char dst[] = "hello \0 ";
+ int volatile y = 0; // buffer to ensure dst and p do not share origins
+ (void)y;
+ char *p = dst;
+ dfsan_set_label(k_label, &p, sizeof(p));
+ dfsan_set_label(i_label, src, sizeof(src));
+ dfsan_set_label(j_label, dst, sizeof(dst));
+ dfsan_origin dst_o = dfsan_get_origin((long)dst[0]);
+ (void)dst_o;
+ char *ret = strncat(p, src, n);
+
+ ASSERT_LABEL(ret, k_label);
+ ASSERT_EQ_ORIGIN(ret, p);
+ assert(ret == dst);
+ assert(strncmp(src, dst + 6, n) == 0);
+ // Origins are assigned for every 4 contiguous 4-aligned bytes. After
+ // appending src to dst, origins of src can overwrite origins of dst if their
+ // application adddresses are within [start_aligned_down, end_aligned_up).
+ // Other origins are not changed.
+ int pad = n % 4;
+ if (pad)
+ pad = 4 - pad;
+
+ char *start_aligned_down = (char *)(((size_t)(dst + 6)) & ~3UL);
+ char *end_aligned_up = (char *)(((size_t)(dst + 6 + n + pad)) & ~3UL);
+
+ for (int i = 0; i < 12; ++i) {
+ if (dst + i < start_aligned_down || dst + i >= end_aligned_up) {
+ ASSERT_INIT_ORIGIN(&dst[i], dst_o);
+ } else {
+ ASSERT_INIT_ORIGIN_EQ_ORIGIN(&dst[i], src[0]);
+ }
+ }
+ for (int i = 0; i < 6; ++i) {
+ ASSERT_LABEL(dst[i], j_label);
+ }
+ for (int i = 6; i < 6 + n; ++i) {
+ ASSERT_LABEL(dst[i], i_label);
+ assert(dfsan_get_label(dst[i]) == dfsan_get_label(src[i - 6]));
+ }
+ for (int i = 6 + n; i < strlen(dst); ++i) {
+ ASSERT_LABEL(dst[i], j_label);
+ }
+ ASSERT_LABEL(dst[11], j_label);
+}
+
void test_strlen() {
char str1[] = "str1";
dfsan_set_label(i_label, &str1[3], 1);
@@ -2110,6 +2161,8 @@ int main(void) {
test_strchr();
test_strcmp();
test_strcat();
+ test_strncat(5);
+ test_strncat(2);
test_strcpy();
test_strdup();
test_strlen();
More information about the llvm-commits
mailing list