/* Creates a denial to get the domain ID. */
EXPECT_EQ(-1, kill(getppid(), 0));
EXPECT_EQ(EPERM, errno);
EXPECT_EQ(0,
matches_log_signal(_metadata, self->audit_fd,
getppid(), &denial_dom));
EXPECT_EQ(0, matches_log_domain_allocated(
self->audit_fd, getpid(),
&allocated_dom));
EXPECT_NE(denial_dom, 1);
EXPECT_NE(denial_dom, 0);
EXPECT_EQ(denial_dom, allocated_dom);
/* Checks that the new domain is younger than the previous one. */
EXPECT_GT(allocated_dom, prev_dom);
prev_dom = allocated_dom;
(*domain_stack)[i] = allocated_dom;
}
/* Checks that we reached the maximum number of layers. */
EXPECT_EQ(-1, landlock_restrict_self(ruleset_fd, 0));
EXPECT_EQ(E2BIG, errno);
/* Updates filter rules to match the drop record. */
set_cap(_metadata, CAP_AUDIT_CONTROL);
EXPECT_EQ(0, audit_filter_drop(self->audit_fd, AUDIT_ADD_RULE));
EXPECT_EQ(0,
audit_filter_exe(self->audit_fd, &self->audit_filter,
AUDIT_DEL_RULE));
clear_cap(_metadata, CAP_AUDIT_CONTROL);
/* Checks that the PID tied to a domain is not a TID but the TGID. */
TEST_F(audit, thread)
{ conststruct landlock_ruleset_attr ruleset_attr = {
.scoped = LANDLOCK_SCOPE_SIGNAL,
};
__u64 denial_dom = 1;
__u64 allocated_dom = 2;
__u64 deallocated_dom = 3;
pthread_t thread; int pipe_child[2], pipe_parent[2]; char buffer; struct thread_data child_data;
/* TGID and TID are the same for the initial thread . */
EXPECT_EQ(getpid(), gettid());
EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
ASSERT_EQ(0, pthread_create(&thread, NULL, thread_audit_test,
&child_data));
/* Waits for the child to generate a denial. */
ASSERT_EQ(1, read(pipe_child[0], &buffer, 1));
EXPECT_EQ(0, close(pipe_child[0]));
/* Matches the signal log to get the domain ID. */
EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
child_data.parent_pid, &denial_dom));
EXPECT_NE(denial_dom, 1);
EXPECT_NE(denial_dom, 0);
/* Updates filter rules to match the drop record. */
set_cap(_metadata, CAP_AUDIT_CONTROL);
EXPECT_EQ(0, audit_filter_drop(self->audit_fd, AUDIT_ADD_RULE));
EXPECT_EQ(0, audit_filter_exe(self->audit_fd, &self->audit_filter,
AUDIT_DEL_RULE));
clear_cap(_metadata, CAP_AUDIT_CONTROL);
/* Signals the thread to exit, which will generate a domain deallocation. */
ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
EXPECT_EQ(0, close(pipe_parent[1]));
ASSERT_EQ(0, pthread_join(thread, NULL));
/* Checks domain information records. */
EXPECT_EQ(0, matches_log_domain_allocated(
self->audit_fd, getpid(),
&allocated_dom));
EXPECT_NE(*self->domain_id, 1);
EXPECT_NE(*self->domain_id, 0);
EXPECT_EQ(*self->domain_id, allocated_dom);
}
/* Second signal checks to test audit_count_records(). */
EXPECT_EQ(-1, kill(getppid(), 0));
EXPECT_EQ(EPERM, errno);
/* Makes sure there is no superfluous logged records. */
EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); if (variant->restrict_flags &
LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF) {
EXPECT_EQ(0, records.access);
} else {
EXPECT_EQ(1, records.access);
}
EXPECT_EQ(0, records.domain);
/* Updates filter rules to match the drop record. */
set_cap(_metadata, CAP_AUDIT_CONTROL);
EXPECT_EQ(0, audit_filter_drop(self->audit_fd, AUDIT_ADD_RULE));
EXPECT_EQ(0,
audit_filter_exe(self->audit_fd, &self->audit_filter,
AUDIT_DEL_RULE));
clear_cap(_metadata, CAP_AUDIT_CONTROL);
/* Waits for the child. */
EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
/* Tests that there was no denial until now. */
EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
EXPECT_EQ(0, records.access);
EXPECT_EQ(0, records.domain);
/* * Wait for the child to do a first denied action by layer1 and * sandbox itself with layer2.
*/
EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
/* Tests that the audit record only matches the child. */ if (variant->restrict_flags & LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON) { /* Matches the current domain. */
EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
getpid(), NULL));
}
/* Checks that we didn't miss anything. */
EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
EXPECT_EQ(0, records.access);
/* * Wait for the child to do a second denied action by layer1 and * layer2, and sandbox itself with layer3.
*/
EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
/* Tests that the audit record only matches the child. */ if (variant->restrict_flags & LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON) { /* Matches the current domain. */
EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
getpid(), NULL));
}
if (!(variant->restrict_flags &
LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)) { /* Matches the child domain. */
EXPECT_EQ(0, matches_log_fs_read_root(self->audit_fd));
}
/* Checks that we didn't miss anything. */
EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
EXPECT_EQ(0, records.access);
/* Waits for the child to terminate. */
EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
ASSERT_EQ(child, waitpid(child, &status, 0));
ASSERT_EQ(1, WIFEXITED(status));
ASSERT_EQ(0, WEXITSTATUS(status));
/* Tests that the audit record only matches the child. */ if (!(variant->restrict_flags &
LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)) { /* * Matches the child domains, which tests that the * llcred->domain_exec bitmask is correctly updated with a new * domain.
*/
EXPECT_EQ(0, matches_log_fs_read_root(self->audit_fd));
EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
getpid(), NULL));
}
/* Checks that we didn't miss anything. */
EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
EXPECT_EQ(0, records.access);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.