Skip to content

Commit 74f0051

Browse files
tkuchtabrowneee
authored andcommitted
[DFSAN] Add support for strsep.
Reviewed-by: browneee Differential Revision: https://reviews.llvm.org/D141389
1 parent 1245a1e commit 74f0051

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

compiler-rt/lib/dfsan/dfsan_custom.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,57 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strpbrk(
204204
return const_cast<char *>(ret);
205205
}
206206

207+
SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strsep(char **s, const char *delim,
208+
dfsan_label s_label,
209+
dfsan_label delim_label,
210+
dfsan_label *ret_label) {
211+
dfsan_label base_label = dfsan_read_label(s, sizeof(*s));
212+
char *base = *s;
213+
char *res = strsep(s, delim);
214+
if (res != *s) {
215+
char *token_start = res;
216+
int token_length = strlen(res);
217+
// the delimiter byte has been set to NULL
218+
dfsan_set_label(0, token_start + token_length, 1);
219+
}
220+
221+
if (flags().strict_data_dependencies) {
222+
*ret_label = res ? base_label : 0;
223+
} else {
224+
size_t s_bytes_read = (res ? strlen(res) : strlen(base)) + 1;
225+
*ret_label = dfsan_union(
226+
dfsan_union(base_label, dfsan_read_label(base, sizeof(s_bytes_read))),
227+
dfsan_union(dfsan_read_label(delim, strlen(delim) + 1),
228+
dfsan_union(s_label, delim_label)));
229+
}
230+
231+
return res;
232+
}
233+
234+
SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strsep(
235+
char **s, const char *delim, dfsan_label s_label, dfsan_label delim_label,
236+
dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin delim_origin,
237+
dfsan_origin *ret_origin) {
238+
dfsan_origin base_origin = dfsan_read_origin_of_first_taint(s, sizeof(*s));
239+
char *res = __dfsw_strsep(s, delim, s_label, delim_label, ret_label);
240+
if (flags().strict_data_dependencies) {
241+
if (res)
242+
*ret_origin = base_origin;
243+
} else {
244+
if (*ret_label) {
245+
if (base_origin) {
246+
*ret_origin = base_origin;
247+
} else {
248+
dfsan_origin o =
249+
dfsan_read_origin_of_first_taint(delim, strlen(delim) + 1);
250+
*ret_origin = o ? o : (s_label ? s_origin : delim_origin);
251+
}
252+
}
253+
}
254+
255+
return res;
256+
}
257+
207258
static int dfsan_memcmp_bcmp(const void *s1, const void *s2, size_t n,
208259
size_t *bytes_read) {
209260
const char *cs1 = (const char *) s1, *cs2 = (const char *) s2;

compiler-rt/lib/dfsan/done_abilist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ fun:strncmp=custom
283283
fun:strpbrk=custom
284284
fun:strrchr=custom
285285
fun:strstr=custom
286+
fun:strsep=custom
286287

287288
# Functions which take action based on global state, such as running a callback
288289
# set by a separate function.

compiler-rt/test/dfsan/custom.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,51 @@ void test_strpbrk() {
16301630
#endif
16311631
}
16321632

1633+
void test_strsep() {
1634+
char *s = strdup("Hello world/");
1635+
char *delim = strdup(" /");
1636+
1637+
char *p_s = s;
1638+
char *base = s;
1639+
char *p_delim = delim;
1640+
1641+
// taint delim bytes
1642+
dfsan_set_label(i_label, p_delim, strlen(p_delim));
1643+
// taint delim pointer
1644+
dfsan_set_label(j_label, &p_delim, sizeof(p_delim));
1645+
// taint the string data bytes
1646+
dfsan_set_label(k_label, s, 5);
1647+
// taint the string pointer
1648+
dfsan_set_label(m_label, &p_s, sizeof(p_s));
1649+
1650+
char *rv = strsep(&p_s, p_delim);
1651+
assert(rv == &base[0]);
1652+
#ifdef STRICT_DATA_DEPENDENCIES
1653+
ASSERT_LABEL(rv, m_label);
1654+
ASSERT_READ_LABEL(rv, strlen(rv), k_label);
1655+
#else
1656+
ASSERT_LABEL(rv, dfsan_union(dfsan_union(i_label, j_label),
1657+
dfsan_union(k_label, m_label)));
1658+
ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s);
1659+
#endif
1660+
1661+
// taint the remaining string's pointer
1662+
char **pp_s = &p_s;
1663+
char **pp_s_base = pp_s;
1664+
dfsan_set_label(n_label, pp_s, sizeof(pp_s));
1665+
1666+
rv = strsep(pp_s, p_delim);
1667+
1668+
assert(rv == &base[6]);
1669+
#ifdef STRICT_DATA_DEPENDENCIES
1670+
ASSERT_LABEL(rv, n_label);
1671+
ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, *pp_s);
1672+
#else
1673+
ASSERT_LABEL(rv, dfsan_union(dfsan_union(i_label, j_label), n_label));
1674+
ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, *pp_s);
1675+
#endif
1676+
}
1677+
16331678
void test_memchr() {
16341679
char str1[] = "str1";
16351680
dfsan_set_label(i_label, &str1[3], 1);
@@ -2044,6 +2089,7 @@ int main(void) {
20442089
test_strncmp();
20452090
test_strncpy();
20462091
test_strpbrk();
2092+
test_strsep();
20472093
test_strrchr();
20482094
test_strstr();
20492095
test_strtod();

0 commit comments

Comments
 (0)