Skip to content

Commit

Permalink
Bug 1151607 - Step 1: Add Linux sandboxing hook for when child proces…
Browse files Browse the repository at this point in the history
…ses are still single-threaded. r=kang r=bent

This means that B2G plugin-container must (dynamically) link against
libmozsandbox in order to call into it before initializing Binder.
(Desktop Linux plugin-container already contains the sandbox code.)
  • Loading branch information
rmottola committed Aug 3, 2019
1 parent 19adaff commit e5e67f4
Show file tree
Hide file tree
Showing 12 changed files with 965 additions and 2 deletions.
570 changes: 570 additions & 0 deletions 9c9d8e38dfed864ea319301e93afb7796731186b.diff

Large diffs are not rendered by default.

253 changes: 253 additions & 0 deletions c915a3ef559c7cfad61a23779b5812f1fb3d907c.diff
@@ -0,0 +1,253 @@
diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf
index 96e37fd1090cb..ddcec77fdb82d 100644
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -922,6 +922,18 @@ DOMInterfaces = {
'headerFile': 'HTMLPropertiesCollection.h',
},

+'PushEvent': {
+ 'headerFile': 'ServiceWorkerEvents.h',
+ 'nativeType': 'mozilla::dom::workers::PushEvent',
+ 'workers': True
+},
+
+'PushMessageData': {
+ 'headerFile': 'ServiceWorkerEvents.h',
+ 'nativeType': 'mozilla::dom::workers::PushMessageData',
+ 'workers': True
+},
+
'Range': {
'nativeType': 'nsRange',
'binaryNames': {
diff --git a/dom/bindings/moz.build b/dom/bindings/moz.build
index 10304bac53412..55f27ab517e71 100644
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -111,6 +111,10 @@ if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
# This is needed for Window.webidl
DEFINES['HAVE_SIDEBAR'] = True

+
+if CONFIG['MOZ_SIMPLEPUSH']:
+ DEFINES['MOZ_SIMPLEPUSH'] = True
+
PYTHON_UNIT_TESTS += [
'mozwebidlcodegen/test/test_mozwebidlcodegen.py',
]
diff --git a/dom/interfaces/base/nsIServiceWorkerManager.idl b/dom/interfaces/base/nsIServiceWorkerManager.idl
index fc61a6ae86345..fc0790609c0e7 100644
--- a/dom/interfaces/base/nsIServiceWorkerManager.idl
+++ b/dom/interfaces/base/nsIServiceWorkerManager.idl
@@ -33,7 +33,7 @@ interface nsIServiceWorkerInfo : nsISupports
readonly attribute DOMString waitingCacheName;
};

-[scriptable, builtinclass, uuid(861b55e9-d6ac-47cf-a528-8590e9b44de6)]
+[scriptable, builtinclass, uuid(679732e6-b655-42a2-a787-f43fa322d79d)]
interface nsIServiceWorkerManager : nsISupports
{
/**
@@ -121,6 +121,8 @@ interface nsIServiceWorkerManager : nsISupports
// This is meant to be used only by about:serviceworkers. It returns an array
// of nsIServiceWorkerInfo.
nsIArray getAllRegistrations();
+
+ void sendPushEvent(in ACString scope, in DOMString data);
};

%{ C++
diff --git a/dom/webidl/PushEvent.webidl b/dom/webidl/PushEvent.webidl
new file mode 100644
index 0000000000000..806b786a59dfd
--- /dev/null
+++ b/dom/webidl/PushEvent.webidl
@@ -0,0 +1,19 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * https://w3c.github.io/push-api/
+ */
+
+[Constructor(DOMString type, optional PushEventInit eventInitDict), Exposed=ServiceWorker]
+interface PushEvent : ExtendableEvent {
+ readonly attribute PushMessageData data;
+};
+
+typedef USVString PushMessageDataInit;
+
+dictionary PushEventInit : ExtendableEventInit {
+ PushMessageDataInit data;
+};
\ No newline at end of file
diff --git a/dom/webidl/PushManager.webidl b/dom/webidl/PushManager.webidl
index 1e3a4de601b5d..b320b8b2afb77 100644
--- a/dom/webidl/PushManager.webidl
+++ b/dom/webidl/PushManager.webidl
@@ -2,15 +2,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* The origin of this IDL file is
+* https://w3c.github.io/push-api/
*/

-[NoInterfaceObject,
- NavigatorProperty="push",
- JSImplementation="@mozilla.org/push/PushManager;1",
- CheckPermissions="push",
- Pref="services.push.enabled"]
+[JSImplementation="@mozilla.org/push/PushManager;1",
+ Pref="dom.push.enabled"]
interface PushManager {
- DOMRequest register();
- DOMRequest unregister(DOMString pushEndpoint);
- DOMRequest registrations();
+ Promise<PushSubscription> subscribe();
+ Promise<PushSubscription?> getSubscription();
+ Promise<PushPermissionStatus> hasPermission();
+
+ // We need a setter in the bindings so that the C++ can use it,
+ // but we don't want it exposed to client JS. WebPushMethodHider
+ // always returns false.
+ [Func="ServiceWorkerRegistration::WebPushMethodHider"] void setScope(DOMString scope);
+};
+
+enum PushPermissionStatus
+{
+ "granted",
+ "denied",
+ "default"
};
diff --git a/dom/webidl/PushMessageData.webidl b/dom/webidl/PushMessageData.webidl
new file mode 100644
index 0000000000000..16bd0ca87fdb4
--- /dev/null
+++ b/dom/webidl/PushMessageData.webidl
@@ -0,0 +1,17 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * https://w3c.github.io/push-api/
+ */
+
+[Exposed=ServiceWorker]
+interface PushMessageData
+{
+ ArrayBuffer arrayBuffer();
+ Blob blob();
+ object json();
+ USVString text();
+};
\ No newline at end of file
diff --git a/dom/webidl/PushSubscription.webidl b/dom/webidl/PushSubscription.webidl
new file mode 100644
index 0000000000000..236a8fb5add99
--- /dev/null
+++ b/dom/webidl/PushSubscription.webidl
@@ -0,0 +1,17 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this file,
+* You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* The origin of this IDL file is
+* https://w3c.github.io/push-api/
+*/
+
+[JSImplementation="@mozilla.org/push/PushSubscription;1",
+ Constructor(DOMString pushEndpoint, DOMString scope, DOMString pageURL), ChromeOnly]
+interface PushSubscription
+{
+ readonly attribute USVString endpoint;
+ readonly attribute DOMString subscriptionId;
+ Promise<boolean> unsubscribe();
+};
\ No newline at end of file
diff --git a/dom/webidl/ServiceWorkerContainer.webidl b/dom/webidl/ServiceWorkerContainer.webidl
index d162221a8c051..a28badf2f8361 100644
--- a/dom/webidl/ServiceWorkerContainer.webidl
+++ b/dom/webidl/ServiceWorkerContainer.webidl
@@ -27,7 +27,7 @@ interface ServiceWorkerContainer : EventTarget {
Promise<ServiceWorkerRegistration> getRegistration(optional USVString documentURL = "");

[Throws]
- Promise<sequence<ServiceWorkerRegistration>> getRegistrations();
+ Promise<sequence<ServiceWorkerRegistration>> getRegistrations();

attribute EventHandler oncontrollerchange;
attribute EventHandler onreloadpage;
diff --git a/dom/webidl/ServiceWorkerRegistration.webidl b/dom/webidl/ServiceWorkerRegistration.webidl
index a9b18481e261e..5f04198558c3f 100644
--- a/dom/webidl/ServiceWorkerRegistration.webidl
+++ b/dom/webidl/ServiceWorkerRegistration.webidl
@@ -23,3 +23,10 @@ interface ServiceWorkerRegistration : EventTarget {
// event
attribute EventHandler onupdatefound;
};
+
+partial interface ServiceWorkerRegistration {
+#ifndef MOZ_SIMPLEPUSH
+ [Throws, Pref="dom.push.enabled"]
+ readonly attribute PushManager pushManager;
+#endif
+};
diff --git a/dom/webidl/SimplePushManager.webidl b/dom/webidl/SimplePushManager.webidl
index ab99ca36d4324..b1f97ad95724d 100644
--- a/dom/webidl/SimplePushManager.webidl
+++ b/dom/webidl/SimplePushManager.webidl
@@ -8,7 +8,7 @@
JSImplementation="@mozilla.org/push/PushManager;1",
CheckPermissions="push",
Pref="services.push.enabled"]
-interface PushManager {
+interface SimplePushManager {
DOMRequest register();
DOMRequest unregister(DOMString pushEndpoint);
DOMRequest registrations();
diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
index a5897aff259f7..a8d3f7578d7c3 100644
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -11,6 +11,7 @@ GENERATED_WEBIDL_FILES = [
PREPROCESSED_WEBIDL_FILES = [
'HTMLMediaElement.webidl',
'Navigator.webidl',
+ 'ServiceWorkerRegistration.webidl',
'Window.webidl',
]

@@ -381,7 +382,6 @@ WEBIDL_FILES = [
'ServiceWorker.webidl',
'ServiceWorkerContainer.webidl',
'ServiceWorkerGlobalScope.webidl',
- 'ServiceWorkerRegistration.webidl',
'SettingChangeNotification.webidl',
'SettingsManager.webidl',
'ShadowRoot.webidl',
@@ -661,9 +661,16 @@ if CONFIG['MOZ_B2G_BT']:
]

if CONFIG['MOZ_SIMPLEPUSH']:
- WEBIDL_FILES += SimplePushManager.webidl
+ WEBIDL_FILES += [
+ 'SimplePushManager.webidl'
+ ]
else:
WEBIDL_FILES += [
+ 'PushEvent.webidl',
+ 'PushManager.webidl',
+ 'PushManager.webidl',
+ 'PushMessageData.webidl',
+ 'PushSubscription.webidl',
]

if CONFIG['MOZ_NFC']:
3 changes: 3 additions & 0 deletions dom/ipc/ContentChild.cpp
Expand Up @@ -2779,6 +2779,9 @@ NS_EXPORT void
AfterNuwaFork()
{
SetCurrentProcessPrivileges(base::PRIVILEGES_DEFAULT);
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
mozilla::SandboxEarlyInit(XRE_GetProcessType(), /* isNuwa: */ false);
#endif
}

#endif // MOZ_NUWA_PROCESS
Expand Down
2 changes: 1 addition & 1 deletion ipc/app/moz.build
Expand Up @@ -62,7 +62,7 @@ if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
'sha256.c',
]

if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] == 'Linux':
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] in ('Linux', 'Android'):
USE_LIBS += [
'mozsandbox',
]
Expand Down
16 changes: 15 additions & 1 deletion ipc/contentproc/plugin-container.cpp
Expand Up @@ -54,7 +54,11 @@
"Goanna:MozillaRntimeMain", __VA_ARGS__)) \
: (void)0 )

