From ecc5a07874d44307b835ff5dbd091343961fbc93 Mon Sep 17 00:00:00 2001 From: Shishir Jaiswal Date: Sat, 2 Dec 2017 15:12:32 +0530 Subject: Bug#26585560 - MYSQL DAEMON SHOULD CREATE ITS PID FILE AS ROOT DESCRIPTION =========== If the .pid file is created at a world-writable location, it can be compromised by replacing the server's pid with another running server's (or some other non-mysql process) PID causing abnormal behaviour. ANALYSIS ======== In such a case, user should be warned that .pid file is being created at a world-writable location. FIX === A new function is_file_or_dir_world_writable() is defined and it is called in create_pid_file() before .pid file creation. If the location is world-writable, a relevant warning is thrown. NOTE ==== 1. PID file is always created with permission bit 0664, so for outside world its read-only. 2. Ignoring the case when permission is denied to get the dir stats since the .pid file creation would fail anyway in such a case. --- sql/mysqld.cc | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'sql/mysqld.cc') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c969fd8a62a..fd39e252c26 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify @@ -7996,6 +7996,40 @@ static int test_if_case_insensitive(const char *dir_name) static void create_pid_file() { File file; + bool check_parent_path= 1, is_path_accessible= 1; + char pid_filepath[FN_REFLEN], *pos= NULL; + /* Copy pid file name to get pid file path */ + strcpy(pid_filepath, pidfile_name); + + /* Iterate through the entire path to check if even one of the sub-dirs + is world-writable */ + while (check_parent_path && (pos= strrchr(pid_filepath, FN_LIBCHAR)) + && (pos != pid_filepath)) /* shouldn't check root */ + { + *pos= '\0'; /* Trim the inner-most dir */ + switch (is_file_or_dir_world_writable(pid_filepath)) + { + case -2: + is_path_accessible= 0; + break; + case -1: + sql_perror("Can't start server: can't check PID filepath"); + exit(1); + case 1: + sql_print_warning("Insecure configuration for --pid-file: Location " + "'%s' in the path is accessible to all OS users. " + "Consider choosing a different directory.", + pid_filepath); + check_parent_path= 0; + break; + case 0: + continue; /* Keep checking the parent dir */ + } + } + if (!is_path_accessible) + { + sql_print_warning("Few location(s) are inaccessible while checking PID filepath."); + } if ((file= mysql_file_create(key_file_pid, pidfile_name, 0664, O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0) { -- cgit v1.2.1