GetKernelObjectSecurity support and ACE mask representation for a named pipe created with SDDL GRGW

fengchun chen 20 Reputation points
2026-09-18T14:28:44.6466667+00:00

Hello,

We are reviewing documented Windows behavior for a named pipe created with an explicit security descriptor. Could you clarify the following two points and, where available, provide authoritative Microsoft documentation references?

1. GetKernelObjectSecurity applicability

Is GetKernelObjectSecurity, when called on a server-side handle returned by CreateNamedPipeW with the required READ_CONTROL access, a supported operation for retrieving the named pipe's owner and DACL?

If so, what applicability or handle-access restrictions apply?

2. ACE mask representation for SDDL GRGW

When the named pipe is created using a security descriptor produced by ConvertStringSecurityDescriptorToSecurityDescriptorW from SDDL containing GRGW, what supported relationship exists between those generic ACE rights and the ACE mask subsequently returned through that security-descriptor read-back?

Are the generic bits retained, or are they mapped to named-pipe-specific rights? What documented mapping or representation guarantees apply?

Our purpose is to compare the actual ACE masks against independently established expected masks. We are not requesting alternative APIs or changes to Windows behavior.

Thank you.

Windows development | Windows API - Win32
0 comments No comments

Answer accepted by question author
Taki Ly (WICLOUD CORPORATION) 5,710 Reputation points Microsoft External Staff Moderator
2026-09-21T08:36:17.5+00:00

Hello @fengchun chen ,

I reproduced your scenario on Windows 11 Enterprise (10.0.26200), pipe created from D:(A;;GRGW;;;WD) via ConvertStringSecurityDescriptorToSecurityDescriptorW + CreateNamedPipeW(PIPE_ACCESS_DUPLEX), then read back, and grouped the findings below by what was observed, what the documentation states, and what I'd recommend.

What I observed

Input SD (before create)          : D:(A;;GWGR;;;WD)          mask = 0xC0000000
GetKernelObjectSecurity           : O:LAD:(A;;0x12019f;;;WD)  mask = 0x0012019F
GetSecurityInfo(SE_KERNEL_OBJECT) : O:LAD:(A;;0x12019f;;;WD)  mask = 0x0012019F
Client handle with FILE_READ_DATA only -> GetKernelObjectSecurity fails, ERROR_ACCESS_DENIED (5)
CreateNamedPipeW with READ_CONTROL OR'ed into dwOpenMode -> ERROR_INVALID_PARAMETER (87)

0x0012019F == FILE_GENERIC_READ (0x120089) | FILE_GENERIC_WRITE (0x120116)
  • GetKernelObjectSecurity succeeds on the CreateNamedPipeW server handle and returns exactly the same security descriptor as GetSecurityInfo(SE_KERNEL_OBJECT).
  • The GR/GW generic bits are not retained. The ACE mask read back is FILE_GENERIC_READ | FILE_GENERIC_WRITE; the mapping happens once, when the SD is assigned to the object at creation.
  • A handle without READ_CONTROL cannot read the DACL.

What the documentation states

  • Named Pipe Security and Access Rights names GetSecurityInfo / SetSecurityInfo as the functions for a named pipe's security descriptor. It also states that a PIPE_ACCESS_DUPLEX server handle carries FILE_GENERIC_READ | FILE_GENERIC_WRITE | SYNCHRONIZE, both of which include READ_CONTROL (which is why it cannot be added to dwOpenMode explicitly).
  • GetKernelObjectSecurity is documented generically for "a kernel object"; named pipes are not called out. Its Remarks give the handle requirements: READ_CONTROL for owner/group/DACL, ACCESS_SYSTEM_SECURITY (with SE_SECURITY_NAME enabled) for the SACL.
  • GR = GENERIC_READ, GW = GENERIC_WRITE (ACE Strings). Generic rights map to object-specific rights through the object type's GENERIC_MAPPING (ACCESS_MASK, Generic Access Rights); for files and named pipes, GENERIC_READ -> FILE_GENERIC_READ, GENERIC_WRITE -> FILE_GENERIC_WRITE.
  • The routine that builds the SD for a new object takes that mapping as input: SeAssignSecurityEx (GenericMapping - "mapping between each generic right to object-specific rights"); user-mode equivalent CreatePrivateObjectSecurity.
  • Not stated anywhere: that GetKernelObjectSecurity is supported specifically for named pipes, or that a read-back will always return the expanded object-specific mask rather than generic bits. The behavior above is consistent and long-standing, but there is no sentence guaranteeing it.