#endif
# ifdef MOZ_CONTENT_SANDBOX
# include "mozilla/Sandbox.h"
# endif

#endif // MOZ_WIDGET_GONK

#ifdef MOZ_NUWA_PROCESS
#include <binder/ProcessState.h>
Expand Down Expand Up @@ -155,6 +159,16 @@ content_process_main(int argc, char* argv[])
}
#endif

#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
// This has to happen while we're still single-threaded, and on
// B2G that means before the Android Binder library is
// initialized. Additional special handling is needed for Nuwa:
// the Nuwa process itself needs to be unsandboxed, and the same
// single-threadedness condition applies to its children; see also
// AfterNuwaFork().
mozilla::SandboxEarlyInit(XRE_GetProcessType(), isNuwa);
#endif

#ifdef MOZ_WIDGET_GONK
// This creates a ThreadPool for binder ipc. A ThreadPool is necessary to
// receive binder calls, though not necessary to send binder calls.
Expand Down
7 changes: 7 additions & 0 deletions security/sandbox/linux/Sandbox.cpp
Expand Up @@ -8,6 +8,7 @@
#include "SandboxFilter.h"
#include "SandboxInternal.h"
#include "SandboxLogging.h"
#include "SandboxUtil.h"

#include <unistd.h>
#include <stdio.h>
Expand Down Expand Up @@ -421,6 +422,12 @@ SetCurrentProcessSandbox(SandboxType aType)
BroadcastSetThreadSandbox(aType);
}

