Commit 1132c354 authored by Georgi Kodinov's avatar Georgi Kodinov

On behalf of Kristofer :

Bug#53417 my_getwd() makes assumptions on the buffer sizes which not always hold true
      
The mysys library contains many functions for rewriting file paths. Most of these
functions makes implicit assumptions on the buffer sizes they write to. If a path is put
in my_realpath() it will propagate to my_getwd() which assumes that the buffer holding
the path name is greater than 2. This is not true in cases.
      
In the special case where a VARBIN_ITEM is passed as argument to the LOAD_FILE function
this can lead to a crash.
      
This patch fixes the issue by introduce more safe guards agaist buffer overruns.
parent 0ca7c012
...@@ -34,7 +34,7 @@ char * my_load_path(char * to, const char *path, ...@@ -34,7 +34,7 @@ char * my_load_path(char * to, const char *path,
if ((path[0] == FN_HOMELIB && path[1] == FN_LIBCHAR) || if ((path[0] == FN_HOMELIB && path[1] == FN_LIBCHAR) ||
test_if_hard_path(path)) test_if_hard_path(path))
VOID(strmov(buff,path)); VOID(strnmov(buff, path, FN_REFLEN));
else if ((is_cur=(path[0] == FN_CURLIB && path[1] == FN_LIBCHAR)) || else if ((is_cur=(path[0] == FN_CURLIB && path[1] == FN_LIBCHAR)) ||
(is_prefix(path,FN_PARENTDIR)) || (is_prefix(path,FN_PARENTDIR)) ||
! own_path_prefix) ! own_path_prefix)
...@@ -42,13 +42,14 @@ char * my_load_path(char * to, const char *path, ...@@ -42,13 +42,14 @@ char * my_load_path(char * to, const char *path,
if (is_cur) if (is_cur)
is_cur=2; /* Remove current dir */ is_cur=2; /* Remove current dir */
if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0))) if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0)))
VOID(strcat(buff,path+is_cur)); VOID(strncat(buff, path+is_cur, FN_REFLEN));
else else
VOID(strmov(buff,path)); /* Return org file name */ VOID(strnmov(buff, path, FN_REFLEN)); /* Return org file name */
} }
else else
VOID(strxmov(buff,own_path_prefix,path,NullS)); VOID(strxnmov(buff, FN_REFLEN, own_path_prefix,path, NullS));
strmov(to,buff); strnmov(to, buff, FN_REFLEN);
to[FN_REFLEN-1]= '\0';
DBUG_PRINT("exit",("to: %s",to)); DBUG_PRINT("exit",("to: %s",to));
DBUG_RETURN(to); DBUG_RETURN(to);
} /* my_load_path */ } /* my_load_path */
...@@ -50,11 +50,16 @@ int my_getwd(char * buf, size_t size, myf MyFlags) ...@@ -50,11 +50,16 @@ int my_getwd(char * buf, size_t size, myf MyFlags)
DBUG_PRINT("my",("buf: 0x%lx size: %u MyFlags %d", DBUG_PRINT("my",("buf: 0x%lx size: %u MyFlags %d",
(long) buf, (uint) size, MyFlags)); (long) buf, (uint) size, MyFlags));
if (size < 1)
return(-1);
if (curr_dir[0]) /* Current pos is saved here */ if (curr_dir[0]) /* Current pos is saved here */
VOID(strmake(buf,&curr_dir[0],size-1)); VOID(strmake(buf,&curr_dir[0],size-1));
else else
{ {
#if defined(HAVE_GETCWD) #if defined(HAVE_GETCWD)
if (size < 2)
return(-1);
if (!getcwd(buf,(uint) (size-2)) && MyFlags & MY_WME) if (!getcwd(buf,(uint) (size-2)) && MyFlags & MY_WME)
{ {
my_errno=errno; my_errno=errno;
...@@ -68,6 +73,8 @@ int my_getwd(char * buf, size_t size, myf MyFlags) ...@@ -68,6 +73,8 @@ int my_getwd(char * buf, size_t size, myf MyFlags)
strmake(buf,pathname,size-1); strmake(buf,pathname,size-1);
} }
#elif defined(VMS) #elif defined(VMS)
if (size < 2)
return(-1);
if (!getcwd(buf,size-2,1) && MyFlags & MY_WME) if (!getcwd(buf,size-2,1) && MyFlags & MY_WME)
{ {
my_errno=errno; my_errno=errno;
......
...@@ -5366,13 +5366,25 @@ inline uint char_val(char X) ...@@ -5366,13 +5366,25 @@ inline uint char_val(char X)
X-'a'+10); X-'a'+10);
} }
Item_hex_string::Item_hex_string()
{
hex_string_init("", 0);
}
Item_hex_string::Item_hex_string(const char *str, uint str_length) Item_hex_string::Item_hex_string(const char *str, uint str_length)
{
hex_string_init(str, str_length);
}
void Item_hex_string::hex_string_init(const char *str, uint str_length)
{ {
max_length=(str_length+1)/2; max_length=(str_length+1)/2;
char *ptr=(char*) sql_alloc(max_length+1); char *ptr=(char*) sql_alloc(max_length+1);
if (!ptr) if (!ptr)
{
str_value.set("", 0, &my_charset_bin);
return; return;
}
str_value.set(ptr,max_length,&my_charset_bin); str_value.set(ptr,max_length,&my_charset_bin);
char *end=ptr+max_length; char *end=ptr+max_length;
if (max_length*2 != str_length) if (max_length*2 != str_length)
......
...@@ -2123,7 +2123,7 @@ public: ...@@ -2123,7 +2123,7 @@ public:
class Item_hex_string: public Item_basic_constant class Item_hex_string: public Item_basic_constant
{ {
public: public:
Item_hex_string() {} Item_hex_string();
Item_hex_string(const char *str,uint str_length); Item_hex_string(const char *str,uint str_length);
enum Type type() const { return VARBIN_ITEM; } enum Type type() const { return VARBIN_ITEM; }
double val_real() double val_real()
...@@ -2143,6 +2143,8 @@ public: ...@@ -2143,6 +2143,8 @@ public:
bool eq(const Item *item, bool binary_cmp) const; bool eq(const Item *item, bool binary_cmp) const;
virtual Item *safe_charset_converter(CHARSET_INFO *tocs); virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(uchar *int_arg) {return FALSE;} bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
private:
void hex_string_init(const char *str, uint str_length);
}; };
......
...@@ -8796,6 +8796,9 @@ bool is_secure_file_path(char *path) ...@@ -8796,6 +8796,9 @@ bool is_secure_file_path(char *path)
if (!opt_secure_file_priv) if (!opt_secure_file_priv)
return TRUE; return TRUE;
if (strlen(path) >= FN_REFLEN)
return FALSE;
if (my_realpath(buff1, path, 0)) if (my_realpath(buff1, path, 0))
{ {
/* /*
...@@ -8882,6 +8885,8 @@ static int fix_paths(void) ...@@ -8882,6 +8885,8 @@ static int fix_paths(void)
} }
else else
{ {
if (strlen(opt_secure_file_priv) >= FN_REFLEN)
opt_secure_file_priv[FN_REFLEN-1]= '\0';
if (my_realpath(buff, opt_secure_file_priv, 0)) if (my_realpath(buff, opt_secure_file_priv, 0))
{ {
sql_print_warning("Failed to normalize the argument for --secure-file-priv."); sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
......
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