Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows install failure "could not set file security" #86127

Closed
zooba opened this issue Oct 6, 2020 · 7 comments
Closed

Windows install failure "could not set file security" #86127

zooba opened this issue Oct 6, 2020 · 7 comments
Labels
3.9 OS-windows type-bug An unexpected behavior, bug, or error

Comments

@zooba
Copy link
Member

zooba commented Oct 6, 2020

BPO 41961
Nosy @pfmoore, @tjguk, @zware, @eryksun, @zooba

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2020-10-06.23:32:04.204>
labels = ['type-bug', '3.9', 'OS-windows']
title = 'Windows install failure "could not set file security"'
updated_at = <Date 2020-10-07.16:23:43.435>
user = 'https://github.com/zooba'

bugs.python.org fields:

activity = <Date 2020-10-07.16:23:43.435>
actor = 'eryksun'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Windows']
creation = <Date 2020-10-06.23:32:04.204>
creator = 'steve.dower'
dependencies = []
files = []
hgrepos = []
issue_num = 41961
keywords = []
message_count = 5.0
messages = ['378141', '378142', '378145', '378163', '378169']
nosy_count = 5.0
nosy_names = ['paul.moore', 'tim.golden', 'zach.ware', 'eryksun', 'steve.dower']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'test needed'
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue41961'
versions = ['Python 3.9']

@zooba
Copy link
Member Author

zooba commented Oct 6, 2020

Original report: https://twitter.com/Steve_Casselman/status/1313564671652159488?s=20

A user received MSI error 1926 in a popup dialog, text reading:

Could not set file security for file 'C:\Users\sc\AppData\Roaming\Microsoft\Installer\'. Error: 0. Verify that you have sufficient privileges to modify the security permissions for this file.

OS version: 18362.1082 (Windows 10 Home 1903)

@zooba zooba added 3.9 OS-windows type-bug An unexpected behavior, bug, or error labels Oct 6, 2020
@zooba
Copy link
Member Author

zooba commented Oct 6, 2020

Suspicious points:

  • error 0 means success, so it shouldn't be popping up an error
  • 'Installer\' is a directory, not a file
  • %AppData%\Microsoft\Installer is normally readable by Everyone, but only writable by Administrators, even in the user's directory

So I assume the error came back from the Windows Installer service which couldn't write to the folder for some reason. It may just be system permissions or corrupt ACLs (waiting on user logs for more ideas here).

Anyone else know of any possible causes for this? I'm not sure if it's anything we could even prevent, but maybe we can make it easier to troubleshoot.

@eryksun
Copy link
Contributor

eryksun commented Oct 7, 2020

Anyone else know of any possible causes for this?

The installer service runs as SYSTEM, with an access token at system integrity level that has full privileges and the administrators group enabled. Nothing in the file security should prevent the service from opening "%APPDATA%\Microsoft\Installer" with WRITE_DAC [1] and WRITE_OWNER [2] access, assuming it uses backup semantics with the restore privilege enabled, but apparently it doesn't.

I was able to reproduce the error dialog by changing the owner of the "Installer" folder to the current user and removing the two DACL entries that grant access to Administrators and SYSTEM. I then restored normal operation by changing the owner of the folder back to the Administrators group and adding the full-control DACL entries for Administrators (BA) and SYSTEM (SY):

takeown /a /f "%APPDATA%\Microsoft\Installer"
icacls "%APPDATA%\Microsoft\Installer" /grant:r *BA:(OI)(CI)(F) *SY:(OI)(CI)(F)

---

[1] A security context (access token) is allowed WRITE_DAC access to an object (to modify its discretionary ACL and security attributes) if the object's mandatory label allows write access to the token's integrity level and either the object's discretionary ACL explicitly grants WRITE_DAC access to the token's user and enabled groups or implicitly grants this access given the object's discretionary ACL does not contain an "OWNER RIGHTS" entry and the object's owner is the token's user or in the token's enabled groups. In particular for a kernel file object (e.g. opening a filesystem file/directory), WRITE_DAC access is always allowed if an open uses backup semantics and SeRestorePrivilege is enabled.

[2] A security context (access token) is allowed WRITE_OWNER access to an object (to modify its owner, group, and mandatory label) if the token has SeTakeOwnershipPrivilege enabled or if the object's mandatory label allows write access to the token's integrity level and the object's discretionary ACL grants WRITE_OWNER access to the token's user and enabled groups. The object's owner can be set to any security principal if the token has SeRestorePrivilege enabled, else it's limited to the access token user and any of the enabled groups in the access token that is flagged SE_GROUP_OWNER (typically the Administrators group). In particular for a kernel file object (e.g. opening a filesystem file/directory), WRITE_OWNER access is always allowed if an open uses backup semantics and SeRestorePrivilege is enabled.

