Skip to content

Commit c377a2c

Browse files
author
James Morris
committed
Merge tag 'seccomp-next' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux into next
2 parents 5965453 + 0b5fa22 commit c377a2c

File tree

2 files changed

+42
-25
lines changed

2 files changed

+42
-25
lines changed

kernel/seccomp.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* of Berkeley Packet Filters/Linux Socket Filters.
1414
*/
1515

16-
#include <linux/atomic.h>
16+
#include <linux/refcount.h>
1717
#include <linux/audit.h>
1818
#include <linux/compat.h>
1919
#include <linux/coredump.h>
@@ -56,7 +56,7 @@
5656
* to a task_struct (other than @usage).
5757
*/
5858
struct seccomp_filter {
59-
atomic_t usage;
59+
refcount_t usage;
6060
struct seccomp_filter *prev;
6161
struct bpf_prog *prog;
6262
};
@@ -378,7 +378,7 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
378378
return ERR_PTR(ret);
379379
}
380380

381-
atomic_set(&sfilter->usage, 1);
381+
refcount_set(&sfilter->usage, 1);
382382

383383
return sfilter;
384384
}
@@ -465,7 +465,7 @@ void get_seccomp_filter(struct task_struct *tsk)
465465
if (!orig)
466466
return;
467467
/* Reference count is bounded by the number of total processes. */
468-
atomic_inc(&orig->usage);
468+
refcount_inc(&orig->usage);
469469
}
470470

471471
static inline void seccomp_filter_free(struct seccomp_filter *filter)
@@ -481,7 +481,7 @@ void put_seccomp_filter(struct task_struct *tsk)
481481
{
482482
struct seccomp_filter *orig = tsk->seccomp.filter;
483483
/* Clean up single-reference branches iteratively. */
484-
while (orig && atomic_dec_and_test(&orig->usage)) {
484+
while (orig && refcount_dec_and_test(&orig->usage)) {
485485
struct seccomp_filter *freeme = orig;
486486
orig = orig->prev;
487487
seccomp_filter_free(freeme);
@@ -641,11 +641,12 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
641641
return 0;
642642

643643
case SECCOMP_RET_KILL:
644-
default: {
645-
siginfo_t info;
644+
default:
646645
audit_seccomp(this_syscall, SIGSYS, action);
647646
/* Dump core only if this is the last remaining thread. */
648647
if (get_nr_threads(current) == 1) {
648+
siginfo_t info;
649+
649650
/* Show the original registers in the dump. */
650651
syscall_rollback(current, task_pt_regs(current));
651652
/* Trigger a manual coredump since do_exit skips it. */
@@ -654,7 +655,6 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
654655
}
655656
do_exit(SIGSYS);
656657
}
657-
}
658658

659659
unreachable();
660660

tools/testing/selftests/seccomp/seccomp_bpf.c

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,6 +1822,23 @@ struct tsync_sibling {
18221822
struct __test_metadata *metadata;
18231823
};
18241824

1825+
/*
1826+
* To avoid joining joined threads (which is not allowed by Bionic),
1827+
* make sure we both successfully join and clear the tid to skip a
1828+
* later join attempt during fixture teardown. Any remaining threads
1829+
* will be directly killed during teardown.
1830+
*/
1831+
#define PTHREAD_JOIN(tid, status) \
1832+
do { \
1833+
int _rc = pthread_join(tid, status); \
1834+
if (_rc) { \
1835+
TH_LOG("pthread_join of tid %u failed: %d\n", \
1836+
(unsigned int)tid, _rc); \
1837+
} else { \
1838+
tid = 0; \
1839+
} \
1840+
} while (0)
1841+
18251842
FIXTURE_DATA(TSYNC) {
18261843
struct sock_fprog root_prog, apply_prog;
18271844
struct tsync_sibling sibling[TSYNC_SIBLINGS];
@@ -1890,14 +1907,14 @@ FIXTURE_TEARDOWN(TSYNC)
18901907

18911908
for ( ; sib < self->sibling_count; ++sib) {
18921909
struct tsync_sibling *s = &self->sibling[sib];
1893-
void *status;
18941910

18951911
if (!s->tid)
18961912
continue;
1897-
if (pthread_kill(s->tid, 0)) {
1898-
pthread_cancel(s->tid);
1899-
pthread_join(s->tid, &status);
1900-
}
1913+
/*
1914+
* If a thread is still running, it may be stuck, so hit
1915+
* it over the head really hard.
1916+
*/
1917+
pthread_kill(s->tid, 9);
19011918
}
19021919
pthread_mutex_destroy(&self->mutex);
19031920
pthread_cond_destroy(&self->cond);
@@ -1987,9 +2004,9 @@ TEST_F(TSYNC, siblings_fail_prctl)
19872004
pthread_mutex_unlock(&self->mutex);
19882005

19892006
/* Ensure diverging sibling failed to call prctl. */
1990-
pthread_join(self->sibling[0].tid, &status);
2007+
PTHREAD_JOIN(self->sibling[0].tid, &status);
19912008
EXPECT_EQ(SIBLING_EXIT_FAILURE, (long)status);
1992-
pthread_join(self->sibling[1].tid, &status);
2009+
PTHREAD_JOIN(self->sibling[1].tid, &status);
19932010
EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
19942011
}
19952012

@@ -2029,9 +2046,9 @@ TEST_F(TSYNC, two_siblings_with_ancestor)
20292046
}
20302047
pthread_mutex_unlock(&self->mutex);
20312048
/* Ensure they are both killed and don't exit cleanly. */
2032-
pthread_join(self->sibling[0].tid, &status);
2049+
PTHREAD_JOIN(self->sibling[0].tid, &status);
20332050
EXPECT_EQ(0x0, (long)status);
2034-
pthread_join(self->sibling[1].tid, &status);
2051+
PTHREAD_JOIN(self->sibling[1].tid, &status);
20352052
EXPECT_EQ(0x0, (long)status);
20362053
}
20372054

