Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
c91c0703
Commit
c91c0703
authored
Jan 14, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Re-enable DTB table rebuilding
parent
aec06a6f
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
240 additions
and
259 deletions
+240
-259
dtb.cpp
native/jni/magiskboot/dtb.cpp
+240
-259
No files found.
native/jni/magiskboot/dtb.cpp
View file @
c91c0703
...
...
@@ -124,38 +124,52 @@ static void dtb_print(const char *file, bool fstab) {
munmap
(
dtb
,
size
);
}
static
bool
dtb_patch_rebuild
(
uint8_t
*
dtb
,
size_t
dtb_sz
,
const
char
*
file
);
static
bool
dtb_patch
(
const
char
*
file
)
{
bool
keepverity
=
check_env
(
"KEEPVERITY"
);
bool
patched
=
false
;
bool
keep_verity
=
check_env
(
"KEEPVERITY"
);
bool
have_system
=
false
;
vector
<
pair
<
char
*
,
int
>>
flags_list
;
size_t
size
;
uint8_t
*
dtb
;
fprintf
(
stderr
,
"Loading dtbs from [%s]
\n
"
,
file
);
mmap_rw
(
file
,
dtb
,
size
);
// Loop through all the dtbs
run_finally
f
([
=
]{
munmap
(
dtb
,
size
);
});
// First traverse through DTB to determine whether we need a rebuild
int
dtb_num
=
0
;
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
auto
fdt
=
dtb
+
i
;
fprintf
(
stderr
,
"Loading dtb.%04d
\n
"
,
dtb_num
);
if
(
int
fstab
=
find_fstab
(
fdt
);
fstab
>=
0
)
{
int
node
;
fdt_for_each_subnode
(
node
,
fdt
,
fstab
)
{
const
char
*
name
=
fdt_get_name
(
fdt
,
node
,
nullptr
);
fprintf
(
stderr
,
"Found fstab entry [%s]
\n
"
,
name
);
if
(
!
keepverity
)
{
if
(
!
keep_verity
)
{
int
len
;
auto
value
=
fdt_getprop
(
fdt
,
node
,
"fsmgr_flags"
,
&
len
);
patched
|=
patch_verity
(
const_cast
<
void
*>
(
value
),
len
)
!=
len
;
char
*
value
=
(
char
*
)
fdt_getprop
(
fdt
,
node
,
"fsmgr_flags"
,
&
len
);
flags_list
.
emplace_back
(
value
,
len
)
;
}
if
(
name
==
"system"
sv
)
have_system
=
true
;
}
}
++
dtb_num
;
i
+=
fdt_totalsize
(
fdt
)
-
1
;
++
dtb_num
;
}
}
fprintf
(
stderr
,
"
\n
"
);
munmap
(
dtb
,
size
);
if
(
!
have_system
)
{
// Patch in place with rw mmap
bool
patched
=
false
;
for
(
auto
&
[
value
,
len
]
:
flags_list
)
patched
|=
patch_verity
(
value
,
len
)
!=
len
;
return
patched
;
}
else
{
// Need to rebuild dtb due to additional props
return
dtb_patch_rebuild
(
dtb
,
size
,
file
);
}
}
int
dtb_commands
(
int
argc
,
char
*
argv
[])
{
...
...
@@ -176,93 +190,60 @@ int dtb_commands(int argc, char *argv[]) {
}
namespace
{
// Unused, but keep these precious code as they took TONs of effort to write
struct
fdt_blob
{
struct
fdt_blob
{
void
*
fdt
;
uint32_t
offset
;
uint32_t
len
;
};
template
<
class
Iter
>
class
fdt_map_iter
{
public
:
typedef
decltype
(
std
::
declval
<
typename
Iter
::
value_type
::
second_type
>
().
fdt
)
value_type
;
typedef
value_type
*
pointer
;
typedef
value_type
&
reference
;
explicit
fdt_map_iter
(
Iter
j
)
:
i
(
j
)
{}
fdt_map_iter
&
operator
++
()
{
++
i
;
return
*
this
;
}
fdt_map_iter
operator
++
(
int
)
{
auto
tmp
=
*
this
;
++
(
*
this
);
return
tmp
;
}
fdt_map_iter
&
operator
--
()
{
--
i
;
return
*
this
;
}
fdt_map_iter
operator
--
(
int
)
{
auto
tmp
=
*
this
;
--
(
*
this
);
return
tmp
;
}
bool
operator
==
(
fdt_map_iter
j
)
const
{
return
i
==
j
.
i
;
}
bool
operator
!=
(
fdt_map_iter
j
)
const
{
return
!
(
*
this
==
j
);
}
reference
operator
*
()
{
return
i
->
second
.
fdt
;
}
pointer
operator
->
()
{
return
&
i
->
second
.
fdt
;
}
private
:
Iter
i
;
};
template
<
class
Iter
>
inline
fdt_map_iter
<
Iter
>
make_iter
(
Iter
j
)
{
return
fdt_map_iter
<
Iter
>
(
j
);
}
template
<
typename
Iter
>
static
bool
fdt_patch
(
Iter
first
,
Iter
last
)
{
bool
keepverity
=
check_env
(
"KEEPVERITY"
);
bool
redirect
=
check_env
(
"TWOSTAGEINIT"
);
bool
modified
=
false
;
};
}
int
idx
=
0
;
for
(
auto
it
=
first
;
it
!=
last
;
++
it
)
{
++
idx
;
auto
fdt
=
*
it
;
static
bool
fdt_patch
(
void
*
fdt
)
{
int
fstab
=
find_fstab
(
fdt
);
if
(
fstab
<
0
)
continu
e
;
fprintf
(
stderr
,
"Found fstab in dtb.%04d
\n
"
,
idx
-
1
)
;
int
block
;
fdt_for_each_subnode
(
block
,
fdt
,
fstab
)
{
const
char
*
name
=
fdt_get_name
(
fdt
,
block
,
nullptr
);
fprintf
(
stderr
,
"Found entry [%s] in fstab
\n
"
,
name
);
if
(
!
keepverity
)
{
int
size
;
auto
value
=
fdt_getprop
(
fdt
,
block
,
"fsmgr_flags"
,
&
size
);
char
*
copy
=
static_cast
<
char
*>
(
memcpy
(
malloc
(
size
),
value
,
size
)
);
if
(
patch_verity
(
copy
,
size
)
!=
size
)
{
return
fals
e
;
bool
modified
=
false
;
int
node
;
fdt_for_each_subnode
(
node
,
fdt
,
fstab
)
{
const
char
*
name
=
fdt_get_name
(
fdt
,
node
,
nullptr
);
// Always patch verity if 2SI
int
len
;
auto
value
=
(
const
char
*
)
fdt_getprop
(
fdt
,
node
,
"fsmgr_flags"
,
&
len
)
;
string
copy
(
value
,
len
);
uint32_t
new_len
=
patch_verity
(
copy
.
data
(),
len
);
if
(
new_len
!=
len
)
{
modified
=
true
;
fdt_setprop_string
(
fdt
,
block
,
"fsmgr_flags"
,
copy
);
}
free
(
copy
);
fdt_setprop
(
fdt
,
node
,
"fsmgr_flags"
,
copy
.
data
(),
new_len
);
}
if
(
redirect
&&
name
==
"system"
sv
)
{
if
(
name
==
"system"
sv
)
{
fprintf
(
stderr
,
"Setting [mnt_point] to [/system_root]
\n
"
);
fdt_setprop_string
(
fdt
,
node
,
"mnt_point"
,
"/system_root"
);
modified
=
true
;
fprintf
(
stderr
,
"Changing mnt_point to /system_root
\n
"
);
fdt_setprop_string
(
fdt
,
block
,
"mnt_point"
,
"/system_root"
);
}
}
}
return
modified
;
}
}
#define MAX_FDT_GROWTH 256
template
<
class
Table
,
class
Header
>
static
int
dt_table_patch
(
const
Header
*
hdr
,
const
char
*
out
)
{
template
<
class
Table
,
class
Header
>
static
bool
dt_table_patch
(
const
Header
*
hdr
,
const
char
*
out
)
{
map
<
uint32_t
,
fdt_blob
>
dtb_map
;
auto
buf
=
reinterpret_cast
<
const
uint8_t
*>
(
hdr
);
auto
tables
=
reinterpret_cast
<
const
Table
*>
(
hdr
+
1
);
auto
tables
=
reinterpret_cast
<
const
Table
*>
(
buf
+
sizeof
(
Header
)
);
constexpr
bool
is_dt_table
=
std
::
is_same_v
<
Header
,
dt_table_header
>
;
constexpr
bool
is_aosp
=
std
::
is_same_v
<
Header
,
dt_table_header
>
;
// AOSP DTB store ints in big endian
using
endian_conv
=
uint32_t
(
*
)(
uint32_t
);
endian_conv
be_to_le
;
endian_conv
le_to_be
;
if
constexpr
(
is_dt_table
)
{
if
constexpr
(
is_aosp
)
{
be_to_le
=
fdt32_to_cpu
;
le_to_be
=
cpu_to_fdt32
;
}
else
{
be_to_le
=
le_to_be
=
[](
uint32_t
x
)
->
auto
{
return
x
;
};
be_to_le
=
le_to_be
=
[](
uint32_t
x
)
{
return
x
;
};
}
// Collect all dtbs
...
...
@@ -279,15 +260,19 @@ namespace {
}
}
if
(
dtb_map
.
empty
())
return
1
;
return
false
;
// Patch fdt
if
(
!
fdt_patch
(
make_iter
(
dtb_map
.
begin
()),
make_iter
(
dtb_map
.
end
())))
return
1
;
bool
modified
=
false
;
for
(
auto
&
[
_
,
blob
]
:
dtb_map
)
modified
|=
fdt_patch
(
blob
.
fdt
);
if
(
!
modified
)
return
false
;
unlink
(
out
);
int
fd
=
xopen
(
out
,
O_RDWR
|
O_CREAT
|
O_CLOEXEC
,
0644
);
// This value is only used if AOSP DTB
uint32_t
total_size
=
0
;
// Copy headers and tables
...
...
@@ -299,7 +284,7 @@ namespace {
// Guess alignment using gcd
uint32_t
align
=
1
;
if
constexpr
(
!
is_dt_table
)
{
if
constexpr
(
!
is_aosp
)
{
auto
it
=
dtb_map
.
begin
();
align
=
(
it
++
)
->
first
;
for
(;
it
!=
dtb_map
.
end
();
++
it
)
...
...
@@ -313,14 +298,15 @@ namespace {
fdt_pack
(
fdt
);
auto
size
=
fdt_totalsize
(
fdt
);
total_size
+=
xwrite
(
fd
,
fdt
,
size
);
if
constexpr
(
!
is_aosp
)
{
val
.
second
.
len
=
do_align
(
size
,
align
);
write_zero
(
fd
,
align_off
(
lseek
(
fd
,
0
,
SEEK_CUR
),
align
));
// total_size += align_off(lseek(fd, 0, SEEK_CUR), align); /* Not needed */
}
free
(
fdt
);
}
// Patch headers
if
constexpr
(
is_dt_table
)
{
if
constexpr
(
is_aosp
)
{
auto
hdr_rw
=
reinterpret_cast
<
Header
*>
(
addr
);
hdr_rw
->
total_size
=
le_to_be
(
total_size
);
}
...
...
@@ -334,12 +320,13 @@ namespace {
munmap
(
addr
,
mmap_sz
);
close
(
fd
);
return
0
;
}
return
true
;
}
static
int
blob_patch
(
uint8_t
*
dtb
,
size_t
dtb_sz
,
const
char
*
out
)
{
static
bool
blob_patch
(
uint8_t
*
dtb
,
size_t
dtb_sz
,
const
char
*
out
)
{
vector
<
uint8_t
*>
fdt_list
;
vector
<
uint32_t
>
padding_list
;
for
(
int
i
=
0
;
i
<
dtb_sz
;
++
i
)
{
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
auto
len
=
fdt_totalsize
(
dtb
+
i
);
...
...
@@ -354,8 +341,11 @@ namespace {
}
}
if
(
!
fdt_patch
(
fdt_list
.
begin
(),
fdt_list
.
end
()))
return
1
;
bool
modified
=
false
;
for
(
auto
fdt
:
fdt_list
)
modified
|=
fdt_patch
(
fdt
);
if
(
!
modified
)
return
false
;
unlink
(
out
);
int
fd
=
xopen
(
out
,
O_WRONLY
|
O_CREAT
|
O_CLOEXEC
,
0644
);
...
...
@@ -373,82 +363,73 @@ namespace {
}
close
(
fd
);
return
0
;
}
return
true
;
}
#define MATCH(s) (memcmp(dtb, s, sizeof(s) - 1) == 0)
[[
maybe_unused
]]
static
int
dtb_patch
(
const
char
*
in
,
const
char
*
out
)
{
if
(
!
out
)
out
=
in
;
size_t
dtb_sz
;
uint8_t
*
dtb
;
fprintf
(
stderr
,
"Loading dtbs from [%s]
\n
"
,
in
);
mmap_ro
(
in
,
dtb
,
dtb_sz
);
run_finally
f
([
&
]{
munmap
(
dtb
,
dtb_sz
);
});
static
bool
dtb_patch_rebuild
(
uint8_t
*
dtb
,
size_t
dtb_sz
,
const
char
*
file
)
{
if
(
MATCH
(
QCDT_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
qcdt_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
1
:
fprintf
(
stderr
,
"QCDT v1
\n
"
);
return
dt_table_patch
<
qctable_v1
>
(
hdr
,
out
);
return
dt_table_patch
<
qctable_v1
>
(
hdr
,
file
);
case
2
:
fprintf
(
stderr
,
"QCDT v2
\n
"
);
return
dt_table_patch
<
qctable_v2
>
(
hdr
,
out
);
return
dt_table_patch
<
qctable_v2
>
(
hdr
,
file
);
case
3
:
fprintf
(
stderr
,
"QCDT v3
\n
"
);
return
dt_table_patch
<
qctable_v3
>
(
hdr
,
out
);
return
dt_table_patch
<
qctable_v3
>
(
hdr
,
file
);
default
:
return
1
;
return
false
;
}
}
else
if
(
MATCH
(
DTBH_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
dtbh_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
2
:
fprintf
(
stderr
,
"DTBH v2
\n
"
);
return
dt_table_patch
<
bhtable_v2
>
(
hdr
,
out
);
return
dt_table_patch
<
bhtable_v2
>
(
hdr
,
file
);
default
:
return
1
;
return
false
;
}
}
else
if
(
MATCH
(
PXADT_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
pxadt_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
1
:
fprintf
(
stderr
,
"PXA-DT v1
\n
"
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
out
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
file
);
default
:
return
1
;
return
false
;
}
}
else
if
(
MATCH
(
PXA19xx_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
pxa19xx_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
1
:
fprintf
(
stderr
,
"PXA-19xx v1
\n
"
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
out
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
file
);
default
:
return
1
;
return
false
;
}
}
else
if
(
MATCH
(
SPRD_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
sprd_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
1
:
fprintf
(
stderr
,
"SPRD v1
\n
"
);
return
dt_table_patch
<
sprdtable_v1
>
(
hdr
,
out
);
return
dt_table_patch
<
sprdtable_v1
>
(
hdr
,
file
);
default
:
return
1
;
return
false
;
}
}
else
if
(
MATCH
(
DT_TABLE_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
dt_table_header
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
0
:
fprintf
(
stderr
,
"DT_TABLE v0
\n
"
);
return
dt_table_patch
<
dt_table_entry
>
(
hdr
,
out
);
return
dt_table_patch
<
dt_table_entry
>
(
hdr
,
file
);
default
:
return
1
;
return
false
;
}
}
else
{
return
blob_patch
(
dtb
,
dtb_sz
,
out
);
}
return
blob_patch
(
dtb
,
dtb_sz
,
file
);
}
}
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