Bug 1899516 - Warn user when missing unprivileged user namespace r=firefox-desktop-core-reviewers ,fluent-reviewers,Gijs,flod, a=dmeehan, l10n=bolsson

Differential Revision: https://phabricator.services.mozilla.com/D212024
This commit is contained in:
Alexandre Lissy 2024-07-15 12:11:54 +00:00
parent f39b3a13e0
commit 7119cc28b9
7 changed files with 247 additions and 0 deletions

View file

@ -82,6 +82,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
ResetPBMPanel: "resource:///modules/ResetPBMPanel.sys.mjs",
SafeBrowsing: "resource://gre/modules/SafeBrowsing.sys.mjs",
Sanitizer: "resource:///modules/Sanitizer.sys.mjs",
SandboxUtils: "resource://gre/modules/SandboxUtils.sys.mjs",
SaveToPocket: "chrome://pocket/content/SaveToPocket.sys.mjs",
ScreenshotsUtils: "resource:///modules/ScreenshotsUtils.sys.mjs",
SearchSERPCategorization: "resource:///modules/SearchSERPTelemetry.sys.mjs",
@ -1692,6 +1693,16 @@ BrowserGlue.prototype = {
);
},
_verifySandboxUserNamespaces: function BG_verifySandboxUserNamespaces(aWin) {
if (!AppConstants.MOZ_SANDBOX) {
return;
}
lazy.SandboxUtils.maybeWarnAboutMissingUserNamespaces(
aWin.gNotificationBox
);
},
_earlyBlankFirstPaint(cmdLine) {
let startTime = Cu.now();
if (
@ -1954,6 +1965,8 @@ BrowserGlue.prototype = {
"browser.contentblocking.features.strict",
this._setPrefExpectationsAndUpdate
);
this._verifySandboxUserNamespaces(aWindow);
},
_maybeOfferProfileReset() {

View file

@ -13,6 +13,8 @@ skip-if = ["os == 'linux'"]
["browser_browserGlue_upgradeDialog_trigger.js"]
["browser_browserGlue_userNamespacesNotification.js"]
["browser_bug538331.js"]
skip-if = ["!updater"]
reason = "test depends on update channel"

View file

@ -0,0 +1,154 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const kCID = "@mozilla.org/browser/browserglue;1";
const BrowserGlue = Cc[kCID].getService(Ci.nsISupports).wrappedJSObject;
const kNotificationSelector =
'notification-message[message-bar-type="infobar"]' +
'[value="sandbox-unprivileged-namespaces"]';
function closeExistingNotification() {
const notification = document.querySelector(kNotificationSelector);
if (notification) {
notification.remove();
}
Assert.equal(
null,
document.querySelector(kNotificationSelector),
"No more notification"
);
}
function setHasUsernamespaces(isPresent) {
Services.sysinfo
.QueryInterface(Ci.nsIWritablePropertyBag2)
.setPropertyAsBool("hasUserNamespaces", isPresent);
}
async function getNotification(shouldBeNull = false) {
await TestUtils.waitForCondition(() => {
if (shouldBeNull) {
return document.querySelector(kNotificationSelector) === null;
}
return document.querySelector(kNotificationSelector) !== null;
}, "Trying to get a notification");
return document.querySelector(kNotificationSelector);
}
if (AppConstants.platform === "linux" && AppConstants.MOZ_SANDBOX) {
add_setup(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [["security.sandbox.warn_unprivileged_namespaces", true]],
});
closeExistingNotification();
const originalValue = Services.sysinfo.getProperty("hasUserNamespaces");
registerCleanupFunction(() => {
Services.sysinfo
.QueryInterface(Ci.nsIWritablePropertyBag2)
.setPropertyAsBool("hasUserNamespaces", originalValue);
});
});
add_task(async function doNotShowNotificationCorrectly() {
Assert.equal(
null,
document.querySelector(kNotificationSelector),
"No existing notification"
);
setHasUsernamespaces(true);
BrowserGlue._verifySandboxUserNamespaces(window);
const notification = await getNotification(/* shouldBeNull */ true);
Assert.equal(
null,
notification,
"Notification is not shown when the feature is supported"
);
});
add_task(async function showNotificationCorrectly() {
Assert.equal(
null,
document.querySelector(kNotificationSelector),
"No existing notification"
);
setHasUsernamespaces(false);
BrowserGlue._verifySandboxUserNamespaces(window);
const notification = await getNotification();
Assert.notEqual(
null,
notification,
"Notification is shown when the feature is not supported"
);
closeExistingNotification();
});
add_task(async function prefDisablesNotification() {
Assert.equal(
null,
document.querySelector(kNotificationSelector),
"No existing notification"
);
await SpecialPowers.pushPrefEnv({
set: [["security.sandbox.warn_unprivileged_namespaces", false]],
});
setHasUsernamespaces(false);
BrowserGlue._verifySandboxUserNamespaces(window);
const notification = await getNotification(/* shouldBeNull */ true);
Assert.equal(
null,
notification,
"Notification is not shown when the feature is unsupported but pref disabled"
);
});
add_task(async function dontShowAgainTogglePref() {
Assert.equal(
null,
document.querySelector(kNotificationSelector),
"No existing notification"
);
await SpecialPowers.pushPrefEnv({
set: [["security.sandbox.warn_unprivileged_namespaces", true]],
});
Assert.equal(
Services.prefs.getBoolPref(
"security.sandbox.warn_unprivileged_namespaces"
),
true,
"Pref is enabled"
);
setHasUsernamespaces(false);
BrowserGlue._verifySandboxUserNamespaces(window);
const notification = await getNotification();
const dontShowAgain = notification.querySelector(".notification-button");
Assert.notEqual(null, dontShowAgain, "Found dismiss for ever button");
dontShowAgain.click();
Assert.equal(
Services.prefs.getBoolPref(
"security.sandbox.warn_unprivileged_namespaces"
),
false,
"Pref is disabled"
);
});
} else {
add_task(async function doNotShowNotificationCorrectly() {
Assert.equal(
null,
document.querySelector(kNotificationSelector),
"No existing notification"
);
BrowserGlue._verifySandboxUserNamespaces(window);
const notification = await getNotification(/* shouldBeNull */ true);
Assert.equal(null, notification, "Notification is not shown on non linux");
});
}