void
SandboxEarlyInit(GeckoProcessType aType, bool aIsNuwa)
{
MOZ_RELEASE_ASSERT(IsSingleThreaded());
}

#ifdef MOZ_CONTENT_SANDBOX
/**
* Starts the seccomp sandbox for a content process. Should be called
Expand Down
4 changes: 4 additions & 0 deletions security/sandbox/linux/Sandbox.h
Expand Up @@ -8,6 +8,7 @@
#define mozilla_Sandbox_h

#include "mozilla/Types.h"
#include "nsXULAppAPI.h"

// This defines the entry points for a content process to start
// sandboxing itself. See also common/SandboxInfo.h for what parts of
Expand All @@ -23,6 +24,9 @@

namespace mozilla {

// This must be called early, while the process is still single-threaded.
MOZ_SANDBOX_EXPORT void SandboxEarlyInit(GeckoProcessType aType, bool aIsNuwa);

#ifdef MOZ_CONTENT_SANDBOX
// Call only if SandboxInfo::CanSandboxContent() returns true.
// (No-op if MOZ_DISABLE_CONTENT_SANDBOX is set.)
Expand Down
35 changes: 35 additions & 0 deletions security/sandbox/linux/SandboxUtil.cpp
@@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "SandboxUtil.h"
#include "SandboxLogging.h"

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "mozilla/Assertions.h"

namespace mozilla {

bool
IsSingleThreaded()
{
// This detects the thread count indirectly. /proc/<pid>/task has a
// subdirectory for each thread in <pid>'s thread group, and the
// link count on the "task" directory follows Unix expectations: the
// link from its parent, the "." link from itself, and the ".." link
// from each subdirectory; thus, 2+N links for N threads.
struct stat sb;
if (stat("/proc/self/task", &sb) < 0) {
MOZ_DIAGNOSTIC_ASSERT(false, "Couldn't access /proc/self/task!");
return false;
}
MOZ_DIAGNOSTIC_ASSERT(sb.st_nlink >= 3);
return sb.st_nlink == 3;
}

} // namespace mozilla
16 changes: 16 additions & 0 deletions security/sandbox/linux/SandboxUtil.h
@@ -0,0 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_SandboxUtil_h
#define mozilla_SandboxUtil_h

namespace mozilla {

bool IsSingleThreaded();

} // namespace mozilla

#endif // mozilla_SandboxUtil_h

0 comments on commit e5e67f4

Please sign in to comment.