Bug 813994 - Alarm API - Need additional security checks for the "alarms" permission. r=bent, a=blocking-basecamp
authorGene Lian <clian@mozilla.com>
Wed, 28 Nov 2012 19:13:58 +0800
changeset 121818 d265118050c85ae63527bc8d7fd85653a5ed0172
parent 121817 26070fd9985b838b8348f09989856fa40fb11cdf
child 121819 eefe52b408c4b5dab9c4311333332789760ecd4e
push id1997
push userakeybl@mozilla.com
push dateMon, 07 Jan 2013 21:25:26 +0000
treeherdermozilla-beta@4baf45cdcf21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent, blocking-basecamp
bugs813994
milestone19.0a2
Bug 813994 - Alarm API - Need additional security checks for the "alarms" permission. r=bent, a=blocking-basecamp
dom/alarm/AlarmService.jsm
dom/alarm/AlarmsManager.js
--- a/dom/alarm/AlarmService.jsm
+++ b/dom/alarm/AlarmService.jsm
@@ -79,16 +79,26 @@ this.AlarmService = {
 
     if (!this._alarmHalService.setAlarm(this._getAlarmTime(aAlarm) / 1000, 0))
       throw Components.results.NS_ERROR_FAILURE;
   },
 
   receiveMessage: function receiveMessage(aMessage) {
     debug("receiveMessage(): " + aMessage.name);
 
+    // To prevent hacked child processes from sending commands to parent
+    // to schedule alarms, we need to check their installed permissions.
+    if (["AlarmsManager:GetAll", "AlarmsManager:Add", "AlarmsManager:Remove"]
+          .indexOf(aMessage.name) != -1) {
+      if (!aMessage.target.assertPermission("alarms")) {
+        debug("Got message from a child process with no 'alarms' permission.");
+        return null;
+      }
+    }
+
     let mm = aMessage.target.QueryInterface(Ci.nsIMessageSender);
     let json = aMessage.json;
     switch (aMessage.name) {
       case "AlarmsManager:GetAll":
         this._db.getAll(
           json.manifestURL,
           function getAllSuccessCb(aAlarms) {
             debug("Callback after getting alarms from database: " + JSON.stringify(aAlarms));
--- a/dom/alarm/AlarmsManager.js
+++ b/dom/alarm/AlarmsManager.js
@@ -136,25 +136,20 @@ AlarmsManager.prototype = {
   // nsIDOMGlobalPropertyInitializer implementation
   init: function init(aWindow) {
     debug("init()");
 
     // Set navigator.mozAlarms to null.
     if (!Services.prefs.getBoolPref("dom.mozAlarms.enabled"))
       return null;
 
+    // Only pages with perm set can use the alarms.
     let principal = aWindow.document.nodePrincipal;
-    let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
-
     let perm = Services.perms.testExactPermissionFromPrincipal(principal, "alarms");
-
-    // Only pages with perm set can use the alarms.
-    this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
-
-    if (!this.hasPrivileges)
+    if (perm != Ci.nsIPermissionManager.ALLOW_ACTION)
       return null;
 
     this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
 
     // Add the valid messages to be listened.
     this.initHelper(aWindow, ["AlarmsManager:Add:Return:OK", "AlarmsManager:Add:Return:KO", 
                               "AlarmsManager:GetAll:Return:OK", "AlarmsManager:GetAll:Return:KO"]);