Bug 1416016 - Resolve symlinks in the file broker as a last resort. r=jld

MozReview-Commit-ID: B7OMyARk9u8

--HG--
extra : rebase_source : 1106c8f877f748a2ef7e6af3b8e6965a3cf67e33
This commit is contained in:
Gian-Carlo Pascutto 2018-03-09 21:14:39 +01:00
Родитель 49a6cb8875
Коммит 4fb9bf8576
2 изменённых файлов: 30 добавлений и 13 удалений

Просмотреть файл

@ -546,9 +546,8 @@ DoConnect(const char* aPath, size_t aLen, int aType)
}
size_t
SandboxBroker::ConvertToRealPath(char* aPath, size_t aBufSize, size_t aPathLen)
SandboxBroker::RealPath(char* aPath, size_t aBufSize, size_t aPathLen)
{
if (strstr(aPath, "..") != nullptr) {
char* result = realpath(aPath, nullptr);
if (result != nullptr) {
base::strlcpy(aPath, result, aBufSize);
@ -556,7 +555,14 @@ SandboxBroker::ConvertToRealPath(char* aPath, size_t aBufSize, size_t aPathLen)
// Size changed, but guaranteed to be 0 terminated
aPathLen = strlen(aPath);
}
// ValidatePath will handle failure to translate
return aPathLen;
}
size_t
SandboxBroker::ConvertRelativePath(char* aPath, size_t aBufSize, size_t aPathLen)
{
if (strstr(aPath, "..") != nullptr) {
return RealPath(aPath, aBufSize, aPathLen);
}
return aPathLen;
}
@ -784,7 +790,7 @@ SandboxBroker::ThreadMain(void)
pathLen = first_len;
// Look up the first pathname but first translate relative paths.
pathLen = ConvertToRealPath(pathBuf, sizeof(pathBuf), pathLen);
pathLen = ConvertRelativePath(pathBuf, sizeof(pathBuf), pathLen);
perms = mPolicy->Lookup(nsDependentCString(pathBuf, pathLen));
// We don't have permissions on the requested dir.
@ -796,11 +802,21 @@ SandboxBroker::ThreadMain(void)
// Did we arrive from a symlink in a path that is not writable?
// Then try to figure out the original path and see if that is
// readable. Work on the original path, this reverses
// ConvertToRealPath above.
// ConvertRelative above.
int symlinkPerms = SymlinkPermissions(recvBuf, first_len);
if (symlinkPerms > 0) {
perms = symlinkPerms;
}
if (!perms) {
// Now try the opposite case: translate symlinks to their
// actual destination file. Firefox always resolves symlinks,
// and in most cases we have whitelisted fixed paths that
// libraries will rely on and try to open. So this codepath
// is mostly useful for Mesa which had its kernel interface
// moved around.
pathLen = RealPath(pathBuf, sizeof(pathBuf), pathLen);
perms = mPolicy->Lookup(nsDependentCString(pathBuf, pathLen));
}
}
}
@ -809,7 +825,7 @@ SandboxBroker::ThreadMain(void)
if (pathLen2 > 0) {
// Force 0 termination.
pathBuf2[pathLen2] = '\0';
pathLen2 = ConvertToRealPath(pathBuf2, sizeof(pathBuf2), pathLen2);
pathLen2 = ConvertRelativePath(pathBuf2, sizeof(pathBuf2), pathLen2);
int perms2 = mPolicy->Lookup(nsDependentCString(pathBuf2, pathLen2));
// Take the intersection of the permissions for both paths.

Просмотреть файл

@ -145,7 +145,8 @@ class SandboxBroker final
void AuditPermissive(int aOp, int aFlags, int aPerms, const char* aPath);
void AuditDenial(int aOp, int aFlags, int aPerms, const char* aPath);
// Remap relative paths to absolute paths.
size_t ConvertToRealPath(char* aPath, size_t aBufSize, size_t aPathLen);
size_t ConvertRelativePath(char* aPath, size_t aBufSize, size_t aPathLen);
size_t RealPath(char* aPath, size_t aBufSize, size_t aPathLen);
// Remap references to /tmp and friends to the content process tempdir
size_t RemapTempDirs(char* aPath, size_t aBufSize, size_t aPathLen);
nsCString ReverseSymlinks(const nsACString& aPath);