@zooba
Copy link
Member Author

zooba commented Oct 7, 2020

I was able to reproduce the error dialog by changing the owner of the "Installer" folder to the current user and removing the two DACL entries that grant access to Administrators and SYSTEM.

Yeah, I'd assumed the most likely cause was the ACLs having been reset on the machine in question, though I'd expect that to cause most installs to fail. It might be that Python is the first/only MSI that the user has tried though?

It sounds like just resetting the owner isn't enough on its own, but the inherited ACLs should include SYSTEM and not prevent it from working. So I wonder if something else is at play?

Also, did your change reproduce the "Error: 0"? Or did you get an actual error code?

@eryksun
Copy link
Contributor

eryksun commented Oct 7, 2020

It might be that Python is the first/only MSI that the user
has tried though?

It's likely the first per-user MSI install attempted since the security of the "Installer" directory was modified. There's no problem with a per-machine install.

did your change reproduce the "Error: 0"?

It's the same "Could not set file security for file... Error: 0" dialog, which is created by the python-3.9.0.exe child process that executes from a copy in %TEMP%.

In Process Monitor, I see the actual access-denied error due to the installer service trying to open the directory with WRITE_DAC and WRITE_OWNER access.

If I also remove the Everyone group that grants read and execute access, the installer service fails at an earlier step, which results in an 0x80070643 fatal installation error.

It sounds like just resetting the owner isn't enough on its own,
but the inherited ACLs should include SYSTEM and not prevent it
from working.

The security descriptor that the installer service sets prevents inheritance of discretionary access control entries (i.e. the DACL is protected):

    >>> sd = GetFileSecurity('Installer', DACL_SECURITY_INFORMATION)
    >>> sd.GetSecurityDescriptorControl()[0] & SE_DACL_PROTECTED
    4096

Thus the entries in the ACL for SYSTEM and Administrators groups are set explicitly instead of inherited from the parent directory. If something else rewrites the security on the directory, it can just as easily protect the DACL from inheritance.

In my first experiment, I had left the entry for Everyone (WD) in the DACL, but, as mentioned above, it turns out that it's required at an earlier step. So a fix has to also add it back:

>icacls "%APPDATA%\Microsoft\Installer" /grant:r *WD:(OI)(CI)(RX)

Also, in my first message, I manually re-added the SYSTEM and Administrators entries unnecessarily -- though it doesn't hurt to do so. It turns out that all the service needs is for the directory's owner to be set back to the Administrators group. Then it implicitly has WRITE_DAC access. It gets WRITE_OWNER access as well, even though the file security at the time doesn't grant it (the owner of an object does not implicitly have WRITE_OWNER access to it), so presumably the service is temporarily enabling SeTakeOwnershipPrivilege for the process or thread.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@rizopus
Copy link

rizopus commented Dec 19, 2022

Just a notice to those who are stuck with the same error. This is not a python's installer bug at least under the following conditions.

The bug happens if you want to install Python for the current user who has no admin rights (not in Administrators group), and the folder %appdata%\Microsoft\Installer has a junction in any of its components. This applies to more or less recent versions of Windows.

A Windows Installer impersonates itself as the current user and elevates back to NT AUTHORITY\SYSTEM when it needs to do priviledged operations. When it creates (or checks existance of) a directory %appdata%\Microsoft\Installer, it also tries to set an owner, groups and DACL of the directory*. This is a priviledged operation, e.g. a non-admin user has no SE_TAKE_OWNERSHIP_NAME priv by default. So, Windows Installer needs to elevate. It does, but if any component of the path %appdata%\Microsoft\Installer has a junction, Installer explicitly disables elevation when calling SetFileSecurityW on that folder.

I don't know why this is done, maybe for security reasons.

* sddl for the security descriptor is
O:BAG:SYD:PAI(A;OICI;0x1200a9;;;WD)(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)
and can be viewed with powershell command ConvertFrom-SddlString -Sddl

@zooba
Copy link
Member Author

zooba commented Jan 9, 2023

Thanks for the additional info. This could well be a Windows bug, but it's not ours, so I'm closing the issue.

@zooba zooba closed this as not planned Won't fix, can't repro, duplicate, stale Jan 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.9 OS-windows type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants