diff mbox series

[v3,2/3] libselinux: avoid dynamic allocation in openattr()

Message ID 20241120123412.50088-1-cgoettsche@seltendoof.de (mailing list archive)
State New
Headers show
Series None | expand

Commit Message

Christian Göttsche Nov. 20, 2024, 12:34 p.m. UTC
From: Christian Göttsche <cgzones@googlemail.com>

openattr() supplies the simplementation for the getcon(3) interface
family.  Use a short local buffer instead of descend into memory
allocation.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
v3:
  - use sizeof(uint32_t) instead of magic number
v2:
  - minimize buffer from 56 to 44 characters and assert pid_t is not
    wider than 32bit
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 libselinux/src/procattr.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)
diff mbox series

Patch

diff --git a/libselinux/src/procattr.c b/libselinux/src/procattr.c
index ddcc7f8d..aa16c934 100644
--- a/libselinux/src/procattr.c
+++ b/libselinux/src/procattr.c
@@ -1,9 +1,11 @@ 
+#include <assert.h>
 #include <sys/syscall.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <pthread.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <errno.h>
 #include "selinux_internal.h"
@@ -86,32 +88,34 @@  static void init_procattr(void)
 static int openattr(pid_t pid, const char *attr, int flags)
 {
 	int fd, rc;
-	char *path;
+	char path[44];  /* must hold "/proc/self/task/%d/attr/sockcreate" */
 	pid_t tid;
 
+	static_assert(sizeof(pid_t) <= sizeof(uint32_t), "content written to path might get truncated");
+
 	if (pid > 0) {
-		rc = asprintf(&path, "/proc/%d/attr/%s", pid, attr);
+		rc = snprintf(path, sizeof(path), "/proc/%d/attr/%s", pid, attr);
 	} else if (pid == 0) {
-		rc = asprintf(&path, "/proc/thread-self/attr/%s", attr);
-		if (rc < 0)
+		rc = snprintf(path, sizeof(path), "/proc/thread-self/attr/%s", attr);
+		if (rc < 0 || (size_t)rc >= sizeof(path)) {
+			errno = EOVERFLOW;
 			return -1;
+		}
 		fd = open(path, flags | O_CLOEXEC);
 		if (fd >= 0 || errno != ENOENT)
-			goto out;
-		free(path);
+			return fd;
 		tid = selinux_gettid();
-		rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr);
+		rc = snprintf(path, sizeof(path), "/proc/self/task/%d/attr/%s", tid, attr);
 	} else {
 		errno = EINVAL;
 		return -1;
 	}
-	if (rc < 0)
+	if (rc < 0 || (size_t)rc >= sizeof(path)) {
+		errno = EOVERFLOW;
 		return -1;
+	}
 
-	fd = open(path, flags | O_CLOEXEC);
-out:
-	free(path);
-	return fd;
+	return open(path, flags | O_CLOEXEC);
 }
 
 static int getprocattrcon_raw(char **context, pid_t pid, const char *attr,