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
17d3a87b
Commit
17d3a87b
authored
May 30, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prevent resetprop function signature duplicate with libc
parent
14c5c608
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
156 additions
and
932 deletions
+156
-932
Android.mk
jni/Android.mk
+0
-1
bootstages.c
jni/daemon/bootstages.c
+3
-0
_system_properties.h
jni/resetprop/_system_properties.h
+20
-20
libc_logging.cpp
jni/resetprop/libc_logging.cpp
+0
-659
libc_logging.h
jni/resetprop/libc_logging.h
+0
-115
resetprop.cpp
jni/resetprop/resetprop.cpp
+10
-8
system_properties.cpp
jni/resetprop/system_properties.cpp
+108
-114
system_properties.h
jni/resetprop/system_properties.h
+15
-15
No files found.
jni/Android.mk
View file @
17d3a87b
...
...
@@ -34,7 +34,6 @@ LOCAL_SRC_FILES := \
magiskpolicy/sepolicy.c \
magiskpolicy/api.c \
resetprop/resetprop.cpp \
resetprop/libc_logging.cpp \
resetprop/system_properties.cpp \
su/su.c \
su/activity.c \
...
...
jni/daemon/bootstages.c
View file @
17d3a87b
...
...
@@ -693,6 +693,9 @@ void post_fs_data(int client) {
bind_mount
(
HOSTSFILE
,
"/system/etc/hosts"
);
}
// Initialize resetprop for the daemon
init_resetprop
();
// Start magiskhide if enabled
char
*
hide_prop
=
getprop
(
MAGISKHIDE_PROP
);
if
(
hide_prop
)
{
...
...
jni/resetprop/_system_properties.h
View file @
17d3a87b
...
...
@@ -62,38 +62,38 @@ __BEGIN_DECLS
** Map the property area from the specified filename. This
** method is for testing only.
*/
int
__system_property_set_filename
(
const
char
*
filename
);
int
__system_property_set_filename
2
(
const
char
*
filename
);
/*
** Initialize the area to be used to store properties. Can
** only be done by a single process that has write access to
** the property area.
*/
int
__system_property_area_init
();
int
__system_property_area_init
2
();
/* Read the global serial number of the system properties
**
** Called to predict if a series of cached __system_property_find
** objects will have seen __system_property_serial values change.
** Called to predict if a series of cached __system_property_find
2
** objects will have seen __system_property_serial
2
values change.
** But also aids the converse, as changes in the global serial can
** also be used to predict if a failed __system_property_find
** also be used to predict if a failed __system_property_find
2
** could in-turn now find a new object; thus preventing the
** cycles of effort to poll __system_property_find.
** cycles of effort to poll __system_property_find
2
.
**
** Typically called at beginning of a cache cycle to signal if _any_ possible
** changes have occurred since last. If there is, one may check each individual
** __system_property_serial
to confirm dirty, or __system_property_find
** to check if the property now exists. If a call to __system_property_add
** or __system_property_update has completed between two calls to
** __system_property_area_serial then the second call will return a larger
** __system_property_serial
2 to confirm dirty, or __system_property_find2
** to check if the property now exists. If a call to __system_property_add
2
** or __system_property_update
2
has completed between two calls to
** __system_property_area_serial
2
then the second call will return a larger
** value than the first call. Beware of race conditions as changes to the
** properties are not atomic, the main value of this call is to determine
** whether the expensive __system_property_find is worth retrying to see if
** whether the expensive __system_property_find
2
is worth retrying to see if
** a property now exists.
**
** Returns the serial number on success, -1 on error.
*/
uint32_t
__system_property_area_serial
();
uint32_t
__system_property_area_serial
2
();
/* Add a new system property. Can only be done by a single
** process that has write access to the property area, and
...
...
@@ -103,7 +103,7 @@ uint32_t __system_property_area_serial();
**
** Returns 0 on success, -1 if the property area is full.
*/
int
__system_property_add
(
const
char
*
name
,
unsigned
int
namelen
,
const
char
*
value
,
unsigned
int
valuelen
);
int
__system_property_add
2
(
const
char
*
name
,
unsigned
int
namelen
,
const
char
*
value
,
unsigned
int
valuelen
);
/* Delete a new system property. Added in resetprop
**
...
...
@@ -112,21 +112,21 @@ int __system_property_add(const char *name, unsigned int namelen, const char *va
int
__system_property_del
(
const
char
*
name
);
/* Update the value of a system property returned by
** __system_property_find. Can only be done by a single process
** __system_property_find
2
. Can only be done by a single process
** that has write access to the property area, and that process
** must handle sequencing to ensure that only one property is
** updated at a time.
**
** Returns 0 on success, -1 if the parameters are incorrect.
*/
int
__system_property_update
(
prop_info
*
pi
,
const
char
*
value
,
unsigned
int
len
);
int
__system_property_update
2
(
prop_info
*
pi
,
const
char
*
value
,
unsigned
int
len
);
/* Read the serial number of a system property returned by
** __system_property_find.
** __system_property_find
2
.
**
** Returns the serial number on success, -1 on error.
*/
uint32_t
__system_property_serial
(
const
prop_info
*
pi
);
uint32_t
__system_property_serial
2
(
const
prop_info
*
pi
);
/* Initialize the system properties area in read only mode.
* Should be done by all processes that need to read system
...
...
@@ -134,10 +134,10 @@ uint32_t __system_property_serial(const prop_info* pi);
*
* Returns 0 on success, -1 otherwise.
*/
int
__system_properties_init
();
int
__system_properties_init
2
();
/* Deprecated: use __system_property_wait instead. */
uint32_t
__system_property_wait_any
(
uint32_t
old_serial
);
/* Deprecated: use __system_property_wait
2
instead. */
uint32_t
__system_property_wait_any
2
(
uint32_t
old_serial
);
__END_DECLS
...
...
jni/resetprop/libc_logging.cpp
deleted
100644 → 0
View file @
14c5c608
/*
* Copyright (C) 2010 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "libc_logging.h" // Relative path so we can #include this .cpp file for testing.
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include "_system_properties.h"
static
pthread_mutex_t
g_abort_msg_lock
=
PTHREAD_MUTEX_INITIALIZER
;
__LIBC_HIDDEN__
abort_msg_t
**
__abort_message_ptr
;
// Accessible to __libc_init_common.
// Must be kept in sync with frameworks/base/core/java/android/util/EventLog.java.
enum
AndroidEventLogType
{
EVENT_TYPE_INT
=
0
,
EVENT_TYPE_LONG
=
1
,
EVENT_TYPE_STRING
=
2
,
EVENT_TYPE_LIST
=
3
,
EVENT_TYPE_FLOAT
=
4
,
};
struct
BufferOutputStream
{
public
:
BufferOutputStream
(
char
*
buffer
,
size_t
size
)
:
total
(
0
)
{
buffer_
=
buffer
;
end_
=
buffer
+
size
-
1
;
pos_
=
buffer_
;
pos_
[
0
]
=
'\0'
;
}
~
BufferOutputStream
()
{
}
void
Send
(
const
char
*
data
,
int
len
)
{
if
(
len
<
0
)
{
len
=
strlen
(
data
);
}
total
+=
len
;
while
(
len
>
0
)
{
int
avail
=
end_
-
pos_
;
if
(
avail
==
0
)
{
return
;
}
if
(
avail
>
len
)
{
avail
=
len
;
}
memcpy
(
pos_
,
data
,
avail
);
pos_
+=
avail
;
pos_
[
0
]
=
'\0'
;
len
-=
avail
;
}
}
size_t
total
;
private
:
char
*
buffer_
;
char
*
pos_
;
char
*
end_
;
};
struct
FdOutputStream
{
public
:
FdOutputStream
(
int
fd
)
:
total
(
0
),
fd_
(
fd
)
{
}
void
Send
(
const
char
*
data
,
int
len
)
{
if
(
len
<
0
)
{
len
=
strlen
(
data
);
}
total
+=
len
;
while
(
len
>
0
)
{
int
rc
=
TEMP_FAILURE_RETRY
(
write
(
fd_
,
data
,
len
));
if
(
rc
==
-
1
)
{
return
;
}
data
+=
rc
;
len
-=
rc
;
}
}
size_t
total
;
private
:
int
fd_
;
};
/*** formatted output implementation
***/
/* Parse a decimal string from 'format + *ppos',
* return the value, and writes the new position past
* the decimal string in '*ppos' on exit.
*
* NOTE: Does *not* handle a sign prefix.
*/
static
unsigned
parse_decimal
(
const
char
*
format
,
int
*
ppos
)
{
const
char
*
p
=
format
+
*
ppos
;
unsigned
result
=
0
;
for
(;;)
{
int
ch
=
*
p
;
unsigned
d
=
static_cast
<
unsigned
>
(
ch
-
'0'
);
if
(
d
>=
10U
)
{
break
;
}
result
=
result
*
10
+
d
;
p
++
;
}
*
ppos
=
p
-
format
;
return
result
;
}
// Writes number 'value' in base 'base' into buffer 'buf' of size 'buf_size' bytes.
// Assumes that buf_size > 0.
static
void
format_unsigned
(
char
*
buf
,
size_t
buf_size
,
uint64_t
value
,
int
base
,
bool
caps
)
{
char
*
p
=
buf
;
char
*
end
=
buf
+
buf_size
-
1
;
// Generate digit string in reverse order.
while
(
value
)
{
unsigned
d
=
value
%
base
;
value
/=
base
;
if
(
p
!=
end
)
{
char
ch
;
if
(
d
<
10
)
{
ch
=
'0'
+
d
;
}
else
{
ch
=
(
caps
?
'A'
:
'a'
)
+
(
d
-
10
);
}
*
p
++
=
ch
;
}
}
// Special case for 0.
if
(
p
==
buf
)
{
if
(
p
!=
end
)
{
*
p
++
=
'0'
;
}
}
*
p
=
'\0'
;
// Reverse digit string in-place.
size_t
length
=
p
-
buf
;
for
(
size_t
i
=
0
,
j
=
length
-
1
;
i
<
j
;
++
i
,
--
j
)
{
char
ch
=
buf
[
i
];
buf
[
i
]
=
buf
[
j
];
buf
[
j
]
=
ch
;
}
}
static
void
format_integer
(
char
*
buf
,
size_t
buf_size
,
uint64_t
value
,
char
conversion
)
{
// Decode the conversion specifier.
int
is_signed
=
(
conversion
==
'd'
||
conversion
==
'i'
||
conversion
==
'o'
);
int
base
=
10
;
if
(
conversion
==
'x'
||
conversion
==
'X'
)
{
base
=
16
;
}
else
if
(
conversion
==
'o'
)
{
base
=
8
;
}
bool
caps
=
(
conversion
==
'X'
);
if
(
is_signed
&&
static_cast
<
int64_t
>
(
value
)
<
0
)
{
buf
[
0
]
=
'-'
;
buf
+=
1
;
buf_size
-=
1
;
value
=
static_cast
<
uint64_t
>
(
-
static_cast
<
int64_t
>
(
value
));
}
format_unsigned
(
buf
,
buf_size
,
value
,
base
,
caps
);
}
template
<
typename
Out
>
static
void
SendRepeat
(
Out
&
o
,
char
ch
,
int
count
)
{
char
pad
[
8
];
memset
(
pad
,
ch
,
sizeof
(
pad
));
const
int
pad_size
=
static_cast
<
int
>
(
sizeof
(
pad
));
while
(
count
>
0
)
{
int
avail
=
count
;
if
(
avail
>
pad_size
)
{
avail
=
pad_size
;
}
o
.
Send
(
pad
,
avail
);
count
-=
avail
;
}
}
/* Perform formatted output to an output target 'o' */
template
<
typename
Out
>
static
void
out_vformat
(
Out
&
o
,
const
char
*
format
,
va_list
args
)
{
int
nn
=
0
;
for
(;;)
{
int
mm
;
int
padZero
=
0
;
int
padLeft
=
0
;
char
sign
=
'\0'
;
int
width
=
-
1
;
int
prec
=
-
1
;
size_t
bytelen
=
sizeof
(
int
);
int
slen
;
char
buffer
[
32
];
/* temporary buffer used to format numbers */
char
c
;
/* first, find all characters that are not 0 or '%' */
/* then send them to the output directly */
mm
=
nn
;
do
{
c
=
format
[
mm
];
if
(
c
==
'\0'
||
c
==
'%'
)
break
;
mm
++
;
}
while
(
1
);
if
(
mm
>
nn
)
{
o
.
Send
(
format
+
nn
,
mm
-
nn
);
nn
=
mm
;
}
/* is this it ? then exit */
if
(
c
==
'\0'
)
break
;
/* nope, we are at a '%' modifier */
nn
++
;
// skip it
/* parse flags */
for
(;;)
{
c
=
format
[
nn
++
];
if
(
c
==
'\0'
)
{
/* single trailing '%' ? */
c
=
'%'
;
o
.
Send
(
&
c
,
1
);
return
;
}
else
if
(
c
==
'0'
)
{
padZero
=
1
;
continue
;
}
else
if
(
c
==
'-'
)
{
padLeft
=
1
;
continue
;
}
else
if
(
c
==
' '
||
c
==
'+'
)
{
sign
=
c
;
continue
;
}
break
;
}
/* parse field width */
if
((
c
>=
'0'
&&
c
<=
'9'
))
{
nn
--
;
width
=
static_cast
<
int
>
(
parse_decimal
(
format
,
&
nn
));
c
=
format
[
nn
++
];
}
/* parse precision */
if
(
c
==
'.'
)
{
prec
=
static_cast
<
int
>
(
parse_decimal
(
format
,
&
nn
));
c
=
format
[
nn
++
];
}
/* length modifier */
switch
(
c
)
{
case
'h'
:
bytelen
=
sizeof
(
short
);
if
(
format
[
nn
]
==
'h'
)
{
bytelen
=
sizeof
(
char
);
nn
+=
1
;
}
c
=
format
[
nn
++
];
break
;
case
'l'
:
bytelen
=
sizeof
(
long
);
if
(
format
[
nn
]
==
'l'
)
{
bytelen
=
sizeof
(
long
long
);
nn
+=
1
;
}
c
=
format
[
nn
++
];
break
;
case
'z'
:
bytelen
=
sizeof
(
size_t
);
c
=
format
[
nn
++
];
break
;
case
't'
:
bytelen
=
sizeof
(
ptrdiff_t
);
c
=
format
[
nn
++
];
break
;
default
:
;
}
/* conversion specifier */
const
char
*
str
=
buffer
;
if
(
c
==
's'
)
{
/* string */
str
=
va_arg
(
args
,
const
char
*
);
if
(
str
==
NULL
)
{
str
=
"(null)"
;
}
}
else
if
(
c
==
'c'
)
{
/* character */
/* NOTE: char is promoted to int when passed through the stack */
buffer
[
0
]
=
static_cast
<
char
>
(
va_arg
(
args
,
int
));
buffer
[
1
]
=
'\0'
;
}
else
if
(
c
==
'p'
)
{
uint64_t
value
=
reinterpret_cast
<
uintptr_t
>
(
va_arg
(
args
,
void
*
));
buffer
[
0
]
=
'0'
;
buffer
[
1
]
=
'x'
;
format_integer
(
buffer
+
2
,
sizeof
(
buffer
)
-
2
,
value
,
'x'
);
}
else
if
(
c
==
'd'
||
c
==
'i'
||
c
==
'o'
||
c
==
'u'
||
c
==
'x'
||
c
==
'X'
)
{
/* integers - first read value from stack */
uint64_t
value
;
int
is_signed
=
(
c
==
'd'
||
c
==
'i'
||
c
==
'o'
);
/* NOTE: int8_t and int16_t are promoted to int when passed
* through the stack
*/
switch
(
bytelen
)
{
case
1
:
value
=
static_cast
<
uint8_t
>
(
va_arg
(
args
,
int
));
break
;
case
2
:
value
=
static_cast
<
uint16_t
>
(
va_arg
(
args
,
int
));
break
;
case
4
:
value
=
va_arg
(
args
,
uint32_t
);
break
;
case
8
:
value
=
va_arg
(
args
,
uint64_t
);
break
;
default
:
return
;
/* should not happen */
}
/* sign extension, if needed */
if
(
is_signed
)
{
int
shift
=
64
-
8
*
bytelen
;
value
=
static_cast
<
uint64_t
>
((
static_cast
<
int64_t
>
(
value
<<
shift
))
>>
shift
);
}
/* format the number properly into our buffer */
format_integer
(
buffer
,
sizeof
(
buffer
),
value
,
c
);
}
else
if
(
c
==
'%'
)
{
buffer
[
0
]
=
'%'
;
buffer
[
1
]
=
'\0'
;
}
else
{
__assert
(
__FILE__
,
__LINE__
,
"conversion specifier unsupported"
);
}
/* if we are here, 'str' points to the content that must be
* outputted. handle padding and alignment now */
slen
=
strlen
(
str
);
if
(
sign
!=
'\0'
||
prec
!=
-
1
)
{
__assert
(
__FILE__
,
__LINE__
,
"sign/precision unsupported"
);
}
if
(
slen
<
width
&&
!
padLeft
)
{
char
padChar
=
padZero
?
'0'
:
' '
;
SendRepeat
(
o
,
padChar
,
width
-
slen
);
}
o
.
Send
(
str
,
slen
);
if
(
slen
<
width
&&
padLeft
)
{
char
padChar
=
padZero
?
'0'
:
' '
;
SendRepeat
(
o
,
padChar
,
width
-
slen
);
}
}
}
int
__libc_format_buffer
(
char
*
buffer
,
size_t
buffer_size
,
const
char
*
format
,
...)
{
BufferOutputStream
os
(
buffer
,
buffer_size
);
va_list
args
;
va_start
(
args
,
format
);
out_vformat
(
os
,
format
,
args
);
va_end
(
args
);
return
os
.
total
;
}
int
__libc_format_fd
(
int
fd
,
const
char
*
format
,
...)
{
FdOutputStream
os
(
fd
);
va_list
args
;
va_start
(
args
,
format
);
out_vformat
(
os
,
format
,
args
);
va_end
(
args
);
return
os
.
total
;
}
static
int
__libc_write_stderr
(
const
char
*
tag
,
const
char
*
msg
)
{
int
fd
=
TEMP_FAILURE_RETRY
(
open
(
"/dev/stderr"
,
O_CLOEXEC
|
O_WRONLY
|
O_APPEND
));
if
(
fd
==
-
1
)
{
return
-
1
;
}
iovec
vec
[
4
];
vec
[
0
].
iov_base
=
const_cast
<
char
*>
(
tag
);
vec
[
0
].
iov_len
=
strlen
(
tag
);
vec
[
1
].
iov_base
=
const_cast
<
char
*>
(
": "
);
vec
[
1
].
iov_len
=
2
;
vec
[
2
].
iov_base
=
const_cast
<
char
*>
(
msg
);
vec
[
2
].
iov_len
=
strlen
(
msg
);
vec
[
3
].
iov_base
=
const_cast
<
char
*>
(
"
\n
"
);
vec
[
3
].
iov_len
=
1
;
int
result
=
TEMP_FAILURE_RETRY
(
writev
(
fd
,
vec
,
4
));
close
(
fd
);
return
result
;
}
static
int
__libc_open_log_socket
()
{
// ToDo: Ideally we want this to fail if the gid of the current
// process is AID_LOGD, but will have to wait until we have
// registered this in private/android_filesystem_config.h. We have
// found that all logd crashes thus far have had no problem stuffing
// the UNIX domain socket and moving on so not critical *today*.
int
log_fd
=
TEMP_FAILURE_RETRY
(
socket
(
PF_UNIX
,
SOCK_DGRAM
|
SOCK_CLOEXEC
,
0
));
if
(
log_fd
<
0
)
{
return
-
1
;
}
if
(
fcntl
(
log_fd
,
F_SETFL
,
O_NONBLOCK
)
==
-
1
)
{
close
(
log_fd
);
return
-
1
;
}
union
{
struct
sockaddr
addr
;
struct
sockaddr_un
addrUn
;
}
u
;
memset
(
&
u
,
0
,
sizeof
(
u
));
u
.
addrUn
.
sun_family
=
AF_UNIX
;
strlcpy
(
u
.
addrUn
.
sun_path
,
"/dev/socket/logdw"
,
sizeof
(
u
.
addrUn
.
sun_path
));
if
(
TEMP_FAILURE_RETRY
(
connect
(
log_fd
,
&
u
.
addr
,
sizeof
(
u
.
addrUn
)))
!=
0
)
{
close
(
log_fd
);
return
-
1
;
}
return
log_fd
;
}
struct
cache
{
const
prop_info
*
pinfo
;
uint32_t
serial
;
char
c
;
};
static
void
refresh_cache
(
struct
cache
*
cache
,
const
char
*
key
)
{
if
(
!
cache
->
pinfo
)
{
cache
->
pinfo
=
__system_property_find
(
key
);
if
(
!
cache
->
pinfo
)
{
return
;
}
}
uint32_t
serial
=
__system_property_serial
(
cache
->
pinfo
);
if
(
serial
==
cache
->
serial
)
{
return
;
}
cache
->
serial
=
serial
;
char
buf
[
PROP_VALUE_MAX
];
__system_property_read
(
cache
->
pinfo
,
0
,
buf
);
cache
->
c
=
buf
[
0
];
}
// Timestamp state generally remains constant, since a change is
// rare, we can accept a trylock failure gracefully.
static
pthread_mutex_t
lock_clockid
=
PTHREAD_MUTEX_INITIALIZER
;
static
clockid_t
__android_log_clockid
()
{
static
struct
cache
r_time_cache
=
{
NULL
,
static_cast
<
uint32_t
>
(
-
1
),
0
};
static
struct
cache
p_time_cache
=
{
NULL
,
static_cast
<
uint32_t
>
(
-
1
),
0
};
char
c
;
if
(
pthread_mutex_trylock
(
&
lock_clockid
))
{
// We are willing to accept some race in this context
if
(
!
(
c
=
p_time_cache
.
c
))
{
c
=
r_time_cache
.
c
;
}
}
else
{
static
uint32_t
serial
;
uint32_t
current_serial
=
__system_property_area_serial
();
if
(
current_serial
!=
serial
)
{
refresh_cache
(
&
r_time_cache
,
"ro.logd.timestamp"
);
refresh_cache
(
&
p_time_cache
,
"persist.logd.timestamp"
);
serial
=
current_serial
;
}
if
(
!
(
c
=
p_time_cache
.
c
))
{
c
=
r_time_cache
.
c
;
}
pthread_mutex_unlock
(
&
lock_clockid
);
}
return
(
tolower
(
c
)
==
'm'
)
?
CLOCK_MONOTONIC
:
CLOCK_REALTIME
;
}
struct
log_time
{
// Wire format
uint32_t
tv_sec
;
uint32_t
tv_nsec
;
};
int
__libc_write_log
(
int
priority
,
const
char
*
tag
,
const
char
*
msg
)
{
int
main_log_fd
=
__libc_open_log_socket
();
if
(
main_log_fd
==
-
1
)
{
// Try stderr instead.
return
__libc_write_stderr
(
tag
,
msg
);
}
iovec
vec
[
6
];
char
log_id
=
(
priority
==
ANDROID_LOG_FATAL
)
?
LOG_ID_CRASH
:
LOG_ID_MAIN
;
vec
[
0
].
iov_base
=
&
log_id
;
vec
[
0
].
iov_len
=
sizeof
(
log_id
);
uint16_t
tid
=
gettid
();
vec
[
1
].
iov_base
=
&
tid
;
vec
[
1
].
iov_len
=
sizeof
(
tid
);
timespec
ts
;
clock_gettime
(
__android_log_clockid
(),
&
ts
);
log_time
realtime_ts
;
realtime_ts
.
tv_sec
=
ts
.
tv_sec
;
realtime_ts
.
tv_nsec
=
ts
.
tv_nsec
;
vec
[
2
].
iov_base
=
&
realtime_ts
;
vec
[
2
].
iov_len
=
sizeof
(
realtime_ts
);
vec
[
3
].
iov_base
=
&
priority
;
vec
[
3
].
iov_len
=
1
;
vec
[
4
].
iov_base
=
const_cast
<
char
*>
(
tag
);
vec
[
4
].
iov_len
=
strlen
(
tag
)
+
1
;
vec
[
5
].
iov_base
=
const_cast
<
char
*>
(
msg
);
vec
[
5
].
iov_len
=
strlen
(
msg
)
+
1
;
int
result
=
TEMP_FAILURE_RETRY
(
writev
(
main_log_fd
,
vec
,
sizeof
(
vec
)
/
sizeof
(
vec
[
0
])));
close
(
main_log_fd
);
return
result
;
}
int
__libc_format_log_va_list
(
int
priority
,
const
char
*
tag
,
const
char
*
format
,
va_list
args
)
{
char
buffer
[
1024
];
BufferOutputStream
os
(
buffer
,
sizeof
(
buffer
));
out_vformat
(
os
,
format
,
args
);
return
__libc_write_log
(
priority
,
tag
,
buffer
);
}
int
__libc_format_log
(
int
priority
,
const
char
*
tag
,
const
char
*
format
,
...)
{
va_list
args
;
va_start
(
args
,
format
);
int
result
=
__libc_format_log_va_list
(
priority
,
tag
,
format
,
args
);
va_end
(
args
);
return
result
;
}
static
int
__libc_android_log_event
(
int32_t
tag
,
char
type
,
const
void
*
payload
,
size_t
len
)
{
iovec
vec
[
6
];
char
log_id
=
LOG_ID_EVENTS
;
vec
[
0
].
iov_base
=
&
log_id
;
vec
[
0
].
iov_len
=
sizeof
(
log_id
);
uint16_t
tid
=
gettid
();
vec
[
1
].
iov_base
=
&
tid
;
vec
[
1
].
iov_len
=
sizeof
(
tid
);
timespec
ts
;
clock_gettime
(
__android_log_clockid
(),
&
ts
);
log_time
realtime_ts
;
realtime_ts
.
tv_sec
=
ts
.
tv_sec
;
realtime_ts
.
tv_nsec
=
ts
.
tv_nsec
;
vec
[
2
].
iov_base
=
&
realtime_ts
;
vec
[
2
].
iov_len
=
sizeof
(
realtime_ts
);
vec
[
3
].
iov_base
=
&
tag
;
vec
[
3
].
iov_len
=
sizeof
(
tag
);
vec
[
4
].
iov_base
=
&
type
;
vec
[
4
].
iov_len
=
sizeof
(
type
);
vec
[
5
].
iov_base
=
const_cast
<
void
*>
(
payload
);
vec
[
5
].
iov_len
=
len
;
int
event_log_fd
=
__libc_open_log_socket
();
if
(
event_log_fd
==
-
1
)
{
return
-
1
;
}
int
result
=
TEMP_FAILURE_RETRY
(
writev
(
event_log_fd
,
vec
,
sizeof
(
vec
)
/
sizeof
(
vec
[
0
])));
close
(
event_log_fd
);
return
result
;
}
void
__libc_android_log_event_int
(
int32_t
tag
,
int
value
)
{
__libc_android_log_event
(
tag
,
EVENT_TYPE_INT
,
&
value
,
sizeof
(
value
));
}
void
__libc_android_log_event_uid
(
int32_t
tag
)
{
__libc_android_log_event_int
(
tag
,
getuid
());
}
void
__fortify_chk_fail
(
const
char
*
msg
,
uint32_t
tag
)
{
if
(
tag
!=
0
)
{
__libc_android_log_event_uid
(
tag
);
}
__libc_fatal
(
"FORTIFY: %s"
,
msg
);
}
void
__libc_fatal_no_abort
(
const
char
*
format
,
...)
{
va_list
args
;
va_start
(
args
,
format
);
__libc_fatal
(
format
,
args
);
va_end
(
args
);
}
void
__libc_fatal
(
const
char
*
format
,
...)
{
va_list
args
;
va_start
(
args
,
format
);
__libc_fatal
(
format
,
args
);
va_end
(
args
);
abort
();
}
\ No newline at end of file
jni/resetprop/libc_logging.h
deleted
100644 → 0
View file @
14c5c608
/*
* Copyright (C) 2010 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _LIBC_LOGGING_H
#define _LIBC_LOGGING_H
#include <sys/cdefs.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
__BEGIN_DECLS
enum
{
ANDROID_LOG_UNKNOWN
=
0
,
ANDROID_LOG_DEFAULT
,
/* only for SetMinPriority() */
ANDROID_LOG_VERBOSE
,
ANDROID_LOG_DEBUG
,
ANDROID_LOG_INFO
,
ANDROID_LOG_WARN
,
ANDROID_LOG_ERROR
,
ANDROID_LOG_FATAL
,
ANDROID_LOG_SILENT
,
/* only for SetMinPriority(); must be last */
};
enum
{
LOG_ID_MIN
=
0
,
LOG_ID_MAIN
=
0
,
LOG_ID_RADIO
=
1
,
LOG_ID_EVENTS
=
2
,
LOG_ID_SYSTEM
=
3
,
LOG_ID_CRASH
=
4
,
LOG_ID_MAX
};
struct
abort_msg_t
{
size_t
size
;
char
msg
[
0
];
};
//
// Formats a message to the log (priority 'fatal'), then aborts.
//
__LIBC_HIDDEN__
__noreturn
void
__libc_fatal
(
const
char
*
format
,
...)
__printflike
(
1
,
2
);
//
// Formats a message to the log (priority 'fatal'), but doesn't abort.
// Used by the malloc implementation to ensure that debuggerd dumps memory
// around the bad address.
//
__LIBC_HIDDEN__
void
__libc_fatal_no_abort
(
const
char
*
format
,
...)
__printflike
(
1
,
2
);
//
// Formatting routines for the C library's internal debugging.
// Unlike the usual alternatives, these don't allocate, and they don't drag in all of stdio.
//
__LIBC_HIDDEN__
int
__libc_format_buffer
(
char
*
buffer
,
size_t
buffer_size
,
const
char
*
format
,
...)
__printflike
(
3
,
4
);
__LIBC_HIDDEN__
int
__libc_format_fd
(
int
fd
,
const
char
*
format
,
...)
__printflike
(
2
,
3
);
__LIBC_HIDDEN__
int
__libc_format_log
(
int
priority
,
const
char
*
tag
,
const
char
*
format
,
...)
__printflike
(
3
,
4
);
__LIBC_HIDDEN__
int
__libc_format_log_va_list
(
int
priority
,
const
char
*
tag
,
const
char
*
format
,
va_list
ap
);
__LIBC_HIDDEN__
int
__libc_write_log
(
int
priority
,
const
char
*
tag
,
const
char
*
msg
);
//
// Event logging.
//
__LIBC_HIDDEN__
void
__libc_android_log_event_int
(
int32_t
tag
,
int
value
);
__LIBC_HIDDEN__
void
__libc_android_log_event_uid
(
int32_t
tag
);
__LIBC_HIDDEN__
__noreturn
void
__fortify_chk_fail
(
const
char
*
msg
,
uint32_t
event_tag
);
__END_DECLS
#endif
jni/resetprop/resetprop.cpp
View file @
17d3a87b
...
...
@@ -11,7 +11,7 @@
*
* Functions that need to be patched/added in system_properties.cpp
*
* int __system_properties_init()
* int __system_properties_init
2
()
* on android 7, first tear down the everything then let it initialize again:
* if (initialized) {
* //list_foreach(contexts, [](context_node* l) { l->reset_access(); });
...
...
@@ -123,7 +123,7 @@ static int usage(char* arg0) {
int
init_resetprop
()
{
PRINT_D
(
"resetprop: Initializing...
\n
"
);
if
(
__system_properties_init
())
{
if
(
__system_properties_init
2
())
{
PRINT_E
(
"resetprop: Initialize error
\n
"
);
return
-
1
;
}
...
...
@@ -136,12 +136,12 @@ static void read_prop_info(void* cookie, const char *name, const char *value, ui
// Get prop by name, return string (should free manually!)
char
*
getprop
(
const
char
*
name
)
{
const
prop_info
*
pi
=
__system_property_find
(
name
);
const
prop_info
*
pi
=
__system_property_find
2
(
name
);
if
(
pi
==
NULL
)
{
return
NULL
;
}
char
value
[
PROP_VALUE_MAX
];
__system_property_read_callback
(
pi
,
read_prop_info
,
value
);
__system_property_read_callback
2
(
pi
,
read_prop_info
,
value
);
PRINT_D
(
"resetprop: getprop [%s]: [%s]
\n
"
,
name
,
value
);
return
strdup
(
value
);
}
...
...
@@ -158,16 +158,16 @@ int setprop2(const char *name, const char *value, const int trigger) {
free
(
check
);
if
(
trigger
)
{
if
(
!
strncmp
(
name
,
"ro."
,
3
))
deleteprop
(
name
);
ret
=
__system_property_set
(
name
,
value
);
ret
=
__system_property_set
2
(
name
,
value
);
}
else
{
ret
=
__system_property_update
((
prop_info
*
)
__system_property_find
(
name
),
value
,
strlen
(
value
));
ret
=
__system_property_update
2
((
prop_info
*
)
__system_property_find2
(
name
),
value
,
strlen
(
value
));
}
}
else
{
PRINT_D
(
"resetprop: New prop [%s]
\n
"
,
name
);
if
(
trigger
)
{
ret
=
__system_property_set
(
name
,
value
);
ret
=
__system_property_set
2
(
name
,
value
);
}
else
{
ret
=
__system_property_add
(
name
,
strlen
(
name
),
value
,
strlen
(
value
));
ret
=
__system_property_add
2
(
name
,
strlen
(
name
),
value
,
strlen
(
value
));
}
}
...
...
@@ -276,6 +276,8 @@ int resetprop_main(int argc, char *argv[]) {
}
}
init_resetprop
();
if
(
file
)
{
return
read_prop_file
(
filename
,
trigger
);
}
else
if
(
del
)
{
...
...
jni/resetprop/system_properties.cpp
View file @
17d3a87b
...
...
@@ -54,11 +54,12 @@
#include "_system_properties.h"
#include "system_properties.h"
// #include <async_safe/log.h>
#include "ErrnoRestorer.h"
#include "bionic_futex.h"
#include "bionic_lock.h"
#include "bionic_macros.h"
#include "libc_logging.h"
static
constexpr
int
PROP_FILENAME_MAX
=
1024
;
...
...
@@ -90,6 +91,16 @@ static const char* kServiceVersionPropertyName = "ro.property_service.version";
* +-----+ +-----+ +-----+ +===========+
*/
// This is a alternative implementation for async_safe_format_buffer
// A workaround to not include the async_safe header
static
int
async_safe_format_buffer
(
char
*
s
,
size_t
n
,
const
char
*
format
,
...)
{
va_list
vl
;
va_start
(
vl
,
format
);
int
ret
=
vsnprintf
(
s
,
n
,
format
,
vl
);
va_end
(
vl
);
return
ret
;
}
// Represents a node in the trie.
struct
prop_bt
{
uint32_t
namelen
;
...
...
@@ -202,17 +213,9 @@ struct prop_info {
DISALLOW_IMPLICIT_CONSTRUCTORS
(
prop_info
);
};
struct
find_nth_cookie
{
uint32_t
count
;
const
uint32_t
n
;
const
prop_info
*
pi
;
explicit
find_nth_cookie
(
uint32_t
n
)
:
count
(
0
),
n
(
n
),
pi
(
nullptr
)
{
}
};
// This is public because it was exposed in the NDK. As of 2017-01, ~60 apps reference this symbol.
prop_area
*
__system_property_area__
=
nullptr
;
// Change to static, we don't want to use the global libc reference
static
prop_area
*
__system_property_area__
=
nullptr
;
static
char
property_filename
[
PROP_FILENAME_MAX
]
=
PROP_FILENAME
;
static
size_t
pa_data_size
;
...
...
@@ -238,8 +241,8 @@ static prop_area* map_prop_area_rw(const char* filename, const char* context,
if
(
context
)
{
if
(
fsetxattr
(
fd
,
XATTR_NAME_SELINUX
,
context
,
strlen
(
context
)
+
1
,
0
)
!=
0
)
{
__libc
_format_log
(
ANDROID_LOG_ERROR
,
"libc"
,
"fsetxattr failed to set context (%s) for
\"
%s
\"
"
,
context
,
filename
);
// async_safe
_format_log(ANDROID_LOG_ERROR, "libc",
//
"fsetxattr failed to set context (%s) for \"%s\"", context, filename);
/*
* fsetxattr() will fail during system properties tests due to selinux policy.
* We do not want to create a custom policy for the tester, so we will continue in
...
...
@@ -694,9 +697,9 @@ static int send_prop_msg(const prop_msg* msg) {
// ms so callers who do read-after-write can reliably see
// what they've written. Most of the time.
// TODO: fix the system properties design.
__libc
_format_log
(
ANDROID_LOG_WARN
,
"libc"
,
"Property service has timed out while trying to set
\"
%s
\"
to
\"
%s
\"
"
,
msg
->
name
,
msg
->
value
);
// async_safe
_format_log(ANDROID_LOG_WARN, "libc",
//
"Property service has timed out while trying to set \"%s\" to \"%s\"",
//
msg->name, msg->value);
result
=
0
;
}
}
...
...
@@ -704,14 +707,6 @@ static int send_prop_msg(const prop_msg* msg) {
return
result
;
}
static
void
find_nth_fn
(
const
prop_info
*
pi
,
void
*
ptr
)
{
find_nth_cookie
*
cookie
=
reinterpret_cast
<
find_nth_cookie
*>
(
ptr
);
if
(
cookie
->
n
==
cookie
->
count
)
cookie
->
pi
=
pi
;
cookie
->
count
++
;
}
bool
prop_area
::
foreach_property
(
prop_bt
*
const
trie
,
void
(
*
propfn
)(
const
prop_info
*
pi
,
void
*
cookie
),
void
*
cookie
)
{
if
(
!
trie
)
return
false
;
...
...
@@ -872,7 +867,8 @@ bool context_node::open(bool access_rw, bool* fsetxattr_failed) {
}
char
filename
[
PROP_FILENAME_MAX
];
int
len
=
__libc_format_buffer
(
filename
,
sizeof
(
filename
),
"%s/%s"
,
property_filename
,
context_
);
int
len
=
async_safe_format_buffer
(
filename
,
sizeof
(
filename
),
"%s/%s"
,
property_filename
,
context_
);
if
(
len
<
0
||
len
>
PROP_FILENAME_MAX
)
{
lock_
.
unlock
();
return
false
;
...
...
@@ -907,7 +903,8 @@ void context_node::reset_access() {
bool
context_node
::
check_access
()
{
char
filename
[
PROP_FILENAME_MAX
];
int
len
=
__libc_format_buffer
(
filename
,
sizeof
(
filename
),
"%s/%s"
,
property_filename
,
context_
);
int
len
=
async_safe_format_buffer
(
filename
,
sizeof
(
filename
),
"%s/%s"
,
property_filename
,
context_
);
if
(
len
<
0
||
len
>
PROP_FILENAME_MAX
)
{
return
false
;
}
...
...
@@ -930,7 +927,8 @@ void context_node::unmap() {
static
bool
map_system_property_area
(
bool
access_rw
,
bool
*
fsetxattr_failed
)
{
char
filename
[
PROP_FILENAME_MAX
];
int
len
=
__libc_format_buffer
(
filename
,
sizeof
(
filename
),
"%s/properties_serial"
,
property_filename
);
async_safe_format_buffer
(
filename
,
sizeof
(
filename
),
"%s/properties_serial"
,
property_filename
);
if
(
len
<
0
||
len
>
PROP_FILENAME_MAX
)
{
__system_property_area__
=
nullptr
;
return
false
;
...
...
@@ -1145,7 +1143,7 @@ static void free_and_unmap_contexts() {
}
}
int
__system_properties_init
()
{
int
__system_properties_init
2
()
{
// This is called from __libc_init_common, and should leave errno at 0 (http://b/37248982).
ErrnoRestorer
errno_restorer
;
...
...
@@ -1175,7 +1173,7 @@ int __system_properties_init() {
return
0
;
}
int
__system_property_set_filename
(
const
char
*
filename
)
{
int
__system_property_set_filename
2
(
const
char
*
filename
)
{
size_t
len
=
strlen
(
filename
);
if
(
len
>=
sizeof
(
property_filename
))
return
-
1
;
...
...
@@ -1183,7 +1181,7 @@ int __system_property_set_filename(const char* filename) {
return
0
;
}
int
__system_property_area_init
()
{
int
__system_property_area_init
2
()
{
free_and_unmap_contexts
();
mkdir
(
property_filename
,
S_IRWXU
|
S_IXGRP
|
S_IXOTH
);
if
(
!
initialize_properties
())
{
...
...
@@ -1204,23 +1202,23 @@ int __system_property_area_init() {
return
fsetxattr_failed
?
-
2
:
0
;
}
uint32_t
__system_property_area_serial
()
{
uint32_t
__system_property_area_serial
2
()
{
prop_area
*
pa
=
__system_property_area__
;
if
(
!
pa
)
{
return
-
1
;
}
// Make sure this read fulfilled before __system_property_serial
// Make sure this read fulfilled before __system_property_serial
2
return
atomic_load_explicit
(
pa
->
serial
(),
memory_order_acquire
);
}
const
prop_info
*
__system_property_find
(
const
char
*
name
)
{
const
prop_info
*
__system_property_find
2
(
const
char
*
name
)
{
if
(
!
__system_property_area__
)
{
return
nullptr
;
}
prop_area
*
pa
=
get_prop_area_for_name
(
name
);
if
(
!
pa
)
{
__libc
_format_log
(
ANDROID_LOG_ERROR
,
"libc"
,
"Access denied finding property
\"
%s
\"
"
,
name
);
// async_safe
_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name);
return
nullptr
;
}
...
...
@@ -1234,7 +1232,6 @@ int __system_property_del(const char *name) {
prop_area
*
pa
=
get_prop_area_for_name
(
name
);
if
(
!
pa
)
{
__libc_format_log
(
ANDROID_LOG_ERROR
,
"libc"
,
"Access denied finding property
\"
%s
\"
"
,
name
);
return
1
;
}
...
...
@@ -1257,9 +1254,9 @@ static inline uint_least32_t load_const_atomic(const atomic_uint_least32_t* s, m
return
atomic_load_explicit
(
non_const_s
,
mo
);
}
int
__system_property_read
(
const
prop_info
*
pi
,
char
*
name
,
char
*
value
)
{
int
__system_property_read
2
(
const
prop_info
*
pi
,
char
*
name
,
char
*
value
)
{
while
(
true
)
{
uint32_t
serial
=
__system_property_serial
(
pi
);
// acquire semantics
uint32_t
serial
=
__system_property_serial
2
(
pi
);
// acquire semantics
size_t
len
=
SERIAL_VALUE_LEN
(
serial
);
memcpy
(
value
,
pi
->
value
,
len
+
1
);
// TODO: Fix the synchronization scheme here.
...
...
@@ -1274,34 +1271,34 @@ int __system_property_read(const prop_info* pi, char* name, char* value) {
if
(
serial
==
load_const_atomic
(
&
(
pi
->
serial
),
memory_order_relaxed
))
{
if
(
name
!=
nullptr
)
{
size_t
namelen
=
strlcpy
(
name
,
pi
->
name
,
PROP_NAME_MAX
);
if
(
namelen
>=
PROP_NAME_MAX
)
{
__libc
_format_log
(
ANDROID_LOG_ERROR
,
"libc"
,
"The property name length for
\"
%s
\"
is >= %d;"
" please use __system_property_read_callback
"
" to read this property. (the name is truncated to
\"
%s
\"
)"
,
pi
->
name
,
PROP_NAME_MAX
-
1
,
name
);
}
//
if (namelen >= PROP_NAME_MAX) {
// async_safe
_format_log(ANDROID_LOG_ERROR, "libc",
//
"The property name length for \"%s\" is >= %d;"
// " please use __system_property_read_callback2
"
//
" to read this property. (the name is truncated to \"%s\")",
//
pi->name, PROP_NAME_MAX - 1, name);
//
}
}
return
len
;
}
}
}
void
__system_property_read_callback
(
const
prop_info
*
pi
,
void
__system_property_read_callback
2
(
const
prop_info
*
pi
,
void
(
*
callback
)(
void
*
cookie
,
const
char
*
name
,
const
char
*
value
,
uint32_t
serial
),
void
*
cookie
)
{
while
(
true
)
{
uint32_t
serial
=
__system_property_serial
(
pi
);
// acquire semantics
uint32_t
serial
=
__system_property_serial
2
(
pi
);
// acquire semantics
size_t
len
=
SERIAL_VALUE_LEN
(
serial
);
char
value_buf
[
len
+
1
];
memcpy
(
value_buf
,
pi
->
value
,
len
);
value_buf
[
len
]
=
'\0'
;
// TODO: see todo in __system_property_read function
// TODO: see todo in __system_property_read
2
function
atomic_thread_fence
(
memory_order_acquire
);
if
(
serial
==
load_const_atomic
(
&
(
pi
->
serial
),
memory_order_relaxed
))
{
callback
(
cookie
,
pi
->
name
,
value_buf
,
serial
);
...
...
@@ -1310,11 +1307,11 @@ void __system_property_read_callback(const prop_info* pi,
}
}
int
__system_property_get
(
const
char
*
name
,
char
*
value
)
{
const
prop_info
*
pi
=
__system_property_find
(
name
);
int
__system_property_get
2
(
const
char
*
name
,
char
*
value
)
{
const
prop_info
*
pi
=
__system_property_find
2
(
name
);
if
(
pi
!=
0
)
{
return
__system_property_read
(
pi
,
nullptr
,
value
);
return
__system_property_read
2
(
pi
,
nullptr
,
value
);
}
else
{
value
[
0
]
=
0
;
return
0
;
...
...
@@ -1328,25 +1325,25 @@ static atomic_uint_least32_t g_propservice_protocol_version = 0;
static
void
detect_protocol_version
()
{
char
value
[
PROP_VALUE_MAX
];
if
(
__system_property_get
(
kServiceVersionPropertyName
,
value
)
==
0
)
{
if
(
__system_property_get
2
(
kServiceVersionPropertyName
,
value
)
==
0
)
{
g_propservice_protocol_version
=
kProtocolVersion1
;
__libc
_format_log
(
ANDROID_LOG_WARN
,
"libc"
,
"Using old property service protocol (
\"
%s
\"
is not set)"
,
kServiceVersionPropertyName
);
// async_safe
_format_log(ANDROID_LOG_WARN, "libc",
//
"Using old property service protocol (\"%s\" is not set)",
//
kServiceVersionPropertyName);
}
else
{
uint32_t
version
=
static_cast
<
uint32_t
>
(
atoll
(
value
));
if
(
version
>=
kProtocolVersion2
)
{
g_propservice_protocol_version
=
kProtocolVersion2
;
}
else
{
__libc
_format_log
(
ANDROID_LOG_WARN
,
"libc"
,
"Using old property service protocol (
\"
%s
\"
=
\"
%s
\"
)"
,
kServiceVersionPropertyName
,
value
);
// async_safe
_format_log(ANDROID_LOG_WARN, "libc",
//
"Using old property service protocol (\"%s\"=\"%s\")",
//
kServiceVersionPropertyName, value);
g_propservice_protocol_version
=
kProtocolVersion1
;
}
}
}
int
__system_property_set
(
const
char
*
key
,
const
char
*
value
)
{
int
__system_property_set
2
(
const
char
*
key
,
const
char
*
value
)
{
if
(
key
==
nullptr
)
return
-
1
;
if
(
value
==
nullptr
)
value
=
""
;
if
(
strlen
(
value
)
>=
PROP_VALUE_MAX
)
return
-
1
;
...
...
@@ -1370,50 +1367,50 @@ int __system_property_set(const char* key, const char* value) {
// Use proper protocol
PropertyServiceConnection
connection
;
if
(
!
connection
.
IsValid
())
{
errno
=
connection
.
GetLastError
();
__libc
_format_log
(
ANDROID_LOG_WARN
,
"libc"
,
"Unable to set property
\"
%s
\"
to
\"
%s
\"
: connection failed; errno=%d (%s)"
,
key
,
value
,
errno
,
strerror
(
errno
));
//
errno = connection.GetLastError();
// async_safe
_format_log(ANDROID_LOG_WARN,
//
"libc",
//
"Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)",
//
key,
//
value,
//
errno,
//
strerror(errno));
return
-
1
;
}
SocketWriter
writer
(
&
connection
);
if
(
!
writer
.
WriteUint32
(
PROP_MSG_SETPROP2
).
WriteString
(
key
).
WriteString
(
value
).
Send
())
{
errno
=
connection
.
GetLastError
();
__libc
_format_log
(
ANDROID_LOG_WARN
,
"libc"
,
"Unable to set property
\"
%s
\"
to
\"
%s
\"
: write failed; errno=%d (%s)"
,
key
,
value
,
errno
,
strerror
(
errno
));
//
errno = connection.GetLastError();
// async_safe
_format_log(ANDROID_LOG_WARN,
//
"libc",
//
"Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)",
//
key,
//
value,
//
errno,
//
strerror(errno));
return
-
1
;
}
int
result
=
-
1
;
if
(
!
connection
.
RecvInt32
(
&
result
))
{
errno
=
connection
.
GetLastError
();
__libc
_format_log
(
ANDROID_LOG_WARN
,
"libc"
,
"Unable to set property
\"
%s
\"
to
\"
%s
\"
: recv failed; errno=%d (%s)"
,
key
,
value
,
errno
,
strerror
(
errno
));
//
errno = connection.GetLastError();
// async_safe
_format_log(ANDROID_LOG_WARN,
//
"libc",
//
"Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)",
//
key,
//
value,
//
errno,
//
strerror(errno));
return
-
1
;
}
if
(
result
!=
PROP_SUCCESS
)
{
__libc
_format_log
(
ANDROID_LOG_WARN
,
"libc"
,
"Unable to set property
\"
%s
\"
to
\"
%s
\"
: error code: 0x%x"
,
key
,
value
,
result
);
// async_safe
_format_log(ANDROID_LOG_WARN,
//
"libc",
//
"Unable to set property \"%s\" to \"%s\": error code: 0x%x",
//
key,
//
value,
//
result);
return
-
1
;
}
...
...
@@ -1421,7 +1418,7 @@ int __system_property_set(const char* key, const char* value) {
}
}
int
__system_property_update
(
prop_info
*
pi
,
const
char
*
value
,
unsigned
int
len
)
{
int
__system_property_update
2
(
prop_info
*
pi
,
const
char
*
value
,
unsigned
int
len
)
{
if
(
len
>=
PROP_VALUE_MAX
)
{
return
-
1
;
}
...
...
@@ -1451,7 +1448,7 @@ int __system_property_update(prop_info* pi, const char* value, unsigned int len)
return
0
;
}
int
__system_property_add
(
const
char
*
name
,
unsigned
int
namelen
,
const
char
*
value
,
int
__system_property_add
2
(
const
char
*
name
,
unsigned
int
namelen
,
const
char
*
value
,
unsigned
int
valuelen
)
{
if
(
valuelen
>=
PROP_VALUE_MAX
)
{
return
-
1
;
...
...
@@ -1468,7 +1465,7 @@ int __system_property_add(const char* name, unsigned int namelen, const char* va
prop_area
*
pa
=
get_prop_area_for_name
(
name
);
if
(
!
pa
)
{
__libc
_format_log
(
ANDROID_LOG_ERROR
,
"libc"
,
"Access denied adding property
\"
%s
\"
"
,
name
);
// async_safe
_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name);
return
-
1
;
}
...
...
@@ -1488,7 +1485,7 @@ int __system_property_add(const char* name, unsigned int namelen, const char* va
}
// Wait for non-locked serial, and retrieve it with acquire semantics.
uint32_t
__system_property_serial
(
const
prop_info
*
pi
)
{
uint32_t
__system_property_serial
2
(
const
prop_info
*
pi
)
{
uint32_t
serial
=
load_const_atomic
(
&
pi
->
serial
,
memory_order_acquire
);
while
(
SERIAL_DIRTY
(
serial
))
{
__futex_wait
(
const_cast
<
_Atomic
(
uint_least32_t
)
*>
(
&
pi
->
serial
),
serial
,
nullptr
);
...
...
@@ -1497,13 +1494,13 @@ uint32_t __system_property_serial(const prop_info* pi) {
return
serial
;
}
uint32_t
__system_property_wait_any
(
uint32_t
old_serial
)
{
uint32_t
__system_property_wait_any
2
(
uint32_t
old_serial
)
{
uint32_t
new_serial
;
__system_property_wait
(
nullptr
,
old_serial
,
&
new_serial
,
nullptr
);
__system_property_wait
2
(
nullptr
,
old_serial
,
&
new_serial
,
nullptr
);
return
new_serial
;
}
bool
__system_property_wait
(
const
prop_info
*
pi
,
bool
__system_property_wait
2
(
const
prop_info
*
pi
,
uint32_t
old_serial
,
uint32_t
*
new_serial_ptr
,
const
timespec
*
relative_timeout
)
{
...
...
@@ -1529,33 +1526,30 @@ bool __system_property_wait(const prop_info* pi,
return
true
;
}
/* Deprecated, we won't use it anyways */
// const prop_info* __system_property_find_nth(unsigned n) {
// if (bionic_get_application_target_sdk_version() >= __ANDROID_API_O__) {
// __libc_fatal(
// "__system_property_find_nth is not supported since Android O,"
// " please use __system_property_foreach instead.");
// }
const
prop_info
*
__system_property_find_nth2
(
unsigned
n
)
{
struct
find_nth
{
const
uint32_t
sought
;
uint32_t
current
;
const
prop_info
*
result
;
// find_nth_cookie cookie(n);
// const int err = __system_property_foreach(find_nth_fn, &cookie
);
// if (err < 0) {
// return nullptr;
// }
// return cookie.pi
;
//
}
explicit
find_nth
(
uint32_t
n
)
:
sought
(
n
),
current
(
0
),
result
(
nullptr
)
{}
static
void
fn
(
const
prop_info
*
pi
,
void
*
ptr
)
{
find_nth
*
self
=
reinterpret_cast
<
find_nth
*>
(
ptr
);
if
(
self
->
current
++
==
self
->
sought
)
self
->
result
=
pi
;
}
}
state
(
n
);
__system_property_foreach2
(
find_nth
::
fn
,
&
state
);
return
state
.
result
;
}
int
__system_property_foreach
(
void
(
*
propfn
)(
const
prop_info
*
pi
,
void
*
cookie
),
void
*
cookie
)
{
int
__system_property_foreach
2
(
void
(
*
propfn
)(
const
prop_info
*
pi
,
void
*
cookie
),
void
*
cookie
)
{
if
(
!
__system_property_area__
)
{
return
-
1
;
}
list_foreach
(
contexts
,
[
propfn
,
cookie
](
context_node
*
l
)
{
if
(
l
->
check_access_and_open
())
{
l
->
pa
()
->
foreach
(
propfn
,
cookie
);
l
->
pa
()
->
foreach
(
propfn
,
cookie
);
}
});
return
0
;
...
...
jni/resetprop/system_properties.h
View file @
17d3a87b
...
...
@@ -43,30 +43,30 @@ typedef struct prop_info prop_info;
/*
* Sets system property `key` to `value`, creating the system property if it doesn't already exist.
*/
int
__system_property_set
(
const
char
*
key
,
const
char
*
value
)
__INTRODUCED_IN
(
12
);
int
__system_property_set
2
(
const
char
*
key
,
const
char
*
value
)
__INTRODUCED_IN
(
12
);
/*
* Returns a `prop_info` corresponding system property `name`, or nullptr if it doesn't exist.
* Use __system_property_read_callback to query the current value.
* Use __system_property_read_callback
2
to query the current value.
*
* Property lookup is expensive, so it can be useful to cache the result of this function.
*/
const
prop_info
*
__system_property_find
(
const
char
*
name
);
const
prop_info
*
__system_property_find
2
(
const
char
*
name
);
/*
* Calls `callback` with a consistent trio of name, value, and serial number for property `pi`.
*/
void
__system_property_read_callback
(
const
prop_info
*
pi
,
void
__system_property_read_callback
2
(
const
prop_info
*
pi
,
void
(
*
callback
)(
void
*
cookie
,
const
char
*
name
,
const
char
*
value
,
uint32_t
serial
),
void
*
cookie
)
__INTRODUCED_IN
_FUTURE
;
void
*
cookie
)
__INTRODUCED_IN
(
26
)
;
/*
* Passes a `prop_info` for each system property to the provided
* callback. Use __system_property_read_callback() to read the value.
* callback. Use __system_property_read_callback
2
() to read the value.
*
* This method is for inspecting and debugging the property system, and not generally useful.
*/
int
__system_property_foreach
(
void
(
*
propfn
)(
const
prop_info
*
pi
,
void
*
cookie
),
void
*
cookie
)
int
__system_property_foreach
2
(
void
(
*
propfn
)(
const
prop_info
*
pi
,
void
*
cookie
),
void
*
cookie
)
__INTRODUCED_IN
(
19
);
/*
...
...
@@ -82,20 +82,20 @@ int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie),
* timed out.
*/
struct
timespec
;
bool
__system_property_wait
(
const
prop_info
*
pi
,
bool
__system_property_wait
2
(
const
prop_info
*
pi
,
uint32_t
old_serial
,
uint32_t
*
new_serial_ptr
,
const
struct
timespec
*
relative_timeout
)
__INTRODUCED_IN
_FUTURE
;
__INTRODUCED_IN
(
26
)
;
/* Deprecated. In Android O and above, there's no limit on property name length. */
#define PROP_NAME_MAX 32
/* Deprecated. Use __system_property_read_callback instead. */
int
__system_property_read
(
const
prop_info
*
pi
,
char
*
name
,
char
*
value
);
/* Deprecated. Use __system_property_read_callback instead. */
int
__system_property_get
(
const
char
*
name
,
char
*
value
);
/* Deprecated. Use __system_property_foreach
instead. Aborts in Android O and above
. */
const
prop_info
*
__system_property_find_nth
(
unsigned
n
)
__REMOVED_IN
(
26
);
/* Deprecated. Use __system_property_read_callback
2
instead. */
int
__system_property_read
2
(
const
prop_info
*
pi
,
char
*
name
,
char
*
value
);
/* Deprecated. Use __system_property_read_callback
2
instead. */
int
__system_property_get
2
(
const
char
*
name
,
char
*
value
);
/* Deprecated. Use __system_property_foreach
2 instead
. */
const
prop_info
*
__system_property_find_nth2
(
unsigned
n
);
__END_DECLS
...
...
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