[lxc-devel] [lxc/master] confile: handle overflow in lxc.time.offset.{boot, monotonic}

brauner on Github lxc-bot at linuxcontainers.org
Fri Jun 26 08:09:13 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200626/dc6ae117/attachment.bin>
-------------- next part --------------
From 07f89c1e0e0718971e56189a71caafb35b046cab Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 26 Jun 2020 10:08:32 +0200
Subject: [PATCH] confile: handle overflow in lxc.time.offset.{boot,monotonic}

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/confile.c | 56 +++++++++++++++++++++++++++--------------------
 src/lxc/utils.c   | 12 ++++++++++
 src/lxc/utils.h   |  2 ++
 3 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index c92e19820d..75587d0ac8 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -2831,22 +2831,26 @@ static int set_config_time_offset_boot(const char *key, const char *value,
 	if (ret)
 		return ret;
 
-	/* TODO: Handle overflow. */
 	unit = lxc_trim_whitespace_in_place(buf);
-	if (strcmp(unit, "h") == 0)
-		lxc_conf->timens.s_boot = offset * 3600;
-	else if (strcmp(unit, "m") == 0)
-		lxc_conf->timens.s_boot = offset * 60;
-	else if (strcmp(unit, "s") == 0)
+	if (strcmp(unit, "h") == 0) {
+		if (!multiply_overflow(offset, 3600, &lxc_conf->timens.s_boot))
+			return -EOVERFLOW;
+	} else if (strcmp(unit, "m") == 0) {
+		if (!multiply_overflow(offset, 60, &lxc_conf->timens.s_boot))
+			return -EOVERFLOW;
+	} else if (strcmp(unit, "s") == 0) {
 		lxc_conf->timens.s_boot = offset;
-	else if (strcmp(unit, "ms") == 0)
-		lxc_conf->timens.ns_boot = offset * 1000000;
-	else if (strcmp(unit, "us") == 0)
-		lxc_conf->timens.ns_boot = offset * 1000;
-	else if (strcmp(unit, "ns") == 0)
+	} else if (strcmp(unit, "ms") == 0) {
+		if (!multiply_overflow(offset, 1000000, &lxc_conf->timens.ns_boot))
+			return -EOVERFLOW;
+	} else if (strcmp(unit, "us") == 0) {
+		if (!multiply_overflow(offset, 1000, &lxc_conf->timens.ns_boot))
+			return -EOVERFLOW;
+	} else if (strcmp(unit, "ns") == 0) {
 		lxc_conf->timens.ns_boot = offset;
-	else
+	} else {
 		return ret_errno(EINVAL);
+	}
 
 	return 0;
 }
@@ -2866,22 +2870,26 @@ static int set_config_time_offset_monotonic(const char *key, const char *value,
 	if (ret)
 		return ret;
 
-	// TODO: Handle overflow.
 	unit = lxc_trim_whitespace_in_place(buf);
-	if (strcmp(unit, "h") == 0)
-		lxc_conf->timens.s_monotonic = offset * 3600;
-	else if (strcmp(unit, "m") == 0)
-		lxc_conf->timens.s_monotonic = offset * 60;
-	else if (strcmp(unit, "s") == 0)
+	if (strcmp(unit, "h") == 0) {
+		if (!multiply_overflow(offset, 3600, &lxc_conf->timens.s_monotonic))
+			return -EOVERFLOW;
+	} else if (strcmp(unit, "m") == 0) {
+		if (!multiply_overflow(offset, 60, &lxc_conf->timens.s_monotonic))
+			return -EOVERFLOW;
+	} else if (strcmp(unit, "s") == 0) {
 		lxc_conf->timens.s_monotonic = offset;
-	else if (strcmp(unit, "ms") == 0)
-		lxc_conf->timens.ns_monotonic = offset * 1000000;
-	else if (strcmp(unit, "us") == 0)
-		lxc_conf->timens.ns_monotonic = offset * 1000;
-	else if (strcmp(unit, "ns") == 0)
+	} else if (strcmp(unit, "ms") == 0) {
+		if (!multiply_overflow(offset, 1000000, &lxc_conf->timens.ns_monotonic))
+			return -EOVERFLOW;
+	} else if (strcmp(unit, "us") == 0) {
+		if (!multiply_overflow(offset, 1000, &lxc_conf->timens.ns_monotonic))
+			return -EOVERFLOW;
+	} else if (strcmp(unit, "ns") == 0) {
 		lxc_conf->timens.ns_monotonic = offset;
-	else
+	} else {
 		return ret_errno(EINVAL);
+	}
 
 	return 0;
 }
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 88d0f85ee5..cb7ca1d887 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -1904,3 +1904,15 @@ int fix_stdio_permissions(uid_t uid)
 
 	return fret;
 }
+
+bool multiply_overflow(int64_t base, uint64_t mult, int64_t *res)
+{
+	if (base > 0 && base > (INT64_MAX / mult))
+		return false;
+
+	if (base < 0 && base < (INT64_MIN / mult))
+		return false;
+
+	*res = base * mult;
+	return true;
+}
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index cf2c04251b..8c0e0c4aa5 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -251,4 +251,6 @@ static inline bool gid_valid(gid_t gid)
 	return gid != LXC_INVALID_GID;
 }
 
+extern bool multiply_overflow(int64_t base, uint64_t mult, int64_t *res);
+
 #endif /* __LXC_UTILS_H */


More information about the lxc-devel mailing list