summaryrefslogtreecommitdiff
path: root/src/textfile.c
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz-von@nokia.com>2010-12-17 15:31:26 +0200
committerJohan Hedberg <johan.hedberg@nokia.com>2010-12-17 15:49:31 +0200
commit2d3a762fa7bef764945ea83ddcb1f8d2bf502b7e (patch)
treee1e47dc2feac9828c3ce5d2ca145048d2830883b /src/textfile.c
parentfa2a8b9000a82038c1338ff2c416cd96fe273a9f (diff)
downloadbluez-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.c38
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);