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.
This commit is contained in:
Shishir Jaiswal 2017-12-02 15:12:32 +05:30
commit ecc5a07874
5 changed files with 98 additions and 3 deletions

View file

@ -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)
{