Skip to content

Commit 3829b40

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 d03ea82 commit 3829b40

File tree

1 file changed

+57
-13
lines changed

1 file changed

+57
-13
lines changed

sql/mysqld.cc

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,6 +2582,62 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
25822582
DBUG_RETURN(ip_sock);
25832583
}
25842584

2585+
#ifdef _WIN32
2586+
/*
2587+
Create a security descriptor for pipe.
2588+
- Use low integrity level, so that it is possible to connect
2589+
from any process.
2590+
- Give current user read/write access to pipe.
2591+
- Give Everyone read/write access to pipe minus FILE_CREATE_PIPE_INSTANCE
2592+
*/
2593+
static void init_pipe_security_descriptor()
2594+
{
2595+
#define SDDL_FMT "S:(ML;; NW;;; LW) D:(A;; 0x%08x;;; WD)(A;; FRFW;;; %s)"
2596+
#define EVERYONE_PIPE_ACCESS_MASK \
2597+
(FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES | READ_CONTROL | \
2598+
SYNCHRONIZE | FILE_WRITE_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
2599+
2600+
/*
2601+
Figure out SID of the user that runs the server, then create SDDL string
2602+
for pipe permissions, and convert it to the security descriptor.
2603+
*/
2604+
char sddl_string[sizeof(SDDL_FMT) + 8 + SECURITY_MAX_SID_STRING_CHARACTERS];
2605+
struct
2606+
{
2607+
TOKEN_USER token_user;
2608+
BYTE buffer[SECURITY_MAX_SID_SIZE];
2609+
} token_buffer;
2610+
HANDLE token;
2611+
DWORD tmp;
2612+
2613+
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
2614+
goto fail;
2615+
2616+
if (!GetTokenInformation(token, TokenUser, &token_buffer,
2617+
(DWORD) sizeof(token_buffer), &tmp))
2618+
goto fail;
2619+
2620+
CloseHandle(token);
2621+
2622+
char *current_user_string_sid;
2623+
if (!ConvertSidToStringSid(token_buffer.token_user.User.Sid,
2624+
&current_user_string_sid))
2625+
goto fail;
2626+
2627+
snprintf(sddl_string, sizeof(sddl_string), SDDL_FMT,
2628+
EVERYONE_PIPE_ACCESS_MASK, current_user_string_sid);
2629+
LocalFree(current_user_string_sid);
2630+
2631+
if (ConvertStringSecurityDescriptorToSecurityDescriptor(sddl_string,
2632+
SDDL_REVISION_1, &saPipeSecurity.lpSecurityDescriptor, 0))
2633+
return;
2634+
2635+
fail:
2636+
sql_perror("Can't start server : Initialize security descriptor");
2637+
unireg_abort(1);
2638+
}
2639+
#endif
2640+
25852641
static void network_init(void)
25862642
{
25872643
#ifdef HAVE_SYS_UN_H
@@ -2619,19 +2675,7 @@ static void network_init(void)
26192675

26202676
strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
26212677
mysqld_unix_port, NullS);
2622-
/*
2623-
Create a security descriptor for pipe.
2624-
- Use low integrity level, so that it is possible to connect
2625-
from any process.
2626-
- Give Everyone read/write access to pipe.
2627-
*/
2628-
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
2629-
"S:(ML;; NW;;; LW) D:(A;; FRFW;;; WD)",
2630-
SDDL_REVISION_1, &saPipeSecurity.lpSecurityDescriptor, NULL))
2631-
{
2632-
sql_perror("Can't start server : Initialize security descriptor");
2633-
unireg_abort(1);
2634-
}
2678+
init_pipe_security_descriptor();
26352679
saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
26362680
saPipeSecurity.bInheritHandle = FALSE;
26372681
if ((hPipe= CreateNamedPipe(pipe_name,

0 commit comments

Comments
 (0)