pts: Fix potential crash when resolving symlinks

When the passed path was longer than the local buffer, while still
passing the `opendir()` call (e.g. `/\0` followed by padding), the access
via original chunk length to write a final `/` wrote outside of the
buffer.  The same could happen later when adding directory names because
`path_len` was based on that same length.

Fixes: 2ea1dac203 ("libimcv: Support symlinks introduced by usrmerge")
This commit is contained in:
Tobias Brunner
2026-07-24 08:47:37 +02:00
parent fdf12edd85
commit 2dfc1ac1a8
+14 -9
View File
@@ -327,8 +327,19 @@ METHOD(pts_t, extract_symlinks, pts_symlinks_t*,
struct stat st;
DIR *dir;
path_len = strnlen(pathname.ptr, pathname.len);
if (!path_len)
{
DBG1(DBG_PTS, "empty directory path");
return NULL;
}
if (path_len >= sizeof(path)-1)
{
DBG1(DBG_PTS, "directory path is too long");
return NULL;
}
/* open directory and prepare pathnames */
snprintf(path, BUF_LEN-1, "%.*s", (int)pathname.len, pathname.ptr);
snprintf(path, BUF_LEN-1, "%.*s", (int)path_len, pathname.ptr);
dir = opendir(path);
if (!dir)
{
@@ -336,14 +347,9 @@ METHOD(pts_t, extract_symlinks, pts_symlinks_t*,
strerror(errno));
return NULL;
}
if (pathname.len == 1 && path[0] == '/')
if (path_len > 1 || path[0] != '/')
{
path_len = 1;
}
else
{
path[pathname.len] = '/';
path_len = pathname.len + 1;
path[path_len++] = '/';
}
real_path[0] = '/';
@@ -353,7 +359,6 @@ METHOD(pts_t, extract_symlinks, pts_symlinks_t*,
while (TRUE)
{
entry = readdir(dir);
if (!entry)
{