Skip to content

Commit df8ef23

Browse files
committed
Bug#35304195: ssl_session_data_print creates world readable files by default
When the ssl_session_data_print mysql client command is being output to file, the result file is created as world readable. The solution is to create file with 0600 access permission, instead of using the existing 0644 default. Solution is Unix specific, behaviour stays the same on Windows due to missing group|other permissions concept for this platform within the MySQL posix wrappers. Change-Id: I0e9f8040c0f0dd01e46631cab32b56dc9fc451e6
1 parent c329b4d commit df8ef23

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

client/mysql.cc

+18-10
Original file line numberDiff line numberDiff line change
@@ -4617,34 +4617,42 @@ static int com_ssl_session_data_print(String *buffer [[maybe_unused]],
46174617
char msgbuf[256];
46184618
char *param = get_arg(line, false);
46194619
const char *err_text = nullptr;
4620-
FILE *fo = nullptr;
4621-
void *data = nullptr;
4620+
File fo = -1;
4621+
char *data = nullptr;
4622+
const bool use_outfile = (param != nullptr);
46224623

4623-
if (param) {
4624-
if (nullptr == (fo = fopen(param, "w"))) {
4624+
if (use_outfile) {
4625+
// result file is access protected (0600)
4626+
const MY_MODE file_creation_mode = get_file_perm(USER_READ | USER_WRITE);
4627+
const int access_flags = O_WRONLY | O_TRUNC | O_CREAT;
4628+
4629+
fo = my_create(param, file_creation_mode, access_flags, MYF(0));
4630+
if (fo == -1) {
46254631
err_text = "Failed to open the output file";
46264632
goto end;
46274633
}
4628-
} else
4629-
fo = stdout;
4634+
} else {
4635+
fo = my_fileno(stdout);
4636+
}
46304637

4631-
data = mysql_get_ssl_session_data(&mysql, 0, nullptr);
4638+
data =
4639+
reinterpret_cast<char *>(mysql_get_ssl_session_data(&mysql, 0, nullptr));
46324640
if (!data) {
46334641
err_text = nullptr;
46344642
put_error(&mysql);
46354643
goto end;
46364644
}
4637-
if (0 > fputs(reinterpret_cast<char *>(data), fo)) {
4645+
if (my_write(fo, (uchar *)data, strlen(data), MYF(0)) == MY_FILE_ERROR) {
46384646
snprintf(msgbuf, sizeof(msgbuf), "Write of session data failed: %d (%s)",
46394647
errno, strerror(errno));
46404648
err_text = &msgbuf[0];
46414649
goto end;
46424650
}
4643-
if (fo == stdout) fputs("\n", fo);
4651+
if (!use_outfile && fo != -1) my_write(fo, (const uchar *)"\n", 1, MYF(0));
46444652

46454653
end:
46464654
if (data) mysql_free_ssl_session_data(&mysql, data);
4647-
if (fo && fo != stdout) fclose(fo);
4655+
if (use_outfile && fo != -1) (void)my_close(fo, MYF(0));
46484656
if (err_text) return put_info(err_text, INFO_ERROR);
46494657
return 0;
46504658
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#
2+
# Bug#35304195: ssl_session_data_print creates world readable files by default
3+
#
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--echo #
2+
--echo # Bug#35304195: ssl_session_data_print creates world readable files by default
3+
--echo #
4+
5+
--source include/not_windows.inc
6+
7+
# print SSL session .pem contents to file
8+
let SESSION_FILE=$MYSQLTEST_VARDIR/tmp/ssldata.pem;
9+
exec $MYSQL --ssl-mode=required -e "ssl_session_data_print $SESSION_FILE" 2>&1 > /dev/null;
10+
11+
# assert the file has correct access permissions (0600)
12+
--perl
13+
use strict;
14+
my $mode = (stat($ENV{SESSION_FILE}))[2];
15+
my $perm = sprintf "%04o", ($mode & 07777);
16+
die "Invalid permission $perm for $ENV{SESSION_FILE}" unless $perm == '0600';
17+
EOF
18+
19+
--remove_file $SESSION_FILE

0 commit comments

Comments
 (0)