mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
Merge branch 'af_unix-fix-inconsistent-scc_index'
Kuniyuki Iwashima says: ==================== af_unix: Fix inconsistent scc_index. James Burton reported that a single SCC could have multiple scc_index and unix_vertex_dead() fails to detect a dead SCC. Patch 1 fixes it and Patch 2 adds a test case. ==================== Link: https://patch.msgid.link/20260912030852.1467872-1-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
433cfc3025
|
|
@ -374,7 +374,7 @@ static bool unix_vertex_dead(struct unix_vertex *vertex)
|
|||
static LIST_HEAD(unix_visited_vertices);
|
||||
static unsigned long unix_vertex_grouped_index = UNIX_VERTEX_INDEX_MARK2;
|
||||
|
||||
static bool unix_scc_dead(struct list_head *scc, bool fast)
|
||||
static bool unix_scc_dead(struct list_head *scc)
|
||||
{
|
||||
struct unix_vertex *vertex;
|
||||
bool scc_dead = true;
|
||||
|
|
@ -386,10 +386,6 @@ static bool unix_scc_dead(struct list_head *scc, bool fast)
|
|||
/* Don't restart DFS from this vertex. */
|
||||
list_move_tail(&vertex->entry, &unix_visited_vertices);
|
||||
|
||||
/* Mark vertex as off-stack for __unix_walk_scc(). */
|
||||
if (!fast)
|
||||
vertex->index = unix_vertex_grouped_index;
|
||||
|
||||
if (scc_dead)
|
||||
scc_dead = unix_vertex_dead(vertex);
|
||||
}
|
||||
|
|
@ -521,6 +517,7 @@ static unsigned long __unix_walk_scc(struct unix_vertex *vertex,
|
|||
}
|
||||
|
||||
if (vertex->index == vertex->scc_index) {
|
||||
struct unix_vertex *v;
|
||||
struct list_head scc;
|
||||
|
||||
/* SCC finalised.
|
||||
|
|
@ -530,7 +527,13 @@ static unsigned long __unix_walk_scc(struct unix_vertex *vertex,
|
|||
*/
|
||||
__list_cut_position(&scc, &vertex_stack, &vertex->scc_entry);
|
||||
|
||||
if (unix_scc_dead(&scc, false)) {
|
||||
list_for_each_entry_reverse(v, &scc, scc_entry) {
|
||||
/* Mark vertex as off-stack and assign a unique ID. */
|
||||
v->index = unix_vertex_grouped_index;
|
||||
v->scc_index = vertex->scc_index;
|
||||
}
|
||||
|
||||
if (unix_scc_dead(&scc)) {
|
||||
unix_collect_skb(&scc, hitlist);
|
||||
} else {
|
||||
if (unix_vertex_max_scc_index < vertex->scc_index)
|
||||
|
|
@ -588,7 +591,7 @@ static void unix_walk_scc_fast(struct sk_buff_head *hitlist)
|
|||
vertex = list_first_entry(&unix_unvisited_vertices, typeof(*vertex), entry);
|
||||
list_add(&scc, &vertex->scc_entry);
|
||||
|
||||
if (unix_scc_dead(&scc, true)) {
|
||||
if (unix_scc_dead(&scc)) {
|
||||
cyclic_sccs--;
|
||||
unix_collect_skb(&scc, hitlist);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,4 +378,21 @@ TEST_F(scm_rights, backtrack_from_scc)
|
|||
close_sockets(10);
|
||||
}
|
||||
|
||||
TEST_F(scm_rights, mixed_lowpoint)
|
||||
{
|
||||
create_sockets(6);
|
||||
|
||||
send_fd(0, 1);
|
||||
send_fd(1, 2);
|
||||
send_fd(2, 1);
|
||||
send_fd(1, 0);
|
||||
|
||||
send_fd(3, 4);
|
||||
send_fd(4, 5);
|
||||
send_fd(5, 4);
|
||||
send_fd(4, 3);
|
||||
|
||||
close_sockets(6);
|
||||
}
|
||||
|
||||
TEST_HARNESS_MAIN
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user