View file

@ -14741,6 +14741,13 @@
mirror: once
#endif
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
- name: security.sandbox.warn_unprivileged_namespaces
type: bool
value: true
mirror: always
#endif
# Pref to show warning when submitting from secure to insecure.
- name: security.warn_submit_secure_to_insecure
type: bool

View file

@ -0,0 +1,61 @@
/* 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/. */
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
export var SandboxUtils = {
/**
* Show a notification bar if user is running without unprivileged namespace
*
* @param {NotificationBox} aNotificationBox
* The target notification box where notification will be added
*/
maybeWarnAboutMissingUserNamespaces:
function SU_maybeWarnAboutMissingUserNamespaces(aNotificationBox) {
if (AppConstants.platform !== "linux") {
return;
}
const kSandboxUserNamespacesPref =
"security.sandbox.warn_unprivileged_namespaces";
const kSandboxUserNamespacesPrefValue = Services.prefs.getBoolPref(
kSandboxUserNamespacesPref
);
if (!kSandboxUserNamespacesPrefValue) {
return;
}
const userNamespaces =
Services.sysinfo.getPropertyAsBool("hasUserNamespaces");
if (userNamespaces) {
return;
}
const mozXulElement = aNotificationBox.stack.ownerGlobal.MozXULElement;
mozXulElement.insertFTLIfNeeded("toolkit/updates/elevation.ftl");
let buttons = [
{
supportPage: "install-firefox-linux",
"l10n-id": "sandbox-unprivileged-namespaces-howtofix",
},
{
"l10n-id": "sandbox-unprivileged-namespaces-dismiss-button",
callback: () => {
Services.prefs.setBoolPref(kSandboxUserNamespacesPref, false);
},
},
];
// Now actually create the notification
aNotificationBox.appendNotification(
"sandbox-unprivileged-namespaces",
{
label: { "l10n-id": "sandbox-missing-unprivileged-namespaces" },
priority: aNotificationBox.PRIORITY_WARNING_HIGH,
},
buttons
);
},
};

View file

@ -45,6 +45,10 @@ if CONFIG["MOZ_SANDBOX"] and CONFIG["MOZ_DEBUG"] and CONFIG["ENABLE_TESTS"]:
"/netwerk/base",
]
EXTRA_JS_MODULES += [
"SandboxUtils.sys.mjs",
]
include("/ipc/chromium/chromium-config.mozbuild")
FINAL_LIBRARY = "xul"

View file

@ -20,3 +20,9 @@ elevation-more-elevated =
installed the next time { -brand-short-name } starts. You can restart
{ -brand-short-name } now, continue working and restart later, or decline this
update.
sandbox-missing-unprivileged-namespaces = Some of { -brand-short-name }s security features may offer less protection on your current operating system.
sandbox-unprivileged-namespaces-dismiss-button =
.label = Dont show again
.accesskey = D
sandbox-unprivileged-namespaces-howtofix = How to fix this issue