diff options
author | Andrew Gregory <andrew.gregory.8@gmail.com> | 2015-10-28 05:04:05 +0100 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2015-10-28 05:22:09 +0100 |
commit | dcc1b22cb33a7a9d9477ffc84f833317860bf751 (patch) | |
tree | c74a92c5da3506cf062d6f979c79361fd3625531 | |
parent | 1142a32c7f6f8ab82528581277b7c7cac6b2d1ae (diff) | |
download | pacman-dcc1b22cb33a7a9d9477ffc84f833317860bf751.tar.gz pacman-dcc1b22cb33a7a9d9477ffc84f833317860bf751.tar.xz |
_alpm_hook_run: check path length before copying
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@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r-- | lib/libalpm/hook.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/lib/libalpm/hook.c b/lib/libalpm/hook.c index 463b76a2..0191a21e 100644 --- a/lib/libalpm/hook.c +++ b/lib/libalpm/hook.c @@ -410,30 +410,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) { |