打开文件system/core/init/property_service.c 增加函数
#define HOLD_PROPERTY_DIR "/hold"
static int hold_properties_loaded = 0;
static void load_hold_properties()
{
DIR* dir = opendir(HOLD_PROPERTY_DIR);
int dir_fd;
struct dirent* entry;
char value[PROP_VALUE_MAX];
int fd, length;
struct stat sb;
if (dir == NULL) {
//700为 /data/property的权限,这里改得和它一样,注意,这里不支持system()执行,因为sh还没有启动
// char tmp[100] = {0};
// sprintf(tmp,"mkdir %s && %s %s",HOLD_PROPERTY_DIR,"chmod 700",HOLD_PROPERTY_DIR);
// system(tmp);
ERROR("hold:aaaa check mkdir %s\n",HOLD_PROPERTY_DIR);
// if (mkdir(HOLD_PROPERTY_DIR, 0700) == -1) {
//
// ERROR("hold:Unable mkdir %s\n", HOLD_PROPERTY_DIR);
// }else{
// ERROR("hold:has dir2 %s\n",HOLD_PROPERTY_DIR);
// dir = opendir(HOLD_PROPERTY_DIR);
// }
}else{
ERROR("hold:has dir %s\n",HOLD_PROPERTY_DIR);
}
if (dir) {
dir_fd = dirfd(dir);
while ((entry = readdir(dir)) != NULL) {
if (strncmp("hold.", entry->d_name, strlen("hold.")))
continue;
#if HAVE_DIRENT_D_TYPE
if (entry->d_type != DT_REG)
continue;
#endif
/* open the file and read the property value */
fd = openat(dir_fd, entry->d_name, O_RDONLY | O_NOFOLLOW);
if (fd < 0) {
ERROR("Unable to open hold property file \"%s\" errno: %d\n",
entry->d_name, errno);
continue;
}
if (fstat(fd, &sb) < 0) {
ERROR("fstat on hold file \"%s\" failed errno: %d\n", entry->d_name, errno);
close(fd);
continue;
}
// File must not be accessible to others, be owned by root/root, and
// not be a hard link to any other file.
if (((sb.st_mode & (S_IRWXG | S_IRWXO)) != 0)
|| (sb.st_uid != 0)
|| (sb.st_gid != 0)
|| (sb.st_nlink != 1)) {
ERROR("skipping insecure hold property file %s (uid=%u gid=%u nlink=%d mode=%o)\n",
entry->d_name, (unsigned int)sb.st_uid, (unsigned int)sb.st_gid,
sb.st_nlink, sb.st_mode);
close(fd);
continue;
}
length = read(fd, value, sizeof(value) - 1);
if (length >= 0) {
value[length] = 0;
property_set(entry->d_name, value);
} else {
ERROR("Unable to read hold property file %s errno: %d\n",
entry->d_name, errno);
}
close(fd);
}
closedir(dir);
} else {
ERROR("hold:Unable to open hold property directory %s errno: %d\n", HOLD_PROPERTY_DIR, errno);
}
hold_properties_loaded = 1;
}
static void write_hold_property(const char *name, const char *value)
{
char tempPath[PATH_MAX];
char path[PATH_MAX];
int fd;
snprintf(tempPath, sizeof(tempPath), "%s/.temp.XXXXXX", HOLD_PROPERTY_DIR);
fd = mkstemp(tempPath);
if (fd < 0) {
ERROR("Unable to write hold property to temp file %s errno: %d\n", tempPath, errno);
return;
}
write(fd, value, strlen(value));
fsync(fd);
close(fd);
snprintf(path, sizeof(path), "%s/%s", HOLD_PROPERTY_DIR, name);
if (rename(tempPath, path)) {
unlink(tempPath);
ERROR("Unable to rename hold property file %s to %s\n", tempPath, path);
}
}
然后修改几个地方
void property_init(void)
{
init_property_area();
@@ -550,6 +666,7 @@ void load_persist_props(void)
load_override_properties();
/* Read persistent properties after all default values have been loaded. */
load_persistent_properties();
+ load_hold_properties();
}
void load_all_props(void)
@@ -563,6 +680,7 @@ void load_all_props(void)
/* Read persistent properties after all default values have been loaded. */
load_persistent_properties();
+ load_hold_properties();
}
static bool is_legal_property_name(const char* name, size_t namelen)
{
size_t i;
@@ -264,6 +289,13 @@ int property_set(const char *name, const char *value)
* to prevent them from being overwritten by default values.
*/
write_persistent_property(name, value);
+ }else if (hold_properties_loaded &&
+ strncmp("hold.", name, strlen("hold.")) == 0) {
+ /*
+ * Don't write properties to disk until after we have read all default properties
+ * to prevent them from being overwritten by default values.
+ */
+ write_hold_property(name, value);
} else if (strcmp("selinux.reload_policy", name) == 0 &&
strcmp("1", value) == 0) {
selinux_reload_policy();
@@ -512,6 +544,90 @@ static void load_persistent_properties()
persistent_properties_loaded = 1;
}