Skip to content

Commit 6b83413

Browse files
committed
Fix undefined behaviour and sign extension issues in kstrtok
Prevent read beyond the end of sep if it's an empty string. Change to internally use unsigned char to avoid unwanted sign extension on platforms where 'char' is signed. Fix undefined behaviour where pointers were made to the element before the start of `str`: https://www.securecoding.cert.org/confluence/display/c/ARR30-C.+Do+not+form+or+use+out-of-bounds+pointers+or+array+subscripts
1 parent efd09f0 commit 6b83413

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

kstring.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,29 @@ int ksprintf(kstring_t *s, const char *fmt, ...)
3434
return l;
3535
}
3636

37-
char *kstrtok(const char *str, const char *sep, ks_tokaux_t *aux)
37+
char *kstrtok(const char *str, const char *sep_in, ks_tokaux_t *aux)
3838
{
39-
const char *p, *start;
39+
const unsigned char *p, *start, *sep = (unsigned char *) sep_in;
4040
if (sep) { // set up the table
4141
if (str == 0 && aux->finished) return 0; // no need to set up if we have finished
4242
aux->finished = 0;
43-
if (sep[1]) {
43+
if (sep[0] && sep[1]) {
4444
aux->sep = -1;
4545
aux->tab[0] = aux->tab[1] = aux->tab[2] = aux->tab[3] = 0;
4646
for (p = sep; *p; ++p) aux->tab[*p>>6] |= 1ull<<(*p&0x3f);
4747
} else aux->sep = sep[0];
4848
}
4949
if (aux->finished) return 0;
50-
else if (str) aux->p = str - 1, aux->finished = 0;
50+
else if (str) start = (unsigned char *) str, aux->finished = 0;
51+
else start = (unsigned char *) aux->p + 1;
5152
if (aux->sep < 0) {
52-
for (p = start = aux->p + 1; *p; ++p)
53+
for (p = start; *p; ++p)
5354
if (aux->tab[*p>>6]>>(*p&0x3f)&1) break;
5455
} else {
55-
for (p = start = aux->p + 1; *p; ++p)
56+
for (p = start; *p; ++p)
5657
if (*p == aux->sep) break;
5758
}
58-
aux->p = p; // end of token
59+
aux->p = (const char *) p; // end of token
5960
if (*p == 0) aux->finished = 1; // no more tokens
6061
return (char*)start;
6162
}

0 commit comments

Comments
 (0)