[pacman-dev] [PATCH] _alpm_hook_run: check path length before copying

Andrew Gregory andrew.gregory.8 at gmail.com
Wed Oct 28 04:04:05 UTC 2015


If a hook path equals or exceeds PATH_MAX characters the path will be
left unterminated.  Pre-calculating the path length also allows us to
use the more efficient memcpy over strncpy.

Signed-off-by: Andrew Gregory <andrew.gregory.8 at gmail.com>
---
 lib/libalpm/hook.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/lib/libalpm/hook.c b/lib/libalpm/hook.c
index 668e086..b440e08 100644
--- a/lib/libalpm/hook.c
+++ b/lib/libalpm/hook.c
@@ -621,30 +621,41 @@ int _alpm_hook_run(alpm_handle_t *handle, enum _alpm_hook_when_t when)
 		struct dirent entry, *result;
 		DIR *d;
 
-		if(!(d = opendir(i->data))) {
+		if((dirlen = strlen(i->data)) >= PATH_MAX) {
+			_alpm_log(handle, ALPM_LOG_ERROR, _("could not open directory: %s: %s\n"),
+					(char *)i->data, strerror(ENAMETOOLONG));
+			ret = -1;
+			continue;
+		}
+		memcpy(path, i->data, dirlen + 1);
+
+		if(!(d = opendir(path))) {
 			if(errno == ENOENT) {
 				continue;
 			} else {
-				_alpm_log(handle, ALPM_LOG_ERROR, _("could not open directory: %s: %s\n"),
-						(char *)i->data, strerror(errno));
+				_alpm_log(handle, ALPM_LOG_ERROR,
+						_("could not open directory: %s: %s\n"), path, strerror(errno));
 				ret = -1;
 				continue;
 			}
 		}
 
-		strncpy(path, i->data, PATH_MAX);
-		dirlen = strlen(i->data);
-
 		while((err = readdir_r(d, &entry, &result)) == 0 && result) {
 			struct _alpm_hook_cb_ctx ctx = { handle, NULL };
 			struct stat buf;
-			size_t name_len = strlen(entry.d_name);
+			size_t name_len;
 
 			if(strcmp(entry.d_name, ".") == 0 || strcmp(entry.d_name, "..") == 0) {
 					continue;
 			}
 
-			strncpy(path + dirlen, entry.d_name, PATH_MAX - dirlen);
+			if((name_len = strlen(entry.d_name)) >= PATH_MAX - dirlen) {
+				_alpm_log(handle, ALPM_LOG_ERROR, _("could not open file: %s%s: %s\n"),
+						path, entry.d_name, strerror(ENAMETOOLONG));
+				ret = -1;
+				continue;
+			}
+			memcpy(path + dirlen, entry.d_name, name_len + 1);
 
 			if(name_len < suflen
 					|| strcmp(entry.d_name + name_len - suflen, suffix) != 0) {
-- 
2.6.2


More information about the pacman-dev mailing list