What I recommend

  1. API: use GetSecurityInfo(hPipe, SE_KERNEL_OBJECT, ...) as the documented, supported call for named pipes. GetKernelObjectSecurity works and gives the same result, but I would not cite it as the supported API in a compliance context.
  2. Mask comparison: normalize both sides through the file/pipe generic mapping so the test is correct regardless of which representation is returned:
GENERIC_MAPPING gm = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS };
ACCESS_MASK expected = GENERIC_READ | GENERIC_WRITE;   // from your SDDL
MapGenericMask(&expected, &gm);                        // -> 0x0012019F
ACCESS_MASK actual = ace->Mask;
MapGenericMask(&actual, &gm);                          // no-op if already specific
// compare expected == actual
  1. Security note: on named pipes FILE_APPEND_DATA and FILE_CREATE_PIPE_INSTANCE are the same bit, so GW granted to WD (Everyone) also lets anyone create additional pipe instances. The named-pipe documentation recommends granting individual rights instead of FILE_GENERIC_WRITE.
  2. Formal guarantee: if you need a written statement beyond documented mapping + observed behavior for a compliance deliverable, open a Microsoft support case, or file documentation feedback on the GetKernelObjectSecurity / named-pipe pages asking that named pipes be explicitly called out.

Hope these information help. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guide for your confirmation.

Thank you.

Was this answer helpful?

1 person found this answer helpful.

4 additional answers

