Commit 3829b408 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

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)
parent d03ea827
...@@ -2582,6 +2582,62 @@ static MYSQL_SOCKET activate_tcp_port(uint port) ...@@ -2582,6 +2582,62 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
DBUG_RETURN(ip_sock); DBUG_RETURN(ip_sock);
} }
#ifdef _WIN32
/*
Create a security descriptor for pipe.
- Use low integrity level, so that it is possible to connect
from any process.
- Give current user read/write access to pipe.
- Give Everyone read/write access to pipe minus FILE_CREATE_PIPE_INSTANCE
*/
static void init_pipe_security_descriptor()
{
#define SDDL_FMT "S:(ML;; NW;;; LW) D:(A;; 0x%08x;;; WD)(A;; FRFW;;; %s)"
#define EVERYONE_PIPE_ACCESS_MASK \
(FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | READ_CONTROL | \
SYNCHRONIZE | FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
/*
Figure out SID of the user that runs the server, then create SDDL string
for pipe permissions, and convert it to the security descriptor.
*/
char sddl_string[sizeof(SDDL_FMT) + 8 + SECURITY_MAX_SID_STRING_CHARACTERS];
struct
{
TOKEN_USER token_user;
BYTE buffer[SECURITY_MAX_SID_SIZE];
} token_buffer;
HANDLE token;
DWORD tmp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
goto fail;
if (!GetTokenInformation(token, TokenUser, &token_buffer,
(DWORD) sizeof(token_buffer), &tmp))
goto fail;
CloseHandle(token);
char *current_user_string_sid;
if (!ConvertSidToStringSid(token_buffer.token_user.User.Sid,
&current_user_string_sid))
goto fail;
snprintf(sddl_string, sizeof(sddl_string), SDDL_FMT,
EVERYONE_PIPE_ACCESS_MASK, current_user_string_sid);
LocalFree(current_user_string_sid);
if (ConvertStringSecurityDescriptorToSecurityDescriptor(sddl_string,
SDDL_REVISION_1, &saPipeSecurity.lpSecurityDescriptor, 0))
return;
fail:
sql_perror("Can't start server : Initialize security descriptor");
unireg_abort(1);
}
#endif
static void network_init(void) static void network_init(void)
{ {
#ifdef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H
...@@ -2619,19 +2675,7 @@ static void network_init(void) ...@@ -2619,19 +2675,7 @@ static void network_init(void)
strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\", strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
mysqld_unix_port, NullS); mysqld_unix_port, NullS);
/* init_pipe_security_descriptor();
Create a security descriptor for pipe.
- Use low integrity level, so that it is possible to connect
from any process.
- Give Everyone read/write access to pipe.
*/
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
"S:(ML;; NW;;; LW) D:(A;; FRFW;;; WD)",
SDDL_REVISION_1, &saPipeSecurity.lpSecurityDescriptor, NULL))
{
sql_perror("Can't start server : Initialize security descriptor");
unireg_abort(1);
}
saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
saPipeSecurity.bInheritHandle = FALSE; saPipeSecurity.bInheritHandle = FALSE;
if ((hPipe= CreateNamedPipe(pipe_name, if ((hPipe= CreateNamedPipe(pipe_name,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment