Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
556f5684
Commit
556f5684
authored
Apr 09, 2013
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
init_from_binary_frm_image: verify that we don't read beyond the image buffer
parent
2481db06
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
38 additions
and
9 deletions
+38
-9
sql/table.cc
sql/table.cc
+38
-9
No files found.
sql/table.cc
View file @
556f5684
...
@@ -709,7 +709,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
...
@@ -709,7 +709,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
mysql_file_close
(
file
,
MYF
(
MY_WME
));
mysql_file_close
(
file
,
MYF
(
MY_WME
));
share
->
init_from_binary_frm_image
(
thd
,
NULL
,
buf
,
stats
.
st_size
);
share
->
init_from_binary_frm_image
(
thd
,
NULL
,
buf
,
stats
.
st_size
);
error_given
=
true
;
error_given
=
true
;
// init_from_binary_frm_image has already called my_error()
my_free
(
buf
);
my_free
(
buf
);
if
(
!
share
->
error
)
if
(
!
share
->
error
)
...
@@ -741,8 +741,6 @@ err_not_open:
...
@@ -741,8 +741,6 @@ err_not_open:
28..29 (used to be key_info_length)
28..29 (used to be key_info_length)
They're still set, for compatibility reasons, but never read.
They're still set, for compatibility reasons, but never read.
TODO verify that we never read data from beyond frm_length!
*/
*/
bool
TABLE_SHARE
::
init_from_binary_frm_image
(
THD
*
thd
,
const
char
*
path
,
bool
TABLE_SHARE
::
init_from_binary_frm_image
(
THD
*
thd
,
const
char
*
path
,
...
@@ -758,6 +756,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -758,6 +756,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
bool
use_hash
;
bool
use_hash
;
char
*
keynames
,
*
names
,
*
comment_pos
;
char
*
keynames
,
*
names
,
*
comment_pos
;
const
uchar
*
forminfo
;
const
uchar
*
forminfo
;
const
uchar
*
frm_image_end
=
frm_image
+
frm_length
;
uchar
*
record
,
*
null_flags
,
*
null_pos
;
uchar
*
record
,
*
null_flags
,
*
null_pos
;
const
uchar
*
disk_buff
,
*
strpos
;
const
uchar
*
disk_buff
,
*
strpos
;
ulong
pos
,
record_offset
;
ulong
pos
,
record_offset
;
...
@@ -791,16 +790,22 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -791,16 +790,22 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
if
(
path
&&
writefrm
(
path
,
frm_image
,
frm_length
))
if
(
path
&&
writefrm
(
path
,
frm_image
,
frm_length
))
goto
err
;
goto
err
;
if
(
frm_length
<
64
+
288
)
goto
err
;
new_field_pack_flag
=
frm_image
[
27
];
new_field_pack_flag
=
frm_image
[
27
];
new_frm_ver
=
(
frm_image
[
2
]
-
FRM_VER
);
new_frm_ver
=
(
frm_image
[
2
]
-
FRM_VER
);
field_pack_length
=
new_frm_ver
<
2
?
11
:
17
;
field_pack_length
=
new_frm_ver
<
2
?
11
:
17
;
/* Position of the form in the form file. */
/* Position of the form in the form file. */
len
=
uint2korr
(
frm_image
+
4
);
len
=
uint2korr
(
frm_image
+
4
);
if
(
!
(
pos
=
uint4korr
(
frm_image
+
64
+
len
)))
if
(
frm_length
<
64
+
len
||
!
(
pos
=
uint4korr
(
frm_image
+
64
+
len
)))
goto
err
;
goto
err
;
forminfo
=
frm_image
+
pos
;
forminfo
=
frm_image
+
pos
;
if
(
forminfo
+
288
>=
frm_image_end
)
goto
err
;
share
->
frm_version
=
frm_image
[
2
];
share
->
frm_version
=
frm_image
[
2
];
/*
/*
Check if .frm file created by MySQL 5.0. In this case we want to
Check if .frm file created by MySQL 5.0. In this case we want to
...
@@ -863,6 +868,10 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -863,6 +868,10 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
/* Read keyinformation */
/* Read keyinformation */
disk_buff
=
frm_image
+
uint2korr
(
frm_image
+
6
);
disk_buff
=
frm_image
+
uint2korr
(
frm_image
+
6
);
if
(
disk_buff
+
6
>=
frm_image_end
)
goto
err
;
if
(
disk_buff
[
0
]
&
0x80
)
if
(
disk_buff
[
0
]
&
0x80
)
{
{
share
->
keys
=
keys
=
(
disk_buff
[
1
]
<<
7
)
|
(
disk_buff
[
0
]
&
0x7f
);
share
->
keys
=
keys
=
(
disk_buff
[
1
]
<<
7
)
|
(
disk_buff
[
0
]
&
0x7f
);
...
@@ -912,6 +921,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -912,6 +921,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
{
{
if
(
new_frm_ver
>=
3
)
if
(
new_frm_ver
>=
3
)
{
{
if
(
strpos
+
8
>=
frm_image_end
)
goto
err
;
keyinfo
->
flags
=
(
uint
)
uint2korr
(
strpos
)
^
HA_NOSAME
;
keyinfo
->
flags
=
(
uint
)
uint2korr
(
strpos
)
^
HA_NOSAME
;
keyinfo
->
key_length
=
(
uint
)
uint2korr
(
strpos
+
2
);
keyinfo
->
key_length
=
(
uint
)
uint2korr
(
strpos
+
2
);
keyinfo
->
key_parts
=
(
uint
)
strpos
[
4
];
keyinfo
->
key_parts
=
(
uint
)
strpos
[
4
];
...
@@ -921,6 +932,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -921,6 +932,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
}
}
else
else
{
{
if
(
strpos
+
4
>=
frm_image_end
)
goto
err
;
keyinfo
->
flags
=
((
uint
)
strpos
[
0
])
^
HA_NOSAME
;
keyinfo
->
flags
=
((
uint
)
strpos
[
0
])
^
HA_NOSAME
;
keyinfo
->
key_length
=
(
uint
)
uint2korr
(
strpos
+
1
);
keyinfo
->
key_length
=
(
uint
)
uint2korr
(
strpos
+
1
);
keyinfo
->
key_parts
=
(
uint
)
strpos
[
3
];
keyinfo
->
key_parts
=
(
uint
)
strpos
[
3
];
...
@@ -958,6 +971,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -958,6 +971,8 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
keyinfo
->
rec_per_key
=
rec_per_key
;
keyinfo
->
rec_per_key
=
rec_per_key
;
for
(
j
=
keyinfo
->
key_parts
;
j
--
;
key_part
++
)
for
(
j
=
keyinfo
->
key_parts
;
j
--
;
key_part
++
)
{
{
if
(
strpos
+
(
new_frm_ver
>=
1
?
9
:
7
)
>=
frm_image_end
)
goto
err
;
*
rec_per_key
++=
0
;
*
rec_per_key
++=
0
;
key_part
->
fieldnr
=
(
uint16
)
(
uint2korr
(
strpos
)
&
FIELD_NR_MASK
);
key_part
->
fieldnr
=
(
uint16
)
(
uint2korr
(
strpos
)
&
FIELD_NR_MASK
);
key_part
->
offset
=
(
uint
)
uint2korr
(
strpos
+
2
)
-
1
;
key_part
->
offset
=
(
uint
)
uint2korr
(
strpos
+
2
)
-
1
;
...
@@ -1014,17 +1029,25 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -1014,17 +1029,25 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
share
->
ext_key_parts
+=
keyinfo
->
ext_key_parts
;
share
->
ext_key_parts
+=
keyinfo
->
ext_key_parts
;
}
}
keynames
=
(
char
*
)
key_part
;
keynames
=
(
char
*
)
key_part
;
strpos
+=
(
strmov
(
keynames
,
(
char
*
)
strpos
)
-
keynames
)
+
1
;
strpos
+=
strnmov
(
keynames
,
(
char
*
)
strpos
,
frm_image_end
-
strpos
)
-
keynames
;
if
(
*
strpos
++
)
// key names are \0-terminated
goto
err
;
//reading index comments
//reading index comments
for
(
keyinfo
=
share
->
key_info
,
i
=
0
;
i
<
keys
;
i
++
,
keyinfo
++
)
for
(
keyinfo
=
share
->
key_info
,
i
=
0
;
i
<
keys
;
i
++
,
keyinfo
++
)
{
{
if
(
keyinfo
->
flags
&
HA_USES_COMMENT
)
if
(
keyinfo
->
flags
&
HA_USES_COMMENT
)
{
{
if
(
strpos
+
2
>=
frm_image_end
)
goto
err
;
keyinfo
->
comment
.
length
=
uint2korr
(
strpos
);
keyinfo
->
comment
.
length
=
uint2korr
(
strpos
);
keyinfo
->
comment
.
str
=
strmake_root
(
&
share
->
mem_root
,
(
char
*
)
strpos
+
2
,
strpos
+=
2
;
if
(
strpos
+
keyinfo
->
comment
.
length
>=
frm_image_end
)
goto
err
;
keyinfo
->
comment
.
str
=
strmake_root
(
&
share
->
mem_root
,
(
char
*
)
strpos
,
keyinfo
->
comment
.
length
);
keyinfo
->
comment
.
length
);
strpos
+=
2
+
keyinfo
->
comment
.
length
;
strpos
+=
keyinfo
->
comment
.
length
;
}
}
DBUG_ASSERT
(
test
(
keyinfo
->
flags
&
HA_USES_COMMENT
)
==
DBUG_ASSERT
(
test
(
keyinfo
->
flags
&
HA_USES_COMMENT
)
==
(
keyinfo
->
comment
.
length
>
0
));
(
keyinfo
->
comment
.
length
>
0
));
...
@@ -1038,6 +1061,9 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -1038,6 +1061,9 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
record_offset
=
(
ulong
)
(
uint2korr
(
frm_image
+
6
)
+
record_offset
=
(
ulong
)
(
uint2korr
(
frm_image
+
6
)
+
((
uint2korr
(
frm_image
+
14
)
==
0xffff
?
((
uint2korr
(
frm_image
+
14
)
==
0xffff
?
uint4korr
(
frm_image
+
47
)
:
uint2korr
(
frm_image
+
14
))));
uint4korr
(
frm_image
+
47
)
:
uint2korr
(
frm_image
+
14
))));
if
(
record_offset
+
share
->
reclength
>=
frm_length
)
goto
err
;
if
((
n_length
=
uint4korr
(
frm_image
+
55
)))
if
((
n_length
=
uint4korr
(
frm_image
+
55
)))
{
{
...
@@ -1046,6 +1072,10 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -1046,6 +1072,10 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
DBUG_PRINT
(
"info"
,
(
"extra segment size is %u bytes"
,
n_length
));
DBUG_PRINT
(
"info"
,
(
"extra segment size is %u bytes"
,
n_length
));
next_chunk
=
frm_image
+
record_offset
+
share
->
reclength
;
next_chunk
=
frm_image
+
record_offset
+
share
->
reclength
;
buff_end
=
next_chunk
+
n_length
;
buff_end
=
next_chunk
+
n_length
;
if
(
buff_end
>=
frm_image_end
)
goto
err
;
share
->
connect_string
.
length
=
uint2korr
(
next_chunk
);
share
->
connect_string
.
length
=
uint2korr
(
next_chunk
);
if
(
!
(
share
->
connect_string
.
str
=
strmake_root
(
&
share
->
mem_root
,
if
(
!
(
share
->
connect_string
.
str
=
strmake_root
(
&
share
->
mem_root
,
(
char
*
)
next_chunk
+
2
,
(
char
*
)
next_chunk
+
2
,
...
@@ -1882,8 +1912,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
...
@@ -1882,8 +1912,7 @@ bool TABLE_SHARE::init_from_binary_frm_image(THD *thd, const char *path,
&
share
->
next_number_key_offset
,
&
share
->
next_number_key_offset
,
&
share
->
next_number_keypart
))
<
0
)
&
share
->
next_number_keypart
))
<
0
)
goto
err
;
// Wrong field definition
goto
err
;
// Wrong field definition
else
reg_field
->
flags
|=
AUTO_INCREMENT_FLAG
;
reg_field
->
flags
|=
AUTO_INCREMENT_FLAG
;
}
}
if
(
share
->
blob_fields
)
if
(
share
->
blob_fields
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment