[CRIU] [PATCH 6/8] rpc: Introduce CLI's --action-script analogue

Pavel Emelyanov xemul at parallels.com
Tue Jan 28 10:36:53 PST 2014


Service shouldn't call client provided scripts, as it
creates a security issue (client may be unpriviledged,
while the service is).

In order to let caller do what it would normally do with
criu-scripts, make criu notify it about scripts. Caller
then do whatever it needs and responds back.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 cr-service.c         | 41 +++++++++++++++++++++++++++++++++++++++++
 include/cr-service.h |  1 +
 include/cr_options.h |  3 +++
 protobuf/rpc.proto   | 10 ++++++++++
 util.c               | 10 ++++++++--
 5 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/cr-service.c b/cr-service.c
index 6c876ed..8bfefa4 100644
--- a/cr-service.c
+++ b/cr-service.c
@@ -113,6 +113,35 @@ int send_criu_restore_resp(int socket_fd, bool success, int pid)
 	return send_criu_msg(socket_fd, &msg);
 }
 
+int send_criu_rpc_script(char *script, int fd)
+{
+	int ret;
+	CriuResp msg = CRIU_RESP__INIT;
+	CriuReq *req;
+	CriuNotify cn = CRIU_NOTIFY__INIT;
+
+	msg.type = CRIU_REQ_TYPE__NOTIFY;
+	msg.success = true;
+	msg.notify = &cn;
+	cn.script = script;
+
+	ret = send_criu_msg(fd, &msg);
+	if (ret < 0)
+		return ret;
+
+	ret = recv_criu_msg(fd, &req);
+	if (ret < 0)
+		return ret;
+
+	if (req->type != CRIU_REQ_TYPE__NOTIFY || !req->notify_success) {
+		pr_err("RPC client reported script error\n");
+		return -1;
+	}
+
+	criu_req__free_unpacked(req, NULL);
+	return 0;
+}
+
 static int setup_opts_from_req(int sk, CriuOpts *req)
 {
 	struct ucred ids;
@@ -197,6 +226,18 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
 		opts.ps_port = htons((short)req->ps->port);
 	}
 
+	if (req->notify_scripts) {
+		struct script *script;
+
+		script = xmalloc(sizeof(struct script));
+		if (script == NULL)
+			return -1;
+
+		script->path = SCRIPT_RPC_NOTIFY;
+		script->arg = sk;
+		list_add(&script->node, &opts.scripts);
+	}
+
 	return 0;
 }
 
diff --git a/include/cr-service.h b/include/cr-service.h
index e9e8255..fa048de 100644
--- a/include/cr-service.h
+++ b/include/cr-service.h
@@ -6,6 +6,7 @@
 extern int cr_service(bool deamon_mode);
 
 extern int send_criu_dump_resp(int socket_fd, bool success, bool restored);
+extern int send_criu_rpc_script(char *name, int arg);
 
 extern struct _cr_service_client *cr_service_client;
 extern unsigned int service_sk_ino;
diff --git a/include/cr_options.h b/include/cr_options.h
index ef69f9c..c61b9ce 100644
--- a/include/cr_options.h
+++ b/include/cr_options.h
@@ -8,8 +8,11 @@
 struct script {
 	struct list_head node;
 	char *path;
+	int arg;
 };
 
+#define SCRIPT_RPC_NOTIFY	(char *)0x1
+
 struct cr_options {
 	int			final_state;
 	char			*show_dump_file;
diff --git a/protobuf/rpc.proto b/protobuf/rpc.proto
index a6d2cb3..3bdc8e4 100644
--- a/protobuf/rpc.proto
+++ b/protobuf/rpc.proto
@@ -19,6 +19,8 @@ message criu_opts {
 
 	optional criu_page_server_info ps = 11;
 
+	optional bool notify_scripts	= 12;
+
 	optional string root		= 13;
 	optional string parent_img	= 14;
 	optional bool track_mem		= 15;
@@ -32,6 +34,10 @@ message criu_restore_resp {
 	required int32 pid		= 1;
 }
 
+message criu_notify {
+	optional string script		= 1;
+}
+
 enum criu_req_type {
 	EMPTY		= 0;
 	DUMP		= 1;
@@ -39,6 +45,8 @@ enum criu_req_type {
 	CHECK		= 3;
 	PRE_DUMP	= 4;
 	PAGE_SERVER	= 5;
+
+	NOTIFY		= 6;
 }
 
 /*
@@ -50,6 +58,7 @@ message criu_req {
 	required criu_req_type type	= 1;
 
 	optional criu_opts opts	= 2;
+	optional bool notify_success = 3;
 }
 
 /*
@@ -63,5 +72,6 @@ message criu_resp {
 
 	optional criu_dump_resp	dump	= 3;
 	optional criu_restore_resp restore = 4;
+	optional criu_notify notify = 5;
 	optional criu_page_server_info ps = 6;
 }
diff --git a/util.c b/util.c
index 314cd63..2cf29e4 100644
--- a/util.c
+++ b/util.c
@@ -41,6 +41,7 @@
 
 #include "cr_options.h"
 #include "servicefd.h"
+#include "cr-service.h"
 
 #define VMA_OPT_LEN	128
 
@@ -467,8 +468,13 @@ int run_scripts(char *action)
 	}
 
 	list_for_each_entry(script, &opts.scripts, node) {
-		pr_debug("\t[%s]\n", script->path);
-		ret |= system(script->path);
+		if (script->path == SCRIPT_RPC_NOTIFY) {
+			pr_debug("\tRPC\n");
+			ret |= send_criu_rpc_script(action, script->arg);
+		} else {
+			pr_debug("\t[%s]\n", script->path);
+			ret |= system(script->path);
+		}
 	}
 
 	unsetenv("CRTOOLS_SCRIPT_ACTION");
-- 
1.8.4.2


More information about the CRIU mailing list