From 0a63c91ab051b4dc271a3fc75b3e104653e89abb Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 2 Mar 2018 10:16:46 +1100 Subject: [PATCH 1/2] MDEV-8743: fopen mode e (glibc only) to prevent galera SST scripts accessing server files For RemoteDatafile::read_link_file and buffer poool dumps Note: STR_O_CLOEXEC needs to be at the end of the fopen otherwise fopen will return EINVAL. --- include/my_global.h | 5 +++++ storage/innobase/buf/buf0dump.cc | 4 ++-- storage/innobase/fsp/fsp0file.cc | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 1b17721ddcc..7d3cc13e88e 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -591,6 +591,11 @@ typedef SOCKET_SIZE_TYPE size_socket; #ifndef O_CLOEXEC #define O_CLOEXEC 0 #endif +#ifdef __GLIBC__ +#define STR_O_CLOEXEC "e" +#else +#define STR_O_CLOEXEC "" +#endif #ifndef SOCK_CLOEXEC #define SOCK_CLOEXEC 0 #endif diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index ea660ad3a50..62b4d1ee255 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -275,7 +275,7 @@ buf_dump( buf_dump_status(STATUS_INFO, "Dumping buffer pool(s) to %s", full_filename); - f = fopen(tmp_filename, "w"); + f = fopen(tmp_filename, "w" STR_O_CLOEXEC); if (f == NULL) { buf_dump_status(STATUS_ERR, "Cannot open '%s' for writing: %s", @@ -516,7 +516,7 @@ buf_load() buf_load_status(STATUS_INFO, "Loading buffer pool(s) from %s", full_filename); - f = fopen(full_filename, "r"); + f = fopen(full_filename, "r" STR_O_CLOEXEC); if (f == NULL) { buf_load_status(STATUS_INFO, "Cannot open '%s' for reading: %s", diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 6e9f307ebc8..2a0cb5a8fee 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -1043,7 +1043,7 @@ char* RemoteDatafile::read_link_file( const char* link_filepath) { - FILE* file = fopen(link_filepath, "r+b"); + FILE* file = fopen(link_filepath, "r+b" STR_O_CLOEXEC); if (file == NULL) { return(NULL); } From fafec1a9cc053f132f5ecd67626832a4a739f2b8 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 14 Mar 2018 13:31:28 +1100 Subject: [PATCH 2/2] MDEV-8743: where O_CLOEXEC is available, use for innodb buf_dump As this is the only moderately critical fopened for writing file, create an alternate path to use open and fdopen for non-glibc platforms that support O_CLOEXEC (BSDs). Tested on Linux (by modifing the GLIBC defination) to take this alternate path: $ cd /proc/23874 $ more fdinfo/71 pos: 0 flags: 02100001 mnt_id: 24 $ ls -la fd/71 l-wx------. 1 dan dan 64 Mar 14 13:30 fd/71 -> /dev/shm/var_auto_i7rl/mysqld.1/data/ib_buffer_pool.incomplete --- storage/innobase/buf/buf0dump.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index 62b4d1ee255..3ccb014cae0 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -275,7 +275,20 @@ buf_dump( buf_dump_status(STATUS_INFO, "Dumping buffer pool(s) to %s", full_filename); +#if defined(__GLIBC__) || defined(__WIN__) || O_CLOEXEC == 0 f = fopen(tmp_filename, "w" STR_O_CLOEXEC); +#else + { + int fd; + fd = open(tmp_filename, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, 0640); + if (fd >= 0) { + f = fdopen(fd, "w"); + } + else { + f = NULL; + } + } +#endif if (f == NULL) { buf_dump_status(STATUS_ERR, "Cannot open '%s' for writing: %s",