Sort by: Most helpful
  1. RLWA32 52,936 Reputation points
    2026-09-22T12:01:13.5766667+00:00

    The only instance in which I have observed security descriptor ACEs containing generic rights is in connection with container objects and inheritable aces flagged as INHERIT_ONLY_ACE.

    The following example used GetNamedSecurityInfo for the C:\Users folder.

    Security Descriptor information for C:\Users
    GetNamedSecurityInfo retrieved DACL_SECURITY_INFORMATION
    
    Security Descriptor control (0x9404) is: SE_DACL_PRESENT SE_DACL_AUTO_INHERITED SE_DACL_PROTECTED SE_SELF_RELATIVE 
    
    Security Descriptor ACES in DACL
    Ace is ACCESS_ALLOWED
    Ace Sid is S-1-5-18, Ace flags is 0x03
    	INHERITED_ACE : false
    	CONTAINER_INHERIT_ACE : true
    	INHERIT_ONLY_ACE : false
    	NO_PROPAGATE_INHERIT_ACE : false
    	OBJECT_INHERIT_ACE : true
    Account Name is SYSTEM, Domain is NT AUTHORITY
    Standard Rights : WRITE_DAC WRITE_OWNER DELETE READ_CONTROL SYNCHRONIZE 
    Specific Rights : FILE_READ_ATTRIBUTES FILE_READ_DATA FILE_READ_EA FILE_APPEND_DATA FILE_WRITE_ATTRIBUTES FILE_WRITE_DATA FILE_WRITE_EA FILE_EXECUTE 
    Generic Rights  : 
    
    Ace is ACCESS_ALLOWED
    Ace Sid is S-1-5-32-544, Ace flags is 0x03
    	INHERITED_ACE : false
    	CONTAINER_INHERIT_ACE : true
    	INHERIT_ONLY_ACE : false
    	NO_PROPAGATE_INHERIT_ACE : false
    	OBJECT_INHERIT_ACE : true
    Account Name is Administrators, Domain is BUILTIN
    Standard Rights : WRITE_DAC WRITE_OWNER DELETE READ_CONTROL SYNCHRONIZE 
    Specific Rights : FILE_READ_ATTRIBUTES FILE_READ_DATA FILE_READ_EA FILE_APPEND_DATA FILE_WRITE_ATTRIBUTES FILE_WRITE_DATA FILE_WRITE_EA FILE_EXECUTE 
    Generic Rights  : 
    
    Ace is ACCESS_ALLOWED
    Ace Sid is S-1-5-32-545, Ace flags is 00
    	INHERITED_ACE : false
    	CONTAINER_INHERIT_ACE : false
    	INHERIT_ONLY_ACE : false
    	NO_PROPAGATE_INHERIT_ACE : false
    	OBJECT_INHERIT_ACE : false
    Account Name is Users, Domain is BUILTIN
    Standard Rights : READ_CONTROL SYNCHRONIZE 
    Specific Rights : FILE_READ_ATTRIBUTES FILE_READ_DATA FILE_READ_EA FILE_EXECUTE 
    Generic Rights  : 
    
    Ace is ACCESS_ALLOWED
    Ace Sid is S-1-5-32-545, Ace flags is 0x0b
    	INHERITED_ACE : false
    	CONTAINER_INHERIT_ACE : true
    	INHERIT_ONLY_ACE : true
    	NO_PROPAGATE_INHERIT_ACE : false
    	OBJECT_INHERIT_ACE : true
    Account Name is Users, Domain is BUILTIN
    Standard Rights : 
    Specific Rights : 
    Generic Rights  : GENERIC_EXECUTE GENERIC_READ 
    
    Ace is ACCESS_ALLOWED
    Ace Sid is S-1-1-0, Ace flags is 00
    	INHERITED_ACE : false
    	CONTAINER_INHERIT_ACE : false
    	INHERIT_ONLY_ACE : false
    	NO_PROPAGATE_INHERIT_ACE : false
    	OBJECT_INHERIT_ACE : false
    Account Name is Everyone, Domain is 
    Standard Rights : READ_CONTROL SYNCHRONIZE 
    Specific Rights : FILE_READ_ATTRIBUTES FILE_READ_DATA FILE_READ_EA FILE_EXECUTE 
    Generic Rights  : 
    
    Ace is ACCESS_ALLOWED
    Ace Sid is S-1-1-0, Ace flags is 0x0b
    	INHERITED_ACE : false
    	CONTAINER_INHERIT_ACE : true
    	INHERIT_ONLY_ACE : true
    	NO_PROPAGATE_INHERIT_ACE : false
    	OBJECT_INHERIT_ACE : true
    Account Name is Everyone, Domain is 
    Standard Rights : 
    Specific Rights : 
    Generic Rights  : GENERIC_EXECUTE GENERIC_READ 
    

    Was this answer helpful?

    0 comments No comments

  2. AlanVi-4963 0 Reputation points
    2026-09-22T03:35:21.2166667+00:00

    What the documentation does not clearly support is any claim about the exact ACE mask representation returned after creating a named pipe from SDDL containing GRGW.

    So if someone is using that analysis to argue that Windows must preserve generic bits, or must return expanded object-specific bits, the cited documentation does not prove either proposition. does not prove either proposition.

    Was this answer helpful?

    0 comments No comments

  3. RLWA32 52,936 Reputation points
    2026-09-20T12:07:40.8433333+00:00

    With respect to Question 1 refer to Low-level Security Descriptor Functions. The documentation does not include named pipes as objects for which GetKernelObjectSecurity should be used.

    Was this answer helpful?


  4. AI answer

    2026-09-18T14:29:02.4133333+00:00

    For point 1, the supported fact in the available documentation is that named pipes are securable objects with defined access rights, including READ_CONTROL, which is the right to read the security descriptor for the file or named pipe. The named-pipe security documentation also states that FILE_GENERIC_READ and FILE_GENERIC_WRITE each include reading the pipe’s DACL, and that ACCESS_SYSTEM_SECURITY is required if the SACL must be read or written. The provided documentation does not state GetKernelObjectSecurity applicability specifically for a CreateNamedPipeW server handle, so the supported conclusion is limited to this: reading the named pipe security descriptor requires appropriate access such as READ_CONTROL, and SACL access additionally requires ACCESS_SYSTEM_SECURITY.

    For point 2, the documented relationship is:

    • In SDDL ACE strings, GR means GENERIC_READ and GW means GENERIC_WRITE.
    • For file and named-pipe objects, generic rights have documented mappings.
    • For a named pipe, GENERIC_READ maps to FILE_READ_DATA, FILE_READ_ATTRIBUTES, FILE_READ_EA, SYNCHRONIZE, and READ_CONTROL.
    • For a named pipe, GENERIC_WRITE maps to FILE_WRITE_DATA, FILE_APPEND_DATA, FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, SYNCHRONIZE, and READ_CONTROL.

    So for an ACE expressed in SDDL as GRGW, the documented rights represented are the union of those mapped rights. The named-pipe-specific documentation further explains the semantic grouping:

    • FILE_GENERIC_READ for a named pipe combines the rights to read data from the pipe, read pipe attributes, read extended attributes, and read the pipe's DACL.
    • FILE_GENERIC_WRITE for a named pipe combines the rights to write data, append data, write pipe attributes, write extended attributes, and read the pipe's DACL.

    An important documented caveat is that for named pipes, FILE_APPEND_DATA and FILE_CREATE_PIPE_INSTANCE have the same definition, so FILE_GENERIC_WRITE enables permission to create the pipe. To avoid that problem, the documentation recommends using individual rights instead of FILE_GENERIC_WRITE.

    The available documentation supports the generic-to-object-specific mapping above. It does not provide a guarantee here about whether a later security-descriptor read-back must preserve the ACE mask as generic bits versus returning an object-specific expanded mask. Only the mapping itself is documented in the provided material.


    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.