Skip to content

Commit c5b22c1

Browse files
ssorumgardbjornmu
authored andcommitted
Merge branch 'mysql-5.5' into mysql-5.6
(cherry picked from commit 3084723f76d19990f3573c5ec614709f567df78b)
1 parent 2e1d916 commit c5b22c1

File tree

4 files changed

+129
-10
lines changed

4 files changed

+129
-10
lines changed

sql/log.cc

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -1494,6 +1494,78 @@ bool MYSQL_LOG::init_and_set_log_file_name(const char *log_name,
14941494
}
14951495

14961496

1497+
bool is_valid_log_name(const char *name, size_t len)
1498+
{
1499+
if (len > 3)
1500+
{
1501+
const char *tail= name + len - 4;
1502+
if (my_strcasecmp(system_charset_info, tail, ".ini") == 0 ||
1503+
my_strcasecmp(system_charset_info, tail, ".cnf") == 0)
1504+
{
1505+
return false;
1506+
}
1507+
}
1508+
return true;
1509+
}
1510+
1511+
1512+
/**
1513+
Get the real log file name, and possibly reopen file.
1514+
1515+
Use realpath() to get the path with symbolic links
1516+
expanded. Then, close the file, and reopen the real path using the
1517+
O_NOFOLLOW flag. This will reject following symbolic links.
1518+
1519+
@param file File descriptor.
1520+
@param log_file_key Key for P_S instrumentation.
1521+
@param open_flags Flags to use for opening the file.
1522+
@param opened_file_name Name of the open fd.
1523+
1524+
@retval file descriptor to open file with 'real_file_name', or '-1'
1525+
in case of errors.
1526+
*/
1527+
1528+
#ifndef _WIN32
1529+
static File mysql_file_real_name_reopen(File file,
1530+
#ifdef HAVE_PSI_INTERFACE
1531+
PSI_file_key log_file_key,
1532+
#endif
1533+
int open_flags,
1534+
const char *opened_file_name)
1535+
{
1536+
DBUG_ASSERT(file);
1537+
DBUG_ASSERT(opened_file_name);
1538+
1539+
/* Buffer for realpath must have capacity for PATH_MAX. */
1540+
char real_file_name[PATH_MAX];
1541+
1542+
/* Get realpath, validate, open realpath with O_NOFOLLOW. */
1543+
if (realpath(opened_file_name, real_file_name) == NULL)
1544+
{
1545+
(void) mysql_file_close(file, MYF(0));
1546+
return -1;
1547+
}
1548+
1549+
if (mysql_file_close(file, MYF(0)))
1550+
return -1;
1551+
1552+
if (strlen(real_file_name) > FN_REFLEN)
1553+
return -1;
1554+
1555+
if (!is_valid_log_name(real_file_name, strlen(real_file_name)))
1556+
{
1557+
sql_print_error("Invalid log file name after expanding symlinks: '%s'",
1558+
real_file_name);
1559+
return -1;
1560+
}
1561+
1562+
return mysql_file_open(log_file_key, real_file_name,
1563+
open_flags | O_NOFOLLOW,
1564+
MYF(MY_WME | ME_WAITTANG));
1565+
}
1566+
#endif // _WIN32
1567+
1568+
14971569
/*
14981570
Open a (new) log file.
14991571
@@ -1564,6 +1636,18 @@ bool MYSQL_LOG::open(
15641636
MYF(MY_WME | ME_WAITTANG))) < 0)
15651637
goto err;
15661638

1639+
#ifndef _WIN32
1640+
/* Reopen and validate path. */
1641+
if ((log_type_arg == LOG_UNKNOWN || log_type_arg == LOG_NORMAL) &&
1642+
(file= mysql_file_real_name_reopen(file,
1643+
#ifdef HAVE_PSI_INTERFACE
1644+
log_file_key,
1645+
#endif
1646+
open_flags,
1647+
log_file_name)) < 0)
1648+
goto err;
1649+
#endif // _WIN32
1650+
15671651
if ((pos= mysql_file_tell(file, MYF(MY_WME))) == MY_FILEPOS_ERROR)
15681652
{
15691653
if (my_errno == ESPIPE)

sql/log.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -578,6 +578,16 @@ bool flush_error_log();
578578

579579
char *make_log_name(char *buff, const char *name, const char* log_ext);
580580

581+
/**
582+
Check given log name against certain blacklisted names/extensions.
583+
584+
@param name Log name to check
585+
@param len Length of log name
586+
587+
@returns true if name is valid, false otherwise.
588+
*/
589+
bool is_valid_log_name(const char *name, size_t len);
590+
581591
extern LOGGER logger;
582592

583593
#endif /* LOG_H */

sql/mysqld.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4111,6 +4111,22 @@ int init_common_variables()
41114111
if (!opt_slow_logname || !*opt_slow_logname)
41124112
opt_slow_logname= make_default_log_name(slow_logname_path, "-slow.log");
41134113

4114+
if (opt_logname &&
4115+
!is_valid_log_name(opt_logname, strlen(opt_logname)))
4116+
{
4117+
sql_print_error("Invalid value for --general_log_file: %s",
4118+
opt_logname);
4119+
return 1;
4120+
}
4121+
4122+
if (opt_slow_logname &&
4123+
!is_valid_log_name(opt_slow_logname, strlen(opt_slow_logname)))
4124+
{
4125+
sql_print_error("Invalid value for --slow_query_log_file: %s",
4126+
opt_slow_logname);
4127+
return 1;
4128+
}
4129+
41144130
#if defined(ENABLED_DEBUG_SYNC)
41154131
/* Initialize the debug sync facility. See debug_sync.cc. */
41164132
if (debug_sync_init())

sql/sys_vars.cc

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
22

33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -3682,6 +3682,14 @@ static bool check_log_path(sys_var *self, THD *thd, set_var *var)
36823682
if (!var->save_result.string_value.str)
36833683
return true;
36843684

3685+
if (!is_valid_log_name(var->save_result.string_value.str,
3686+
var->save_result.string_value.length))
3687+
{
3688+
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
3689+
self->name.str, var->save_result.string_value.str);
3690+
return true;
3691+
}
3692+
36853693
if (var->save_result.string_value.length > FN_REFLEN)
36863694
{ // path is too long
36873695
my_error(ER_PATH_LENGTH, MYF(0), self->name.str);
@@ -3728,7 +3736,7 @@ static bool check_log_path(sys_var *self, THD *thd, set_var *var)
37283736
return false;
37293737
}
37303738
static bool fix_log(char** logname, const char* default_logname,
3731-
const char*ext, bool enabled, void (*reopen)(char*))
3739+
const char*ext, bool enabled, bool (*reopen)(char*))
37323740
{
37333741
if (!*logname) // SET ... = DEFAULT
37343742
{
@@ -3740,16 +3748,17 @@ static bool fix_log(char** logname, const char* default_logname,
37403748
}
37413749
logger.lock_exclusive();
37423750
mysql_mutex_unlock(&LOCK_global_system_variables);
3751+
bool error= false;
37433752
if (enabled)
3744-
reopen(*logname);
3753+
error= reopen(*logname);
37453754
logger.unlock();
37463755
mysql_mutex_lock(&LOCK_global_system_variables);
3747-
return false;
3756+
return error;
37483757
}
3749-
static void reopen_general_log(char* name)
3758+
static bool reopen_general_log(char* name)
37503759
{
37513760
logger.get_log_file_handler()->close(0);
3752-
logger.get_log_file_handler()->open_query_log(name);
3761+
return logger.get_log_file_handler()->open_query_log(name);
37533762
}
37543763
static bool fix_general_log_file(sys_var *self, THD *thd, enum_var_type type)
37553764
{
@@ -3762,10 +3771,10 @@ static Sys_var_charptr Sys_general_log_path(
37623771
IN_FS_CHARSET, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
37633772
ON_CHECK(check_log_path), ON_UPDATE(fix_general_log_file));
37643773

3765-
static void reopen_slow_log(char* name)
3774+
static bool reopen_slow_log(char* name)
37663775
{
37673776
logger.get_slow_log_file_handler()->close(0);
3768-
logger.get_slow_log_file_handler()->open_slow_log(name);
3777+
return logger.get_slow_log_file_handler()->open_slow_log(name);
37693778
}
37703779
static bool fix_slow_log_file(sys_var *self, THD *thd, enum_var_type type)
37713780
{

0 commit comments

Comments
 (0)