Commit d7a4a8b6 authored by unknown's avatar unknown

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
parent eb2a4c65
......@@ -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"
......
......@@ -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
......
......@@ -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);
......
Variable_name Value
lower_case_table_names 1
use COM1;
ERROR 42000: Unknown database 'com1'
use LPT1;
ERROR 42000: Unknown database 'lpt1'
use PRN;
ERROR 42000: Unknown database 'prn'
#
# Test of reserved Windows names
#
--require r/reserved_win_names.require
--error 1049
use COM1;
--error 1049
use LPT1;
--error 1049
use PRN;
......@@ -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@
......
......@@ -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;
......
/* 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
......@@ -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));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment