Mesa (staging/19.3): radv: Close all unnecessary fds in secure compile.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Nov 5 17:18:21 UTC 2019


Module: Mesa
Branch: staging/19.3
Commit: 4d21f802b56af984f2f2bfa9e40b84da550662b7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4d21f802b56af984f2f2bfa9e40b84da550662b7

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Fri Nov  1 01:07:02 2019 +0100

radv: Close all unnecessary fds in secure compile.

The seccomp filter allows read/write, let us make sure nobody can
do anything with this.

Fixes: cff53da3748 "radv: enable secure compile support"
Reviewed-by: Timothy Arceri <tarceri at itsqueeze.com>
(cherry picked from commit 8efb8f55a617bebe5f33b9745cc22a2490828db8)

---

 src/amd/vulkan/radv_device.c | 93 ++++++++++++++++++++++++++++++--------------
 1 file changed, 64 insertions(+), 29 deletions(-)

diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index fef5cab6ff2..e35c3e43d83 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -25,6 +25,7 @@
  * IN THE SOFTWARE.
  */
 
+#include "dirent.h"
 #include <errno.h>
 #include <fcntl.h>
 #include <linux/audit.h>
@@ -2066,25 +2067,61 @@ bool radv_sc_read(int fd, void *buf, size_t size, bool timeout)
 	}
 }
 
+static bool radv_close_all_fds(const int *keep_fds, int keep_fd_count)
+{
+	DIR *d;
+	struct dirent *dir;
+	d = opendir("/proc/self/fd");
+	if (!d)
+		return false;
+	int dir_fd = dirfd(d);
+
+	while ((dir = readdir(d)) != NULL) {
+		if (dir->d_name[0] == '.')
+			continue;
+
+		int fd = atoi(dir->d_name);
+		if (fd == dir_fd)
+			continue;
+
+		bool keep = false;
+		for (int i = 0; !keep && i < keep_fd_count; ++i)
+			if (keep_fds[i] == fd)
+				keep = true;
+
+		if (keep)
+			continue;
+
+		close(fd);
+	}
+	closedir(d);
+	return true;
+}
+
 static void run_secure_compile_device(struct radv_device *device, unsigned process,
-				      int *fd_secure_input, int *fd_secure_output)
+				      int fd_secure_input, int fd_secure_output)
 {
 	enum radv_secure_compile_type sc_type;
-	if (install_seccomp_filter() == -1) {
+
+	const int needed_fds[] = {
+		fd_secure_input,
+		fd_secure_output,
+	};
+	if (!radv_close_all_fds(needed_fds, ARRAY_SIZE(needed_fds)) || install_seccomp_filter() == -1) {
 		sc_type = RADV_SC_TYPE_INIT_FAILURE;
 	} else {
 		sc_type = RADV_SC_TYPE_INIT_SUCCESS;
-		device->sc_state->secure_compile_processes[process].fd_secure_input = fd_secure_input[0];
-		device->sc_state->secure_compile_processes[process].fd_secure_output = fd_secure_output[1];
+		device->sc_state->secure_compile_processes[process].fd_secure_input = fd_secure_input;
+		device->sc_state->secure_compile_processes[process].fd_secure_output = fd_secure_output;
 	}
 
-	write(fd_secure_output[1], &sc_type, sizeof(sc_type));
+	write(fd_secure_output, &sc_type, sizeof(sc_type));
 
 	if (sc_type == RADV_SC_TYPE_INIT_FAILURE)
 		goto secure_compile_exit;
 
 	while (true) {
-		radv_sc_read(fd_secure_input[0], &sc_type, sizeof(sc_type), false);
+		radv_sc_read(fd_secure_input, &sc_type, sizeof(sc_type), false);
 
 		if (sc_type == RADV_SC_TYPE_COMPILE_PIPELINE) {
 			struct radv_pipeline *pipeline;
@@ -2097,20 +2134,20 @@ static void run_secure_compile_device(struct radv_device *device, unsigned proce
 
 			/* Read pipeline layout */
 			struct radv_pipeline_layout layout;
-			sc_read = radv_sc_read(fd_secure_input[0], &layout, sizeof(struct radv_pipeline_layout), true);
-			sc_read &= radv_sc_read(fd_secure_input[0], &layout.num_sets, sizeof(uint32_t), true);
+			sc_read = radv_sc_read(fd_secure_input, &layout, sizeof(struct radv_pipeline_layout), true);
+			sc_read &= radv_sc_read(fd_secure_input, &layout.num_sets, sizeof(uint32_t), true);
 			if (!sc_read)
 				goto secure_compile_exit;
 
 			for (uint32_t set = 0; set < layout.num_sets; set++) {
 				uint32_t layout_size;
-				sc_read &= radv_sc_read(fd_secure_input[0], &layout_size, sizeof(uint32_t), true);
+				sc_read &= radv_sc_read(fd_secure_input, &layout_size, sizeof(uint32_t), true);
 				if (!sc_read)
 					goto secure_compile_exit;
 
 				layout.set[set].layout = malloc(layout_size);
 				layout.set[set].layout->layout_size = layout_size;
-				sc_read &= radv_sc_read(fd_secure_input[0], layout.set[set].layout,
+				sc_read &= radv_sc_read(fd_secure_input, layout.set[set].layout,
 							layout.set[set].layout->layout_size, true);
 			}
 
@@ -2118,16 +2155,16 @@ static void run_secure_compile_device(struct radv_device *device, unsigned proce
 
 			/* Read pipeline key */
 			struct radv_pipeline_key key;
-			sc_read &= radv_sc_read(fd_secure_input[0], &key, sizeof(struct radv_pipeline_key), true);
+			sc_read &= radv_sc_read(fd_secure_input, &key, sizeof(struct radv_pipeline_key), true);
 
 			/* Read pipeline create flags */
 			VkPipelineCreateFlags flags;
-			sc_read &= radv_sc_read(fd_secure_input[0], &flags, sizeof(VkPipelineCreateFlags), true);
+			sc_read &= radv_sc_read(fd_secure_input, &flags, sizeof(VkPipelineCreateFlags), true);
 
 			/* Read stage and shader information */
 			uint32_t num_stages;
 			const VkPipelineShaderStageCreateInfo *pStages[MESA_SHADER_STAGES] = { 0, };
-			sc_read &= radv_sc_read(fd_secure_input[0], &num_stages, sizeof(uint32_t), true);
+			sc_read &= radv_sc_read(fd_secure_input, &num_stages, sizeof(uint32_t), true);
 			if (!sc_read)
 				goto secure_compile_exit;
 
@@ -2135,33 +2172,33 @@ static void run_secure_compile_device(struct radv_device *device, unsigned proce
 
 				/* Read stage */
 				gl_shader_stage stage;
-				sc_read &= radv_sc_read(fd_secure_input[0], &stage, sizeof(gl_shader_stage), true);
+				sc_read &= radv_sc_read(fd_secure_input, &stage, sizeof(gl_shader_stage), true);
 
 				VkPipelineShaderStageCreateInfo *pStage = calloc(1, sizeof(VkPipelineShaderStageCreateInfo));
 
 				/* Read entry point name */
 				size_t name_size;
-				sc_read &= radv_sc_read(fd_secure_input[0], &name_size, sizeof(size_t), true);
+				sc_read &= radv_sc_read(fd_secure_input, &name_size, sizeof(size_t), true);
 				if (!sc_read)
 					goto secure_compile_exit;
 
 				char *ep_name = malloc(name_size);
-				sc_read &= radv_sc_read(fd_secure_input[0], ep_name, name_size, true);
+				sc_read &= radv_sc_read(fd_secure_input, ep_name, name_size, true);
 				pStage->pName = ep_name;
 
 				/* Read shader module */
 				size_t module_size;
-				sc_read &= radv_sc_read(fd_secure_input[0], &module_size, sizeof(size_t), true);
+				sc_read &= radv_sc_read(fd_secure_input, &module_size, sizeof(size_t), true);
 				if (!sc_read)
 					goto secure_compile_exit;
 
 				struct radv_shader_module *module = malloc(module_size);
-				sc_read &= radv_sc_read(fd_secure_input[0], module, module_size, true);
+				sc_read &= radv_sc_read(fd_secure_input, module, module_size, true);
 				pStage->module = radv_shader_module_to_handle(module);
 
 				/* Read specialization info */
 				bool has_spec_info;
-				sc_read &= radv_sc_read(fd_secure_input[0], &has_spec_info, sizeof(bool), true);
+				sc_read &= radv_sc_read(fd_secure_input, &has_spec_info, sizeof(bool), true);
 				if (!sc_read)
 					goto secure_compile_exit;
 
@@ -2169,21 +2206,21 @@ static void run_secure_compile_device(struct radv_device *device, unsigned proce
 					VkSpecializationInfo *specInfo = malloc(sizeof(VkSpecializationInfo));
 					pStage->pSpecializationInfo = specInfo;
 
-					sc_read &= radv_sc_read(fd_secure_input[0], &specInfo->dataSize, sizeof(size_t), true);
+					sc_read &= radv_sc_read(fd_secure_input, &specInfo->dataSize, sizeof(size_t), true);
 					if (!sc_read)
 						goto secure_compile_exit;
 
 					void *si_data = malloc(specInfo->dataSize);
-					sc_read &= radv_sc_read(fd_secure_input[0], si_data, specInfo->dataSize, true);
+					sc_read &= radv_sc_read(fd_secure_input, si_data, specInfo->dataSize, true);
 					specInfo->pData = si_data;
 
-					sc_read &= radv_sc_read(fd_secure_input[0], &specInfo->mapEntryCount, sizeof(uint32_t), true);
+					sc_read &= radv_sc_read(fd_secure_input, &specInfo->mapEntryCount, sizeof(uint32_t), true);
 					if (!sc_read)
 						goto secure_compile_exit;
 
 					VkSpecializationMapEntry *mapEntries = malloc(sizeof(VkSpecializationMapEntry) * specInfo->mapEntryCount);
 					for (uint32_t j = 0; j < specInfo->mapEntryCount; j++) {
-						sc_read &= radv_sc_read(fd_secure_input[0], &mapEntries[j], sizeof(VkSpecializationMapEntry), true);
+						sc_read &= radv_sc_read(fd_secure_input, &mapEntries[j], sizeof(VkSpecializationMapEntry), true);
 						if (!sc_read)
 							goto secure_compile_exit;
 					}
@@ -2219,7 +2256,7 @@ static void run_secure_compile_device(struct radv_device *device, unsigned proce
 			vk_free(&device->alloc, pipeline);
 
 			sc_type = RADV_SC_TYPE_COMPILE_PIPELINE_FINISHED;
-			write(fd_secure_output[1], &sc_type, sizeof(sc_type));
+			write(fd_secure_output, &sc_type, sizeof(sc_type));
 
 		} else if (sc_type == RADV_SC_TYPE_DESTROY_DEVICE) {
 			goto secure_compile_exit;
@@ -2227,10 +2264,8 @@ static void run_secure_compile_device(struct radv_device *device, unsigned proce
 	}
 
 secure_compile_exit:
-	close(fd_secure_input[1]);
-	close(fd_secure_input[0]);
-	close(fd_secure_output[1]);
-	close(fd_secure_output[0]);
+	close(fd_secure_input);
+	close(fd_secure_output);
 	_exit(0);
 }
 
@@ -2275,7 +2310,7 @@ static VkResult fork_secure_compile_device(struct radv_device *device)
 	for (unsigned process = 0; process < sc_threads; process++) {
 		if ((device->sc_state->secure_compile_processes[process].sc_pid = fork()) == 0) {
 			device->sc_state->secure_compile_thread_counter = process;
-			run_secure_compile_device(device, process, fd_secure_input[process], fd_secure_output[process]);
+			run_secure_compile_device(device, process, fd_secure_input[process][0], fd_secure_output[process][1]);
 		} else {
 			if (device->sc_state->secure_compile_processes[process].sc_pid == -1)
 				return VK_ERROR_INITIALIZATION_FAILED;




More information about the mesa-commit mailing list