aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2012-09-03 22:41:04 +0200
committerMax Kellermann <max@duempel.org>2012-09-03 22:41:04 +0200
commit27535a7f781d7fbc87b2c6f9ec217cf7daca3323 (patch)
tree68d6428ed01a4dd259ea24be98ed0b45896a8e30
parentacaa725478ae5e6e4fff9e07cf8637d17d314c41 (diff)
update_walk: fix unsafe readlink() usage
-rw-r--r--NEWS1
-rw-r--r--src/update_walk.c12
2 files changed, 11 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index c23739d7..22f42b77 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ ver 0.17.2 (2012/??/??)
* playlist: fix memory leak
* state_file: save song priorities
* player: disable cross-fading in "single" mode
+* update: fix unsafe readlink() usage
ver 0.17.1 (2012/07/31)
diff --git a/src/update_walk.c b/src/update_walk.c
index 615bf41a..8554e8f3 100644
--- a/src/update_walk.c
+++ b/src/update_walk.c
@@ -283,12 +283,20 @@ skip_symlink(const struct directory *directory, const char *utf8_name)
return true;
char buffer[MPD_PATH_MAX];
- ssize_t ret = readlink(path_fs, buffer, sizeof(buffer));
+ ssize_t length = readlink(path_fs, buffer, sizeof(buffer));
g_free(path_fs);
- if (ret < 0)
+ if (length < 0)
/* don't skip if this is not a symlink */
return errno != EINVAL;
+ if ((size_t)length >= sizeof(buffer))
+ /* skip symlinks when the buffer is too small for the
+ link target */
+ return true;
+
+ /* null-terminate the buffer, because readlink() will not */
+ buffer[length] = 0;
+
if (!follow_inside_symlinks && !follow_outside_symlinks) {
/* ignore all symlinks */
return true;