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) {
...
@@ -124,38 +124,52 @@ static void dtb_print(const char *file, bool fstab) {
munmap
(
dtb
,
size
);
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
)
{
static
bool
dtb_patch
(
const
char
*
file
)
{
bool
keepverity
=
check_env
(
"KEEPVERITY"
);
bool
keep_verity
=
check_env
(
"KEEPVERITY"
);
bool
patched
=
false
;
bool
have_system
=
false
;
vector
<
pair
<
char
*
,
int
>>
flags_list
;
size_t
size
;
size_t
size
;
uint8_t
*
dtb
;
uint8_t
*
dtb
;
fprintf
(
stderr
,
"Loading dtbs from [%s]
\n
"
,
file
);
fprintf
(
stderr
,
"Loading dtbs from [%s]
\n
"
,
file
);
mmap_rw
(
file
,
dtb
,
size
);
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
;
int
dtb_num
=
0
;
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
auto
fdt
=
dtb
+
i
;
auto
fdt
=
dtb
+
i
;
fprintf
(
stderr
,
"Loading dtb.%04d
\n
"
,
dtb_num
);
if
(
int
fstab
=
find_fstab
(
fdt
);
fstab
>=
0
)
{
if
(
int
fstab
=
find_fstab
(
fdt
);
fstab
>=
0
)
{
int
node
;
int
node
;
fdt_for_each_subnode
(
node
,
fdt
,
fstab
)
{
fdt_for_each_subnode
(
node
,
fdt
,
fstab
)
{
const
char
*
name
=
fdt_get_name
(
fdt
,
node
,
nullptr
);
const
char
*
name
=
fdt_get_name
(
fdt
,
node
,
nullptr
);
fprintf
(
stderr
,
"Found fstab entry [%s]
\n
"
,
name
);
if
(
!
keep_verity
)
{
if
(
!
keepverity
)
{
int
len
;
int
len
;
auto
value
=
fdt_getprop
(
fdt
,
node
,
"fsmgr_flags"
,
&
len
);
char
*
value
=
(
char
*
)
fdt_getprop
(
fdt
,
node
,
"fsmgr_flags"
,
&
len
);
patched
|=
patch_verity
(
const_cast
<
void
*>
(
value
),
len
)
!=
len
;
flags_list
.
emplace_back
(
value
,
len
)
;
}
}
if
(
name
==
"system"
sv
)
have_system
=
true
;
}
}
}
}
++
dtb_num
;
i
+=
fdt_totalsize
(
fdt
)
-
1
;
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
;
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
[])
{
int
dtb_commands
(
int
argc
,
char
*
argv
[])
{
...
@@ -176,93 +190,60 @@ int dtb_commands(int argc, char *argv[]) {
...
@@ -176,93 +190,60 @@ int dtb_commands(int argc, char *argv[]) {
}
}
namespace
{
namespace
{
// Unused, but keep these precious code as they took TONs of effort to write
struct
fdt_blob
{
struct
fdt_blob
{
void
*
fdt
;
void
*
fdt
;
uint32_t
offset
;
uint32_t
offset
;
uint32_t
len
;
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
;
static
bool
fdt_patch
(
void
*
fdt
)
{
for
(
auto
it
=
first
;
it
!=
last
;
++
it
)
{
++
idx
;
auto
fdt
=
*
it
;
int
fstab
=
find_fstab
(
fdt
);
int
fstab
=
find_fstab
(
fdt
);
if
(
fstab
<
0
)
if
(
fstab
<
0
)
continu
e
;
return
fals
e
;
fprintf
(
stderr
,
"Found fstab in dtb.%04d
\n
"
,
idx
-
1
)
;
bool
modified
=
false
;
int
block
;
int
node
;
fdt_for_each_subnode
(
block
,
fdt
,
fstab
)
{
fdt_for_each_subnode
(
node
,
fdt
,
fstab
)
{
const
char
*
name
=
fdt_get_name
(
fdt
,
block
,
nullptr
);
const
char
*
name
=
fdt_get_name
(
fdt
,
node
,
nullptr
);
fprintf
(
stderr
,
"Found entry [%s] in fstab
\n
"
,
name
);
// Always patch verity if 2SI
if
(
!
keepverity
)
{
int
len
;
int
size
;
auto
value
=
(
const
char
*
)
fdt_getprop
(
fdt
,
node
,
"fsmgr_flags"
,
&
len
)
;
auto
value
=
fdt_getprop
(
fdt
,
block
,
"fsmgr_flags"
,
&
size
);
string
copy
(
value
,
len
);
char
*
copy
=
static_cast
<
char
*>
(
memcpy
(
malloc
(
size
),
value
,
size
)
);
uint32_t
new_len
=
patch_verity
(
copy
.
data
(),
len
);
if
(
patch_verity
(
copy
,
size
)
!=
size
)
{
if
(
new_len
!=
len
)
{
modified
=
true
;
modified
=
true
;
fdt_setprop_string
(
fdt
,
block
,
"fsmgr_flags"
,
copy
);
fdt_setprop
(
fdt
,
node
,
"fsmgr_flags"
,
copy
.
data
(),
new_len
);
}
free
(
copy
);
}
}
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
;
modified
=
true
;
fprintf
(
stderr
,
"Changing mnt_point to /system_root
\n
"
);
fdt_setprop_string
(
fdt
,
block
,
"mnt_point"
,
"/system_root"
);
}
}
}
}
}
return
modified
;
return
modified
;
}
}
#define MAX_FDT_GROWTH 256
#define MAX_FDT_GROWTH 256
template
<
class
Table
,
class
Header
>
template
<
class
Table
,
class
Header
>
static
int
dt_table_patch
(
const
Header
*
hdr
,
const
char
*
out
)
{
static
bool
dt_table_patch
(
const
Header
*
hdr
,
const
char
*
out
)
{
map
<
uint32_t
,
fdt_blob
>
dtb_map
;
map
<
uint32_t
,
fdt_blob
>
dtb_map
;
auto
buf
=
reinterpret_cast
<
const
uint8_t
*>
(
hdr
);
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
);
using
endian_conv
=
uint32_t
(
*
)(
uint32_t
);
endian_conv
be_to_le
;
endian_conv
be_to_le
;
endian_conv
le_to_be
;
endian_conv
le_to_be
;
if
constexpr
(
is_dt_table
)
{
if
constexpr
(
is_aosp
)
{
be_to_le
=
fdt32_to_cpu
;
be_to_le
=
fdt32_to_cpu
;
le_to_be
=
cpu_to_fdt32
;
le_to_be
=
cpu_to_fdt32
;
}
else
{
}
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
// Collect all dtbs
...
@@ -279,15 +260,19 @@ namespace {
...
@@ -279,15 +260,19 @@ namespace {
}
}
}
}
if
(
dtb_map
.
empty
())
if
(
dtb_map
.
empty
())
return
1
;
return
false
;
// Patch fdt
// Patch fdt
if
(
!
fdt_patch
(
make_iter
(
dtb_map
.
begin
()),
make_iter
(
dtb_map
.
end
())))
bool
modified
=
false
;
return
1
;
for
(
auto
&
[
_
,
blob
]
:
dtb_map
)
modified
|=
fdt_patch
(
blob
.
fdt
);
if
(
!
modified
)
return
false
;
unlink
(
out
);
unlink
(
out
);
int
fd
=
xopen
(
out
,
O_RDWR
|
O_CREAT
|
O_CLOEXEC
,
0644
);
int
fd
=
xopen
(
out
,
O_RDWR
|
O_CREAT
|
O_CLOEXEC
,
0644
);
// This value is only used if AOSP DTB
uint32_t
total_size
=
0
;
uint32_t
total_size
=
0
;
// Copy headers and tables
// Copy headers and tables
...
@@ -299,7 +284,7 @@ namespace {
...
@@ -299,7 +284,7 @@ namespace {
// Guess alignment using gcd
// Guess alignment using gcd
uint32_t
align
=
1
;
uint32_t
align
=
1
;
if
constexpr
(
!
is_dt_table
)
{
if
constexpr
(
!
is_aosp
)
{
auto
it
=
dtb_map
.
begin
();
auto
it
=
dtb_map
.
begin
();
align
=
(
it
++
)
->
first
;
align
=
(
it
++
)
->
first
;
for
(;
it
!=
dtb_map
.
end
();
++
it
)
for
(;
it
!=
dtb_map
.
end
();
++
it
)
...
@@ -313,14 +298,15 @@ namespace {
...
@@ -313,14 +298,15 @@ namespace {
fdt_pack
(
fdt
);
fdt_pack
(
fdt
);
auto
size
=
fdt_totalsize
(
fdt
);
auto
size
=
fdt_totalsize
(
fdt
);
total_size
+=
xwrite
(
fd
,
fdt
,
size
);
total_size
+=
xwrite
(
fd
,
fdt
,
size
);
if
constexpr
(
!
is_aosp
)
{
val
.
second
.
len
=
do_align
(
size
,
align
);
val
.
second
.
len
=
do_align
(
size
,
align
);
write_zero
(
fd
,
align_off
(
lseek
(
fd
,
0
,
SEEK_CUR
),
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
);
free
(
fdt
);
}
}
// Patch headers
// Patch headers
if
constexpr
(
is_dt_table
)
{
if
constexpr
(
is_aosp
)
{
auto
hdr_rw
=
reinterpret_cast
<
Header
*>
(
addr
);
auto
hdr_rw
=
reinterpret_cast
<
Header
*>
(
addr
);
hdr_rw
->
total_size
=
le_to_be
(
total_size
);
hdr_rw
->
total_size
=
le_to_be
(
total_size
);
}
}
...
@@ -334,12 +320,13 @@ namespace {
...
@@ -334,12 +320,13 @@ namespace {
munmap
(
addr
,
mmap_sz
);
munmap
(
addr
,
mmap_sz
);
close
(
fd
);
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
<
uint8_t
*>
fdt_list
;
vector
<
uint32_t
>
padding_list
;
vector
<
uint32_t
>
padding_list
;
for
(
int
i
=
0
;
i
<
dtb_sz
;
++
i
)
{
for
(
int
i
=
0
;
i
<
dtb_sz
;
++
i
)
{
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
auto
len
=
fdt_totalsize
(
dtb
+
i
);
auto
len
=
fdt_totalsize
(
dtb
+
i
);
...
@@ -354,8 +341,11 @@ namespace {
...
@@ -354,8 +341,11 @@ namespace {
}
}
}
}
if
(
!
fdt_patch
(
fdt_list
.
begin
(),
fdt_list
.
end
()))
bool
modified
=
false
;
return
1
;
for
(
auto
fdt
:
fdt_list
)
modified
|=
fdt_patch
(
fdt
);
if
(
!
modified
)
return
false
;
unlink
(
out
);
unlink
(
out
);
int
fd
=
xopen
(
out
,
O_WRONLY
|
O_CREAT
|
O_CLOEXEC
,
0644
);
int
fd
=
xopen
(
out
,
O_WRONLY
|
O_CREAT
|
O_CLOEXEC
,
0644
);
...
@@ -373,82 +363,73 @@ namespace {
...
@@ -373,82 +363,73 @@ namespace {
}
}
close
(
fd
);
close
(
fd
);
return
0
;
return
true
;
}
}
#define MATCH(s) (memcmp(dtb, s, sizeof(s) - 1) == 0)
#define MATCH(s) (memcmp(dtb, s, sizeof(s) - 1) == 0)
[[
maybe_unused
]]
static
int
dtb_patch
(
const
char
*
in
,
const
char
*
out
)
{
static
bool
dtb_patch_rebuild
(
uint8_t
*
dtb
,
size_t
dtb_sz
,
const
char
*
file
)
{
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
);
});
if
(
MATCH
(
QCDT_MAGIC
))
{
if
(
MATCH
(
QCDT_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
qcdt_hdr
*>
(
dtb
);
auto
hdr
=
reinterpret_cast
<
qcdt_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
switch
(
hdr
->
version
)
{
case
1
:
case
1
:
fprintf
(
stderr
,
"QCDT v1
\n
"
);
fprintf
(
stderr
,
"QCDT v1
\n
"
);
return
dt_table_patch
<
qctable_v1
>
(
hdr
,
out
);
return
dt_table_patch
<
qctable_v1
>
(
hdr
,
file
);
case
2
:
case
2
:
fprintf
(
stderr
,
"QCDT v2
\n
"
);
fprintf
(
stderr
,
"QCDT v2
\n
"
);
return
dt_table_patch
<
qctable_v2
>
(
hdr
,
out
);
return
dt_table_patch
<
qctable_v2
>
(
hdr
,
file
);
case
3
:
case
3
:
fprintf
(
stderr
,
"QCDT v3
\n
"
);
fprintf
(
stderr
,
"QCDT v3
\n
"
);
return
dt_table_patch
<
qctable_v3
>
(
hdr
,
out
);
return
dt_table_patch
<
qctable_v3
>
(
hdr
,
file
);
default
:
default
:
return
1
;
return
false
;
}
}
}
else
if
(
MATCH
(
DTBH_MAGIC
))
{
}
else
if
(
MATCH
(
DTBH_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
dtbh_hdr
*>
(
dtb
);
auto
hdr
=
reinterpret_cast
<
dtbh_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
switch
(
hdr
->
version
)
{
case
2
:
case
2
:
fprintf
(
stderr
,
"DTBH v2
\n
"
);
fprintf
(
stderr
,
"DTBH v2
\n
"
);
return
dt_table_patch
<
bhtable_v2
>
(
hdr
,
out
);
return
dt_table_patch
<
bhtable_v2
>
(
hdr
,
file
);
default
:
default
:
return
1
;
return
false
;
}
}
}
else
if
(
MATCH
(
PXADT_MAGIC
))
{
}
else
if
(
MATCH
(
PXADT_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
pxadt_hdr
*>
(
dtb
);
auto
hdr
=
reinterpret_cast
<
pxadt_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
switch
(
hdr
->
version
)
{
case
1
:
case
1
:
fprintf
(
stderr
,
"PXA-DT v1
\n
"
);
fprintf
(
stderr
,
"PXA-DT v1
\n
"
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
out
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
file
);
default
:
default
:
return
1
;
return
false
;
}
}
}
else
if
(
MATCH
(
PXA19xx_MAGIC
))
{
}
else
if
(
MATCH
(
PXA19xx_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
pxa19xx_hdr
*>
(
dtb
);
auto
hdr
=
reinterpret_cast
<
pxa19xx_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
switch
(
hdr
->
version
)
{
case
1
:
case
1
:
fprintf
(
stderr
,
"PXA-19xx v1
\n
"
);
fprintf
(
stderr
,
"PXA-19xx v1
\n
"
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
out
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
file
);
default
:
default
:
return
1
;
return
false
;
}
}
}
else
if
(
MATCH
(
SPRD_MAGIC
))
{
}
else
if
(
MATCH
(
SPRD_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
sprd_hdr
*>
(
dtb
);
auto
hdr
=
reinterpret_cast
<
sprd_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
switch
(
hdr
->
version
)
{
case
1
:
case
1
:
fprintf
(
stderr
,
"SPRD v1
\n
"
);
fprintf
(
stderr
,
"SPRD v1
\n
"
);
return
dt_table_patch
<
sprdtable_v1
>
(
hdr
,
out
);
return
dt_table_patch
<
sprdtable_v1
>
(
hdr
,
file
);
default
:
default
:
return
1
;
return
false
;
}
}
}
else
if
(
MATCH
(
DT_TABLE_MAGIC
))
{
}
else
if
(
MATCH
(
DT_TABLE_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
dt_table_header
*>
(
dtb
);
auto
hdr
=
reinterpret_cast
<
dt_table_header
*>
(
dtb
);
switch
(
hdr
->
version
)
{
switch
(
hdr
->
version
)
{
case
0
:
case
0
:
fprintf
(
stderr
,
"DT_TABLE v0
\n
"
);
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
:
default
:
return
1
;
return
false
;
}
}
}
else
{
}
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