in the function query_fileowner, if the user enters a string longer than PATH_MAX then rpath will buffer overflow when lrealpath tries to strcat everything together. Even if we made sure filename was never longer than PATH_MAX this would not help because lrealpath may concatenate filename with the current directory among other things. So simply let lrealpath calculate the size needed and allocate it for us. This also fixes the compiler warning; query.c: In function ‘query_fileowner’: query.c:192:4: warning: ‘strncpy’ specified bound 4096 equals destination size [-Wstringop-truncation] strncpy(rpath, filename, PATH_MAX); The warning could have also been Fixed by using PATH_MAX -1 and explicitly terminating the string. However this would not fix the buffer overflow. Signed-off-by: morganamilo <morganamilo@gmail.com> diff --git a/src/pacman/query.c b/src/pacman/query.c index 00c39638..a1197cea 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -155,10 +155,10 @@ static int query_fileowner(alpm_list_t *targets) for(t = targets; t; t = alpm_list_next(t)) { char *filename = NULL; - char rpath[PATH_MAX], *rel_path; + char *rpath = NULL, *rpathsave, *rel_path; struct stat buf; alpm_list_t *i; - size_t len; + size_t len, rlen; unsigned int found = 0; int is_dir = 0, is_missing = 0; @@ -187,9 +187,15 @@ static int query_fileowner(alpm_list_t *targets) } } - if(!lrealpath(filename, rpath)) { + if(!(rpath = lrealpath(filename, NULL))) { /* Can't canonicalize path, try to proceed anyway */ - strncpy(rpath, filename, PATH_MAX); + rpath = strdup(filename); + } + + rlen = strlen(rpath); + if(rlen + 1 >= PATH_MAX) { + pm_printf(ALPM_LOG_ERROR, _("path too long: %s/\n"), rpath); + goto targcleanup; } if(strncmp(rpath, root, rootlen) != 0) { @@ -201,11 +207,14 @@ static int query_fileowner(alpm_list_t *targets) rel_path = rpath + rootlen; if((is_missing && is_dir) || (!is_missing && (is_dir = S_ISDIR(buf.st_mode)))) { - size_t rlen = strlen(rpath); if(rlen + 2 >= PATH_MAX) { pm_printf(ALPM_LOG_ERROR, _("path too long: %s/\n"), rpath); goto targcleanup; } + if ((rpathsave = realloc(rpath, rlen + 2)) == NULL) { + goto targcleanup; + } + rpath = rpathsave; strcat(rpath + rlen, "/"); } -- 2.19.0