Avoid the leak reported by Serge for sockets that don't get attached to a file. Do this by orphaning the socket on restore if it is marked as SOCK_DEAD. If it is needed later for sending a buffer, temporarily adopt it for that process. Signed-off-by: Dan Smith <danms@xxxxxxxxxx> --- net/checkpoint.c | 13 ++++++++++++- net/unix/checkpoint.c | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletions(-) diff --git a/net/checkpoint.c b/net/checkpoint.c index d22341a..0bfca77 100644 --- a/net/checkpoint.c +++ b/net/checkpoint.c @@ -627,6 +627,7 @@ struct sock *do_sock_restore(struct ckpt_ctx *ctx) { struct ckpt_hdr_socket *h; struct socket *sock; + struct sock *sk; int ret; h = ckpt_read_obj_type(ctx, sizeof(*h), CKPT_HDR_SOCKET); @@ -661,7 +662,14 @@ struct sock *do_sock_restore(struct ckpt_ctx *ctx) ckpt_hdr_put(ctx, h); - return sock->sk; + sk = sock->sk; + if (sock_flag(sk, SOCK_DEAD)) { + sock_orphan(sk); + sock->sk = NULL; + sock_release(sock); + } + + return sk; err: ckpt_hdr_put(ctx, h); sock_release(sock); @@ -688,6 +696,9 @@ struct file *sock_file_restore(struct ckpt_ctx *ctx, struct ckpt_hdr_file *ptr) if (IS_ERR(sk)) return ERR_PTR(PTR_ERR(sk)); + /* We should have a struct socket if we were attached to a file */ + BUG_ON(!sk->sk_socket); + file = sock_alloc_attach_fd(sk->sk_socket); if (IS_ERR(file)) return file; diff --git a/net/unix/checkpoint.c b/net/unix/checkpoint.c index 60f6a0c..da2b408 100644 --- a/net/unix/checkpoint.c +++ b/net/unix/checkpoint.c @@ -180,6 +180,7 @@ static int sock_read_buffer_sendmsg(struct ckpt_ctx *ctx, struct kvec kvec; struct ckpt_hdr_socket_buffer *h; struct sock *sk; + struct socket *sock = NULL; uint8_t sock_shutdown; uint8_t peer_shutdown = 0; void *buf; @@ -229,6 +230,15 @@ static int sock_read_buffer_sendmsg(struct ckpt_ctx *ctx, ckpt_debug("Failed to join: %i\n", ret); goto out; } + } else + + if (!sk->sk_socket) { + ret = sock_create(sk->sk_family, sk->sk_type, 0, &sock); + if (ret < 0) + goto out; + if (unix_sk(sk)->peer) + sock->state = SS_CONNECTED; + sock_graft(sk, sock); } kvec.iov_len = len; @@ -275,6 +285,12 @@ static int sock_read_buffer_sendmsg(struct ckpt_ctx *ctx, ckpt_hdr_put(ctx, h); kfree(buf); + if (sock) { + sock_orphan(sk); + sock->sk = NULL; + sock_release(sock); + } + return ret; } -- 1.6.2.5 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers