Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mruby
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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
mruby
Commits
ecb28f4b
Unverified
Commit
ecb28f4b
authored
Feb 14, 2022
by
Yukihiro "Matz" Matsumoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
load.c: add data boundary check for broken compiled binary.
parent
aba3d427
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
53 additions
and
27 deletions
+53
-27
src/load.c
src/load.c
+53
-27
No files found.
src/load.c
View file @
ecb28f4b
...
...
@@ -59,7 +59,7 @@ str_to_double(mrb_state *mrb, const char *p)
#endif
static
mrb_bool
read_irep_record_1
(
mrb_state
*
mrb
,
const
uint8_t
*
bin
,
size_t
*
len
,
uint8_t
flags
,
mrb_irep
**
irepp
)
read_irep_record_1
(
mrb_state
*
mrb
,
const
uint8_t
*
bin
,
const
uint8_t
*
end
,
size_t
*
len
,
uint8_t
flags
,
mrb_irep
**
irepp
)
{
int
i
;
const
uint8_t
*
src
=
bin
;
...
...
@@ -102,6 +102,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
if
(
SIZE_ERROR_MUL
(
irep
->
ilen
,
sizeof
(
mrb_code
)))
{
return
FALSE
;
}
if
(
src
+
data_len
>
end
)
return
FALSE
;
if
((
flags
&
FLAG_SRC_MALLOC
)
==
0
)
{
irep
->
iseq
=
(
mrb_code
*
)
src
;
irep
->
flags
|=
MRB_ISEQ_NO_FREE
;
...
...
@@ -117,6 +118,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
/* POOL BLOCK */
plen
=
bin_to_uint16
(
src
);
/* number of pool */
src
+=
sizeof
(
uint16_t
);
if
(
src
>
end
)
return
FALSE
;
if
(
plen
>
0
)
{
if
(
SIZE_ERROR_MUL
(
plen
,
sizeof
(
mrb_value
)))
{
return
FALSE
;
...
...
@@ -130,6 +132,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
switch
(
tt
)
{
/* pool data */
case
IREP_TT_INT32
:
{
if
(
src
+
sizeof
(
uint32_t
)
>
end
)
return
FALSE
;
mrb_int
v
=
(
int32_t
)
bin_to_uint32
(
src
);
src
+=
sizeof
(
uint32_t
);
#ifdef MRB_64BIT
...
...
@@ -144,6 +147,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
case
IREP_TT_INT64
:
#ifdef MRB_INT64
{
if
(
src
+
sizeof
(
uint32_t
)
*
2
>
end
)
return
FALSE
;
uint64_t
i64
=
bin_to_uint32
(
src
);
src
+=
sizeof
(
uint32_t
);
i64
<<=
32
;
...
...
@@ -160,6 +164,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
case
IREP_TT_BIGINT
:
pool_data_len
=
bin_to_uint8
(
src
);
/* pool data length */
src
+=
sizeof
(
uint8_t
);
if
(
src
+
pool_data_len
>
end
)
return
FALSE
;
{
char
*
p
;
pool
[
i
].
tt
=
IREP_TT_BIGINT
;
...
...
@@ -172,6 +177,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
case
IREP_TT_FLOAT
:
#ifndef MRB_NO_FLOAT
if
(
src
+
sizeof
(
double
)
>
end
)
return
FALSE
;
pool
[
i
].
tt
=
tt
;
pool
[
i
].
u
.
f
=
str_to_double
(
mrb
,
(
const
char
*
)
src
);
src
+=
sizeof
(
double
);
...
...
@@ -183,6 +189,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
case
IREP_TT_STR
:
pool_data_len
=
bin_to_uint16
(
src
);
/* pool data length */
src
+=
sizeof
(
uint16_t
);
if
(
src
+
pool_data_len
>
end
)
return
FALSE
;
if
(
st
)
{
pool
[
i
].
tt
=
(
pool_data_len
<<
2
)
|
IREP_TT_SSTR
;
pool
[
i
].
u
.
str
=
(
const
char
*
)
src
;
...
...
@@ -208,6 +215,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
/* SYMS BLOCK */
irep
->
slen
=
bin_to_uint16
(
src
);
/* syms length */
src
+=
sizeof
(
uint16_t
);
if
(
src
>
end
)
return
FALSE
;
if
(
irep
->
slen
>
0
)
{
if
(
SIZE_ERROR_MUL
(
irep
->
slen
,
sizeof
(
mrb_sym
)))
{
return
FALSE
;
...
...
@@ -223,6 +231,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
continue
;
}
if
(
src
+
snl
>
end
)
return
FALSE
;
if
(
flags
&
FLAG_SRC_MALLOC
)
{
syms
[
i
]
=
mrb_intern
(
mrb
,
(
char
*
)
src
,
snl
);
}
...
...
@@ -242,10 +251,10 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
}
static
mrb_bool
read_irep_record
(
mrb_state
*
mrb
,
const
uint8_t
*
bin
,
size_t
*
len
,
uint8_t
flags
,
mrb_irep
**
irepp
)
read_irep_record
(
mrb_state
*
mrb
,
const
uint8_t
*
bin
,
const
uint8_t
*
end
,
size_t
*
len
,
uint8_t
flags
,
mrb_irep
**
irepp
)
{
int
ai
=
mrb_gc_arena_save
(
mrb
);
mrb_bool
readsuccess
=
read_irep_record_1
(
mrb
,
bin
,
len
,
flags
,
irepp
);
mrb_bool
readsuccess
=
read_irep_record_1
(
mrb
,
bin
,
end
,
len
,
flags
,
irepp
);
mrb_irep
**
reps
;
int
i
;
...
...
@@ -261,7 +270,7 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags,
for
(
i
=
0
;
i
<
(
*
irepp
)
->
rlen
;
i
++
)
{
size_t
rlen
;
readsuccess
=
read_irep_record
(
mrb
,
bin
,
&
rlen
,
flags
,
&
reps
[
i
]);
readsuccess
=
read_irep_record
(
mrb
,
bin
,
end
,
&
rlen
,
flags
,
&
reps
[
i
]);
mrb_gc_arena_restore
(
mrb
,
ai
);
if
(
!
readsuccess
)
{
return
FALSE
;
...
...
@@ -274,10 +283,9 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags,
}
static
mrb_irep
*
read_section_irep
(
mrb_state
*
mrb
,
const
uint8_t
*
bin
,
uint8_t
flags
,
struct
RProc
**
proc
)
read_section_irep
(
mrb_state
*
mrb
,
const
uint8_t
*
bin
,
size_t
size
,
uint8_t
flags
,
struct
RProc
**
proc
)
{
size_t
len
;
if
(
size
<
sizeof
(
struct
rite_section_irep_header
))
return
NULL
;
/*
* This proc object keeps all the data in progress to avoid memory leaks
* if something goes wrong while reading irep.
...
...
@@ -285,8 +293,9 @@ read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags, struct RPro
*
proc
=
mrb_proc_new
(
mrb
,
NULL
);
mrb_irep
**
irepp
=
(
mrb_irep
**
)
&
(
*
proc
)
->
body
.
irep
;
size_t
len
;
bin
+=
sizeof
(
struct
rite_section_irep_header
);
if
(
read_irep_record
(
mrb
,
bin
,
&
len
,
flags
,
irepp
))
{
if
(
read_irep_record
(
mrb
,
bin
,
bin
+
size
,
&
len
,
flags
,
irepp
))
{
return
*
irepp
;
}
else
{
...
...
@@ -295,7 +304,7 @@ read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags, struct RPro
}
static
int
read_debug_record
(
mrb_state
*
mrb
,
const
uint8_t
*
start
,
mrb_irep
*
irep
,
size_t
*
record_len
,
const
mrb_sym
*
filenames
,
size_t
filenames_len
)
read_debug_record
(
mrb_state
*
mrb
,
const
uint8_t
*
start
,
const
uint8_t
*
end
,
mrb_irep
*
irep
,
size_t
*
record_len
,
const
mrb_sym
*
filenames
,
size_t
filenames_len
)
{
const
uint8_t
*
bin
=
start
;
ptrdiff_t
diff
;
...
...
@@ -313,13 +322,15 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
bin
+=
sizeof
(
uint32_t
);
debug
->
flen
=
bin_to_uint16
(
bin
);
debug
->
files
=
(
mrb_irep_debug_info_file
**
)
mrb_calloc
(
mrb
,
irep
->
debug_info
->
flen
,
sizeof
(
mrb_irep_debug_info
*
));
bin
+=
sizeof
(
uint16_t
);
if
(
bin
>
end
)
return
MRB_DUMP_GENERAL_FAILURE
;
debug
->
files
=
(
mrb_irep_debug_info_file
**
)
mrb_calloc
(
mrb
,
irep
->
debug_info
->
flen
,
sizeof
(
mrb_irep_debug_info
*
));
for
(
f_idx
=
0
;
f_idx
<
debug
->
flen
;
++
f_idx
)
{
mrb_irep_debug_info_file
*
file
;
uint16_t
filename_idx
;
if
(
bin
>
end
)
return
MRB_DUMP_GENERAL_FAILURE
;
file
=
(
mrb_irep_debug_info_file
*
)
mrb_calloc
(
mrb
,
1
,
sizeof
(
*
file
));
debug
->
files
[
f_idx
]
=
file
;
...
...
@@ -338,9 +349,10 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
bin
+=
sizeof
(
uint8_t
);
switch
(
file
->
line_type
)
{
case
mrb_debug_line_ary
:
{
uint32_t
l
;
size_t
l
=
sizeof
(
uint16_t
)
*
(
size_t
)
file
->
line_entry_count
;
file
->
lines
.
ary
=
(
uint16_t
*
)
mrb_malloc
(
mrb
,
sizeof
(
uint16_t
)
*
(
size_t
)(
file
->
line_entry_count
));
if
(
bin
+
l
>
end
)
return
MRB_DUMP_GENERAL_FAILURE
;
file
->
lines
.
ary
=
(
uint16_t
*
)
mrb_malloc
(
mrb
,
l
);
for
(
l
=
0
;
l
<
file
->
line_entry_count
;
++
l
)
{
file
->
lines
.
ary
[
l
]
=
bin_to_uint16
(
bin
);
bin
+=
sizeof
(
uint16_t
);
...
...
@@ -348,11 +360,12 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
}
break
;
case
mrb_debug_line_flat_map
:
{
uint32_t
l
;
size_t
c
=
(
size_t
)
file
->
line_entry_count
;
size_t
n
=
sizeof
(
mrb_irep_debug_info_line
);
file
->
lines
.
flat_map
=
(
mrb_irep_debug_info_line
*
)
mrb_calloc
(
mrb
,
(
size_t
)(
file
->
line_entry_count
),
sizeof
(
mrb_irep_debug_info_line
)
);
for
(
l
=
0
;
l
<
file
->
line_entry_count
;
++
l
)
{
if
(
bin
+
c
*
n
>
end
)
return
MRB_DUMP_GENERAL_FAILURE
;
file
->
lines
.
flat_map
=
(
mrb_irep_debug_info_line
*
)
mrb_calloc
(
mrb
,
c
,
n
);
for
(
size_t
l
=
0
;
l
<
file
->
line_entry_count
;
++
l
)
{
file
->
lines
.
flat_map
[
l
].
start_pos
=
bin_to_uint32
(
bin
);
bin
+=
sizeof
(
uint32_t
);
file
->
lines
.
flat_map
[
l
].
line
=
bin_to_uint16
(
bin
);
...
...
@@ -361,7 +374,10 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
}
break
;
case
mrb_debug_line_packed_map
:
{
file
->
lines
.
packed_map
=
(
uint8_t
*
)
mrb_calloc
(
mrb
,
1
,
(
size_t
)
file
->
line_entry_count
);
size_t
l
=
(
size_t
)
file
->
line_entry_count
;
if
(
bin
+
l
>
end
)
return
MRB_DUMP_GENERAL_FAILURE
;
file
->
lines
.
packed_map
=
(
uint8_t
*
)
mrb_calloc
(
mrb
,
1
,
l
);
memcpy
(
file
->
lines
.
packed_map
,
bin
,
file
->
line_entry_count
);
bin
+=
file
->
line_entry_count
;
}
break
;
...
...
@@ -381,7 +397,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
size_t
len
;
int
ret
;
ret
=
read_debug_record
(
mrb
,
bin
,
(
mrb_irep
*
)
irep
->
reps
[
i
],
&
len
,
filenames
,
filenames_len
);
ret
=
read_debug_record
(
mrb
,
bin
,
end
,
(
mrb_irep
*
)
irep
->
reps
[
i
],
&
len
,
filenames
,
filenames_len
);
if
(
ret
!=
MRB_DUMP_OK
)
return
ret
;
bin
+=
len
;
}
...
...
@@ -394,9 +410,10 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *
}
static
int
read_section_debug
(
mrb_state
*
mrb
,
const
uint8_t
*
start
,
mrb_irep
*
irep
,
uint8_t
flags
)
read_section_debug
(
mrb_state
*
mrb
,
const
uint8_t
*
start
,
size_t
size
,
mrb_irep
*
irep
,
uint8_t
flags
)
{
const
uint8_t
*
bin
;
const
uint8_t
*
end
=
start
+
size
;
ptrdiff_t
diff
;
struct
rite_section_debug_header
*
header
;
uint16_t
i
;
...
...
@@ -412,11 +429,16 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t
filenames_len
=
bin_to_uint16
(
bin
);
bin
+=
sizeof
(
uint16_t
);
if
(
bin
>
end
)
return
MRB_DUMP_GENERAL_FAILURE
;
filenames_obj
=
mrb_str_new
(
mrb
,
NULL
,
sizeof
(
mrb_sym
)
*
(
size_t
)
filenames_len
);
filenames
=
(
mrb_sym
*
)
RSTRING_PTR
(
filenames_obj
);
for
(
i
=
0
;
i
<
filenames_len
;
++
i
)
{
uint16_t
f_len
=
bin_to_uint16
(
bin
);
bin
+=
sizeof
(
uint16_t
);
if
(
bin
+
f_len
>
end
)
{
result
=
MRB_DUMP_GENERAL_FAILURE
;
goto
debug_exit
;
}
if
(
flags
&
FLAG_SRC_MALLOC
)
{
filenames
[
i
]
=
mrb_intern
(
mrb
,
(
const
char
*
)
bin
,
(
size_t
)
f_len
);
}
...
...
@@ -426,7 +448,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t
bin
+=
f_len
;
}
result
=
read_debug_record
(
mrb
,
bin
,
irep
,
&
len
,
filenames
,
filenames_len
);
result
=
read_debug_record
(
mrb
,
bin
,
end
,
irep
,
&
len
,
filenames
,
filenames_len
);
if
(
result
!=
MRB_DUMP_OK
)
goto
debug_exit
;
bin
+=
len
;
...
...
@@ -449,6 +471,7 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec
ptrdiff_t
diff
;
int
i
;
if
(
irep
->
nlocals
==
0
)
return
MRB_DUMP_GENERAL_FAILURE
;
irep
->
lv
=
lv
=
(
mrb_sym
*
)
mrb_malloc
(
mrb
,
sizeof
(
mrb_sym
)
*
(
irep
->
nlocals
-
1
));
for
(
i
=
0
;
i
+
1
<
irep
->
nlocals
;
++
i
)
{
...
...
@@ -482,9 +505,10 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec
}
static
int
read_section_lv
(
mrb_state
*
mrb
,
const
uint8_t
*
start
,
mrb_irep
*
irep
,
uint8_t
flags
)
read_section_lv
(
mrb_state
*
mrb
,
const
uint8_t
*
start
,
size_t
size
,
mrb_irep
*
irep
,
uint8_t
flags
)
{
const
uint8_t
*
bin
;
const
uint8_t
*
end
=
start
+
size
;
ptrdiff_t
diff
;
struct
rite_section_lv_header
const
*
header
;
uint32_t
i
;
...
...
@@ -502,12 +526,13 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t fl
syms_len
=
bin_to_uint32
(
bin
);
bin
+=
sizeof
(
uint32_t
);
if
(
bin
>
end
)
return
MRB_DUMP_READ_FAULT
;
syms_obj
=
mrb_str_new
(
mrb
,
NULL
,
sizeof
(
mrb_sym
)
*
(
size_t
)
syms_len
);
syms
=
(
mrb_sym
*
)
RSTRING_PTR
(
syms_obj
);
for
(
i
=
0
;
i
<
syms_len
;
++
i
)
{
uint16_t
const
str_len
=
bin_to_uint16
(
bin
);
bin
+=
sizeof
(
uint16_t
);
if
(
bin
>
end
)
return
MRB_DUMP_READ_FAULT
;
syms
[
i
]
=
intern_func
(
mrb
,
(
const
char
*
)
bin
,
str_len
);
bin
+=
str_len
;
}
...
...
@@ -580,20 +605,22 @@ read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags)
bin_size
-=
sizeof
(
struct
rite_binary_header
);
while
(
bin_size
>
sizeof
(
struct
rite_section_header
))
{
section_header
=
(
const
struct
rite_section_header
*
)
bin
;
uint32_t
section_size
=
bin_to_uint32
(
section_header
->
section_size
);
if
(
bin_size
<
section_size
)
return
NULL
;
if
(
memcmp
(
section_header
->
section_ident
,
RITE_SECTION_IREP_IDENT
,
sizeof
(
section_header
->
section_ident
))
==
0
)
{
irep
=
read_section_irep
(
mrb
,
bin
,
flags
,
&
proc
);
irep
=
read_section_irep
(
mrb
,
bin
,
bin_size
,
flags
,
&
proc
);
if
(
!
irep
)
return
NULL
;
}
else
if
(
memcmp
(
section_header
->
section_ident
,
RITE_SECTION_DEBUG_IDENT
,
sizeof
(
section_header
->
section_ident
))
==
0
)
{
if
(
!
irep
)
return
NULL
;
/* corrupted data */
result
=
read_section_debug
(
mrb
,
bin
,
irep
,
flags
);
result
=
read_section_debug
(
mrb
,
bin
,
bin_size
,
irep
,
flags
);
if
(
result
<
MRB_DUMP_OK
)
{
return
NULL
;
}
}
else
if
(
memcmp
(
section_header
->
section_ident
,
RITE_SECTION_LV_IDENT
,
sizeof
(
section_header
->
section_ident
))
==
0
)
{
if
(
!
irep
)
return
NULL
;
result
=
read_section_lv
(
mrb
,
bin
,
irep
,
flags
);
result
=
read_section_lv
(
mrb
,
bin
,
bin_size
,
irep
,
flags
);
if
(
result
<
MRB_DUMP_OK
)
{
return
NULL
;
}
...
...
@@ -602,7 +629,6 @@ read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags)
break
;
}
uint32_t
section_size
=
bin_to_uint32
(
section_header
->
section_size
);
bin
+=
section_size
;
bin_size
-=
section_size
;
}
...
...
@@ -615,7 +641,7 @@ mrb_proc_read_irep(mrb_state *mrb, const uint8_t *bin)
{
uint8_t
flags
=
mrb_ro_data_p
((
char
*
)
bin
)
?
FLAG_SRC_STATIC
:
FLAG_SRC_MALLOC
;
return
read_irep
(
mrb
,
bin
,
(
size_t
)
-
1
,
flags
);
return
read_irep
(
mrb
,
bin
,
(
size_t
)
UINT32_MAX
,
flags
);
}
DEFINE_READ_IREP_FUNC
(
...
...
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