[CRIU] [PATCH 4/5] inet: prevent dumping of sockets if they are not collected
Andrey Vagin
avagin at openvz.org
Wed Mar 27 09:23:16 EDT 2013
If inet sockets are not collected and a dumped task has one, crtools
should return an errror instead of dumping it as unconnected socket.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
include/sockets.h | 3 +++
sk-inet.c | 28 +++++++++++++++++++++++++---
sockets.c | 12 ++++++++++++
3 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/include/sockets.h b/include/sockets.h
index 66726c9..5de94a1 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -27,6 +27,9 @@ struct socket_desc {
};
extern bool netlink_collected;
+extern bool tcp_collected[2];
+extern bool udp_collected[2];
+extern bool udplite_collected[2];
extern int dump_socket(struct fd_parms *p, int lfd, const int fdinfo);
extern int dump_socket_opts(int sk, SkOptsEntry *soe);
diff --git a/sk-inet.c b/sk-inet.c
index 66366ac..0e6bf43 100644
--- a/sk-inet.c
+++ b/sk-inet.c
@@ -23,6 +23,10 @@
#define PB_ALEN_INET 1
#define PB_ALEN_INET6 4
+bool tcp_collected[2];
+bool udp_collected[2];
+bool udplite_collected[2];
+
static LIST_HEAD(inet_ports);
struct inet_port {
@@ -160,7 +164,8 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
return 1;
}
-static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p)
+static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p,
+ unsigned int proto)
{
struct inet_sk_desc *sk;
char address;
@@ -188,10 +193,11 @@ static struct inet_sk_desc *gen_uncon_sk(int lfd, const struct fd_parms *p)
ret = do_dump_opt(lfd, SOL_SOCKET, SO_DOMAIN, &sk->sd.family, sizeof(sk->sd.family));
ret |= do_dump_opt(lfd, SOL_SOCKET, SO_TYPE, &sk->type, sizeof(sk->type));
- ret |= do_dump_opt(lfd, SOL_SOCKET, SO_PROTOCOL, &sk->proto, sizeof(sk->proto));
if (ret)
goto err;
+ sk->proto = proto;
+
if (sk->proto == IPPROTO_TCP) {
struct tcp_info info;
@@ -230,7 +236,23 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
sk = (struct inet_sk_desc *)lookup_socket(p->stat.st_ino, family);
if (!sk) {
- sk = gen_uncon_sk(lfd, p);
+ int proto;
+ bool v6 = (family == AF_INET6);
+
+ ret = do_dump_opt(lfd, SOL_SOCKET, SO_PROTOCOL,
+ &proto, sizeof(proto));
+ if (ret)
+ goto err;
+
+ if ((proto == IPPROTO_TCP && !tcp_collected[v6]) ||
+ (proto == IPPROTO_UDP && !udp_collected[v6]) ||
+ (proto == IPPROTO_UDPLITE && !tcp_collected[v6])) {
+ pr_err("Sockets (family %d proto %d) are not collected\n",
+ family, proto);
+ goto err;
+ }
+
+ sk = gen_uncon_sk(lfd, p, proto);
if (!sk)
goto err;
}
diff --git a/sockets.c b/sockets.c
index 0b992f5..07e9cf0 100644
--- a/sockets.c
+++ b/sockets.c
@@ -463,6 +463,8 @@ int collect_sockets(int pid)
tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
if (tmp)
err = tmp;
+ else
+ tcp_collected[0] = true;
/* Collect IPv4 UDP sockets */
req.r.i.sdiag_family = AF_INET;
@@ -472,6 +474,8 @@ int collect_sockets(int pid)
tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
if (tmp)
err = tmp;
+ else
+ udp_collected[0] = true;
/* Collect IPv4 UDP-lite sockets */
req.r.i.sdiag_family = AF_INET;
@@ -481,6 +485,8 @@ int collect_sockets(int pid)
tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
if (tmp)
err = tmp;
+ else
+ udplite_collected[0] = true;
/* Collect IPv6 TCP sockets */
req.r.i.sdiag_family = AF_INET6;
@@ -491,6 +497,8 @@ int collect_sockets(int pid)
tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
if (tmp)
err = tmp;
+ else
+ tcp_collected[1] = true;
/* Collect IPv6 UDP sockets */
req.r.i.sdiag_family = AF_INET6;
@@ -500,6 +508,8 @@ int collect_sockets(int pid)
tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
if (tmp)
err = tmp;
+ else
+ udp_collected[1] = true;
/* Collect IPv6 UDP-lite sockets */
req.r.i.sdiag_family = AF_INET6;
@@ -509,6 +519,8 @@ int collect_sockets(int pid)
tmp = do_rtnl_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
if (tmp)
err = tmp;
+ else
+ udplite_collected[1] = true;
req.r.p.sdiag_family = AF_PACKET;
req.r.p.sdiag_protocol = 0;
--
1.7.11.7
More information about the CRIU
mailing list