summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <reggie@mdk10.(none)>2005-05-20 16:04:10 -0500
committerunknown <reggie@mdk10.(none)>2005-05-20 16:04:10 -0500
commitc1ae672adda45a1b8c5637b8f4d6a3f91378ea20 (patch)
tree3c11d9563166e2b2ee03a1165069c1f02dfba30a
parent25d661adfc144d0de605ff07907ed9004155466d (diff)
downloadmariadb-git-c1ae672adda45a1b8c5637b8f4d6a3f91378ea20.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. VC++Files/mysys/mysys.dsp: added my_access VC++Files/mysys/mysys_ia64.dsp: added my_access.c include/my_sys.h: if on windows, we use my_access. if not on windows, then my_access points to the native access method mysys/Makefile.am: added my_access to mysys build file mysys/mf_pack.c: changed call to access to my_access sql/sql_db.cc: changed call to access to my_access
-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));