WL#6782: Limit the scope of the FILE privilege in the default installation

Affects: Server-5.7   —   Status: Complete   —   Priority: Medium

FILE privilege provides ability to read and write files on the server host to a
user. Such user can read any file on server host that is either world-readable
or readable by MySQL server and write files through commands like SELECT ...
INTO... . In order to limit the scope of FILE privilege, MySQL provides
--secure-file-priv option which, when set to point to a directory, restricts
read and write operation using FILE privilege to that directory.
https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_secure-file-priv

This options defaults NULL which essentially allows users with FILE privilege to
create files at any location where MySQL server has write permission.

To provide a more secure installation, scope of FILE privilege should be
restricted using a secure default value for --secure-file-priv. In addition,
server should warn users of insecure configuration for --secure-file-priv at
start-up time. This worklog will track these changes.
F1 : BUILD_CONFIG parameter of CMAKE should support configuration options for
all supported linuxes and STANDALONE mode Configuration options for installation
layout on FreeBSD, OS X, SLES, GLIBC, Generic .tar.gz installers should be added.

F2 : For deployment other than those done for development, --secure-file-priv
should default to /var/lib/mysql-files on all Unixes.

F3 : At start-up time, Server should should throw warning if insecure
configuration is used for --secure-file-priv. Cases include:
a> Empty string
b> Full or part of data directory
c> A location which is accessible by all users
Following inputs were received from discussion on dev-private:

1> New installation should create a default directory within installation e.g.
.../share and --secure-file-priv will point to such directory by default.
2> --secure-file-priv should support more than one directory.
3> If my.cnf/my.ini does not contain any value for --secure-file-priv, upgrade
process should create a default directory within installation subbranch. If such
a directory already exists, permission should be checked.
4> Installer should inform customer about start up variable, its value and its
impact on external files.
5> GUI based installation program should provide way to set/select directory for
--secure-file-priv option and provide text to be incorporated in config file.
6> Support "NULL" value for --secure-file-priv to indicate that a less secure
configuration has been selected. An appropriate warning should be generated if
"NULL" value is used for --secure-file-priv.
7> Allow session specific values for --secure-file-priv variable. This way
different applications can have their data segregated from that of others and
prevent information leakage from one account to another. This is needed for
shared hosting. RightNow can provide more suggestions.

From above mentioned wishlist:
About 1> : proposes to create /var/lib/share. Instead,
<data_directory>/../mysql-files will be used.

About 2> and 7> : They will not be implemented as a part of this WL. A separate
WL will be filed for them.

About 3> : This will be addressed by packaging scripts should always use correct
build configuration from install_layout.cmake script.

About 4> : This is addressed in slightly different manner. Instead of installer
warning customer, MySQL server will warn customer about impact of insecure value
for --secure-file-priv.

About 5> : None of the linux installer are GUI based and since this WL
concentrates on linuxes, this feature is not implemented by the WL.

About 6> : --secure-file-priv already supports "" which means users can create
files in any directory where MySQL server has write permission.

Interface specification is as follows:


I-1: Introduce CMAKE variable DEFAULT_SECURE_FILE_PRIV_PATH. This variable will
control default value for --secure-file-priv.

I-2: Modify BUILD_CONFIG to support additional values : FREEBSD, GLIBC, OSX,
SLES, TARGZ

CMAKE supports BUILD_CONFIG which takes one of the following values:
RPM, DEB, SVR4, STANDALONE. RPM, DEB and SVR4 are used by packaging scripts for
fedora, debian and solaris OSes respectively. However, configuration option
STANDALONE is used for following OSes: FreeBSD, OS X, SLES, Generic .tar.gz
installers.

This WL proposes to introduce separate configuration for each OS (and generic
.tar.gz) installer. In new configuration, RPM, DEB, SVR4, FREEBSD, GLIBC, OSX,
SLES, TARGZ should be used by packaging scripts to generate packages on various
OSes. STANDALONE mode should be reserved and used for installations created for
development purposes.

This would allow packaging scripts to use platform specific secure locations for
variables such as DEFAULT_SECURE_FILE_PRIV_PATH and at the same time provide
flexibility for dev builds to choose moderate configuration which is easy to
deploy and test.

I-3: For BUILD_CONFIG values other than STANDALONE,
DEFAULT_SECURE_FILE_PRIV_PATH should point to <data_directory>/../mysql-files.

I-3: At start-up, server will throw warnings in following scenarios:
a> If --secure-file-priv points to "" which potentially allows a user to create
file at any location where MySQL server has write permission

b> If --secure-file-priv points to full or part of data directory.

c> If --secure-file-priv points to a directory accessible by other users.

FHS reference: http://www.pathname.com/fhs/pub/fhs-2.2.pdf