forked from mirrors/gecko-dev
		
	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:
		
							parent
							
								
									f39b3a13e0
								
							
						
					
					
						commit
						7119cc28b9
					
				
					 7 changed files with 247 additions and 0 deletions
				
			
		|  | @ -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() { | ||||
|  |  | |||
|  | @ -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" | ||||
|  |  | |||
|  | @ -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"); | ||||
|   }); | ||||
| } | ||||
|  | @ -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 | ||||
|  |  | |||
							
								
								
									
										61
									
								
								security/sandbox/common/SandboxUtils.sys.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								security/sandbox/common/SandboxUtils.sys.mjs
									
									
									
									
									
										Normal 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 | ||||
|       ); | ||||
|     }, | ||||
| }; | ||||
|  | @ -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" | ||||
|  |  | |||
|  | @ -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 = Don’t show again | ||||
|   .accesskey = D | ||||
| sandbox-unprivileged-namespaces-howtofix = How to fix this issue | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Alexandre Lissy
						Alexandre Lissy