Update fails with write but not delete permissions
Categories
(Toolkit :: Application Update, defect, P3)
Tracking
()
People
(Reporter: danbugreportmail, Assigned: dmcintosh)
References
Details
(Whiteboard: [fidedi-ope])
Attachments
(1 file)
1.45 KB,
text/x-log
|
Details |
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
Steps to reproduce:
I'm having difficulty with the auto-updater. Doing an upgrade install works.
On Windows, I clicked the hamburger open menu button -> help -> about Firefox. The update was downloaded. I clicked restart. The update was not installed. I removed the Mozilla Maintenance Service, and removed Firefox, and then installed Firefox 86.01 . The same issue happened. I also uninstalled and before re-installing renamed the Firefox directory in C:\Users......\AppData\Roaming\Mozilla to determine if it was something in the profile directory (or related) that was causing the issue. After that did not change the result I replaced the new profile folder with the data in the old profile folder (side note that it appeared that replacing the profile data caused me to lose the data in my extensions however Firefox recognized the that the extensions were installed. I "removed" the effectively nonexistent extensions and then added it back but lost the data).
The update log shows two errors: error on callback app file open and callback app file in use, failed to exclusively open executable file. I am not sure what if any external program could be blocking accessing Firefox.
Actual results:
The update did not install.
Expected results:
The update should have automatically installed.
Reporter | ||
Updated•4 years ago
|
Updated•4 years ago
|
Comment 1•4 years ago
|
||
The Bugbug bot thinks this bug should belong to the 'Toolkit::Application Update' component, and is moving the bug to that component. Please revert this change in case you think the bot is wrong.
Comment 2•4 years ago
|
||
We've been talking to the reporter on Matrix. I'm going to update the bug with a few details that we've discussed there that I think might be relevant to the problem.
Based on the update log provided here, it looks like we are getting an Access Denied error when we try to lock the executable, here.
The reporter's Firefox installation is on the D: drive, outside of the system "Program Files" directory. The permissions on the Firefox binary look like this:
D:\Program Files\Mozilla Firefox\firefox.exe
BUILTIN\Administrators:(I)(F)
NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Users:(I)(RX,W)
I remember that we don't use the maintenance service for installs outside Program Files any more. After some quick searching, I think that happens here. Because of this, I doubt this location can be updated using the maintenance service.
However, the reporter says that when they run Firefox using a regular user account and let it update, they do not see a UAC prompt. This made me think that Firefox might think (incorrectly) that it can update this location without elevation. To verify this, I had them run these commands in the browser console:
Services.prefs.setBoolPref("app.update.log", true);
let aus = Cc["@mozilla.org/updates/update-service;1"].getService(Ci.nsIApplicationUpdateService);
aus.canApplyUpdates
which resulted in this somewhat unexpected output:
AUS:SVC getCanApplyUpdates - testing write access C:\ProgramData\Mozilla\updates\CDFCF4B7528A39A6\update.test
AUS:SVC isServiceInstalled - returning true
AUS:SVC shouldUseService - returning true
AUS:SVC getCanApplyUpdates - bypass the write checks because the Windows Maintenance Service can be used
This makes me suspect that shouldUseService
may be returning true
in instances when it should not.
But even if we try to use the Service incorrectly, I'd have thought we would have fallen back to using the UAC, which we don't seem to have done. I'll have to dig into the code a bit further to determine what's going on here.
Comment 3•4 years ago
|
||
(In reply to Kirk Steuber (he/him) [:bytesized] from comment #2)
D:\Program Files\Mozilla Firefox\firefox.exe BUILTIN\Administrators:(I)(F) NT AUTHORITY\SYSTEM:(I)(F) BUILTIN\Users:(I)(RX,W)
This was the key, the Users permissions explicitly do not include Delete (or it would say (I)(M)
), so the DELETE flag causes CreateFileW
to fail. It would fail later in the update even if the callback wasn't opened here, the first time a file needed to be removed.
The reporter confirmed that it was fixed by adding permissions on the directory (though I think only Modify was needed):
So Program Files -> Mozilla Firefox -> Properties -> Security. Under the "Users" permission, Edit -> and I checked "Full Permission" and "Modify"
After I did that I restarted Firefox and it installed the update
Normally if there aren't sufficient permissions we would have run the maintenance service, or shown the UAC prompt, but:
useService
gets cleared because this is not the official%programfiles%
location. This ideally would have causedshouldUseService()
to return false, but that isn't implemented. Even if it was in a supported location, though, we would not have attempted to use the service due to 3.Users
did have write permissions, so the update lock file could be opened RW here.- The write checks look for an invalid
updateLockFile
before considering elevation with maintsvc or UAC (and later before prompting for elevation). The lock file was opened fine, so we don't try the maintsvc or prompt for UAC.
There are other write checks in the update service, but these were all skipped because we thought we could use the maintenance service:
- If the user can't elevate, we would have done this check in
getCanApplyUpdates()
. getCanStageUpdates()
uses the gCanStageUpdatesSession check.
Both of these checks may have passed anyway since the ACL [1] gives OWNER CREATOR full access, but it still would be good to make shouldUseService()
more accurate, I filed bug 1702384.
We could attempt to fix this, but because the maintenance service couldn't be used it would show a UAC prompt on every startup (or just showing an error if the user can't elevate). That's still better than silently failing.
I tried adding a request for DELETE
permission, but as long as the file is being created there's no error. With FILE_FLAG_DELETE_ON_CLOSE
set, a user can create the file and delete it on close like this, but without that flag the file can't later be deleted due to the inherited permissions.
We could create and close the file, then open it again for real with the current call + DELETE
, that would cause the failure early enough. But I'm not sure what the fallout would be from leaving the lockfile around when there isn't an update going. If the dir permissions were stuck like this, it would prevent us from ever getting past this check.
I was going to suggest that the installer could refuse to install into such a location, but there is already a check that files can be deleted. The installer always tries to elevate, and by way of BUILTIN\Administrators:(I)(F)
administrators have full permissions.
There was also a note that the update wouldn't apply if Firefox was run as administrator, that's probably because Firefox would have dropped privileges before starting the updater.
This should be a pretty unusual setup, and it can be fixed by fixing the permissions. I set the severity and priority to reflect this.
[1] This the icacls output for the directory from the discussion on Matrix:
D:\Program Files\Mozilla Firefox BUILTIN\Administrators:(I)(F)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)
NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
BUILTIN\Users:(I)(OI)(CI)(RX,W)
And for the record here is an ACL dump of the parent directory I used to reproduce the issue (stage succeeds but replace fails with access denied on callback):
test
D:PAI(A;OICI;0x1201bf;;;BU)(A;OICI;FA;;;BA)(A;OICI;FA;;;SY)(A;;FA;;;BA)(A;OICIIO;FA;;;CO)
Firefox was installed into test\Mozilla Firefox
, created by the installer running elevated.
Updated•4 years ago
|
Updated•4 years ago
|
Assignee | ||
Updated•3 months ago
|
Description
•