Skip to content

Commit 6b7a036

Browse files
q2vengregkh
authored andcommitted
af_unix: Allocate struct unix_edge for each inflight AF_UNIX fd.
commit 29b64e354029cfcf1eea4d91b146c7b769305930 upstream. As with the previous patch, we preallocate to skb's scm_fp_list an array of struct unix_edge in the number of inflight AF_UNIX fds. There we just preallocate memory and do not use immediately because sendmsg() could fail after this point. The actual use will be in the next patch. When we queue skb with inflight edges, we will set the inflight socket's unix_sock as unix_edge->predecessor and the receiver's unix_sock as successor, and then we will link the edge to the inflight socket's unix_vertex.edges. Note that we set NULL to cloned scm_fp_list.edges in scm_fp_dup() so that MSG_PEEK does not change the shape of the directed graph. Signed-off-by: Kuniyuki Iwashima <[email protected]> Acked-by: Paolo Abeni <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Lee Jones <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 1002e86 commit 6b7a036

File tree

4 files changed

+19
-0
lines changed

4 files changed

+19
-0
lines changed

include/net/af_unix.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ struct unix_vertex {
3333
unsigned long out_degree;
3434
};
3535

36+
struct unix_edge {
37+
struct unix_sock *predecessor;
38+
struct unix_sock *successor;
39+
struct list_head vertex_entry;
40+
};
41+
3642
struct sock *unix_peer_get(struct sock *sk);
3743

3844
#define UNIX_HASH_MOD (256 - 1)

include/net/scm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,17 @@ struct scm_creds {
2121
kgid_t gid;
2222
};
2323

24+
#ifdef CONFIG_UNIX
25+
struct unix_edge;
26+
#endif
27+
2428
struct scm_fp_list {
2529
short count;
2630
short count_unix;
2731
short max;
2832
#ifdef CONFIG_UNIX
2933
struct list_head vertices;
34+
struct unix_edge *edges;
3035
#endif
3136
struct user_struct *user;
3237
struct file *fp[SCM_MAX_FD];

net/core/scm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
9090
fpl->max = SCM_MAX_FD;
9191
fpl->user = NULL;
9292
#if IS_ENABLED(CONFIG_UNIX)
93+
fpl->edges = NULL;
9394
INIT_LIST_HEAD(&fpl->vertices);
9495
#endif
9596
}
@@ -379,6 +380,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
379380
new_fpl->max = new_fpl->count;
380381
new_fpl->user = get_uid(fpl->user);
381382
#if IS_ENABLED(CONFIG_UNIX)
383+
new_fpl->edges = NULL;
382384
INIT_LIST_HEAD(&new_fpl->vertices);
383385
#endif
384386
}

net/unix/garbage.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ int unix_prepare_fpl(struct scm_fp_list *fpl)
127127
list_add(&vertex->entry, &fpl->vertices);
128128
}
129129

130+
fpl->edges = kvmalloc_array(fpl->count_unix, sizeof(*fpl->edges),
131+
GFP_KERNEL_ACCOUNT);
132+
if (!fpl->edges)
133+
goto err;
134+
130135
return 0;
131136

132137
err:
@@ -136,6 +141,7 @@ int unix_prepare_fpl(struct scm_fp_list *fpl)
136141

137142
void unix_destroy_fpl(struct scm_fp_list *fpl)
138143
{
144+
kvfree(fpl->edges);
139145
unix_free_vertices(fpl);
140146
}
141147

0 commit comments

Comments
 (0)