summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2020-10-27 20:31:16 +0100
committerVladislav Vaintroub <wlad@mariadb.com>2020-10-27 22:39:21 +0100
commit3829b408d689182f05804ec045c9705da8de4e34 (patch)
treeb8bdd6e62be42946a70a6a9aa525f46819d2d1a0
parentd03ea82759aef7734f162c3137b10aa2476b35e9 (diff)
downloadmariadb-git-bb-10.1-wlad.tar.gz
MDEV-24040 Named pipe permission issuebb-10.1-wlad
Tighten access control - deny FILE_CREATE_PIPE_INSTANCE permission to everyone except current user (the one that runs mysqld)
-rw-r--r--sql/mysqld.cc70
1 files changed, 57 insertions, 13 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 8d00b5af948..3a5222d32de 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2582,6 +2582,62 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
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)
{
#ifdef HAVE_SYS_UN_H
@@ -2619,19 +2675,7 @@ static void network_init(void)
strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
mysqld_unix_port, NullS);
- /*
- 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);
- }
+ init_pipe_security_descriptor();
saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
saPipeSecurity.bInheritHandle = FALSE;
if ((hPipe= CreateNamedPipe(pipe_name,