1

I'm trying to create a named pipe between two Windows processes. The server process runs under a normal account, in a UI session. The client process runs in an unknown security context, apparently rather restricted.

Initially I called

pipe = CreateNamedPipeA(MY_PIPE_NAME, PIPE_ACCESS_DUPLEX,
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, maxClients,
                     pipeChunkSize, pipeChunkSize, 0, nullptr); 

I.e. leave pass no SECURITY_ATTRIBUTES. Usually, this works - no security means no security. Apparently, this is no longer the case for named pips. The caller tried

CreateFileA(MY_PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

and got back a GetLastError=5, access denied. Testing showed that this was due to a security failure; the exact same line would succeed if the client executable was run from a test environment in the same UI session as the server.

The logical solution would be to set the DACL to SECURITY_WORLD_SID_AUTHORITY, KEY_ALL_ACCESS (S-1-1-0) in the SECURITY_ATTRIBUTES used for CreateNamedPipeA. This didn't fix the problem.

The only security downgrade left from "everybody can do everything" would be "no security whatsoever". What do I have to do in CreateNamedPipe so that CreateFileA never fails with an Access Denied?

Security is pretty irrelevant here. PIPE_TYPE_MESSAGE and pipeChunkSize already mean that the server is safe against buffer overflows by rogue clients.

MSalters
  • 173,980
  • 10
  • 155
  • 350

1 Answers1

2

When I want a pipe accessible by anyone (e.g. it's hosted in a service and I can't predict what account will need it), I add a NULL-DACL SD:

static SECURITY_ATTRIBUTES g_sa = {0};

g_sa.nLength = sizeof(g_sa);
g_hsa = GlobalAlloc (GHND,SECURITY_DESCRIPTOR_MIN_LENGTH);
g_sa.lpSecurityDescriptor = GlobalLock(g_hsa);
g_sa.bInheritHandle = TRUE;

if (InitializeSecurityDescriptor (g_sa.lpSecurityDescriptor, 1))
{
   if (SetSecurityDescriptorDacl (g_sa.lpSecurityDescriptor, TRUE,NULL,FALSE))
   {
      DebugMessage ("security descriptor DACL set OK\n");

where &g_sa is added as the param for CreateNamedPipe. Granted, this is blowing-the-bloody-doors-off territory, but if you want anyone to be able to access it, you don't have a lot of choice.

Bob Moore
  • 6,788
  • 3
  • 29
  • 42