Skip to content

Commit e451145

Browse files
committed
MDEV-24040 Named pipe permission issue
Tighten access control - deny FILE_CREATE_PIPE_INSTANCE permission to everyone except current user (the one that runs mysqld)
1 parent ec0e9d6 commit e451145

File tree

1 file changed

+59
-7
lines changed

1 file changed

+59
-7
lines changed

sql/handle_connections_win.cc

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,64 @@ retry :
310310
}
311311
};
312312

313+
/*
314+
Create a security descriptor for pipe.
315+
- Use low integrity level, so that it is possible to connect
316+
from any process.
317+
- Give current user read/write access to pipe.
318+
- Give Everyone read/write access to pipe minus FILE_CREATE_PIPE_INSTANCE
319+
*/
320+
static void init_pipe_security_descriptor()
321+
{
322+
#define SDDL_FMT "S:(ML;; NW;;; LW) D:(A;; 0x%08x;;; WD)(A;; FRFW;;; %s)"
323+
#define EVERYONE_PIPE_ACCESS_MASK \
324+
(FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | READ_CONTROL | \
325+
SYNCHRONIZE | FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
326+
327+
#ifndef SECURITY_MAX_SID_STRING_CHARACTERS
328+
/* Old SDK does not have this constant */
329+
#define SECURITY_MAX_SID_STRING_CHARACTERS 187
330+
#endif
331+
332+
/*
333+
Figure out SID of the user that runs the server, then create SDDL string
334+
for pipe permissions, and convert it to the security descriptor.
335+
*/
336+
char sddl_string[sizeof(SDDL_FMT) + 8 + SECURITY_MAX_SID_STRING_CHARACTERS];
337+
struct
338+
{
339+
TOKEN_USER token_user;
340+
BYTE buffer[SECURITY_MAX_SID_SIZE];
341+
} token_buffer;
342+
HANDLE token;
343+
DWORD tmp;
344+
345+
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
346+
goto fail;
347+
348+
if (!GetTokenInformation(token, TokenUser, &token_buffer,
349+
(DWORD) sizeof(token_buffer), &tmp))
350+
goto fail;
351+
352+
CloseHandle(token);
353+
354+
char *current_user_string_sid;
355+
if (!ConvertSidToStringSid(token_buffer.token_user.User.Sid,
356+
&current_user_string_sid))
357+
goto fail;
358+
359+
snprintf(sddl_string, sizeof(sddl_string), SDDL_FMT,
360+
EVERYONE_PIPE_ACCESS_MASK, current_user_string_sid);
361+
LocalFree(current_user_string_sid);
362+
363+
if (ConvertStringSecurityDescriptorToSecurityDescriptor(sddl_string,
364+
SDDL_REVISION_1, &pipe_security.lpSecurityDescriptor, 0))
365+
return;
366+
367+
fail:
368+
sql_perror("Can't start server : Initialize security descriptor");
369+
unireg_abort(1);
370+
}
313371

314372
/**
315373
Pipe Listener.
@@ -338,13 +396,7 @@ struct Pipe_Listener : public Listener
338396
{
339397
snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\%s", mysqld_unix_port);
340398
open_mode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
341-
if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(
342-
"S:(ML;; NW;;; LW) D:(A;; FRFW;;; WD)",
343-
1, &pipe_security.lpSecurityDescriptor, NULL))
344-
{
345-
sql_perror("Can't start server : Initialize security descriptor");
346-
unireg_abort(1);
347-
}
399+
init_pipe_security_descriptor();
348400
pipe_security.nLength= sizeof(SECURITY_ATTRIBUTES);
349401
pipe_security.bInheritHandle= FALSE;
350402
}

0 commit comments

Comments
 (0)