#include "config.h"
#include "SyscallPolicy.h"
#if ENABLE(SECCOMP_FILTERS)
#include "WebProcessCreationParameters.h"
#include <libgen.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
namespace WebKit {
static String removeTrailingSlash(const String& path)
{
if (path.endsWith('/'))
return path.left(path.length() - 1);
return path;
}
bool SyscallPolicy::hasPermissionForPath(const char* path, Permission permission) const
{
ASSERT(m_directoryPermission.contains("/"));
if (permission == NotAllowed)
return false;
char* basePath = strdup(path);
char* canonicalPath = canonicalize_file_name(basePath);
while (canonicalPath) {
struct stat pathStat;
if (stat(canonicalPath, &pathStat) == -1) {
free(basePath);
free(canonicalPath);
return false;
}
if (S_ISDIR(pathStat.st_mode))
break;
PermissionMap::const_iterator policy = m_filePermission.find(String(canonicalPath));
if (policy != m_filePermission.end()) {
free(basePath);
free(canonicalPath);
return (permission & policy->value) == permission;
}
free(canonicalPath);
canonicalPath = 0;
}
while (!canonicalPath) {
char* currentBaseDirectory = dirname(basePath);
canonicalPath = canonicalize_file_name(currentBaseDirectory);
}
PermissionMap::const_iterator policy = m_directoryPermission.find(String(canonicalPath));
while (policy == m_directoryPermission.end()) {
char* currentBaseDirectory = dirname(canonicalPath);
policy = m_directoryPermission.find(String(currentBaseDirectory));
}
free(basePath);
free(canonicalPath);
return (permission & policy->value) == permission;
}
void SyscallPolicy::addFilePermission(const String& path, Permission permission)
{
ASSERT(!path.isEmpty() && path.startsWith('/') && !path.endsWith('/') && !path.contains("//"));
m_filePermission.set(path, permission);
}
void SyscallPolicy::addDirectoryPermission(const String& path, Permission permission)
{
ASSERT(path.startsWith('/') && !path.contains("//") && (path.length() == 1 || !path.endsWith('/')));
m_directoryPermission.set(path, permission);
}
void SyscallPolicy::addDefaultWebProcessPolicy(const WebProcessCreationParameters& parameters)
{
if (!parameters.applicationCacheDirectory.isEmpty())
addDirectoryPermission(removeTrailingSlash(parameters.applicationCacheDirectory), ReadAndWrite);
if (!parameters.databaseDirectory.isEmpty())
addDirectoryPermission(removeTrailingSlash(parameters.databaseDirectory), ReadAndWrite);
if (!parameters.localStorageDirectory.isEmpty())
addDirectoryPermission(removeTrailingSlash(parameters.localStorageDirectory), ReadAndWrite);
if (!parameters.diskCacheDirectory.isEmpty())
addDirectoryPermission(removeTrailingSlash(parameters.diskCacheDirectory), ReadAndWrite);
if (!parameters.cookieStorageDirectory.isEmpty())
addDirectoryPermission(removeTrailingSlash(parameters.cookieStorageDirectory), ReadAndWrite);
#if USE(SOUP)
if (!parameters.cookiePersistentStoragePath.isEmpty())
addDirectoryPermission(removeTrailingSlash(parameters.cookiePersistentStoragePath), ReadAndWrite);
#endif
addDirectoryPermission(ASCIILiteral("/"), NotAllowed);
addDirectoryPermission(ASCIILiteral("/lib"), Read);
addDirectoryPermission(ASCIILiteral("/usr/lib"), Read);
addDirectoryPermission(ASCIILiteral("/usr/share"), Read);
addDirectoryPermission(ASCIILiteral("/etc/ssl/certs"), Read);
addDirectoryPermission(ASCIILiteral("/etc/fonts"), Read);
addDirectoryPermission(ASCIILiteral("/var/cache/fontconfig"), Read);
addDirectoryPermission(ASCIILiteral("/dev"), ReadAndWrite);
addDirectoryPermission(ASCIILiteral("/tmp"), ReadAndWrite);
addDirectoryPermission(ASCIILiteral("/proc/") + String::number(getpid()), ReadAndWrite);
addDirectoryPermission(ASCIILiteral("/run/shm"), ReadAndWrite);
addFilePermission(ASCIILiteral("/etc/gai.conf"), Read);
addFilePermission(ASCIILiteral("/etc/host.conf"), Read);
addFilePermission(ASCIILiteral("/etc/hosts"), Read);
addFilePermission(ASCIILiteral("/etc/localtime"), Read);
addFilePermission(ASCIILiteral("/etc/nsswitch.conf"), Read);
addFilePermission(ASCIILiteral("/etc/resolv.conf"), Read);
addFilePermission(ASCIILiteral("/run/resolvconf/resolv.conf"), Read);
addFilePermission(ASCIILiteral("/etc/group"), Read);
addFilePermission(ASCIILiteral("/etc/passwd"), Read);
addFilePermission(ASCIILiteral("/etc/ld.so.cache"), Read);
addFilePermission(ASCIILiteral("/proc/cpuinfo"), Read);
addFilePermission(ASCIILiteral("/proc/filesystems"), Read);
addFilePermission(ASCIILiteral("/proc/meminfo"), Read);
addFilePermission(ASCIILiteral("/proc/stat"), Read);
addFilePermission(ASCIILiteral("/var/lib/dbus/machine-id"), Read);
char* homeDir = getenv("HOME");
if (homeDir) {
addFilePermission(String::fromUTF8(homeDir) + "/.Xauthority", Read);
addDirectoryPermission(String::fromUTF8(homeDir) + "/.local/share/mime", Read);
}
}
}
#endif // ENABLE(SECCOMP_FILTERS)