From 8ad56e8eda4a63e9a81c275e4eb26e9239237ad4 Mon Sep 17 00:00:00 2001
From: gcontini <1121667+gcontini@users.noreply.github.com>
Date: 周六, 28 11月 2020 09:31:41 +0800
Subject: [PATCH] replace strncpy with a more safe alternative

---
 src/library/base/string_utils.cpp |   13 +++++++++++++
 src/library/os/linux/network.cpp  |    2 +-
 src/library/licensecc.cpp         |    5 +++--
 src/library/base/string_utils.h   |    3 +++
 src/library/os/linux/os_linux.cpp |   20 +++++++++++---------
 5 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/src/library/base/string_utils.cpp b/src/library/base/string_utils.cpp
index 74b0458..1736863 100644
--- a/src/library/base/string_utils.cpp
+++ b/src/library/base/string_utils.cpp
@@ -107,4 +107,17 @@
 	return count;
 }
 
+size_t mstrlcpy(char *dst, const char *src, size_t n) {
+	size_t n_orig = n;
+	if (n > 0) {
+		char *pd;
+		const char *ps;
+
+		for (--n, pd = dst, ps = src; n > 0 && *ps != '\0'; --n, ++pd, ++ps) *pd = *ps;
+
+		*pd = '\0';
+	}
+
+	return n_orig - n;
+}
 } /* namespace license */
diff --git a/src/library/base/string_utils.h b/src/library/base/string_utils.h
index 02a679d..a8157a7 100644
--- a/src/library/base/string_utils.h
+++ b/src/library/base/string_utils.h
@@ -33,6 +33,9 @@
 // strnln_s is not well supported and strlen is marked unsafe..
 size_t mstrnlen_s(const char* szptr, size_t maxsize);
 
+// strlcpy is not a standard function but it's the safest way to copy to c strings...
+// let's provide a custom implementation
+size_t mstrlcpy(char* dst, const char* src, size_t n);
 typedef enum {
 	INI, BASE64, UNKNOWN
 } FILE_FORMAT;
diff --git a/src/library/licensecc.cpp b/src/library/licensecc.cpp
index f9807a2..2642811 100644
--- a/src/library/licensecc.cpp
+++ b/src/library/licensecc.cpp
@@ -18,6 +18,7 @@
 #include <licensecc_properties.h>
 
 #include "base/logger.h"
+#include "base/string_utils.h"
 #include "hw_identifier/hw_identifier_facade.hpp"
 #include "os/execution_environment.hpp"
 #include "limits/license_verifier.hpp"
