WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
0011-GTK-Add-API-for-web-process-filesystem-sandbox-exten.patch (text/plain), 39.73 KB, created by
Michael Catanzaro
on 2015-01-04 21:07:04 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Michael Catanzaro
Created:
2015-01-04 21:07:04 PST
Size:
39.73 KB
patch
obsolete
>From 77cb676f281a41c9c4e787f6ac93d1fea3321242 Mon Sep 17 00:00:00 2001 >From: Michael Catanzaro <mcatanzaro@igalia.com> >Date: Sun, 4 Jan 2015 23:05:24 -0600 >Subject: [PATCH] [GTK] Add API for web process filesystem sandbox extensions > >This makes it possible for a web extension to have limited access to the >filesystem. >--- > Source/WebKit2/ChangeLog | 30 ++ > .../Shared/WebProcessCreationParameters.cpp | 24 ++ > .../WebKit2/Shared/WebProcessCreationParameters.h | 9 + > .../Shared/linux/SeccompFilters/SyscallPolicy.cpp | 13 + > .../WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp | 72 ++++ > .../WebKit2/UIProcess/API/gtk/WebKitWebContext.h | 44 +++ > .../UIProcess/API/gtk/docs/webkit2gtk-sections.txt | 3 + > Source/WebKit2/UIProcess/WebContext.cpp | 43 +++ > Source/WebKit2/UIProcess/WebContext.h | 18 + > Tools/ChangeLog | 35 ++ > .../TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt | 4 + > .../Tests/WebKit2Gtk/TestSandboxExtensions.cpp | 375 +++++++++++++++++++++ > .../Tests/WebKit2Gtk/WebExtensionTest.cpp | 30 ++ > 13 files changed, 700 insertions(+) > create mode 100644 Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSandboxExtensions.cpp > >diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog >index e99bdc2..56fdd5b 100644 >--- a/Source/WebKit2/ChangeLog >+++ b/Source/WebKit2/ChangeLog >@@ -1,5 +1,35 @@ > 2015-01-04 Michael Catanzaro <mcatanzaro@igalia.com> > >+ [GTK] Add API for web process filesystem sandbox extensions >+ https://bugs.webkit.org/show_bug.cgi?id=140073 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This makes it possible for a web extension to have limited access to the >+ filesystem. >+ >+ * Shared/WebProcessCreationParameters.cpp: >+ (WebKit::WebProcessCreationParameters::encode): >+ (WebKit::WebProcessCreationParameters::decode): >+ * Shared/WebProcessCreationParameters.h: >+ * Shared/linux/SeccompFilters/SyscallPolicy.cpp: >+ (WebKit::SyscallPolicy::addDefaultWebProcessPolicy): >+ * UIProcess/API/gtk/WebKitWebContext.cpp: >+ (webkit_web_context_add_filesystem_sandbox_extension): >+ * UIProcess/API/gtk/WebKitWebContext.h: >+ * UIProcess/API/gtk/docs/webkit2gtk-sections.txt: >+ * UIProcess/WebContext.cpp: >+ (WebKit::WebContext::createNewWebProcess): >+ (WebKit::WebContext::addExtraDirectoryReadPermission): >+ (WebKit::WebContext::addExtraDirectoryWritePermission): >+ (WebKit::WebContext::addExtraDirectoryReadAndWritePermission): >+ (WebKit::WebContext::addExtraFileReadPermission): >+ (WebKit::WebContext::addExtraFileWritePermission): >+ (WebKit::WebContext::addExtraFileReadAndWritePermission): >+ * UIProcess/WebContext.h: >+ >+2015-01-04 Michael Catanzaro <mcatanzaro@igalia.com> >+ > [GTK] Add seccomp filters support > https://bugs.webkit.org/show_bug.cgi?id=110014 > >diff --git a/Source/WebKit2/Shared/WebProcessCreationParameters.cpp b/Source/WebKit2/Shared/WebProcessCreationParameters.cpp >index 55979a0..1793204 100644 >--- a/Source/WebKit2/Shared/WebProcessCreationParameters.cpp >+++ b/Source/WebKit2/Shared/WebProcessCreationParameters.cpp >@@ -140,6 +140,15 @@ void WebProcessCreationParameters::encode(IPC::ArgumentEncoder& encoder) const > encoder << hasSelectionServices; > encoder << hasRichContentServices; > #endif >+ >+#if ENABLE(SECCOMP_FILTERS) >+ encoder << extraDirectoryReadPermissions; >+ encoder << extraDirectoryWritePermissions; >+ encoder << extraDirectoryReadAndWritePermissions; >+ encoder << extraFileReadPermissions; >+ encoder << extraFileWritePermissions; >+ encoder << extraFileReadAndWritePermissions; >+#endif > } > > bool WebProcessCreationParameters::decode(IPC::ArgumentDecoder& decoder, WebProcessCreationParameters& parameters) >@@ -296,6 +305,21 @@ bool WebProcessCreationParameters::decode(IPC::ArgumentDecoder& decoder, WebProc > return false; > #endif > >+#if ENABLE(SECCOMP_FILTERS) >+ if (!decoder.decode(parameters.extraDirectoryReadPermissions)) >+ return false; >+ if (!decoder.decode(parameters.extraDirectoryWritePermissions)) >+ return false; >+ if (!decoder.decode(parameters.extraDirectoryReadAndWritePermissions)) >+ return false; >+ if (!decoder.decode(parameters.extraFileReadPermissions)) >+ return false; >+ if (!decoder.decode(parameters.extraFileWritePermissions)) >+ return false; >+ if (!decoder.decode(parameters.extraFileReadAndWritePermissions)) >+ return false; >+#endif >+ > return true; > } > >diff --git a/Source/WebKit2/Shared/WebProcessCreationParameters.h b/Source/WebKit2/Shared/WebProcessCreationParameters.h >index ee1acb6..aa7624f 100644 >--- a/Source/WebKit2/Shared/WebProcessCreationParameters.h >+++ b/Source/WebKit2/Shared/WebProcessCreationParameters.h >@@ -163,6 +163,15 @@ struct WebProcessCreationParameters { > bool hasSelectionServices; > bool hasRichContentServices; > #endif >+ >+#if ENABLE(SECCOMP_FILTERS) >+ Vector<String> extraDirectoryReadPermissions; >+ Vector<String> extraDirectoryWritePermissions; >+ Vector<String> extraDirectoryReadAndWritePermissions; >+ Vector<String> extraFileReadPermissions; >+ Vector<String> extraFileWritePermissions; >+ Vector<String> extraFileReadAndWritePermissions; >+#endif > }; > > } // namespace WebKit >diff --git a/Source/WebKit2/Shared/linux/SeccompFilters/SyscallPolicy.cpp b/Source/WebKit2/Shared/linux/SeccompFilters/SyscallPolicy.cpp >index 4cb1a0f..022bf05 100644 >--- a/Source/WebKit2/Shared/linux/SeccompFilters/SyscallPolicy.cpp >+++ b/Source/WebKit2/Shared/linux/SeccompFilters/SyscallPolicy.cpp >@@ -130,6 +130,19 @@ void SyscallPolicy::addDefaultWebProcessPolicy(const WebProcessCreationParameter > addDirectoryPermission(removeTrailingSlash(parameters.cookiePersistentStoragePath), ReadAndWrite); > #endif > >+ for (const String& path : parameters.extraDirectoryReadPermissions) >+ addDirectoryPermission(path, Read); >+ for (const String& path : parameters.extraDirectoryWritePermissions) >+ addDirectoryPermission(path, Write); >+ for (const String& path : parameters.extraDirectoryReadAndWritePermissions) >+ addDirectoryPermission(path, ReadAndWrite); >+ for (const String& path : parameters.extraFileReadPermissions) >+ addFilePermission(path, Read); >+ for (const String& path : parameters.extraFileWritePermissions) >+ addFilePermission(path, Write); >+ for (const String& path : parameters.extraFileReadAndWritePermissions) >+ addFilePermission(path, ReadAndWrite); >+ > // The root policy will block access to any directory or > // file unless white listed bellow or by platform. > addDirectoryPermission(ASCIILiteral("/"), NotAllowed); >diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp >index ed416e4..582961e 100644 >--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp >+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp >@@ -1086,6 +1086,78 @@ WebKitProcessModel webkit_web_context_get_process_model(WebKitWebContext* contex > return toWebKitProcessModel(context->priv->context->processModel()); > } > >+/** >+ * webkit_web_context_add_filesystem_sandbox_extension: >+ * @context: the #WebKitWebContext >+ * @path: the file or directory to grant access to >+ * @permission: a #WebKitFilesystemPermission >+ * @permission_type: a #WebKitFilesystemPermissionType >+ * >+ * Adds a path to the web process sandbox's whitelist. The web process will be >+ * granted read, write, or both read and write access to @path, as determined by >+ * @permission. Use this function to grant your web extension access to the >+ * filesystem. If the web process sandbox is enabled and the web process >+ * attempts to access a file that is not whitelisted using a function like >+ * open(), the call will fail. >+ * >+ * The new permission will be granted only to web processes that have not yet >+ * been created. #WebKitWebContext::initialize-web-extensions signals the last >+ * possible opportunity to use this function before the first web process is >+ * created. >+ * >+ * Since: 2.8 >+ */ >+void webkit_web_context_add_filesystem_sandbox_extension(WebKitWebContext* context, const gchar* path, WebKitFilesystemPermission permission, WebKitFilesystemPermissionType permission_type) >+{ >+ g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); >+ >+#if ENABLE(SECCOMP_FILTERS) >+ GUniquePtr<char> filterPath(g_strdup(path)); >+ if (g_str_has_suffix(path, G_DIR_SEPARATOR_S)) { >+ if (permission_type == WEBKIT_FILESYSTEM_PERMISSION_TYPE_DIRECTORY) { >+ filterPath.get()[strlen(path) - 1] = '\0'; >+ } else { >+ g_assert(permission_type == WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE); >+ g_error("File filter %s should not end with a directory separator", path); >+ return; >+ } >+ } >+ >+ switch (permission) { >+ case WEBKIT_FILESYSTEM_PERMISSION_READ: >+ if (permission_type == WEBKIT_FILESYSTEM_PERMISSION_TYPE_DIRECTORY) >+ context->priv->context->addExtraDirectoryReadPermission(filterPath.get()); >+ else if (permission_type == WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE) >+ context->priv->context->addExtraFileReadPermission(filterPath.get()); >+ else >+ g_assert_not_reached(); >+ break; >+ case WEBKIT_FILESYSTEM_PERMISSION_WRITE: >+ if (permission_type == WEBKIT_FILESYSTEM_PERMISSION_TYPE_DIRECTORY) >+ context->priv->context->addExtraDirectoryWritePermission(filterPath.get()); >+ else if (permission_type == WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE) >+ context->priv->context->addExtraFileWritePermission(filterPath.get()); >+ else >+ g_assert_not_reached(); >+ break; >+ case WEBKIT_FILESYSTEM_PERMISSION_READ_AND_WRITE: >+ if (permission_type == WEBKIT_FILESYSTEM_PERMISSION_TYPE_DIRECTORY) >+ context->priv->context->addExtraDirectoryReadAndWritePermission(filterPath.get()); >+ else if (permission_type == WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE) >+ context->priv->context->addExtraFileReadAndWritePermission(filterPath.get()); >+ else >+ g_assert_not_reached(); >+ break; >+ default: >+ g_assert_not_reached(); >+ } >+#else >+ UNUSED_PARAM(path); >+ UNUSED_PARAM(permission); >+ UNUSED_PARAM(permission_type); >+#endif >+} >+ > WebKitDownload* webkitWebContextGetOrCreateDownload(DownloadProxy* downloadProxy) > { > GRefPtr<WebKitDownload> download = downloadsMap().get(downloadProxy); >diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h >index 8c428c2..48f0348 100644 >--- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h >+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h >@@ -62,6 +62,44 @@ typedef enum { > } WebKitCacheModel; > > /** >+ * WebKitFilesystemPermission: >+ * @WEBKIT_FILESYSTEM_PERMISSION_READ: Grant the web process read access to a >+ * file or directory. >+ * @WEBKIT_FILESYSTEM_PERMISSION_WRITE: Grant the web process write access to a >+ * file or directory. For directory permissions (but not for file >+ * permissions), this includes the ability to create new files in the >+ * directory. >+ * @WEBKIT_FILESYSTEM_PERMISSION_READ_AND_WRITE: Grant the web process both read >+ * and write access to a file or directory. >+ * >+ * Enum values used to denote the permissions the web process should have for a >+ * file or directory. >+ * >+ * Since: 2.8 >+ */ >+typedef enum { >+ WEBKIT_FILESYSTEM_PERMISSION_READ, >+ WEBKIT_FILESYSTEM_PERMISSION_WRITE, >+ WEBKIT_FILESYSTEM_PERMISSION_READ_AND_WRITE >+} WebKitFilesystemPermission; >+ >+/** >+ * WebKitFilesystemPermissionType: >+ * @WEBKIT_FILESYSTEM_PERMISSION_TYPE_DIRECTORY: Grant the web process access to >+ * an entire directory, including all subdirectories. >+ * @WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE: Grant the web process access to a >+ * single file. The file must already exist. >+ * >+ * Enum values used to provide the web process with access to the filesystem. >+ * >+ * Since: 2.8 >+ */ >+typedef enum { >+ WEBKIT_FILESYSTEM_PERMISSION_TYPE_DIRECTORY, >+ WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE >+} WebKitFilesystemPermissionType; >+ >+/** > * WebKitProcessModel: > * @WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS: Use a single process to > * perform content rendering. The process is shared among all the >@@ -231,6 +269,12 @@ webkit_web_context_set_web_extensions_initialization_user_data > GVariant *user_data); > > WEBKIT_API void >+webkit_web_context_add_filesystem_sandbox_extension (WebKitWebContext *context, >+ const gchar *path, >+ WebKitFilesystemPermission permission, >+ WebKitFilesystemPermissionType permission_type); >+ >+WEBKIT_API void > webkit_web_context_prefetch_dns (WebKitWebContext *context, > const gchar *hostname); > >diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt >index f366d0a..0051c03 100644 >--- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt >+++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt >@@ -25,6 +25,8 @@ WEBKIT_DEPRECATED_FOR > <TITLE>WebKitWebContext</TITLE> > WebKitWebContext > WebKitCacheModel >+WebKitFilesystemPermission >+WebKitFilesystemPermissionType > WebKitProcessModel > WebKitTLSErrorsPolicy > webkit_web_context_get_default >@@ -50,6 +52,7 @@ webkit_web_context_set_tls_errors_policy > webkit_web_context_get_tls_errors_policy > webkit_web_context_set_web_extensions_directory > webkit_web_context_set_web_extensions_initialization_user_data >+webkit_web_context_add_filesystem_sandbox_extension > webkit_web_context_prefetch_dns > webkit_web_context_set_disk_cache_directory > webkit_web_context_allow_tls_certificate_for_host >diff --git a/Source/WebKit2/UIProcess/WebContext.cpp b/Source/WebKit2/UIProcess/WebContext.cpp >index 3664392..48b9d7d 100644 >--- a/Source/WebKit2/UIProcess/WebContext.cpp >+++ b/Source/WebKit2/UIProcess/WebContext.cpp >@@ -706,6 +706,17 @@ WebProcessProxy& WebContext::createNewWebProcess() > RefPtr<API::Object> injectedBundleInitializationUserData = m_injectedBundleClient.getInjectedBundleInitializationUserData(this); > if (!injectedBundleInitializationUserData) > injectedBundleInitializationUserData = m_injectedBundleInitializationUserData; >+ >+#if ENABLE(SECCOMP_FILTERS) >+ // These may be set as late as during the call to m_injectedBundleClient.getInjectedBundleInitializationUserData(). >+ parameters.extraDirectoryReadPermissions = m_extraDirectoryReadPermissions; >+ parameters.extraDirectoryWritePermissions = m_extraDirectoryWritePermissions; >+ parameters.extraDirectoryReadAndWritePermissions = m_extraDirectoryReadAndWritePermissions; >+ parameters.extraFileReadPermissions = m_extraFileReadPermissions; >+ parameters.extraFileWritePermissions = m_extraFileWritePermissions; >+ parameters.extraFileReadAndWritePermissions = m_extraFileReadAndWritePermissions; >+#endif >+ > process->send(Messages::WebProcess::InitializeWebProcess(parameters, WebContextUserMessageEncoder(injectedBundleInitializationUserData.get(), process)), 0); > > #if PLATFORM(COCOA) >@@ -1493,4 +1504,36 @@ void WebContext::setMemoryCacheDisabled(bool disabled) > sendToAllProcesses(Messages::WebProcess::SetMemoryCacheDisabled(disabled)); > } > >+#if ENABLE(SECCOMP_FILTERS) >+void WebContext::addExtraDirectoryReadPermission(const char* path) >+{ >+ m_extraDirectoryReadPermissions.append(String::fromUTF8(path)); >+} >+ >+void WebContext::addExtraDirectoryWritePermission(const char* path) >+{ >+ m_extraDirectoryWritePermissions.append(String::fromUTF8(path)); >+} >+ >+void WebContext::addExtraDirectoryReadAndWritePermission(const char* path) >+{ >+ m_extraDirectoryReadAndWritePermissions.append(String::fromUTF8(path)); >+} >+ >+void WebContext::addExtraFileReadPermission(const char* path) >+{ >+ m_extraFileReadPermissions.append(String::fromUTF8(path)); >+} >+ >+void WebContext::addExtraFileWritePermission(const char* path) >+{ >+ m_extraFileWritePermissions.append(String::fromUTF8(path)); >+} >+ >+void WebContext::addExtraFileReadAndWritePermission(const char* path) >+{ >+ m_extraFileReadAndWritePermissions.append(String::fromUTF8(path)); >+} >+#endif >+ > } // namespace WebKit >diff --git a/Source/WebKit2/UIProcess/WebContext.h b/Source/WebKit2/UIProcess/WebContext.h >index 329f98e..4be7e3b 100644 >--- a/Source/WebKit2/UIProcess/WebContext.h >+++ b/Source/WebKit2/UIProcess/WebContext.h >@@ -365,6 +365,15 @@ public: > return m_processSuppressionDisabledForPageCounter.token<ProcessSuppressionDisabledTokenType>(); > } > >+#if ENABLE(SECCOMP_FILTERS) >+ void addExtraDirectoryReadPermission(const char* path); >+ void addExtraDirectoryWritePermission(const char* path); >+ void addExtraDirectoryReadAndWritePermission(const char* path); >+ void addExtraFileReadPermission(const char* path); >+ void addExtraFileWritePermission(const char* path); >+ void addExtraFileReadAndWritePermission(const char* path); >+#endif >+ > private: > void platformInitialize(); > >@@ -527,6 +536,15 @@ private: > HTTPCookieAcceptPolicy m_initialHTTPCookieAcceptPolicy; > #endif > >+#if ENABLE(SECCOMP_FILTERS) >+ Vector<String> m_extraDirectoryReadPermissions; >+ Vector<String> m_extraDirectoryWritePermissions; >+ Vector<String> m_extraDirectoryReadAndWritePermissions; >+ Vector<String> m_extraFileReadPermissions; >+ Vector<String> m_extraFileWritePermissions; >+ Vector<String> m_extraFileReadAndWritePermissions; >+#endif >+ > #if PLATFORM(MAC) > RetainPtr<NSObject> m_enhancedAccessibilityObserver; > RetainPtr<NSObject> m_automaticTextReplacementNotificationObserver; >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index c07696f..c5d0ed0 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,5 +1,40 @@ > 2015-01-04 Michael Catanzaro <mcatanzaro@igalia.com> > >+ [GTK] Add API for web process filesystem sandbox extensions >+ https://bugs.webkit.org/show_bug.cgi?id=140073 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ New tests >+ >+ * TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt: >+ * TestWebKitAPI/Tests/WebKit2Gtk/TestSandboxExtensions.cpp: Added. >+ (clearAndDeleteFile): >+ (deleteFileIfPresent): >+ (deleteFile): >+ (createFileFromCurrentProcess): >+ (createFileFromWebProcess): >+ (ensureWebProcessFileCreationSucceeds): >+ (ensureWebProcessFileCreationFails): >+ (openFileFromWebProcess): >+ (ensureWebProcessFileOpenSucceeds): >+ (ensureWebProcessFileOpenFails): >+ (createWebExtensionProxy): >+ (testReadOnlyDirectorySandboxExtension): >+ (testWriteOnlyDirectorySandboxExtension): >+ (testReadAndWriteDirectorySandboxExtension): >+ (testReadOnlyFileSandboxExtension): >+ (testWriteOnlyFileSandboxExtension): >+ (testReadAndWriteFileSandboxExtension): >+ (testFileSandboxExtensionWithTrailingSlash): >+ (testFileSandboxExtensionForNonexistentFile): >+ (beforeAll): >+ (afterAll): >+ * TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp: >+ (methodCallCallback): >+ >+2015-01-04 Michael Catanzaro <mcatanzaro@igalia.com> >+ > [GTK] Enable seccomp filters by default > https://bugs.webkit.org/show_bug.cgi?id=140072 > >diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt >index 72ed45d..765646f 100644 >--- a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt >+++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/CMakeLists.txt >@@ -117,6 +117,10 @@ ADD_WK2_TEST(TestWebKitWebContext TestWebKitWebContext.cpp) > ADD_WK2_TEST(TestWebKitWebView TestWebKitWebView.cpp) > ADD_WK2_TEST(TestWebKitUserContentManager TestWebKitUserContentManager.cpp) > >+if (ENABLE_SECCOMP_FILTERS) >+ ADD_WK2_TEST(TestSandboxExtensions TestSandboxExtensions.cpp) >+endif () >+ > if (ATSPI_FOUND) > ADD_WK2_TEST(AccessibilityTestServer AccessibilityTestServer.cpp) > ADD_WK2_TEST(TestWebKitAccessibility TestWebKitAccessibility.cpp) >diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSandboxExtensions.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSandboxExtensions.cpp >new file mode 100644 >index 0000000..60596d2 >--- /dev/null >+++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestSandboxExtensions.cpp >@@ -0,0 +1,375 @@ >+/* >+ * Copyright (C) 2014 Igalia S.L. >+ * >+ * This library is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Lesser General Public >+ * License as published by the Free Software Foundation; either >+ * version 2,1 of the License, or (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ * Library General Public License for more details. >+ * >+ * You should have received a copy of the GNU Library General Public License >+ * along with this library; see the file COPYING.LIB. If not, write to >+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, >+ * Boston, MA 02110-1301, USA. >+ */ >+ >+#include "config.h" >+ >+#include "WebKitTestBus.h" >+#include "WebViewTest.h" >+#include <fcntl.h> >+#include <wtf/gobject/GRefPtr.h> >+ >+static WebKitTestBus* bus; >+ >+static void clearAndDeleteFile(GFile* file) >+{ >+ if (!file) >+ return; >+ >+ g_file_delete(file, nullptr, nullptr); >+ g_object_unref(file); >+} >+ >+class SeccompFiltersTest: public Test { >+public: >+ MAKE_GLIB_TEST_FIXTURE(SeccompFiltersTest); >+ >+ SeccompFiltersTest() >+ : m_mainLoop(g_main_loop_new(nullptr, TRUE)) >+ , m_webView(WEBKIT_WEB_VIEW(g_object_ref_sink(webkit_web_view_new_with_context(m_webContext.get())))) >+ { >+ } >+ >+ virtual ~SeccompFiltersTest() >+ { >+ clearAndDeleteFile(m_readOnlyFile); >+ clearAndDeleteFile(m_writeOnlyFile); >+ clearAndDeleteFile(m_readAndWriteFile); >+ clearAndDeleteFile(m_initiallyNonexistentFile); >+ >+ clearAndDeleteFile(m_readOnlyDirectory); >+ clearAndDeleteFile(m_writeOnlyDirectory); >+ clearAndDeleteFile(m_readAndWriteDirectory); >+ clearAndDeleteFile(m_unwhitelistedDirectory); >+ >+ g_object_unref(m_webView); >+ g_main_loop_unref(m_mainLoop); >+ } >+ >+ // Prohibit overrides because this is called when the web view is created >+ // in our constructor, before a derived class's vtable is ready. >+ void initializeWebExtensions() override final >+ { >+ // Can't use a tmp directory since it would be whitelisted. >+ GUniquePtr<char> unwhitelistedDirectoryPath(g_build_filename(g_get_user_data_dir(), "webkitgtk", "SeccompFiltersTest", nullptr)); >+ m_unwhitelistedDirectory = g_file_new_for_path(unwhitelistedDirectoryPath.get()); >+ GUniqueOutPtr<GError> error; >+ g_file_make_directory_with_parents(m_unwhitelistedDirectory, nullptr, &error.outPtr()); >+ if (error) >+ g_assert(g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_EXISTS)); >+ >+ GUniquePtr<char> readOnlyDirectoryPath(g_build_filename(unwhitelistedDirectoryPath.get(), "ReadOnlyDirectory", nullptr)); >+ m_readOnlyDirectory = g_file_new_for_path(readOnlyDirectoryPath.get()); >+ g_file_make_directory_with_parents(m_readOnlyDirectory, nullptr, &error.outPtr()); >+ if (error) >+ g_assert(g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_EXISTS)); >+ >+ GUniquePtr<char> writeOnlyDirectoryPath(g_build_filename(unwhitelistedDirectoryPath.get(), "WriteOnlyDirectory", nullptr)); >+ m_writeOnlyDirectory = g_file_new_for_path(writeOnlyDirectoryPath.get()); >+ g_file_make_directory_with_parents(m_writeOnlyDirectory, nullptr, &error.outPtr()); >+ if (error) >+ g_assert(g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_EXISTS)); >+ >+ GUniquePtr<char> tmp(g_build_filename(unwhitelistedDirectoryPath.get(), "ReadAndWriteDirectory", nullptr)); >+ // Make sure a trailing slash is ignored. >+ GUniquePtr<char> readAndWriteDirectoryPath(g_strdup_printf("%s" G_DIR_SEPARATOR_S, tmp.get())); >+ m_readAndWriteDirectory = g_file_new_for_path(readAndWriteDirectoryPath.get()); >+ g_file_make_directory_with_parents(m_readAndWriteDirectory, nullptr, &error.outPtr()); >+ if (error) >+ g_assert(g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_EXISTS)); >+ >+ GUniquePtr<char> readOnlyFilePath(g_build_filename(unwhitelistedDirectoryPath.get(), "ReadOnlyFile", nullptr)); >+ m_readOnlyFile = g_file_new_for_path(readOnlyFilePath.get()); >+ g_file_create(m_readOnlyFile, G_FILE_CREATE_NONE, nullptr, &error.outPtr()); >+ if (error) >+ g_assert(g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_EXISTS)); >+ >+ GUniquePtr<char> writeOnlyFilePath(g_build_filename(unwhitelistedDirectoryPath.get(), "WriteOnlyFile", nullptr)); >+ m_writeOnlyFile = g_file_new_for_path(writeOnlyFilePath.get()); >+ g_file_create(m_writeOnlyFile, G_FILE_CREATE_NONE, nullptr, &error.outPtr()); >+ if (error) >+ g_assert(g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_EXISTS)); >+ >+ GUniquePtr<char> readAndWriteFilePath(g_build_filename(unwhitelistedDirectoryPath.get(), "ReadAndWriteFile", nullptr)); >+ m_readAndWriteFile = g_file_new_for_path(readAndWriteFilePath.get()); >+ g_file_create(m_readAndWriteFile, G_FILE_CREATE_NONE, nullptr, &error.outPtr()); >+ if (error) >+ g_assert(g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_EXISTS)); >+ >+ GUniquePtr<char> initiallyNonexistentFilePath(g_build_filename(unwhitelistedDirectoryPath.get(), "NonexistentFile", nullptr)); >+ m_initiallyNonexistentFile = g_file_new_for_path(initiallyNonexistentFilePath.get()); >+ >+ webkit_web_context_add_filesystem_sandbox_extension(m_webContext.get(), readOnlyDirectoryPath.get(), >+ WEBKIT_FILESYSTEM_PERMISSION_READ, WEBKIT_FILESYSTEM_PERMISSION_TYPE_DIRECTORY); >+ webkit_web_context_add_filesystem_sandbox_extension(m_webContext.get(), writeOnlyDirectoryPath.get(), >+ WEBKIT_FILESYSTEM_PERMISSION_WRITE, WEBKIT_FILESYSTEM_PERMISSION_TYPE_DIRECTORY); >+ webkit_web_context_add_filesystem_sandbox_extension(m_webContext.get(), readAndWriteDirectoryPath.get(), >+ WEBKIT_FILESYSTEM_PERMISSION_READ_AND_WRITE, WEBKIT_FILESYSTEM_PERMISSION_TYPE_DIRECTORY); >+ webkit_web_context_add_filesystem_sandbox_extension(m_webContext.get(), readOnlyFilePath.get(), >+ WEBKIT_FILESYSTEM_PERMISSION_READ, WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE); >+ webkit_web_context_add_filesystem_sandbox_extension(m_webContext.get(), writeOnlyFilePath.get(), >+ WEBKIT_FILESYSTEM_PERMISSION_WRITE, WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE); >+ webkit_web_context_add_filesystem_sandbox_extension(m_webContext.get(), readAndWriteFilePath.get(), >+ WEBKIT_FILESYSTEM_PERMISSION_READ_AND_WRITE, WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE); >+ webkit_web_context_add_filesystem_sandbox_extension(m_webContext.get(), initiallyNonexistentFilePath.get(), >+ WEBKIT_FILESYSTEM_PERMISSION_READ_AND_WRITE, WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE); >+ >+ // Make sure a file permission has no effect on a directory. >+ webkit_web_context_add_filesystem_sandbox_extension(m_webContext.get(), readOnlyDirectoryPath.get(), >+ WEBKIT_FILESYSTEM_PERMISSION_WRITE, WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE); >+ >+ Test::initializeWebExtensions(); >+ } >+ >+ GFile* m_unwhitelistedDirectory = nullptr; >+ GFile* m_readOnlyDirectory = nullptr; >+ GFile* m_writeOnlyDirectory = nullptr; >+ GFile* m_readAndWriteDirectory = nullptr; >+ >+ GFile* m_readOnlyFile = nullptr; >+ GFile* m_writeOnlyFile = nullptr; >+ GFile* m_readAndWriteFile = nullptr; >+ GFile* m_initiallyNonexistentFile = nullptr; >+ >+ GMainLoop* m_mainLoop; >+ WebKitWebView* m_webView; >+}; >+ >+static void deleteFileIfPresent(GFile* file) >+{ >+ GUniqueOutPtr<GError> error; >+ g_file_delete(file, nullptr, &error.outPtr()); >+ if (error) >+ g_assert(g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_NOT_FOUND)); >+} >+ >+static void deleteFile(GFile* file) >+{ >+ GUniqueOutPtr<GError> error; >+ g_file_delete(file, nullptr, &error.outPtr()); >+ g_assert(!error); >+} >+ >+static void createFileFromCurrentProcess(GFile* file) >+{ >+ GUniqueOutPtr<GError> error; >+ g_file_create(file, G_FILE_CREATE_NONE, nullptr, &error.outPtr()); >+ g_assert(!error); >+} >+ >+static void createFileFromWebProcess(GFile* file, GDBusProxy* proxy) >+{ >+ const char* path = g_file_get_path(file); >+ GUniqueOutPtr<GError> error; >+ GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync( >+ proxy, >+ "CreateFile", >+ g_variant_new("(s)", path), >+ G_DBUS_CALL_FLAGS_NONE, >+ -1, 0, &error.outPtr())); >+ g_assert(!error); >+ g_assert(result); >+} >+ >+static void ensureWebProcessFileCreationSucceeds(GFile* file, GDBusProxy* proxy) >+{ >+ createFileFromWebProcess(file, proxy); >+ g_assert(g_file_query_exists(file, nullptr)); >+} >+ >+static void ensureWebProcessFileCreationFails(GFile* file, GDBusProxy* proxy) >+{ >+ createFileFromWebProcess(file, proxy); >+ g_assert(!g_file_query_exists(file, nullptr)); >+} >+ >+static int openFileFromWebProcess(GFile* file, int flags, GDBusProxy* proxy) >+{ >+ const char* path = g_file_get_path(file); >+ GUniqueOutPtr<GError> error; >+ GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync( >+ proxy, >+ "OpenFile", >+ g_variant_new("(si)", path, flags), >+ G_DBUS_CALL_FLAGS_NONE, >+ -1, 0, &error.outPtr())); >+ g_assert(!error); >+ g_assert(result); >+ >+ int ret; >+ g_variant_get(result.get(), "(i)", &ret); >+ return ret; >+} >+ >+static void ensureWebProcessFileOpenSucceeds(GFile* file, int flags, GDBusProxy* proxy) >+{ >+ g_assert_cmpint(openFileFromWebProcess(file, flags, proxy), >=, 0); >+} >+ >+static void ensureWebProcessFileOpenFails(GFile* file, int flags, GDBusProxy* proxy) >+{ >+ g_assert_cmpint(openFileFromWebProcess(file, flags, proxy), ==, -1); >+} >+ >+static GRefPtr<GDBusProxy> createWebExtensionProxy(SeccompFiltersTest* test) >+{ >+ GUniquePtr<char> extensionBusName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", Test::s_webExtensionID)); >+ return adoptGRef(bus->createProxy(extensionBusName.get(), >+ "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", test->m_mainLoop)); >+} >+ >+static void testReadOnlyDirectorySandboxExtension(SeccompFiltersTest* test, gconstpointer) >+{ >+ GRefPtr<GDBusProxy> proxy = createWebExtensionProxy(test); >+ >+ GUniquePtr<char> readOnlyDirectoryPath(g_file_get_path(test->m_readOnlyDirectory)); >+ GUniquePtr<char> fileInReadOnlyDirectoryPath(g_build_filename(readOnlyDirectoryPath.get(), "file", nullptr)); >+ GRefPtr<GFile> fileInReadOnlyDirectory = adoptGRef(g_file_new_for_path(fileInReadOnlyDirectoryPath.get())); >+ >+ deleteFileIfPresent(fileInReadOnlyDirectory.get()); >+ >+ ensureWebProcessFileCreationFails(fileInReadOnlyDirectory.get(), proxy.get()); >+ createFileFromCurrentProcess(fileInReadOnlyDirectory.get()); >+ >+ ensureWebProcessFileOpenSucceeds(fileInReadOnlyDirectory.get(), O_RDONLY, proxy.get()); >+ ensureWebProcessFileOpenFails(fileInReadOnlyDirectory.get(), O_WRONLY, proxy.get()); >+ ensureWebProcessFileOpenFails(fileInReadOnlyDirectory.get(), O_RDWR, proxy.get()); >+ >+ deleteFile(fileInReadOnlyDirectory.get()); >+} >+ >+static void testWriteOnlyDirectorySandboxExtension(SeccompFiltersTest* test, gconstpointer) >+{ >+ GRefPtr<GDBusProxy> proxy = createWebExtensionProxy(test); >+ >+ GUniquePtr<char> writeOnlyDirectoryPath(g_file_get_path(test->m_writeOnlyDirectory)); >+ GUniquePtr<char> fileInWriteOnlyDirectoryPath(g_build_filename(writeOnlyDirectoryPath.get(), "file", nullptr)); >+ GRefPtr<GFile> fileInWriteOnlyDirectory = adoptGRef(g_file_new_for_path(fileInWriteOnlyDirectoryPath.get())); >+ >+ deleteFileIfPresent(fileInWriteOnlyDirectory.get()); >+ >+ ensureWebProcessFileCreationSucceeds(fileInWriteOnlyDirectory.get(), proxy.get()); >+ ensureWebProcessFileOpenFails(fileInWriteOnlyDirectory.get(), O_RDONLY, proxy.get()); >+ ensureWebProcessFileOpenSucceeds(fileInWriteOnlyDirectory.get(), O_WRONLY, proxy.get()); >+ ensureWebProcessFileOpenFails(fileInWriteOnlyDirectory.get(), O_RDWR, proxy.get()); >+ >+ deleteFile(fileInWriteOnlyDirectory.get()); >+} >+ >+static void testReadAndWriteDirectorySandboxExtension(SeccompFiltersTest* test, gconstpointer) >+{ >+ GRefPtr<GDBusProxy> proxy = createWebExtensionProxy(test); >+ >+ GUniquePtr<char> readAndWriteDirectoryPath(g_file_get_path(test->m_readAndWriteDirectory)); >+ GUniquePtr<char> fileInReadAndWriteDirectoryPath(g_build_filename(readAndWriteDirectoryPath.get(), "file", nullptr)); >+ GRefPtr<GFile> fileInReadAndWriteDirectory = adoptGRef(g_file_new_for_path(fileInReadAndWriteDirectoryPath.get())); >+ >+ deleteFileIfPresent(fileInReadAndWriteDirectory.get()); >+ >+ ensureWebProcessFileCreationSucceeds(fileInReadAndWriteDirectory.get(), proxy.get()); >+ ensureWebProcessFileOpenSucceeds(fileInReadAndWriteDirectory.get(), O_RDONLY, proxy.get()); >+ ensureWebProcessFileOpenSucceeds(fileInReadAndWriteDirectory.get(), O_WRONLY, proxy.get()); >+ ensureWebProcessFileOpenSucceeds(fileInReadAndWriteDirectory.get(), O_RDWR, proxy.get()); >+ >+ deleteFile(fileInReadAndWriteDirectory.get()); >+} >+ >+static void testReadOnlyFileSandboxExtension(SeccompFiltersTest* test, gconstpointer) >+{ >+ GRefPtr<GDBusProxy> proxy = createWebExtensionProxy(test); >+ >+ ensureWebProcessFileOpenSucceeds(test->m_readOnlyFile, O_RDONLY, proxy.get()); >+ ensureWebProcessFileOpenFails(test->m_readOnlyFile, O_WRONLY, proxy.get()); >+ ensureWebProcessFileOpenFails(test->m_readOnlyFile, O_RDWR, proxy.get()); >+ >+ deleteFile(test->m_readOnlyFile); >+} >+ >+static void testWriteOnlyFileSandboxExtension(SeccompFiltersTest* test, gconstpointer) >+{ >+ GRefPtr<GDBusProxy> proxy = createWebExtensionProxy(test); >+ >+ ensureWebProcessFileOpenFails(test->m_writeOnlyFile, O_RDONLY, proxy.get()); >+ ensureWebProcessFileOpenSucceeds(test->m_writeOnlyFile, O_WRONLY, proxy.get()); >+ ensureWebProcessFileOpenFails(test->m_writeOnlyFile, O_RDWR, proxy.get()); >+ >+ deleteFile(test->m_writeOnlyFile); >+} >+ >+static void testReadAndWriteFileSandboxExtension(SeccompFiltersTest* test, gconstpointer) >+{ >+ GRefPtr<GDBusProxy> proxy = createWebExtensionProxy(test); >+ >+ ensureWebProcessFileOpenSucceeds(test->m_readAndWriteFile, O_RDONLY, proxy.get()); >+ ensureWebProcessFileOpenSucceeds(test->m_readAndWriteFile, O_WRONLY, proxy.get()); >+ ensureWebProcessFileOpenSucceeds(test->m_readAndWriteFile, O_RDWR, proxy.get()); >+ >+ deleteFile(test->m_readAndWriteFile); >+} >+ >+static void testFileSandboxExtensionWithTrailingSlash(SeccompFiltersTest* test, gconstpointer) >+{ >+ if (g_test_subprocess()) { >+ // This should emit a warning, failing the test. >+ webkit_web_context_add_filesystem_sandbox_extension(test->m_webContext.get(), "fail" G_DIR_SEPARATOR_S, >+ WEBKIT_FILESYSTEM_PERMISSION_READ_AND_WRITE, WEBKIT_FILESYSTEM_PERMISSION_TYPE_FILE); >+ } >+ >+ g_test_trap_subprocess(nullptr, 0, static_cast<GTestSubprocessFlags>(0)); >+ g_test_trap_assert_failed(); >+ g_test_trap_assert_stderr("*File filter fail" G_DIR_SEPARATOR_S " should not end with a directory separator*"); >+} >+ >+static void testFileSandboxExtensionForNonexistentFile(SeccompFiltersTest* test, gconstpointer) >+{ >+ GRefPtr<GDBusProxy> proxy = createWebExtensionProxy(test); >+ >+ deleteFileIfPresent(test->m_initiallyNonexistentFile); >+ ensureWebProcessFileOpenFails(test->m_initiallyNonexistentFile, O_RDWR, proxy.get()); >+ >+ // For whatever reason, a file sandbox extension will never allow access to >+ // a file that does not already exist. We may or may not want to change >+ // this. Test it to ensure the behavior doesn't change on us unexpectedly. >+ ensureWebProcessFileCreationFails(test->m_initiallyNonexistentFile, proxy.get()); >+ >+ createFileFromCurrentProcess(test->m_initiallyNonexistentFile); >+ ensureWebProcessFileOpenSucceeds(test->m_initiallyNonexistentFile, O_RDWR, proxy.get()); >+ >+ deleteFile(test->m_initiallyNonexistentFile); >+} >+ >+void beforeAll() >+{ >+ bus = new WebKitTestBus(); >+ if (!bus->run()) >+ return; >+ >+ SeccompFiltersTest::add("WebKitWebContext", "directory-sandbox-extension-r", testReadOnlyDirectorySandboxExtension); >+ SeccompFiltersTest::add("WebKitWebContext", "directory-sandbox-extension-w", testWriteOnlyDirectorySandboxExtension); >+ SeccompFiltersTest::add("WebKitWebContext", "directory-sandbox-extension-rw", testReadAndWriteDirectorySandboxExtension); >+ SeccompFiltersTest::add("WebKitWebContext", "file-sandbox-extension-r", testReadOnlyFileSandboxExtension); >+ SeccompFiltersTest::add("WebKitWebContext", "file-sandbox-extension-w", testWriteOnlyFileSandboxExtension); >+ SeccompFiltersTest::add("WebKitWebContext", "file-sandbox-extension-rw", testReadAndWriteFileSandboxExtension); >+ SeccompFiltersTest::add("WebKitWebContext", "file-sandbox-extension-trailing-slash", testFileSandboxExtensionWithTrailingSlash); >+ SeccompFiltersTest::add("WebKitWebContext", "file-sandbox-extension-nonexistent-file", testFileSandboxExtensionForNonexistentFile); >+} >+ >+void afterAll() >+{ >+ delete bus; >+} >diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp >index fd09596..7919a95 100644 >--- a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp >+++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/WebExtensionTest.cpp >@@ -21,7 +21,9 @@ > > #include <JavaScriptCore/JSContextRef.h> > #include <JavaScriptCore/JSRetainPtr.h> >+#include <fcntl.h> > #include <gio/gio.h> >+#include <glib/gstdio.h> > #include <stdlib.h> > #include <string.h> > #include <webkit2/webkit-web-extension.h> >@@ -54,6 +56,14 @@ static const char introspectionXML[] = > " <method name='GetProcessIdentifier'>" > " <arg type='u' name='identifier' direction='out'/>" > " </method>" >+ " <method name='CreateFile'>" >+ " <arg type='s' name='path' direction='in'/>" >+ " </method>" >+ " <method name='OpenFile'>" >+ " <arg type='s' name='pathname' direction='in'/>" >+ " <arg type='i' name='flags' direction='in'/>" >+ " <arg type='i' name='result' direction='out'/>" >+ " </method>" > " <signal name='DocumentLoaded'/>" > " <signal name='URIChanged'>" > " <arg type='s' name='uri' direction='out'/>" >@@ -303,6 +313,26 @@ static void methodCallCallback(GDBusConnection* connection, const char* sender, > } else if (!g_strcmp0(methodName, "GetProcessIdentifier")) { > g_dbus_method_invocation_return_value(invocation, > g_variant_new("(u)", static_cast<guint32>(getCurrentProcessID()))); >+ } else if (!g_strcmp0(methodName, "CreateFile")) { >+ const char* path; >+ g_variant_get(parameters, "(&s)", &path); >+ GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path)); >+ GUniqueOutPtr<GError> error; >+ g_file_create(file.get(), G_FILE_CREATE_NONE, nullptr, &error.outPtr()); >+ if (error) >+ g_assert(!g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_EXISTS)); >+ g_dbus_method_invocation_return_value(invocation, nullptr); >+ } else if (!g_strcmp0(methodName, "OpenFile")) { >+ const char* pathname; >+ int flags; >+ g_variant_get(parameters, "(&si)", &pathname, &flags); >+ int ret = g_open(pathname, flags, 0); >+ if (ret >= 0) { >+ GUniqueOutPtr<GError> error; >+ g_close(ret, &error.outPtr()); >+ g_assert(!error); >+ } >+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", ret)); > } > } > >-- >2.1.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 140073
: 243962