summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorreggie@mdk10.(none) <>2005-05-20 16:04:10 -0500
committerreggie@mdk10.(none) <>2005-05-20 16:04:10 -0500
commit48c584537d3f45263be1fa8bbadab5c14267d3ff (patch)
tree3c11d9563166e2b2ee03a1165069c1f02dfba30a
parentd7a98ea7b8812dd63f5eb2cceaa2adaa5c0525dc (diff)
downloadmariadb-git-48c584537d3f45263be1fa8bbadab5c14267d3ff.tar.gz
BUG# 9148: Denial of service
The problem was that on Windows the access method indicates that access to file such as "com1" and "lpt1" is allowed (since they are device names) and this causes mysql to attempt to open them as databases or tables. The fix was to write our own my_access method that uses other Win32 functions to determine if the given argument is indeed a file and has to requested mode.
-rw-r--r--VC++Files/mysys/mysys.dsp5
-rw-r--r--VC++Files/mysys/mysys_ia64.dsp7
-rw-r--r--include/my_sys.h5
-rw-r--r--mysql-test/r/reserved_win_names.require2
-rw-r--r--mysql-test/r/reserved_win_names.result7
-rw-r--r--mysql-test/t/reserved_win_names-master.opt1
-rw-r--r--mysql-test/t/reserved_win_names.test12
-rw-r--r--mysys/Makefile.am2
-rw-r--r--mysys/mf_pack.c2
-rw-r--r--mysys/my_access.c53
-rw-r--r--sql/sql_db.cc2
11 files changed, 95 insertions, 3 deletions
diff --git a/VC++Files/mysys/mysys.dsp b/VC++Files/mysys/mysys.dsp
index ad6caf1986e..f47203d37bf 100644
--- a/VC++Files/mysys/mysys.dsp
+++ b/VC++Files/mysys/mysys.dsp
@@ -186,6 +186,11 @@ SOURCE=.\array.c
!ENDIF
# End Source File
+
+# Begin Source File
+SOURCE=".\my_access.c"
+# End Source File
+
# Begin Source File
SOURCE=".\charset-def.c"
diff --git a/VC++Files/mysys/mysys_ia64.dsp b/VC++Files/mysys/mysys_ia64.dsp
index ed2dac53579..a0877457286 100644
--- a/VC++Files/mysys/mysys_ia64.dsp
+++ b/VC++Files/mysys/mysys_ia64.dsp
@@ -163,6 +163,13 @@ LIB32=link.exe -lib
# Name "mysys - WinIA64 Max"
# Name "mysys - WinIA64 TLS_DEBUG"
# Name "mysys - WinIA64 TLS"
+
+# Begin Source File
+
+SOURCE=.\my_access.c
+
+# End Source File
+
# Begin Source File
SOURCE=.\array.c
diff --git a/include/my_sys.h b/include/my_sys.h
index c9552f8558b..a0a008056ae 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -573,6 +573,11 @@ extern char *_my_strdup_with_length(const byte *from, uint length,
const char *sFile, uint uLine,
myf MyFlag);
+#ifdef __WIN__
+extern int my_access(const char *path, int amode);
+#else
+#define my_access access
+#endif
#ifndef TERMINATE
extern void TERMINATE(FILE *file);
diff --git a/mysql-test/r/reserved_win_names.require b/mysql-test/r/reserved_win_names.require
new file mode 100644
index 00000000000..7f803aca482
--- /dev/null
+++ b/mysql-test/r/reserved_win_names.require
@@ -0,0 +1,2 @@
+Variable_name Value
+lower_case_table_names 1
diff --git a/mysql-test/r/reserved_win_names.result b/mysql-test/r/reserved_win_names.result
new file mode 100644
index 00000000000..eaa0f71513f
--- /dev/null
+++ b/mysql-test/r/reserved_win_names.result
@@ -0,0 +1,7 @@
+use COM1;
+ERROR 42000: Unknown database 'com1'
+use LPT1;
+ERROR 42000: Unknown database 'lpt1'
+use PRN;
+ERROR 42000: Unknown database 'prn'
+
diff --git a/mysql-test/t/reserved_win_names-master.opt b/mysql-test/t/reserved_win_names-master.opt
new file mode 100644
index 00000000000..62ab6dad1e0
--- /dev/null
+++ b/mysql-test/t/reserved_win_names-master.opt
@@ -0,0 +1 @@
+--lower_case_table_names=1
diff --git a/mysql-test/t/reserved_win_names.test b/mysql-test/t/reserved_win_names.test
new file mode 100644
index 00000000000..d9b23935ddf
--- /dev/null
+++ b/mysql-test/t/reserved_win_names.test
@@ -0,0 +1,12 @@
+#
+# Test of reserved Windows names
+#
+--require r/reserved_win_names.require
+
+--error 1049
+use COM1;
+--error 1049
+use LPT1;
+--error 1049
+use PRN;
+
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 3ae9c05bff5..ab35ccb21ba 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -53,7 +53,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c \
my_net.c my_semaphore.c my_port.c my_sleep.c \
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
my_gethostbyname.c rijndael.c my_aes.c sha1.c \
- my_handler.c my_netware.c my_windac.c
+ my_handler.c my_netware.c my_windac.c my_access.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index 9193238708d..79b194289c6 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -226,7 +226,7 @@ void symdirget(char *dir)
{
char buff[FN_REFLEN];
char *pos=strend(dir);
- if (dir[0] && pos[-1] != FN_DEVCHAR && access(dir, F_OK))
+ if (dir[0] && pos[-1] != FN_DEVCHAR && !my_access(dir, F_OK))
{
File file;
uint length;
diff --git a/mysys/my_access.c b/mysys/my_access.c
new file mode 100644
index 00000000000..6a8887e42a6
--- /dev/null
+++ b/mysys/my_access.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 2000 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mysys_priv.h"
+
+#ifdef __WIN__
+
+/*
+ * Check a file or path for accessability.
+ *
+ * SYNOPSIS
+ * file_access()
+ * pathpath to check
+ * amodemode to check
+ *
+ * DESCRIPTION
+ * This function wraps the normal access method because the access
+ * available in MSVCRT> +reports that filenames such as LPT1 and
+ * COM1 are valid (they are but should not be so for us).
+ *
+ * RETURN VALUES
+ * 0 ok
+ * -1 error
+ */
+int my_access(const char *path, int amode)
+{
+ WIN32_FILE_ATTRIBUTE_DATA fileinfo;
+ BOOL result;
+
+ result = GetFileAttributesEx(path, GetFileExInfoStandard,
+ &fileinfo);
+ if (! result)
+ return -1;
+ if ((fileinfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) &&
+ (amode & 2))
+ return -1;
+ return 0;
+}
+
+#endif
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index c918480812c..ad6845572e1 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -946,7 +946,7 @@ bool mysql_change_db(THD *thd, const char *name)
length=unpack_dirname(path,path); // Convert if not unix
if (length && path[length-1] == FN_LIBCHAR)
path[length-1]=0; // remove ending '\'
- if (access(path,F_OK))
+ if (my_access(path,F_OK))
{
net_printf(thd,ER_BAD_DB_ERROR,dbname);
my_free(dbname,MYF(0));