@@ -34,7 +35,7 @@
 	if (*bufSize > LCC_API_PC_IDENTIFIER_SIZE && chbuffer != nullptr) {
 		try {
 			const string pc_id = license::hw_identifier::HwIdentifierFacade::generate_user_pc_signature(pc_id_method);
-			strncpy(chbuffer, pc_id.c_str(), *bufSize);
+			license::mstrlcpy(chbuffer, pc_id.c_str(), *bufSize);
 			result = true;
 		} catch (const std::exception& ex) {
 			LOG_ERROR("Error calculating hw_identifier: %s", ex.what());
@@ -45,8 +46,8 @@
 	} else {
 		*bufSize = LCC_API_PC_IDENTIFIER_SIZE + 1;
 	}
+	static const license::os::ExecutionEnvironment exec_env;
 	if (execution_environment_info != nullptr) {
-		const license::os::ExecutionEnvironment exec_env;
 		execution_environment_info->cloud_provider = exec_env.cloud_provider();
 		execution_environment_info->virtualization = exec_env.virtualization();
 		execution_environment_info->virtualization_detail = exec_env.virtualization_detail();
diff --git a/src/library/os/linux/network.cpp b/src/library/os/linux/network.cpp
index 8720c50..56c7fc8 100644
--- a/src/library/os/linux/network.cpp
+++ b/src/library/os/linux/network.cpp
@@ -67,7 +67,7 @@
 		if (adapterByName.find(if_name) == adapterByName.end()) {
 			OsAdapterInfo newAdapter;
 			memset(&newAdapter, 0, sizeof(OsAdapterInfo));
-			strncpy(&newAdapter.description[0], ifa->ifa_name, LCC_ADAPTER_DESCRIPTION_LEN);
+			mstrlcpy(&newAdapter.description[0], ifa->ifa_name, LCC_ADAPTER_DESCRIPTION_LEN);
 			adapterByName[if_name] = newAdapter;
 		}
 		auto it = adapterByName.find(if_name);
diff --git a/src/library/os/linux/os_linux.cpp b/src/library/os/linux/os_linux.cpp
index 2915808..bbf4341 100644
--- a/src/library/os/linux/os_linux.cpp
+++ b/src/library/os/linux/os_linux.cpp
@@ -12,6 +12,7 @@
 #include <sstream>
 #include "../os.h"
 #include "../../base/logger.h"
+#include "../../base/string_utils.h"
 
 #include <mntent.h>
 #include <dirent.h>
@@ -30,6 +31,8 @@
 #ifdef USE_DBUS
 #include <dbus-1.0/dbus/dbus.h>
 #endif
+
+using namespace license;
 
 /**
  *Usually uuid are hex number separated by "-". this method read up to 8 hex
@@ -104,9 +107,9 @@
 		std::string cur_dev = blkid_file_content.substr(oldpos, pos);
 		diskInfo.id = diskNum++;
 		std::string device = cur_dev.substr(cur_dev.find_last_of(">") + 1);
-		strncpy(diskInfo.device, device.c_str(), MAX_PATH);
+		mstrlcpy(diskInfo.device, device.c_str(), MAX_PATH);
 		std::string label = getAttribute(cur_dev, "PARTLABEL");
-		strncpy(diskInfo.label, label.c_str(), 255);
+		mstrlcpy(diskInfo.label, label.c_str(), 255);
 		std::string disk_sn = getAttribute(cur_dev, "UUID");
 		parseUUID(disk_sn.c_str(), diskInfo.disk_sn, sizeof(diskInfo.disk_sn));
 		std::string disk_type = getAttribute(cur_dev, "TYPE");
@@ -167,7 +170,7 @@
 				bool found = false;
 				for (auto &diskInfo : disk_infos) {
 					if (((int)(sym_stat.st_ino)) == diskInfo.id) {
-						strncpy(diskInfo.label, dir->d_name, 255 - 1);
+						mstrlcpy(diskInfo.label, dir->d_name, 255);
 						diskInfo.label_initialized = true;
 						LOG_DEBUG("Label for disk ino %d device %s, set to %s", sym_stat.st_ino, diskInfo.device,
 								  diskInfo.label);
@@ -214,7 +217,7 @@
 					if (pos != std::string::npos) {
 						device_name_s = device_name_s.substr(pos + 1);
 					}
-					strncpy(tmpDiskInfo.device, device_name_s.c_str(), sizeof(tmpDiskInfo.device));
+					mstrlcpy(tmpDiskInfo.device, device_name_s.c_str(), sizeof(tmpDiskInfo.device));
 					PARSE_ID_FUNC(dir->d_name, tmpDiskInfo.disk_sn, sizeof(tmpDiskInfo.disk_sn));
 					tmpDiskInfo.sn_initialized = true;
 					tmpDiskInfo.label_initialized = false;
@@ -365,12 +368,11 @@
 	strcat(proc_path, "/exe");
 
 	int ch = readlink(proc_path, path, MAX_PATH - 1);
-	if (ch != -1) {
-		path[ch] = '\0';
-		strncpy(buffer, path, ch);
-		result = FUNC_RET_OK;
-	} else {
+	if (ch > MAX_PATH || ch < 0) {
 		result = FUNC_RET_ERROR;
+	} else {
+		mstrlcpy(buffer, path, ch + 1);
+		result = FUNC_RET_OK;
 	}
 	return result;
 }

--
Gitblit v1.9.1