Closed Bug 2006512 Opened 2 months ago Closed 1 month ago

An early I/O error during installation of one add-on can nuke the whole staged directory, preventing concurrent installations from succeeding

Categories

(Toolkit :: Add-ons Manager, defect, P3)

defect

Tracking

()

RESOLVED FIXED
149 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr140 --- wontfix
firefox146 --- wontfix
firefox147 --- wontfix
firefox148 --- wontfix
firefox149 --- fixed

People

(Reporter: robwu, Assigned: robwu)

References

(Blocks 1 open bug, Regression)

Details

(Keywords: regression)

Attachments

(1 file)

Simplified, the relevant code involving the staging directory ("staged") is as follows (source, with many unrelevant lines deleted):

    let stagedAddon = this.location.installer.getStagingDir();
    try {
      await this.unstageInstall(stagedAddon);
      stagedAddon.append(`${this.addon.id}.xpi`);
    } catch (e) {
      if (stagedAddon.exists()) {
        recursiveRemove(stagedAddon);
      }

The problem with this logic is that the logic assumes stagedAddon to be pointing to the xpi file that is being installed.
But if unstageInstall throws for whatever reason (e.g. file being locked), the whole staging directory ends up being nuked instead.

If there are concurrent add-on installations (e.g. during a background update check), this can prevent all other extensions from updating.

This is a subtle regression introduced a long time ago in bug 1231172 by this change.
Previously, stagedAddon was immediately set to an item in the staging directory. That refactor moved the logic in a (then) new unstageInstall method, taking the directory, and no longer mutating the staging directory. Consequently, if any of the intermediate steps failed, the caller would still have stagedAddon at the staging directory.

Set release status flags based on info from the regressing bug 1231172

Directory installation was removed in bug 1457072, so a way to fix this could be to remove the directory-deletion logic from https://searchfox.org/firefox-main/rev/f37efeb9fd346125bfc98d132ae0dea48a1e2584/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs#2111

and restructure the code to avoid passing stagingDir around where addonDir was meant.

and also, this is dead code: https://searchfox.org/firefox-main/rev/f37efeb9fd346125bfc98d132ae0dea48a1e2584/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs#1126,1131,1244-1247

(I'm looking at this code currently because I'm trying to figure out the best way to fix bug 2006489)

See Also: → 1457072, 2006489

The deleted logic became obsolete in bug 1457072.

Assignee: nobody → rob
Status: NEW → ASSIGNED
Severity: -- → S4
Priority: -- → P3

The initial version of my patch triggers the following test failure:

TEST-UNEXPECTED-FAIL | xpcshell.toml:toolkit/mozapps/extensions/test/xpcshell/test_undouninstall.js | xpcshell return code: 0
Error: Test cleanup: path /tmp/xpc-profile-ln95givh/extensions/staged exists when it should not at resource://testing-common/AddonTestUtils.sys.mjs:326

Upon further inspection, it turns out that there is still code that creates an empty directory at https://searchfox.org/firefox-main/rev/5917a9f2af3294b27a325371c5c499e7dd9554fd/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs#5040-5055

That directory-creating code should have been removed in bug 1448221 because part 3 of that patch stack removed the logic that scans the staged directory at https://searchfox.org/firefox-main/diff/ef130246087b29842cc1922b217fc6cf76a66b66/toolkit/mozapps/extensions/internal/XPIProvider.jsm#2744-2745. So there is no point in creating ProfD/extensions/staged/<addon-id> any more.

(In reply to Rob Wu [:robwu] from comment #2)

Directory installation was removed in bug 1457072, so a way to fix this could be to remove the directory-deletion logic from https://searchfox.org/firefox-main/rev/f37efeb9fd346125bfc98d132ae0dea48a1e2584/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs#2111

The fact that we have continued to create this empty directory for the past 7 years despite its obsolescence means that we cannot remove this directory-deleting logic yet. That's OK, the patch does not rely on it anyway to fix this bug.

Blocks: 2010271
See Also: → 2006318
Status: ASSIGNED → RESOLVED
Closed: 1 month ago
Resolution: --- → FIXED
Target Milestone: --- → 149 Branch

The patch landed in nightly and beta is affected.
:robwu, is this bug important enough to require an uplift?

For more information, please visit BugBot documentation.

Flags: needinfo?(rob)
Flags: needinfo?(rob)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: