|
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. |
2 | 2 |
|
3 | 3 | This program is free software; you can redistribute it and/or modify |
4 | 4 | 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, |
1494 | 1494 | } |
1495 | 1495 |
|
1496 | 1496 |
|
| 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 | + |
1497 | 1569 | /* |
1498 | 1570 | Open a (new) log file. |
1499 | 1571 |
|
@@ -1564,6 +1636,18 @@ bool MYSQL_LOG::open( |
1564 | 1636 | MYF(MY_WME | ME_WAITTANG))) < 0) |
1565 | 1637 | goto err; |
1566 | 1638 |
|
| 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 | + |
1567 | 1651 | if ((pos= mysql_file_tell(file, MYF(MY_WME))) == MY_FILEPOS_ERROR) |
1568 | 1652 | { |
1569 | 1653 | if (my_errno == ESPIPE) |
|
0 commit comments