Bug 1387837 - Add library paths from /etc/ld.so.conf to broker read access policy. r?jld
MozReview-Commit-ID: S5vq6suTU4
--- a/config/system-headers
+++ b/config/system-headers
@@ -489,16 +489,17 @@ gdk/gdkx.h
gdk/gdkdirectfb.h
gdk/gdkwayland.h
gdk-pixbuf/gdk-pixbuf.h
Gestalt.h
getopt.h
glibconfig.h
glib.h
glib-object.h
+glob.h
gmodule.h
gnome.h
gnu/libc-version.h
gps.h
grp.h
gssapi_generic.h
gssapi/gssapi_generic.h
gssapi/gssapi.h
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
@@ -17,29 +17,36 @@
#include "mozilla/dom/ContentChild.h"
#include "nsPrintfCString.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "SpecialSystemDirectory.h"
+#include "nsReadableUtils.h"
+#include "nsIFileStreams.h"
+#include "nsILineInputStream.h"
+#include "nsNetCID.h"
#ifdef ANDROID
#include "cutils/properties.h"
#endif
#ifdef MOZ_WIDGET_GTK
#include <glib.h>
#endif
#include <dirent.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
+#ifndef ANDROID
+#include <glob.h>
+#endif
namespace mozilla {
#if defined(MOZ_CONTENT_SANDBOX)
namespace {
static const int rdonly = SandboxBroker::MAY_READ;
static const int wronly = SandboxBroker::MAY_WRITE;
static const int rdwr = rdonly | wronly;
@@ -80,16 +87,101 @@ AddMesaSysfsPaths(SandboxBroker::Policy*
}
}
}
}
closedir(dir);
}
}
+static void
+AddPathsFromFile(SandboxBroker::Policy* aPolicy, nsACString& aPath)
+{
+ nsresult rv;
+ nsCOMPtr<nsIFile> ldconfig(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
+ if (NS_FAILED(rv)) {
+ return;
+ }
+ rv = ldconfig->InitWithNativePath(aPath);
+ if (NS_FAILED(rv)) {
+ return;
+ }
+ nsCOMPtr<nsIFileInputStream> fileStream(
+ do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv));
+ if (NS_FAILED(rv)) {
+ return;
+ }
+ rv = fileStream->Init(ldconfig, -1, -1, 0);
+ if (NS_FAILED(rv)) {
+ return;
+ }
+ nsCOMPtr<nsILineInputStream> lineStream(do_QueryInterface(fileStream, &rv));
+ if (NS_FAILED(rv)) {
+ return;
+ }
+ nsAutoCString line;
+ bool more = true;
+ do {
+ rv = lineStream->ReadLine(line, &more);
+ // Cut off any comments at the end of the line, also catches lines
+ // that are entirely a comment
+ int32_t hash = line.FindChar('#');
+ if (hash >= 0) {
+ line = Substring(line, 0, hash);
+ }
+ // Simplify our following parsing by trimming whitespace
+ line.CompressWhitespace(true, true);
+ if (line.IsEmpty()) {
+ // Skip comment lines
+ continue;
+ }
+ // Check for any included files and recursively process
+ nsACString::const_iterator start, end, token_end;
+
+ line.BeginReading(start);
+ line.EndReading(end);
+ token_end = end;
+
+ if (FindInReadable(NS_LITERAL_CSTRING("include "), start, token_end)) {
+ nsAutoCString includes(Substring(token_end, end));
+ for (const nsACString& includeGlob : includes.Split(' ')) {
+ glob_t globbuf;
+ if (!glob(PromiseFlatCString(includeGlob).get(), GLOB_NOSORT, nullptr, &globbuf)) {
+ for (size_t fileIdx = 0; fileIdx < globbuf.gl_pathc; fileIdx++) {
+ nsAutoCString filePath(globbuf.gl_pathv[fileIdx]);
+ AddPathsFromFile(aPolicy, filePath);
+ }
+ globfree(&globbuf);
+ }
+ }
+ }
+ // Skip anything left over that isn't an absolute path
+ if (line.First() != '/') {
+ continue;
+ }
+ // Cut off anything behind an = sign, used by dirname=TYPE directives
+ int32_t equals = line.FindChar('=');
+ if (equals >= 0) {
+ line = Substring(line, 0, equals);
+ }
+ char* resolvedPath = realpath(line.get(), nullptr);
+ if (resolvedPath) {
+ aPolicy->AddDir(rdonly, resolvedPath);
+ free(resolvedPath);
+ }
+ } while (more);
+}
+
+static void
+AddLdconfigPaths(SandboxBroker::Policy* aPolicy)
+{
+ nsAutoCString ldconfigPath(NS_LITERAL_CSTRING("/etc/ld.so.conf"));
+ AddPathsFromFile(aPolicy, ldconfigPath);
+}
+
SandboxBrokerPolicyFactory::SandboxBrokerPolicyFactory()
{
// Policy entries that are the same in every process go here, and
// are cached over the lifetime of the factory.
#if defined(MOZ_CONTENT_SANDBOX)
SandboxBroker::Policy* policy = new SandboxBroker::Policy;
policy->AddDir(rdwrcr, "/dev/shm");
// Write permssions
@@ -162,16 +254,17 @@ SandboxBrokerPolicyFactory::SandboxBroke
policy->AddDir(rdonly, "/var/tmp");
// Various places where fonts reside
policy->AddDir(rdonly, "/usr/X11R6/lib/X11/fonts");
policy->AddDir(rdonly, "/nix/store");
policy->AddDir(rdonly, "/run/host/fonts");
policy->AddDir(rdonly, "/run/host/user-fonts");
AddMesaSysfsPaths(policy);
+ AddLdconfigPaths(policy);
// Bug 1385715: NVIDIA PRIME support
policy->AddPath(rdonly, "/proc/modules");
#ifdef MOZ_PULSEAUDIO
// See bug 1384986 comment #1.
if (const auto xauth = PR_GetEnv("XAUTHORITY")) {
policy->AddPath(rdonly, xauth);