Improve builtin selinux implementation

This commit is contained in:
topjohnwu
2019-03-14 06:34:22 -04:00
parent b7e2e972c7
commit da0a72e8b0
5 changed files with 142 additions and 78 deletions

View File

@@ -27,15 +27,17 @@ static int is_excl(const char *name) {
return 0;
}
int fd_getpath(int fd, char *path, size_t size) {
ssize_t fd_path(int fd, char *path, size_t size) {
snprintf(path, size, "/proc/self/fd/%d", fd);
return xreadlink(path, path, size) == -1;
return xreadlink(path, path, size);
}
int fd_getpathat(int dirfd, const char *name, char *path, size_t size) {
if (fd_getpath(dirfd, path, size))
return 1;
snprintf(path, size, "%s/%s", path, name);
int fd_pathat(int dirfd, const char *name, char *path, size_t size) {
ssize_t len = fd_path(dirfd, path, size);
if (len < 0)
return -1;
path[len] = '/';
strlcpy(&path[len + 1], name, size - len - 1);
return 0;
}
@@ -85,7 +87,7 @@ void rm_rf(const char *path) {
if (lstat(path, &st) < 0)
return;
if (S_ISDIR(st.st_mode)) {
int fd = open(path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
int fd = open(path, O_RDONLY | O_CLOEXEC);
frm_rf(fd);
close(fd);
}
@@ -211,7 +213,7 @@ void clone_dir(int src, int dest) {
case DT_REG:
destfd = xopenat(dest, entry->d_name, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC);
srcfd = xopenat(src, entry->d_name, O_RDONLY | O_CLOEXEC);
xsendfile(destfd, srcfd, 0, a.st.st_size);
xsendfile(destfd, srcfd, nullptr, a.st.st_size);
fsetattr(destfd, &a);
close(destfd);
close(srcfd);
@@ -263,16 +265,21 @@ int getattr(const char *path, struct file_attr *a) {
return 0;
}
int getattrat(int dirfd, const char *pathname, struct file_attr *a) {
char path[PATH_MAX];
fd_getpathat(dirfd, pathname, path, sizeof(path));
int getattrat(int dirfd, const char *name, struct file_attr *a) {
char path[4096];
fd_pathat(dirfd, name, path, sizeof(path));
return getattr(path, a);
}
int fgetattr(int fd, struct file_attr *a) {
char path[PATH_MAX];
fd_getpath(fd, path, sizeof(path));
return getattr(path, a);
if (xfstat(fd, &a->st) < 0)
return -1;
char *con;
if (fgetfilecon(fd, &con) < 0)
return -1;
strcpy(a->con, con);
freecon(con);
return 0;
}
int setattr(const char *path, struct file_attr *a) {
@@ -280,21 +287,25 @@ int setattr(const char *path, struct file_attr *a) {
return -1;
if (chown(path, a->st.st_uid, a->st.st_gid) < 0)
return -1;
if (strlen(a->con) && lsetfilecon(path, a->con) < 0)
if (a->con[0] && lsetfilecon(path, a->con) < 0)
return -1;
return 0;
}
int setattrat(int dirfd, const char *pathname, struct file_attr *a) {
char path[PATH_MAX];
fd_getpathat(dirfd, pathname, path, sizeof(path));
int setattrat(int dirfd, const char *name, struct file_attr *a) {
char path[4096];
fd_pathat(dirfd, name, path, sizeof(path));
return setattr(path, a);
}
int fsetattr(int fd, struct file_attr *a) {
char path[PATH_MAX];
fd_getpath(fd, path, sizeof(path));
return setattr(path, a);
if (fchmod(fd, a->st.st_mode & 0777) < 0)
return -1;
if (fchown(fd, a->st.st_uid, a->st.st_gid) < 0)
return -1;
if (a->con[0] && fsetfilecon(fd, a->con) < 0)
return -1;
return 0;
}
void clone_attr(const char *source, const char *target) {
@@ -346,17 +357,6 @@ void full_read(const char *filename, void **buf, size_t *size) {
close(fd);
}
void full_read_at(int dirfd, const char *filename, void **buf, size_t *size) {
int fd = xopenat(dirfd, filename, O_RDONLY | O_CLOEXEC);
if (fd < 0) {
*buf = nullptr;
*size = 0;
return;
}
fd_full_read(fd, buf, size);
close(fd);
}
void write_zero(int fd, size_t size) {
char buf[4096] = {0};
size_t len;