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:
+14
-9
@@ -327,8 +327,19 @@ METHOD(pts_t, extract_symlinks, pts_symlinks_t*,
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
DIR *dir;
|
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 */
|
/* 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);
|
dir = opendir(path);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
{
|
{
|
||||||
@@ -336,14 +347,9 @@ METHOD(pts_t, extract_symlinks, pts_symlinks_t*,
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (pathname.len == 1 && path[0] == '/')
|
if (path_len > 1 || path[0] != '/')
|
||||||
{
|
{
|
||||||
path_len = 1;
|
path[path_len++] = '/';
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
path[pathname.len] = '/';
|
|
||||||
path_len = pathname.len + 1;
|
|
||||||
}
|
}
|
||||||
real_path[0] = '/';
|
real_path[0] = '/';
|
||||||
|
|
||||||
@@ -353,7 +359,6 @@ METHOD(pts_t, extract_symlinks, pts_symlinks_t*,
|
|||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
|
|
||||||
entry = readdir(dir);
|
entry = readdir(dir);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user