.clang-format: increase indent width
All checks were successful
Test / Create distribution (push) Successful in 26s
Test / Sandbox (push) Successful in 2m27s
Test / Hakurei (push) Successful in 3m17s
Test / Hpkg (push) Successful in 3m27s
Test / Sandbox (race detector) (push) Successful in 4m21s
Test / Hakurei (race detector) (push) Successful in 4m59s
Test / Flake checks (push) Successful in 1m31s
All checks were successful
Test / Create distribution (push) Successful in 26s
Test / Sandbox (push) Successful in 2m27s
Test / Hakurei (push) Successful in 3m17s
Test / Hpkg (push) Successful in 3m27s
Test / Sandbox (race detector) (push) Successful in 4m21s
Test / Hakurei (race detector) (push) Successful in 4m59s
Test / Flake checks (push) Successful in 1m31s
This significantly increases readability. This patch is pretty big so it is being done after mostly everything has settled. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
38b5ff0cec
commit
b73a789dfe
@ -1 +1,2 @@
|
|||||||
ColumnLimit: 0
|
ColumnLimit: 0
|
||||||
|
IndentWidth: 4
|
||||||
|
|||||||
@ -14,125 +14,125 @@ int32_t hakurei_scmp_make_filter(
|
|||||||
uint32_t arch, uint32_t multiarch,
|
uint32_t arch, uint32_t multiarch,
|
||||||
struct hakurei_syscall_rule *rules,
|
struct hakurei_syscall_rule *rules,
|
||||||
size_t rules_sz, hakurei_export_flag flags) {
|
size_t rules_sz, hakurei_export_flag flags) {
|
||||||
int i;
|
int i;
|
||||||
int last_allowed_family;
|
int last_allowed_family;
|
||||||
int disallowed;
|
int disallowed;
|
||||||
struct hakurei_syscall_rule *rule;
|
struct hakurei_syscall_rule *rule;
|
||||||
void *buf;
|
void *buf;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
int32_t res = 0; /* refer to resPrefix for message */
|
int32_t res = 0; /* refer to resPrefix for message */
|
||||||
|
|
||||||
/* Blocklist all but unix, inet, inet6 and netlink */
|
/* Blocklist all but unix, inet, inet6 and netlink */
|
||||||
struct {
|
struct {
|
||||||
int family;
|
int family;
|
||||||
hakurei_export_flag flags_mask;
|
hakurei_export_flag flags_mask;
|
||||||
} socket_family_allowlist[] = {
|
} socket_family_allowlist[] = {
|
||||||
/* NOTE: Keep in numerical order */
|
/* NOTE: Keep in numerical order */
|
||||||
{AF_UNSPEC, 0},
|
{AF_UNSPEC, 0},
|
||||||
{AF_LOCAL, 0},
|
{AF_LOCAL, 0},
|
||||||
{AF_INET, 0},
|
{AF_INET, 0},
|
||||||
{AF_INET6, 0},
|
{AF_INET6, 0},
|
||||||
{AF_NETLINK, 0},
|
{AF_NETLINK, 0},
|
||||||
{AF_CAN, HAKUREI_EXPORT_CAN},
|
{AF_CAN, HAKUREI_EXPORT_CAN},
|
||||||
{AF_BLUETOOTH, HAKUREI_EXPORT_BLUETOOTH},
|
{AF_BLUETOOTH, HAKUREI_EXPORT_BLUETOOTH},
|
||||||
};
|
};
|
||||||
|
|
||||||
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
|
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
res = 1;
|
res = 1;
|
||||||
goto out;
|
|
||||||
} else
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
/* We only really need to handle arches on multiarch systems.
|
|
||||||
* If only one arch is supported the default is fine */
|
|
||||||
if (arch != 0) {
|
|
||||||
/* This *adds* the target arch, instead of replacing the
|
|
||||||
* native one. This is not ideal, because we'd like to only
|
|
||||||
* allow the target arch, but we can't really disallow the
|
|
||||||
* native arch at this point, because then bubblewrap
|
|
||||||
* couldn't continue running. */
|
|
||||||
*ret_p = seccomp_arch_add(ctx, arch);
|
|
||||||
if (*ret_p < 0 && *ret_p != -EEXIST) {
|
|
||||||
res = 2;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & HAKUREI_EXPORT_MULTIARCH && multiarch != 0) {
|
|
||||||
*ret_p = seccomp_arch_add(ctx, multiarch);
|
|
||||||
if (*ret_p < 0 && *ret_p != -EEXIST) {
|
|
||||||
res = 3;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
} else
|
||||||
}
|
errno = 0;
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < rules_sz; i++) {
|
/* We only really need to handle arches on multiarch systems.
|
||||||
rule = &rules[i];
|
* If only one arch is supported the default is fine */
|
||||||
assert(rule->m_errno == EPERM || rule->m_errno == ENOSYS);
|
if (arch != 0) {
|
||||||
|
/* This *adds* the target arch, instead of replacing the
|
||||||
|
* native one. This is not ideal, because we'd like to only
|
||||||
|
* allow the target arch, but we can't really disallow the
|
||||||
|
* native arch at this point, because then bubblewrap
|
||||||
|
* couldn't continue running. */
|
||||||
|
*ret_p = seccomp_arch_add(ctx, arch);
|
||||||
|
if (*ret_p < 0 && *ret_p != -EEXIST) {
|
||||||
|
res = 2;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (rule->arg)
|
if (flags & HAKUREI_EXPORT_MULTIARCH && multiarch != 0) {
|
||||||
*ret_p = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(rule->m_errno), rule->syscall, 1, *rule->arg);
|
*ret_p = seccomp_arch_add(ctx, multiarch);
|
||||||
else
|
if (*ret_p < 0 && *ret_p != -EEXIST) {
|
||||||
*ret_p = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(rule->m_errno), rule->syscall, 0);
|
res = 3;
|
||||||
|
goto out;
|
||||||
if (*ret_p == -EFAULT) {
|
}
|
||||||
res = 4;
|
}
|
||||||
goto out;
|
|
||||||
} else if (*ret_p < 0) {
|
|
||||||
res = 5;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Socket filtering doesn't work on e.g. i386, so ignore failures here
|
|
||||||
* However, we need to user seccomp_rule_add_exact to avoid libseccomp doing
|
|
||||||
* something else: https://github.com/seccomp/libseccomp/issues/8 */
|
|
||||||
last_allowed_family = -1;
|
|
||||||
for (i = 0; i < LEN(socket_family_allowlist); i++) {
|
|
||||||
if (socket_family_allowlist[i].flags_mask != 0 &&
|
|
||||||
(socket_family_allowlist[i].flags_mask & flags) != socket_family_allowlist[i].flags_mask)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (disallowed = last_allowed_family + 1; disallowed < socket_family_allowlist[i].family; disallowed++) {
|
|
||||||
/* Blocklist the in-between valid families */
|
|
||||||
seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_EQ, disallowed));
|
|
||||||
}
|
|
||||||
last_allowed_family = socket_family_allowlist[i].family;
|
|
||||||
}
|
|
||||||
/* Blocklist the rest */
|
|
||||||
seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_GE, last_allowed_family + 1));
|
|
||||||
|
|
||||||
if (allocate_p == 0) {
|
|
||||||
*ret_p = seccomp_load(ctx);
|
|
||||||
if (*ret_p != 0) {
|
|
||||||
res = 7;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*ret_p = seccomp_export_bpf_mem(ctx, NULL, &len);
|
|
||||||
if (*ret_p != 0) {
|
|
||||||
res = 6;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = hakurei_scmp_allocate(allocate_p, len);
|
for (i = 0; i < rules_sz; i++) {
|
||||||
if (buf == NULL) {
|
rule = &rules[i];
|
||||||
res = 4;
|
assert(rule->m_errno == EPERM || rule->m_errno == ENOSYS);
|
||||||
goto out;
|
|
||||||
|
if (rule->arg)
|
||||||
|
*ret_p = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(rule->m_errno), rule->syscall, 1, *rule->arg);
|
||||||
|
else
|
||||||
|
*ret_p = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(rule->m_errno), rule->syscall, 0);
|
||||||
|
|
||||||
|
if (*ret_p == -EFAULT) {
|
||||||
|
res = 4;
|
||||||
|
goto out;
|
||||||
|
} else if (*ret_p < 0) {
|
||||||
|
res = 5;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret_p = seccomp_export_bpf_mem(ctx, buf, &len);
|
/* Socket filtering doesn't work on e.g. i386, so ignore failures here
|
||||||
if (*ret_p != 0) {
|
* However, we need to user seccomp_rule_add_exact to avoid libseccomp doing
|
||||||
res = 6;
|
* something else: https://github.com/seccomp/libseccomp/issues/8 */
|
||||||
goto out;
|
last_allowed_family = -1;
|
||||||
|
for (i = 0; i < LEN(socket_family_allowlist); i++) {
|
||||||
|
if (socket_family_allowlist[i].flags_mask != 0 &&
|
||||||
|
(socket_family_allowlist[i].flags_mask & flags) != socket_family_allowlist[i].flags_mask)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (disallowed = last_allowed_family + 1; disallowed < socket_family_allowlist[i].family; disallowed++) {
|
||||||
|
/* Blocklist the in-between valid families */
|
||||||
|
seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_EQ, disallowed));
|
||||||
|
}
|
||||||
|
last_allowed_family = socket_family_allowlist[i].family;
|
||||||
|
}
|
||||||
|
/* Blocklist the rest */
|
||||||
|
seccomp_rule_add_exact(ctx, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_GE, last_allowed_family + 1));
|
||||||
|
|
||||||
|
if (allocate_p == 0) {
|
||||||
|
*ret_p = seccomp_load(ctx);
|
||||||
|
if (*ret_p != 0) {
|
||||||
|
res = 7;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*ret_p = seccomp_export_bpf_mem(ctx, NULL, &len);
|
||||||
|
if (*ret_p != 0) {
|
||||||
|
res = 6;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = hakurei_scmp_allocate(allocate_p, len);
|
||||||
|
if (buf == NULL) {
|
||||||
|
res = 4;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret_p = seccomp_export_bpf_mem(ctx, buf, &len);
|
||||||
|
if (*ret_p != 0) {
|
||||||
|
res = 6;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (ctx)
|
if (ctx)
|
||||||
seccomp_release(ctx);
|
seccomp_release(ctx);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,15 +7,15 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HAKUREI_EXPORT_MULTIARCH = 1 << 0,
|
HAKUREI_EXPORT_MULTIARCH = 1 << 0,
|
||||||
HAKUREI_EXPORT_CAN = 1 << 1,
|
HAKUREI_EXPORT_CAN = 1 << 1,
|
||||||
HAKUREI_EXPORT_BLUETOOTH = 1 << 2,
|
HAKUREI_EXPORT_BLUETOOTH = 1 << 2,
|
||||||
} hakurei_export_flag;
|
} hakurei_export_flag;
|
||||||
|
|
||||||
struct hakurei_syscall_rule {
|
struct hakurei_syscall_rule {
|
||||||
int syscall;
|
int syscall;
|
||||||
int m_errno;
|
int m_errno;
|
||||||
struct scmp_arg_cmp *arg;
|
struct scmp_arg_cmp *arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void *hakurei_scmp_allocate(uintptr_t f, size_t len);
|
extern void *hakurei_scmp_allocate(uintptr_t f, size_t len);
|
||||||
|
|||||||
@ -6,85 +6,85 @@
|
|||||||
|
|
||||||
int hakurei_acl_update_file_by_uid(const char *path_p, uid_t uid,
|
int hakurei_acl_update_file_by_uid(const char *path_p, uid_t uid,
|
||||||
acl_perm_t *perms, size_t plen) {
|
acl_perm_t *perms, size_t plen) {
|
||||||
int ret;
|
int ret;
|
||||||
bool v;
|
bool v;
|
||||||
int i;
|
int i;
|
||||||
acl_t acl;
|
acl_t acl;
|
||||||
acl_entry_t entry;
|
acl_entry_t entry;
|
||||||
acl_tag_t tag_type;
|
acl_tag_t tag_type;
|
||||||
void *qualifier_p;
|
void *qualifier_p;
|
||||||
acl_permset_t permset;
|
acl_permset_t permset;
|
||||||
|
|
||||||
ret = -1; /* acl_get_file */
|
ret = -1; /* acl_get_file */
|
||||||
acl = acl_get_file(path_p, ACL_TYPE_ACCESS);
|
acl = acl_get_file(path_p, ACL_TYPE_ACCESS);
|
||||||
if (acl == NULL)
|
if (acl == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* prune entries by uid */
|
/* prune entries by uid */
|
||||||
for (i = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); i == 1;
|
for (i = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); i == 1;
|
||||||
i = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
|
i = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
|
||||||
ret = -2; /* acl_get_tag_type */
|
ret = -2; /* acl_get_tag_type */
|
||||||
if (acl_get_tag_type(entry, &tag_type) != 0)
|
if (acl_get_tag_type(entry, &tag_type) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
if (tag_type != ACL_USER)
|
if (tag_type != ACL_USER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = -3; /* acl_get_qualifier */
|
ret = -3; /* acl_get_qualifier */
|
||||||
qualifier_p = acl_get_qualifier(entry);
|
qualifier_p = acl_get_qualifier(entry);
|
||||||
if (qualifier_p == NULL)
|
if (qualifier_p == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
v = *(uid_t *)qualifier_p == uid;
|
v = *(uid_t *)qualifier_p == uid;
|
||||||
acl_free(qualifier_p);
|
acl_free(qualifier_p);
|
||||||
|
|
||||||
if (!v)
|
if (!v)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = -4; /* acl_delete_entry */
|
ret = -4; /* acl_delete_entry */
|
||||||
if (acl_delete_entry(acl, entry) != 0)
|
if (acl_delete_entry(acl, entry) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plen == 0)
|
if (plen == 0)
|
||||||
goto set;
|
goto set;
|
||||||
|
|
||||||
ret = -5; /* acl_create_entry */
|
ret = -5; /* acl_create_entry */
|
||||||
if (acl_create_entry(&acl, &entry) != 0)
|
if (acl_create_entry(&acl, &entry) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = -6; /* acl_get_permset */
|
ret = -6; /* acl_get_permset */
|
||||||
if (acl_get_permset(entry, &permset) != 0)
|
if (acl_get_permset(entry, &permset) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = -7; /* acl_add_perm */
|
ret = -7; /* acl_add_perm */
|
||||||
for (i = 0; i < plen; i++) {
|
for (i = 0; i < plen; i++) {
|
||||||
if (acl_add_perm(permset, perms[i]) != 0)
|
if (acl_add_perm(permset, perms[i]) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = -8; /* acl_set_tag_type */
|
ret = -8; /* acl_set_tag_type */
|
||||||
if (acl_set_tag_type(entry, ACL_USER) != 0)
|
if (acl_set_tag_type(entry, ACL_USER) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = -9; /* acl_set_qualifier */
|
ret = -9; /* acl_set_qualifier */
|
||||||
if (acl_set_qualifier(entry, (void *)&uid) != 0)
|
if (acl_set_qualifier(entry, (void *)&uid) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
set:
|
set:
|
||||||
ret = -10; /* acl_calc_mask */
|
ret = -10; /* acl_calc_mask */
|
||||||
if (acl_calc_mask(&acl) != 0)
|
if (acl_calc_mask(&acl) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = -11; /* acl_valid */
|
ret = -11; /* acl_valid */
|
||||||
if (acl_valid(acl) != 0)
|
if (acl_valid(acl) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = -12; /* acl_set_file */
|
ret = -12; /* acl_set_file */
|
||||||
if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) == 0)
|
if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) == 0)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free((void *)path_p);
|
free((void *)path_p);
|
||||||
if (acl != NULL)
|
if (acl != NULL)
|
||||||
acl_free((void *)acl);
|
acl_free((void *)acl);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,53 +10,53 @@ static int hakurei_shim_fd = -1;
|
|||||||
|
|
||||||
/* see shim.go for handling of the message */
|
/* see shim.go for handling of the message */
|
||||||
static inline ssize_t hakurei_shim_write(hakurei_shim_msg msg) {
|
static inline ssize_t hakurei_shim_write(hakurei_shim_msg msg) {
|
||||||
int savedErrno = errno;
|
int savedErrno = errno;
|
||||||
unsigned char buf = (unsigned char)msg;
|
unsigned char buf = (unsigned char)msg;
|
||||||
ssize_t ret = write(hakurei_shim_fd, &buf, 1);
|
ssize_t ret = write(hakurei_shim_fd, &buf, 1);
|
||||||
if (ret == -1 && errno != EAGAIN)
|
if (ret == -1 && errno != EAGAIN)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
errno = savedErrno;
|
errno = savedErrno;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hakurei_shim_sigaction(int sig, siginfo_t *si, void *ucontext) {
|
static void hakurei_shim_sigaction(int sig, siginfo_t *si, void *ucontext) {
|
||||||
if (sig != SIGCONT || si == NULL) {
|
if (sig != SIGCONT || si == NULL) {
|
||||||
hakurei_shim_write(HAKUREI_SHIM_INVALID);
|
hakurei_shim_write(HAKUREI_SHIM_INVALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (si->si_pid == hakurei_shim_param_ppid) {
|
if (si->si_pid == hakurei_shim_param_ppid) {
|
||||||
hakurei_shim_write(HAKUREI_SHIM_EXIT_REQUESTED);
|
hakurei_shim_write(HAKUREI_SHIM_EXIT_REQUESTED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hakurei_shim_write(HAKUREI_SHIM_BAD_PID);
|
hakurei_shim_write(HAKUREI_SHIM_BAD_PID);
|
||||||
|
|
||||||
if (getppid() != hakurei_shim_param_ppid)
|
if (getppid() != hakurei_shim_param_ppid)
|
||||||
hakurei_shim_write(HAKUREI_SHIM_ORPHAN);
|
hakurei_shim_write(HAKUREI_SHIM_ORPHAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hakurei_shim_setup_cont_signal(pid_t ppid, int fd) {
|
void hakurei_shim_setup_cont_signal(pid_t ppid, int fd) {
|
||||||
if (hakurei_shim_param_ppid != -1 || hakurei_shim_fd != -1)
|
if (hakurei_shim_param_ppid != -1 || hakurei_shim_fd != -1)
|
||||||
*(volatile int *)NULL = 0; /* unreachable */
|
*(volatile int *)NULL = 0; /* unreachable */
|
||||||
|
|
||||||
struct sigaction new_action = {0}, old_action = {0};
|
struct sigaction new_action = {0}, old_action = {0};
|
||||||
if (sigaction(SIGCONT, NULL, &old_action) != 0)
|
if (sigaction(SIGCONT, NULL, &old_action) != 0)
|
||||||
return;
|
return;
|
||||||
if (old_action.sa_handler != SIG_DFL) {
|
if (old_action.sa_handler != SIG_DFL) {
|
||||||
errno = ENOTRECOVERABLE;
|
errno = ENOTRECOVERABLE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_action.sa_sigaction = hakurei_shim_sigaction;
|
new_action.sa_sigaction = hakurei_shim_sigaction;
|
||||||
if (sigemptyset(&new_action.sa_mask) != 0)
|
if (sigemptyset(&new_action.sa_mask) != 0)
|
||||||
return;
|
return;
|
||||||
new_action.sa_flags = SA_ONSTACK | SA_SIGINFO;
|
new_action.sa_flags = SA_ONSTACK | SA_SIGINFO;
|
||||||
|
|
||||||
if (sigaction(SIGCONT, &new_action, NULL) != 0)
|
if (sigaction(SIGCONT, &new_action, NULL) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
hakurei_shim_param_ppid = ppid;
|
hakurei_shim_param_ppid = ppid;
|
||||||
hakurei_shim_fd = fd;
|
hakurei_shim_fd = fd;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
/* see shim.go for documentation */
|
/* see shim.go for documentation */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HAKUREI_SHIM_EXIT_REQUESTED,
|
HAKUREI_SHIM_EXIT_REQUESTED,
|
||||||
HAKUREI_SHIM_ORPHAN,
|
HAKUREI_SHIM_ORPHAN,
|
||||||
HAKUREI_SHIM_INVALID,
|
HAKUREI_SHIM_INVALID,
|
||||||
HAKUREI_SHIM_BAD_PID,
|
HAKUREI_SHIM_BAD_PID,
|
||||||
} hakurei_shim_msg;
|
} hakurei_shim_msg;
|
||||||
|
|
||||||
void hakurei_shim_setup_cont_signal(pid_t ppid, int fd);
|
void hakurei_shim_setup_cont_signal(pid_t ppid, int fd);
|
||||||
|
|||||||
@ -14,10 +14,10 @@ static void registry_handle_global(
|
|||||||
uint32_t name,
|
uint32_t name,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
uint32_t version) {
|
uint32_t version) {
|
||||||
struct wp_security_context_manager_v1 **out = data;
|
struct wp_security_context_manager_v1 **out = data;
|
||||||
|
|
||||||
if (strcmp(interface, wp_security_context_manager_v1_interface.name) == 0)
|
if (strcmp(interface, wp_security_context_manager_v1_interface.name) == 0)
|
||||||
*out = wl_registry_bind(registry, name, &wp_security_context_manager_v1_interface, 1);
|
*out = wl_registry_bind(registry, name, &wp_security_context_manager_v1_interface, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void registry_handle_global_remove(
|
static void registry_handle_global_remove(
|
||||||
@ -36,82 +36,82 @@ hakurei_wayland_res hakurei_security_context_bind(
|
|||||||
const char *app_id,
|
const char *app_id,
|
||||||
const char *instance_id,
|
const char *instance_id,
|
||||||
int close_fd) {
|
int close_fd) {
|
||||||
hakurei_wayland_res res = HAKUREI_WAYLAND_SUCCESS; /* see wayland.go for handling */
|
hakurei_wayland_res res = HAKUREI_WAYLAND_SUCCESS; /* see wayland.go for handling */
|
||||||
|
|
||||||
struct wl_display *display = NULL;
|
struct wl_display *display = NULL;
|
||||||
struct wl_registry *registry;
|
struct wl_registry *registry;
|
||||||
struct wp_security_context_manager_v1 *security_context_manager = NULL;
|
struct wp_security_context_manager_v1 *security_context_manager = NULL;
|
||||||
int event_cnt;
|
int event_cnt;
|
||||||
int listen_fd = -1;
|
int listen_fd = -1;
|
||||||
struct sockaddr_un sockaddr = {0};
|
struct sockaddr_un sockaddr = {0};
|
||||||
struct wp_security_context_v1 *security_context;
|
struct wp_security_context_v1 *security_context;
|
||||||
|
|
||||||
display = wl_display_connect_to_fd(server_fd);
|
display = wl_display_connect_to_fd(server_fd);
|
||||||
if (display == NULL) {
|
if (display == NULL) {
|
||||||
res = HAKUREI_WAYLAND_CONNECT;
|
res = HAKUREI_WAYLAND_CONNECT;
|
||||||
goto out;
|
goto out;
|
||||||
};
|
};
|
||||||
|
|
||||||
registry = wl_display_get_registry(display);
|
registry = wl_display_get_registry(display);
|
||||||
if (wl_registry_add_listener(registry, ®istry_listener, &security_context_manager) < 0) {
|
if (wl_registry_add_listener(registry, ®istry_listener, &security_context_manager) < 0) {
|
||||||
res = HAKUREI_WAYLAND_LISTENER;
|
res = HAKUREI_WAYLAND_LISTENER;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
event_cnt = wl_display_roundtrip(display);
|
event_cnt = wl_display_roundtrip(display);
|
||||||
wl_registry_destroy(registry);
|
wl_registry_destroy(registry);
|
||||||
if (event_cnt < 0) {
|
if (event_cnt < 0) {
|
||||||
res = HAKUREI_WAYLAND_ROUNDTRIP;
|
res = HAKUREI_WAYLAND_ROUNDTRIP;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (security_context_manager == NULL) {
|
if (security_context_manager == NULL) {
|
||||||
res = HAKUREI_WAYLAND_NOT_AVAIL;
|
res = HAKUREI_WAYLAND_NOT_AVAIL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (listen_fd < 0) {
|
if (listen_fd < 0) {
|
||||||
res = HAKUREI_WAYLAND_SOCKET;
|
res = HAKUREI_WAYLAND_SOCKET;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr.sun_family = AF_UNIX;
|
sockaddr.sun_family = AF_UNIX;
|
||||||
snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s", socket_path);
|
snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s", socket_path);
|
||||||
if (bind(listen_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != 0) {
|
if (bind(listen_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != 0) {
|
||||||
res = HAKUREI_WAYLAND_BIND;
|
res = HAKUREI_WAYLAND_BIND;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(listen_fd, 0) != 0) {
|
if (listen(listen_fd, 0) != 0) {
|
||||||
res = HAKUREI_WAYLAND_LISTEN;
|
res = HAKUREI_WAYLAND_LISTEN;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
security_context = wp_security_context_manager_v1_create_listener(security_context_manager, listen_fd, close_fd);
|
security_context = wp_security_context_manager_v1_create_listener(security_context_manager, listen_fd, close_fd);
|
||||||
if (security_context == NULL) { /* not reached */
|
if (security_context == NULL) { /* not reached */
|
||||||
res = HAKUREI_WAYLAND_NOT_AVAIL;
|
res = HAKUREI_WAYLAND_NOT_AVAIL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
wp_security_context_v1_set_sandbox_engine(security_context, "app.hakurei");
|
wp_security_context_v1_set_sandbox_engine(security_context, "app.hakurei");
|
||||||
wp_security_context_v1_set_app_id(security_context, app_id);
|
wp_security_context_v1_set_app_id(security_context, app_id);
|
||||||
wp_security_context_v1_set_instance_id(security_context, instance_id);
|
wp_security_context_v1_set_instance_id(security_context, instance_id);
|
||||||
wp_security_context_v1_commit(security_context);
|
wp_security_context_v1_commit(security_context);
|
||||||
wp_security_context_v1_destroy(security_context);
|
wp_security_context_v1_destroy(security_context);
|
||||||
if (wl_display_roundtrip(display) < 0) {
|
if (wl_display_roundtrip(display) < 0) {
|
||||||
res = HAKUREI_WAYLAND_ROUNDTRIP;
|
res = HAKUREI_WAYLAND_ROUNDTRIP;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (listen_fd >= 0)
|
if (listen_fd >= 0)
|
||||||
close(listen_fd);
|
close(listen_fd);
|
||||||
if (security_context_manager != NULL)
|
if (security_context_manager != NULL)
|
||||||
wp_security_context_manager_v1_destroy(security_context_manager);
|
wp_security_context_manager_v1_destroy(security_context_manager);
|
||||||
if (display != NULL)
|
if (display != NULL)
|
||||||
wl_display_disconnect(display);
|
wl_display_disconnect(display);
|
||||||
|
|
||||||
free((void *)socket_path);
|
free((void *)socket_path);
|
||||||
free((void *)app_id);
|
free((void *)app_id);
|
||||||
free((void *)instance_id);
|
free((void *)instance_id);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,28 +2,28 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HAKUREI_WAYLAND_SUCCESS,
|
HAKUREI_WAYLAND_SUCCESS,
|
||||||
/* wl_display_connect_to_fd failed, errno */
|
/* wl_display_connect_to_fd failed, errno */
|
||||||
HAKUREI_WAYLAND_CONNECT,
|
HAKUREI_WAYLAND_CONNECT,
|
||||||
/* wl_registry_add_listener failed, errno */
|
/* wl_registry_add_listener failed, errno */
|
||||||
HAKUREI_WAYLAND_LISTENER,
|
HAKUREI_WAYLAND_LISTENER,
|
||||||
/* wl_display_roundtrip failed, errno */
|
/* wl_display_roundtrip failed, errno */
|
||||||
HAKUREI_WAYLAND_ROUNDTRIP,
|
HAKUREI_WAYLAND_ROUNDTRIP,
|
||||||
/* compositor does not implement wp_security_context_v1 */
|
/* compositor does not implement wp_security_context_v1 */
|
||||||
HAKUREI_WAYLAND_NOT_AVAIL,
|
HAKUREI_WAYLAND_NOT_AVAIL,
|
||||||
/* socket failed, errno */
|
/* socket failed, errno */
|
||||||
HAKUREI_WAYLAND_SOCKET,
|
HAKUREI_WAYLAND_SOCKET,
|
||||||
/* bind failed, errno */
|
/* bind failed, errno */
|
||||||
HAKUREI_WAYLAND_BIND,
|
HAKUREI_WAYLAND_BIND,
|
||||||
/* listen failed, errno */
|
/* listen failed, errno */
|
||||||
HAKUREI_WAYLAND_LISTEN,
|
HAKUREI_WAYLAND_LISTEN,
|
||||||
|
|
||||||
/* ensure pathname failed, implemented in conn.go */
|
/* ensure pathname failed, implemented in conn.go */
|
||||||
HAKUREI_WAYLAND_CREAT,
|
HAKUREI_WAYLAND_CREAT,
|
||||||
/* socket for host server failed, implemented in conn.go */
|
/* socket for host server failed, implemented in conn.go */
|
||||||
HAKUREI_WAYLAND_HOST_SOCKET,
|
HAKUREI_WAYLAND_HOST_SOCKET,
|
||||||
/* connect for host server failed, implemented in conn.go */
|
/* connect for host server failed, implemented in conn.go */
|
||||||
HAKUREI_WAYLAND_HOST_CONNECT,
|
HAKUREI_WAYLAND_HOST_CONNECT,
|
||||||
} hakurei_wayland_res;
|
} hakurei_wayland_res;
|
||||||
|
|
||||||
hakurei_wayland_res hakurei_security_context_bind(
|
hakurei_wayland_res hakurei_security_context_bind(
|
||||||
@ -35,6 +35,6 @@ hakurei_wayland_res hakurei_security_context_bind(
|
|||||||
|
|
||||||
/* returns whether the specified size fits in the sun_path field of sockaddr_un */
|
/* returns whether the specified size fits in the sun_path field of sockaddr_un */
|
||||||
static inline bool hakurei_is_valid_size_sun_path(size_t sz) {
|
static inline bool hakurei_is_valid_size_sun_path(size_t sz) {
|
||||||
struct sockaddr_un sockaddr;
|
struct sockaddr_un sockaddr;
|
||||||
return sz <= sizeof(sockaddr.sun_path);
|
return sz <= sizeof(sockaddr.sun_path);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user