diff options
author | Luiz Augusto von Dentz <luiz.dentz-von@nokia.com> | 2010-12-17 15:31:26 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2010-12-17 15:49:31 +0200 |
commit | 2d3a762fa7bef764945ea83ddcb1f8d2bf502b7e (patch) | |
tree | e1e47dc2feac9828c3ce5d2ca145048d2830883b /src/textfile.c | |
parent | fa2a8b9000a82038c1338ff2c416cd96fe273a9f (diff) | |
download | bluez-2d3a762fa7bef764945ea83ddcb1f8d2bf502b7e.tar.gz |
Fix crash when mmaping files which size is multiple of page size
In this case the buffer returned by mmap is not NULL terminated so
functions like strpbrk that expect a string goes out of bounds.
To fix this strpbrk_len was introduced which takes the size of the buffer
making sure it never goes out of bounds.
Diffstat (limited to 'src/textfile.c')
-rw-r--r-- | src/textfile.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/textfile.c b/src/textfile.c index 2429cc70c..d115ff6a0 100644 --- a/src/textfile.c +++ b/src/textfile.c @@ -156,6 +156,28 @@ static inline int write_key_value(int fd, const char *key, const char *value) return err; } +static char *strnpbrk(const char *s, ssize_t len, const char *accept) +{ + const char *p = s; + const char *end; + + end = s + len - 1; + + while (p <= end && *p) { + const char *a = accept; + + while (*a) { + if (*p == *a) + return (char *) p; + a++; + } + + p++; + } + + return NULL; +} + static int write_key(const char *pathname, const char *key, const char *value, int icase) { struct stat st; @@ -207,7 +229,7 @@ static int write_key(const char *pathname, const char *key, const char *value, i base = off - map; - end = strpbrk(off, "\r\n"); + end = strnpbrk(off, size, "\r\n"); if (!end) { err = EILSEQ; goto unmap; @@ -315,7 +337,7 @@ static char *read_key(const char *pathname, const char *key, int icase) goto unmap; } - end = strpbrk(off, "\r\n"); + end = strnpbrk(off, size - (map - off), "\r\n"); if (!end) { err = EILSEQ; goto unmap; @@ -404,8 +426,8 @@ int textfile_foreach(const char *pathname, textfile_cb func, void *data) off = map; - while (1) { - end = strpbrk(off, " "); + while (size - (off - map) > 0) { + end = strnpbrk(off, size - (off - map), " "); if (!end) { err = EILSEQ; break; @@ -424,7 +446,13 @@ int textfile_foreach(const char *pathname, textfile_cb func, void *data) off = end + 1; - end = strpbrk(off, "\r\n"); + if (size - (off - map) < 0) { + err = EILSEQ; + free(key); + break; + } + + end = strnpbrk(off, size - (off - map), "\r\n"); if (!end) { err = EILSEQ; free(key); |