[CRIU] [PATCH] service: allocate buffers for messages dinamically (v2)

Andrey Vagin avagin at openvz.org
Fri Apr 17 06:45:46 PDT 2015


Currently we use a static buffer, but it is too small.

Error (cr-service.c:58): Failed unpacking request: Success
Error (cr-service.c:694): Can't recv request: Success
data too short after length-prefix of 1217

v2: use recv instead on recvmsg

Reported-by: Ross Boucher <rboucher at gmail.com>
Cc: Ross Boucher <rboucher at gmail.com>
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-service.c               | 23 +++++++++++++++++------
 include/cr-service-const.h |  1 -
 lib/criu.c                 | 19 +++++++++++++++----
 3 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/cr-service.c b/cr-service.c
index 0f0e2e2..2173376 100644
--- a/cr-service.c
+++ b/cr-service.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
+#include <alloca.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -36,12 +37,20 @@
 
 unsigned int service_sk_ino = -1;
 
-static int recv_criu_msg(int socket_fd, CriuReq **msg)
+static int recv_criu_msg(int socket_fd, CriuReq **req)
 {
-	unsigned char buf[CR_MAX_MSG_SIZE];
+	unsigned char *buf;
 	int len;
 
-	len = read(socket_fd, buf, CR_MAX_MSG_SIZE);
+	len = recv(socket_fd, NULL, 0, MSG_TRUNC | MSG_PEEK);
+	if (len == -1) {
+		pr_perror("Can't read request");
+		return -1;
+	}
+
+	buf = alloca(len);
+
+	len = recv(socket_fd, buf, len, MSG_TRUNC);
 	if (len == -1) {
 		pr_perror("Can't read request");
 		return -1;
@@ -53,8 +62,8 @@ static int recv_criu_msg(int socket_fd, CriuReq **msg)
 		return -1;
 	}
 
-	*msg = criu_req__unpack(NULL, len, buf);
-	if (!*msg) {
+	*req = criu_req__unpack(NULL, len, buf);
+	if (!*req) {
 		pr_perror("Failed unpacking request");
 		return -1;
 	}
@@ -64,11 +73,13 @@ static int recv_criu_msg(int socket_fd, CriuReq **msg)
 
 static int send_criu_msg(int socket_fd, CriuResp *msg)
 {
-	unsigned char buf[CR_MAX_MSG_SIZE];
+	unsigned char *buf;
 	int len;
 
 	len = criu_resp__get_packed_size(msg);
 
+	buf = alloca(len);
+
 	if (criu_resp__pack(msg, buf) != len) {
 		pr_perror("Failed packing response");
 		return -1;
diff --git a/include/cr-service-const.h b/include/cr-service-const.h
index 668882b..b8827f4 100644
--- a/include/cr-service-const.h
+++ b/include/cr-service-const.h
@@ -1,7 +1,6 @@
 #ifndef __CR_SERVICE_CONST_H__
 #define __CR_SERVICE_CONST_H__
 
-#define CR_MAX_MSG_SIZE 1024
 #define CR_DEFAULT_SERVICE_ADDRESS "/var/run/criu_service.socket"
 
 #endif /* __CR_SERVICE_CONST_H__ */
diff --git a/lib/criu.c b/lib/criu.c
index 9308250..ff7e400 100644
--- a/lib/criu.c
+++ b/lib/criu.c
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <signal.h>
+#include <alloca.h>
 
 #include "criu.h"
 #include "rpc.pb-c.h"
@@ -311,13 +312,21 @@ er:
 
 static CriuResp *recv_resp(int socket_fd)
 {
-	unsigned char buf[CR_MAX_MSG_SIZE];
+	unsigned char *buf;
 	int len;
 	CriuResp *msg = 0;
 
-	len = read(socket_fd, buf, CR_MAX_MSG_SIZE);
+	len = recv(socket_fd, NULL, 0, MSG_TRUNC | MSG_PEEK);
 	if (len == -1) {
-		perror("Can't read response");
+		perror("Can't read request");
+		goto err;
+	}
+
+	buf = alloca(len);
+
+	len = recv(socket_fd, buf, len, MSG_TRUNC);
+	if (len == -1) {
+		perror("Can't read request");
 		goto err;
 	}
 
@@ -335,11 +344,13 @@ err:
 
 static int send_req(int socket_fd, CriuReq *req)
 {
-	unsigned char buf[CR_MAX_MSG_SIZE];
+	unsigned char *buf;
 	int len;
 
 	len = criu_req__get_packed_size(req);
 
+	buf = alloca(len);
+
 	if (criu_req__pack(req, buf) != len) {
 		perror("Failed packing request");
 		goto err;
-- 
2.1.0



More information about the CRIU mailing list