Merge "adb: configure /system file permission with fs_config"
This commit is contained in:
commit
fcf3d207c5
2 changed files with 65 additions and 10 deletions
|
|
@ -130,7 +130,7 @@ LOCAL_FORCE_STATIC_EXECUTABLE := true
|
||||||
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
|
LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
|
||||||
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
|
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := liblog libcutils libc libmincrypt
|
LOCAL_STATIC_LIBRARIES := liblog libcutils libc libmincrypt libselinux
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,19 +22,32 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <utime.h>
|
#include <utime.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <private/android_filesystem_config.h>
|
||||||
|
#include <selinux/android.h>
|
||||||
#include "sysdeps.h"
|
#include "sysdeps.h"
|
||||||
|
|
||||||
#define TRACE_TAG TRACE_SYNC
|
#define TRACE_TAG TRACE_SYNC
|
||||||
#include "adb.h"
|
#include "adb.h"
|
||||||
#include "file_sync_service.h"
|
#include "file_sync_service.h"
|
||||||
|
|
||||||
|
/* TODO: use fs_config to configure permissions on /data */
|
||||||
|
static bool is_on_system(const char *name) {
|
||||||
|
const char *SYSTEM = "/system/";
|
||||||
|
return (strncmp(SYSTEM, name, strlen(SYSTEM)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
static int mkdirs(char *name)
|
static int mkdirs(char *name)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char *x = name + 1;
|
char *x = name + 1;
|
||||||
|
unsigned int uid, gid;
|
||||||
|
unsigned int mode = 0775;
|
||||||
|
uint64_t cap = 0;
|
||||||
|
uid = getuid();
|
||||||
|
gid = getgid();
|
||||||
|
|
||||||
if(name[0] != '/') return -1;
|
if(name[0] != '/') return -1;
|
||||||
|
|
||||||
|
|
@ -42,11 +55,21 @@ static int mkdirs(char *name)
|
||||||
x = adb_dirstart(x);
|
x = adb_dirstart(x);
|
||||||
if(x == 0) return 0;
|
if(x == 0) return 0;
|
||||||
*x = 0;
|
*x = 0;
|
||||||
ret = adb_mkdir(name, 0775);
|
if (is_on_system(name)) {
|
||||||
|
fs_config(name, 1, &uid, &gid, &mode, &cap);
|
||||||
|
}
|
||||||
|
ret = adb_mkdir(name, mode);
|
||||||
if((ret < 0) && (errno != EEXIST)) {
|
if((ret < 0) && (errno != EEXIST)) {
|
||||||
D("mkdir(\"%s\") -> %s\n", name, strerror(errno));
|
D("mkdir(\"%s\") -> %s\n", name, strerror(errno));
|
||||||
*x = '/';
|
*x = '/';
|
||||||
return ret;
|
return ret;
|
||||||
|
} else if(ret == 0) {
|
||||||
|
ret = chown(name, uid, gid);
|
||||||
|
if (ret < 0) {
|
||||||
|
*x = '/';
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
selinux_android_restorecon(name);
|
||||||
}
|
}
|
||||||
*x++ = '/';
|
*x++ = '/';
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +172,8 @@ static int fail_errno(int s)
|
||||||
return fail_message(s, strerror(errno));
|
return fail_message(s, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
|
static int handle_send_file(int s, char *path, unsigned int uid,
|
||||||
|
unsigned int gid, mode_t mode, char *buffer)
|
||||||
{
|
{
|
||||||
syncmsg msg;
|
syncmsg msg;
|
||||||
unsigned int timestamp = 0;
|
unsigned int timestamp = 0;
|
||||||
|
|
@ -157,8 +181,13 @@ static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
|
||||||
|
|
||||||
fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
||||||
if(fd < 0 && errno == ENOENT) {
|
if(fd < 0 && errno == ENOENT) {
|
||||||
mkdirs(path);
|
if(mkdirs(path) != 0) {
|
||||||
fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
if(fail_errno(s))
|
||||||
|
return -1;
|
||||||
|
fd = -1;
|
||||||
|
} else {
|
||||||
|
fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(fd < 0 && errno == EEXIST) {
|
if(fd < 0 && errno == EEXIST) {
|
||||||
fd = adb_open_mode(path, O_WRONLY, mode);
|
fd = adb_open_mode(path, O_WRONLY, mode);
|
||||||
|
|
@ -167,6 +196,16 @@ static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
|
||||||
if(fail_errno(s))
|
if(fail_errno(s))
|
||||||
return -1;
|
return -1;
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
} else {
|
||||||
|
if(fchown(fd, uid, gid) != 0) {
|
||||||
|
fail_errno(s);
|
||||||
|
errno = 0;
|
||||||
|
}
|
||||||
|
/* fchown clears the setuid bit - restore it if present */
|
||||||
|
if(fchmod(fd, mode) != 0) {
|
||||||
|
fail_errno(s);
|
||||||
|
errno = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
|
@ -206,6 +245,7 @@ static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
|
||||||
if(fd >= 0) {
|
if(fd >= 0) {
|
||||||
struct utimbuf u;
|
struct utimbuf u;
|
||||||
adb_close(fd);
|
adb_close(fd);
|
||||||
|
selinux_android_restorecon(path);
|
||||||
u.actime = timestamp;
|
u.actime = timestamp;
|
||||||
u.modtime = timestamp;
|
u.modtime = timestamp;
|
||||||
utime(path, &u);
|
utime(path, &u);
|
||||||
|
|
@ -249,7 +289,10 @@ static int handle_send_link(int s, char *path, char *buffer)
|
||||||
|
|
||||||
ret = symlink(buffer, path);
|
ret = symlink(buffer, path);
|
||||||
if(ret && errno == ENOENT) {
|
if(ret && errno == ENOENT) {
|
||||||
mkdirs(path);
|
if(mkdirs(path) != 0) {
|
||||||
|
fail_errno(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
ret = symlink(buffer, path);
|
ret = symlink(buffer, path);
|
||||||
}
|
}
|
||||||
if(ret) {
|
if(ret) {
|
||||||
|
|
@ -277,7 +320,7 @@ static int handle_send_link(int s, char *path, char *buffer)
|
||||||
static int do_send(int s, char *path, char *buffer)
|
static int do_send(int s, char *path, char *buffer)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
mode_t mode;
|
unsigned int mode;
|
||||||
int is_link, ret;
|
int is_link, ret;
|
||||||
|
|
||||||
tmp = strrchr(path,',');
|
tmp = strrchr(path,',');
|
||||||
|
|
@ -288,7 +331,7 @@ static int do_send(int s, char *path, char *buffer)
|
||||||
#ifndef HAVE_SYMLINKS
|
#ifndef HAVE_SYMLINKS
|
||||||
is_link = 0;
|
is_link = 0;
|
||||||
#else
|
#else
|
||||||
is_link = S_ISLNK(mode);
|
is_link = S_ISLNK((mode_t) mode);
|
||||||
#endif
|
#endif
|
||||||
mode &= 0777;
|
mode &= 0777;
|
||||||
}
|
}
|
||||||
|
|
@ -307,11 +350,23 @@ static int do_send(int s, char *path, char *buffer)
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
unsigned int uid, gid;
|
||||||
|
uint64_t cap = 0;
|
||||||
|
uid = getuid();
|
||||||
|
gid = getgid();
|
||||||
|
|
||||||
/* copy user permission bits to "group" and "other" permissions */
|
/* copy user permission bits to "group" and "other" permissions */
|
||||||
mode |= ((mode >> 3) & 0070);
|
mode |= ((mode >> 3) & 0070);
|
||||||
mode |= ((mode >> 3) & 0007);
|
mode |= ((mode >> 3) & 0007);
|
||||||
|
|
||||||
ret = handle_send_file(s, path, mode, buffer);
|
tmp = path;
|
||||||
|
if(*tmp == '/') {
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
if (is_on_system(path)) {
|
||||||
|
fs_config(tmp, 0, &uid, &gid, &mode, &cap);
|
||||||
|
}
|
||||||
|
ret = handle_send_file(s, path, uid, gid, mode, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue