aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-core/swupd-server/swupd-server-2.53/0002-Add-system_argv-helper-for-safer-calls-to-system-uti.patch
blob: f0a645a984a886f3dac84f0774e205f1cae3d724 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
From a32179878e8e439948a4a6385515a0aea7a61592 Mon Sep 17 00:00:00 2001
From: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
Date: Fri, 29 Jan 2016 17:48:46 +0200
Subject: [PATCH] Add system_argv() helper for safer calls to system utilities

Often file names contain special characters like hashes or
whitespaces and that makes escaping a difficult task when using
system(). Thus add a new helper system_argv() that is based
on execvp() syscall and doesn't require escaping.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>

Upstream-Status: Backport [v2.54+]

---
 include/swupd.h |  1 +
 src/fullfiles.c |  6 ++----
 src/helpers.c   | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/include/swupd.h b/include/swupd.h
index 522ac2e..ad4b967 100644
--- a/include/swupd.h
+++ b/include/swupd.h
@@ -228,6 +228,7 @@ extern FILE * fopen_exclusive(const char *filename); /* no mode, opens for write
 extern void dump_file_info(struct file *file);
 extern void string_or_die(char **strp, const char *fmt, ...);
 extern void print_elapsed_time(struct timeval *previous_time, struct timeval *current_time);
+extern int system_argv(char *const argv[]);

 extern bool signature_initialize(void);
 extern void signature_terminate(void);
diff --git a/src/fullfiles.c b/src/fullfiles.c
index 1bb581e..fa78293 100644
--- a/src/fullfiles.c
+++ b/src/fullfiles.c
@@ -138,12 +138,10 @@ static void create_fullfile(struct file *file)
 		string_or_die(&tempfile, "%s/%s", empty, file->hash);
 		if (link(origin, tempfile) < 0) {
 			LOG(NULL, "hardlink failed", "%s due to %s (%s -> %s)", file->filename, strerror(errno), origin, tempfile);
-			string_or_die(&tarcommand, "cp -a %s %s", origin, tempfile);
-			if (system(tarcommand) != 0) {
-				LOG(NULL, "Failed to run command:", "%s", tarcommand);
+			char *const argv[] = {"cp", "-a", origin, tempfile, NULL};
+			if (system_argv(argv) != 0) {
 				assert(0);
 			}
-			free(tarcommand);
 		}

 		/* step 2a: tar it with each compression type  */
diff --git a/src/helpers.c b/src/helpers.c
index 65acffd..5884b51 100644
--- a/src/helpers.c
+++ b/src/helpers.c
@@ -29,6 +29,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
+#include <sys/wait.h>
 #include <fcntl.h>
 #include <errno.h>

@@ -124,3 +125,65 @@ void print_elapsed_time(struct timeval *previous_time, struct timeval *current_t

 	free(elapsed);
 }
+
+void concat_str_array(char **output, char *const argv[])
+{
+	int size = 0;
+
+	for (int i = 0; argv[i]; i++) {
+		size += strlen(argv[i]) + 1;
+	}
+
+	*output = malloc(size + 1);
+	if (!*output) {
+		LOG(NULL, "Failed to allocate", "%i bytes", size);
+		assert(0);
+	}
+	strcpy(*output, "");
+	for (int i = 0; argv[i]; i++) {
+		strcat(*output, argv[i]);
+		strcat(*output, " ");
+	}
+}
+
+int system_argv(char *const argv[])
+{
+	int child_exit_status;
+	pid_t pid;
+	int status;
+
+	pid = fork();
+
+	if (pid == 0) { /* child */
+		execvp(*argv, argv);
+		LOG(NULL, "This line must not be reached", "");
+		assert(0);
+	} else if (pid < 0) {
+		LOG(NULL, "Failed to fork a child process", "");
+		assert(0);
+	} else {
+		pid_t ws = waitpid(pid, &child_exit_status, 0);
+
+		if (ws == -1) {
+			LOG(NULL, "Failed to wait for child process", "");
+			assert(0);
+		}
+
+		if (WIFEXITED(child_exit_status)) {
+			status = WEXITSTATUS(child_exit_status);
+		} else {
+			LOG(NULL, "Child process didn't exit", "");
+			assert(0);
+		}
+
+		if (status != 0) {
+			char* cmdline = NULL;
+
+			concat_str_array(&cmdline, argv);
+			LOG(NULL, "Failed to run command:", "%s", cmdline);
+			free(cmdline);
+		}
+
+		return status;
+	}
+}
--
2.5.0