Merge tag 'seccomp-v5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull seccomp updates from Kees Cook:
 "A couple of seccomp updates. They're both mostly bug fixes that I
  wanted to have sit in linux-next for a while:

   - allow TSYNC and USER_NOTIF together (Tycho Andersen)

   - add missing compat_ioctl for notify (Sven Schnelle)"

* tag 'seccomp-v5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  seccomp: Add missing compat_ioctl for notify
  seccomp: allow TSYNC and USER_NOTIF together
This commit is contained in:
Linus Torvalds
2020-03-30 12:53:56 -07:00
4 changed files with 87 additions and 6 deletions

View File

@@ -212,6 +212,10 @@ struct seccomp_notif_sizes {
#define SECCOMP_USER_NOTIF_FLAG_CONTINUE 0x00000001
#endif
#ifndef SECCOMP_FILTER_FLAG_TSYNC_ESRCH
#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4)
#endif
#ifndef seccomp
int seccomp(unsigned int op, unsigned int flags, void *args)
{
@@ -2187,7 +2191,8 @@ TEST(detect_seccomp_filter_flags)
unsigned int flags[] = { SECCOMP_FILTER_FLAG_TSYNC,
SECCOMP_FILTER_FLAG_LOG,
SECCOMP_FILTER_FLAG_SPEC_ALLOW,
SECCOMP_FILTER_FLAG_NEW_LISTENER };
SECCOMP_FILTER_FLAG_NEW_LISTENER,
SECCOMP_FILTER_FLAG_TSYNC_ESRCH };
unsigned int exclusive[] = {
SECCOMP_FILTER_FLAG_TSYNC,
SECCOMP_FILTER_FLAG_NEW_LISTENER };
@@ -2645,6 +2650,55 @@ TEST_F(TSYNC, two_siblings_with_one_divergence)
EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
}
TEST_F(TSYNC, two_siblings_with_one_divergence_no_tid_in_err)
{
long ret, flags;
void *status;
ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
}
ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
ASSERT_NE(ENOSYS, errno) {
TH_LOG("Kernel does not support seccomp syscall!");
}
ASSERT_EQ(0, ret) {
TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
}
self->sibling[0].diverge = 1;
tsync_start_sibling(&self->sibling[0]);
tsync_start_sibling(&self->sibling[1]);
while (self->sibling_count < TSYNC_SIBLINGS) {
sem_wait(&self->started);
self->sibling_count++;
}
flags = SECCOMP_FILTER_FLAG_TSYNC | \
SECCOMP_FILTER_FLAG_TSYNC_ESRCH;
ret = seccomp(SECCOMP_SET_MODE_FILTER, flags, &self->apply_prog);
ASSERT_EQ(ESRCH, errno) {
TH_LOG("Did not return ESRCH for diverged sibling.");
}
ASSERT_EQ(-1, ret) {
TH_LOG("Did not fail on diverged sibling.");
}
/* Wake the threads */
pthread_mutex_lock(&self->mutex);
ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
TH_LOG("cond broadcast non-zero");
}
pthread_mutex_unlock(&self->mutex);
/* Ensure they are both unkilled. */
PTHREAD_JOIN(self->sibling[0].tid, &status);
EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
PTHREAD_JOIN(self->sibling[1].tid, &status);
EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
}
TEST_F(TSYNC, two_siblings_not_under_filter)
{
long ret, sib;
@@ -3196,6 +3250,24 @@ TEST(user_notification_basic)
EXPECT_EQ(0, WEXITSTATUS(status));
}
TEST(user_notification_with_tsync)
{
int ret;
unsigned int flags;
/* these were exclusive */
flags = SECCOMP_FILTER_FLAG_NEW_LISTENER |
SECCOMP_FILTER_FLAG_TSYNC;
ASSERT_EQ(-1, user_trap_syscall(__NR_getppid, flags));
ASSERT_EQ(EINVAL, errno);
/* but now they're not */
flags |= SECCOMP_FILTER_FLAG_TSYNC_ESRCH;
ret = user_trap_syscall(__NR_getppid, flags);
close(ret);
ASSERT_LE(0, ret);
}
TEST(user_notification_kill_in_middle)
{
pid_t pid;