MDEV-27038 Custom configuration file procedure does not work with Docker Desktop for Windows 10+
Docker when mounting a configuration file into a Windows exposes the file with permission 0777. These world writable files are ignored by by MariaDB. Add the access check such that filesystem RO or immutable file is counted as sufficient protection on the file. Test: $ mkdir /tmp/src $ vi /tmp/src/my.cnf $ chmod 666 /tmp/src/my.cnf $ mkdir /tmp/dst $ sudo mount --bind /tmp/src /tmp/dst -o ro $ ls -la /tmp/dst total 4 drwxr-xr-x. 2 dan dan 60 Jun 15 15:12 . drwxrwxrwt. 25 root root 660 Jun 15 15:13 .. -rw-rw-rw-. 1 dan dan 10 Jun 15 15:12 my.cnf $ mount | grep dst tmpfs on /tmp/dst type tmpfs (ro,seclabel,nr_inodes=1048576,inode64) strace client/mariadb --defaults-file=/tmp/dst/my.cnf newfstatat(AT_FDCWD, "/tmp/dst/my.cnf", {st_mode=S_IFREG|0666, st_size=10, ...}, 0) = 0 access("/tmp/dst/my.cnf", W_OK) = -1 EROFS (Read-only file system) openat(AT_FDCWD, "/tmp/dst/my.cnf", O_RDONLY|O_CLOEXEC) = 3 The one failing test, but this isn't a regression, just not a total fix: $ chmod u-w /tmp/src/my.cnf $ ls -la /tmp/src/my.cnf -r--rw-rw-. 1 dan dan 18 Jun 16 10:22 /tmp/src/my.cnf $ strace -fe trace=access client/mariadb --defaults-file=/tmp/dst/my.cnf access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) access("/etc/system-fips", F_OK) = -1 ENOENT (No such file or directory) access("/tmp/dst/my.cnf", W_OK) = -1 EACCES (Permission denied) Warning: World-writable config file '/tmp/dst/my.cnf' is ignored Windows test (Docker Desktop ~4.21) which was the important one to fix: dan@LAPTOP-5B5P7RCK:~$ docker run --rm -v /mnt/c/Users/danie/Desktop/conf:/etc/mysql/conf.d/:ro -e MARIADB_ROOT_PASSWORD=bob quay.io/m ariadb-foundation/mariadb-devel:10.4-MDEV-27038-ro-mounts-pkgtest ls -la /etc/mysql/conf.d total 4 drwxrwxrwx 1 root root 512 Jun 15 13:57 . drwxr-xr-x 4 root root 4096 Jun 15 07:32 .. -rwxrwxrwx 1 root root 43 Jun 15 13:56 myapp.cnf root@a59b38b45af1:/# strace -fe trace=access mariadb access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) access("/etc/mysql/conf.d/myapp.cnf", W_OK) = -1 EROFS (Read-only file system)
This commit is contained in:
parent
7a5c984fa3
commit
23d53913fb
@ -786,12 +786,27 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
|
||||
if (!my_stat(name,&stat_info,MYF(0)))
|
||||
return 1;
|
||||
/*
|
||||
Ignore world-writable regular files.
|
||||
This is mainly done to protect us to not read a file created by
|
||||
the mysqld server, but the check is still valid in most context.
|
||||
Ignore world-writable regular files (exceptions apply).
|
||||
This is mainly done to protect us to not read a file that may be
|
||||
modified by anyone.
|
||||
|
||||
Also check access so that read only mounted (EROFS)
|
||||
or immutable files (EPERM) that are suitable protections.
|
||||
|
||||
The main case we are allowing is a container readonly volume mount
|
||||
from a filesystem that doesn't have unix permissions. This will
|
||||
have a 0777 permission and access will set errno = EROFS.
|
||||
|
||||
Note if a ROFS has a file with permissions 04n6, access sets errno
|
||||
EACCESS, rather the ROFS, so in this case we'll error, even though
|
||||
the ROFS is protecting the file.
|
||||
|
||||
An ideal, race free, implementation would do fstat / fstatvfs / ioctl
|
||||
for permission, read only filesystem, and immutability resprectively.
|
||||
*/
|
||||
if ((stat_info.st_mode & S_IWOTH) &&
|
||||
(stat_info.st_mode & S_IFMT) == S_IFREG)
|
||||
(stat_info.st_mode & S_IFMT) == S_IFREG &&
|
||||
(access(name, W_OK) == 0 || (errno != EROFS && errno != EPERM)))
|
||||
{
|
||||
fprintf(stderr, "Warning: World-writable config file '%s' is ignored\n",
|
||||
name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user