@@ -2055,9 +2072,9 @@ TEST_F(TSYNC, two_sibling_want_nnp)
20552072
pthread_mutex_unlock(&self->mutex);
20562073

20572074
/* Ensure they are both upset about lacking nnp. */
2058-
pthread_join(self->sibling[0].tid, &status);
2075+
PTHREAD_JOIN(self->sibling[0].tid, &status);
20592076
EXPECT_EQ(SIBLING_EXIT_NEWPRIVS, (long)status);
2060-
pthread_join(self->sibling[1].tid, &status);
2077+
PTHREAD_JOIN(self->sibling[1].tid, &status);
20612078
EXPECT_EQ(SIBLING_EXIT_NEWPRIVS, (long)status);
20622079
}
20632080

@@ -2095,9 +2112,9 @@ TEST_F(TSYNC, two_siblings_with_no_filter)
20952112
pthread_mutex_unlock(&self->mutex);
20962113

20972114
/* Ensure they are both killed and don't exit cleanly. */
2098-
pthread_join(self->sibling[0].tid, &status);
2115+
PTHREAD_JOIN(self->sibling[0].tid, &status);
20992116
EXPECT_EQ(0x0, (long)status);
2100-
pthread_join(self->sibling[1].tid, &status);
2117+
PTHREAD_JOIN(self->sibling[1].tid, &status);
21012118
EXPECT_EQ(0x0, (long)status);
21022119
}
21032120

@@ -2140,9 +2157,9 @@ TEST_F(TSYNC, two_siblings_with_one_divergence)
21402157
pthread_mutex_unlock(&self->mutex);
21412158

21422159
/* Ensure they are both unkilled. */
2143-
pthread_join(self->sibling[0].tid, &status);
2160+
PTHREAD_JOIN(self->sibling[0].tid, &status);
21442161
EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
2145-
pthread_join(self->sibling[1].tid, &status);
2162+
PTHREAD_JOIN(self->sibling[1].tid, &status);
21462163
EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
21472164
}
21482165

@@ -2199,7 +2216,7 @@ TEST_F(TSYNC, two_siblings_not_under_filter)
21992216
TH_LOG("cond broadcast non-zero");
22002217
}
22012218
pthread_mutex_unlock(&self->mutex);
2202-
pthread_join(self->sibling[sib].tid, &status);
2219+
PTHREAD_JOIN(self->sibling[sib].tid, &status);
22032220
EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
22042221
/* Poll for actual task death. pthread_join doesn't guarantee it. */
22052222
while (!kill(self->sibling[sib].system_tid, 0))
@@ -2224,7 +2241,7 @@ TEST_F(TSYNC, two_siblings_not_under_filter)
22242241
TH_LOG("cond broadcast non-zero");
22252242
}
22262243
pthread_mutex_unlock(&self->mutex);
2227-
pthread_join(self->sibling[sib].tid, &status);
2244+
PTHREAD_JOIN(self->sibling[sib].tid, &status);
22282245
EXPECT_EQ(0, (long)status);
22292246
/* Poll for actual task death. pthread_join doesn't guarantee it. */
22302247
while (!kill(self->sibling[sib].system_tid, 0))

0 commit comments

Comments
 (0)