Windows – How does `chmod +x` work in cygwin

cygwin;file-permissionswindows

I just downloaded an executable via cygwin's wget and found I cannot execute it.

In cygwin I get

$ ./clink_0.4.4_setup.exe
-bash: ./clink_0.4.4_setup.exe: Permission denied

and when I try to execute it from explorer, I get

Windows cannot access the specified device, path, or file. You may not have appropriate permissions to access the item.

This seems clear – in Linux/Unix, I would chmod +x, and indeed that works here, too. But I thought Windows doesn't have the "executable" bit. I can imagine that cygwin stores its permissions in Alternate Data Streams, and can prevent me from executing it, but how does it enforce this outside of cygwin? I can't find anything obvious in the file's properties (in explorer).

Best Answer

How does chmod +x work in cygwin?

You need to read all of Chapter 3. Using Cygwin- POSIX accounts, permission, and security to completely understand this.

Some extracts follow.


POSIX accounts, permission, and security

This section discusses how the Windows security model is utilized in Cygwin to implement POSIX account information, POSIX-like permissions, and how the Windows authentication model is used to allow cygwin applications to switch users in a POSIX-like fashion.

The setting of POSIX-like file and directory permissions is controlled by the mount option (no)acl which is set to acl by default.

We start with a short overview. Note that this overview must be necessarily short. If you want to learn more about the Windows security model, see the Access Control article in MSDN documentation.

POSIX concepts and in particular the POSIX security model are not discussed here, but assumed to be understood by the reader. If you don't know the POSIX security model, search the web for beginner documentation.

Brief overview of Windows security

In the Windows security model, almost any "object" is securable. "Objects" are files, processes, threads, semaphores, etc.

Every object has a data structure attached, called a "security descriptor" (SD). The SD contains all information necessary to control who can access an object, and to determine what they are allowed to do to or with it. The SD of an object consists of five parts:

  • Flags which control several aspects of this SD. This is not discussed here.

  • The SID of the object owner.

  • The SID of the object owner group.

  • A list of "Access Control Entries" (ACE), called the "Discretionary Access Control List" (DACL).

  • Another list of ACEs, called the "Security Access Control List" (SACL), which doesn't matter for our purpose. We ignore it here.

Every ACE contains a so-called "Security IDentifier" (SID) and other stuff which is explained a bit later. Let's talk about the SID first.

A SID is a unique identifier for users, groups, computers and Active Directory (AD) domains. SIDs are basically comparable to POSIX user ids (UIDs) and group ids (GIDs), but are more complicated because they are unique across multiple machines or domains. A SID is a structure of multiple numerical values. There's a convenient convention to type SIDs, as a string of numerical fields separated by hyphen characters.

...

File permissions

On NTFS and if the noacl mount option is not specified for a mount point, Cygwin sets file permissions as on POSIX systems. Basically this is done by defining a Security Descriptor with the matching owner and group SIDs, and a DACL which contains ACEs for the owner, the group and for "Everyone", which represents what POSIX calls "others".

There's just one problem when trying to map the POSIX permission model onto the Windows permission model.

There's a leak in the definition of a "correct" ACL which disallows a certain POSIX permission setting. The official documentation explains in short the following:

  • The requested permissions are checked against all ACEs of the user as well as all groups the user is member of. The permissions given in these user and groups access allowed ACEs are accumulated and the resulting set is the set of permissions of that user given for that object.

  • The order of ACEs is important. The system reads them in sequence until either any single requested permission is denied or all requested permissions are granted. Reading stops when this condition is met. Later ACEs are not taken into account.

  • All access denied ACEs should precede any access allowed ACE. ACLs following this rule are called "canonical".

Note that the last rule is a preference or a definition of correctness. It's not an absolute requirement. All Windows kernels will correctly deal with the ACL regardless of the order of allow and deny ACEs. The second rule is not modified to get the ACEs in the preferred order.

Unfortunately the security tab in the file properties dialog of the Windows Explorer insists to rearrange the order of the ACEs to canonical order before you can read them. Thank God, the sort order remains unchanged if one presses the Cancel button. But don't even think of pressing OK...

Canonical ACLs are unable to reflect each possible combination of POSIX permissions. Example:

rw-r-xrw-

Ok, so here's the first try to create a matching ACL, assuming the Windows permissions only have three bits, as their POSIX counterpart:

UserAllow:   110
GroupAllow:  101
OthersAllow: 110

Hmm, because of the accumulation of allow rights the user may execute because the group may execute.

Second try:

UserDeny:    001
GroupAllow:  101
OthersAllow: 110

Now the user may read and write but not execute. Better? No! Unfortunately the group may write now because others may write.

Third try:

UserDeny:    001
GroupDeny:   010
GroupAllow:  001
OthersAllow: 110

Now the group may not write as intended but unfortunately the user may not write anymore, either. How should this problem be solved? According to the canonical order a UserAllow has to follow the GroupDeny but it's easy to see that this can never be solved that way.

The only chance:

UserDeny:    001
UserAllow:   010
GroupDeny:   010
GroupAllow:  001
OthersAllow: 110

Again: This works on all existing versions of Windows NT, at the time of writing from at least Windows XP up to Server 2012 R2. Only the GUIs aren't able (or willing) to deal with that order.

Source POSIX accounts, permission, and security


Further reading

Related Question