Blame SOURCES/open-lldp-v1.0.1-24-switch-from-sysv-to-posix-shared-memory-apis.patch

436175
From 3124c4b4537083618b82f230b05997c70096c897 Mon Sep 17 00:00:00 2001
436175
From: Chris Leech <cleech@redhat.com>
436175
Date: Mon, 20 Jul 2015 17:32:02 -0700
436175
Subject: [PATCH] switch from sysv to posix shared memory apis
436175
436175
The use of SysV shared memory, to pass state between running instances of
436175
lldpad in the initramfs and then from the root fs, is difficult to work
436175
with from a security policy.  When lldpad runs in the initramfs there is
436175
no security policy loaded.  Then when it's restarted after an SELinux
436175
policy has been loaded, there is no way to correct the context on the
436175
already existing shared memory segment.  This would result in the need
436175
for an overly permissive policy for lldpad.
436175
436175
By switching to POSIX APIs the segment is mapped from a tmpfs file with
436175
a directory entry under /dev/shm/.  This lets us add a file contents
436175
entry to the SELinux policy that matches that path, and a proper
436175
security context can be restored to it before restarting lldpad.
436175
436175
- Chris
436175
---
436175
 Makefile.am          |   2 +-
436175
 include/lldpad_shm.h |   2 +-
436175
 lldpad_shm.c         | 169 ++++++++++++++++++++++++++++++---------------------
436175
 3 files changed, 103 insertions(+), 70 deletions(-)
436175
436175
diff --git a/Makefile.am b/Makefile.am
436175
index 84d68ee..551d4c7 100644
436175
--- a/Makefile.am
436175
+++ b/Makefile.am
436175
@@ -17,7 +17,7 @@ parse_cli.o: CFLAGS+=-U_FORTIFY_SOURCE -Wno-error
436175
 
436175
 ## system requires a shared libconfig
436175
 AM_CFLAGS = -Wall -Werror -Wextra -Wformat=2 $(LIBCONFIG_CFLAGS) $(LIBNL_CFLAGS)
436175
-AM_LDFLAGS = $(LIBCONFIG_LIBS) $(LIBNL_LIBS)
436175
+AM_LDFLAGS = $(LIBCONFIG_LIBS) $(LIBNL_LIBS) -lrt
436175
 
436175
 ## header files to be installed, for programs using the client interface to lldpad 
436175
 lldpad_includedir= ${includedir}/lldpad
436175
diff --git a/include/lldpad_shm.h b/include/lldpad_shm.h
436175
index 00d20eb..587b555 100644
436175
--- a/include/lldpad_shm.h
436175
+++ b/include/lldpad_shm.h
436175
@@ -31,7 +31,7 @@
436175
 #include "lldpad.h"
436175
 #include "lldp_rtnl.h"
436175
 
436175
-#define LLDPAD_SHM_KEY ((('l'<<24) | ('l'<<16) | ('d'<<8) | ('p')) + 'a' + 'd' + 1)
436175
+#define LLDPAD_SHM_PATH "/lldpad.state"
436175
 #define LLDPAD_SHM_SIZE 4096
436175
 
436175
 /* PID value used to indicate pid field is uninitialized */
436175
diff --git a/lldpad_shm.c b/lldpad_shm.c
436175
index 4afcf73..d8bc0c5 100644
436175
--- a/lldpad_shm.c
436175
+++ b/lldpad_shm.c
436175
@@ -29,7 +29,9 @@
436175
 #include <string.h>
436175
 #include <syslog.h>
436175
 #include <sys/ipc.h>
436175
-#include <sys/shm.h>
436175
+#include <sys/mman.h>
436175
+#include <sys/stat.h>
436175
+#include <fcntl.h>
436175
 #include <sys/types.h>
436175
 #include <unistd.h>
436175
 #include <errno.h>
436175
@@ -39,16 +41,7 @@
436175
 
436175
 void mark_lldpad_shm_for_removal()
436175
 {
436175
-	int shmid;
436175
-	struct shmid_ds shminfo;
436175
-
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
-
436175
-	if (shmid < 0)
436175
-		return;
436175
-
436175
-	if (shmctl(shmid, IPC_RMID, &shminfo) < 0)
436175
-		return;
436175
+	shm_unlink(LLDPAD_SHM_PATH);
436175
 }
436175
 
436175
 /* return: 1 = success, 0 = failed */
436175
@@ -101,16 +94,21 @@ int lldpad_shm_get_msap(const char *device_name, int type, char *info, size_t *l
436175
 	unsigned num_entries;
436175
 	int version;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
-	if (shmid < 0 && errno == ENOENT)
436175
-		shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE,
436175
-			IPC_CREAT | IPC_EXCL | 0x180);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0)
436175
 		return rval;
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
-	if ((long) shmaddr == -1)
436175
+	if (ftruncate(shmid, LLDPAD_SHM_SIZE)) {
436175
+		close(shmid);
436175
+		return rval;
436175
+	}
436175
+
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED)
436175
 		return rval;
436175
 
436175
 	version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT;
436175
@@ -147,7 +145,7 @@ int lldpad_shm_get_msap(const char *device_name, int type, char *info, size_t *l
436175
 		rval = 1;
436175
 	}
436175
 done:
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 
436175
 	return rval;
436175
 }
436175
@@ -162,16 +160,21 @@ int lldpad_shm_set_msap(const char *device_name, int type, char *info, size_t le
436175
 	int version;
436175
 	unsigned num_entries;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
-	if (shmid < 0 && errno == ENOENT)
436175
-		shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE,
436175
-			IPC_CREAT | IPC_EXCL | 0x180);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0)
436175
 		return rval;
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
-	if ((long) shmaddr == -1)
436175
+	if (ftruncate(shmid, LLDPAD_SHM_SIZE)) {
436175
+		close(shmid);
436175
+		return rval;
436175
+	}
436175
+
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED)
436175
 		return rval;
436175
 
436175
 	version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT;
436175
@@ -212,7 +215,7 @@ int lldpad_shm_set_msap(const char *device_name, int type, char *info, size_t le
436175
 	}
436175
 
436175
 done:
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 
436175
 	return rval;
436175
 }
436175
@@ -226,16 +229,21 @@ int lldpad_shm_get_dcbx(const char *device_name)
436175
 	unsigned num_entries;
436175
 	int version;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
-	if (shmid < 0 && errno == ENOENT)
436175
-		shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE,
436175
-			IPC_CREAT | IPC_EXCL | 0x180);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0)
436175
 		return rval;
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
-	if ((long) shmaddr == -1)
436175
+	if (ftruncate(shmid, LLDPAD_SHM_SIZE)) {
436175
+		close(shmid);
436175
+		return rval;
436175
+	}
436175
+
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED)
436175
 		return rval;
436175
 
436175
 	version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT;
436175
@@ -264,7 +272,7 @@ int lldpad_shm_get_dcbx(const char *device_name)
436175
 	}
436175
 
436175
 done:
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 
436175
 	return rval;
436175
 }
436175
@@ -279,16 +287,21 @@ int lldpad_shm_set_dcbx(const char *device_name, int dcbx_mode)
436175
 	unsigned num_entries;
436175
 	int version;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
-	if (shmid < 0 && errno == ENOENT)
436175
-		shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE,
436175
-			IPC_CREAT | IPC_EXCL | 0x180);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0)
436175
 		return rval;
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
-	if ((long) shmaddr == -1)
436175
+	if (ftruncate(shmid, LLDPAD_SHM_SIZE)) {
436175
+		close(shmid);
436175
+		return rval;
436175
+	}
436175
+
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED)
436175
 		return rval;
436175
 
436175
 	version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT;
436175
@@ -330,7 +343,7 @@ int lldpad_shm_set_dcbx(const char *device_name, int dcbx_mode)
436175
 	}
436175
 
436175
 done:
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 
436175
 	return rval;
436175
 }
436175
@@ -346,16 +359,21 @@ pid_t lldpad_shm_getpid()
436175
 	pid_t rval = -1;
436175
 	int version;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
-	if (shmid < 0 && errno == ENOENT)
436175
-		shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE,
436175
-			IPC_CREAT | IPC_EXCL | 0x180);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0)
436175
 		return rval;
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
-	if ((long) shmaddr == -1)
436175
+	if (ftruncate(shmid, LLDPAD_SHM_SIZE)) {
436175
+		close(shmid);
436175
+		return rval;
436175
+	}
436175
+
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED)
436175
 		return rval;
436175
 
436175
 	version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT;
436175
@@ -366,7 +384,7 @@ pid_t lldpad_shm_getpid()
436175
 
436175
 	rval = shmaddr->pid;
436175
 
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 
436175
 	return rval;
436175
 }
436175
@@ -379,13 +397,16 @@ int lldpad_shm_setpid(pid_t pid)
436175
 	pid_t rval = 0;
436175
 	int version;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0)
436175
 		return rval;
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
-	if ((long) shmaddr == -1)
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED)
436175
 		return rval;
436175
 
436175
 	version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT;
436175
@@ -396,7 +417,7 @@ int lldpad_shm_setpid(pid_t pid)
436175
 
436175
 	shmaddr->pid = pid;
436175
 
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 
436175
 	return 1;
436175
 }
436175
@@ -410,13 +431,16 @@ int clear_dcbx_state()
436175
 	int version;
436175
 	unsigned num_entries;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0)
436175
 		return 0;
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
-	if ((long) shmaddr == -1)
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED)
436175
 		return 0;
436175
 
436175
 	version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT;
436175
@@ -437,7 +461,7 @@ int clear_dcbx_state()
436175
 				sizeof(dcbx_state));
436175
 
436175
 done:
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 	return 1;
436175
 }
436175
 
436175
@@ -451,13 +475,16 @@ int set_dcbx_state(const char *device_name, dcbx_state *state)
436175
 	int version;
436175
 	unsigned num_entries;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0)
436175
 		return rval;
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
-	if ((long) shmaddr == -1)
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED)
436175
 		return rval;
436175
 
436175
 	version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT;
436175
@@ -487,7 +514,7 @@ int set_dcbx_state(const char *device_name, dcbx_state *state)
436175
 	}
436175
 
436175
 done:
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 
436175
 	return rval;
436175
 }
436175
@@ -505,13 +532,16 @@ int get_dcbx_state(const char *device_name, dcbx_state *state)
436175
 	int version;
436175
 	unsigned num_entries;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0)
436175
 		return rval;
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
-	if ((long) shmaddr == -1)
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED)
436175
 		return rval;
436175
 
436175
 	version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT;
436175
@@ -537,7 +567,7 @@ int get_dcbx_state(const char *device_name, dcbx_state *state)
436175
 		}
436175
 
436175
 done:
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 
436175
 	return rval;
436175
 }
436175
@@ -562,17 +592,20 @@ int print_lldpad_shm()
436175
 	int ent_size;
436175
 	struct lldpad_shm_entry *entry_ptr = NULL;
436175
 
436175
-	shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0);
436175
+	shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR);
436175
 
436175
 	if (shmid < 0) {
436175
-		printf("failed to shmget\n");
436175
+		printf("failed to shm_open\n");
436175
 		return rval;
436175
 	}
436175
 
436175
-	shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0);
436175
+	shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE,
436175
+			                         PROT_READ | PROT_WRITE,
436175
+						 MAP_SHARED, shmid, 0);
436175
 	shmaddr_ver0 = (struct lldpad_shm_tbl_ver0 *)shmaddr;
436175
-	if ((long) shmaddr == -1) {
436175
-		printf("failed to shmat\n");
436175
+	close(shmid);
436175
+	if (shmaddr == MAP_FAILED) {
436175
+		printf("failed to mmap\n");
436175
 		return rval;
436175
 	}
436175
 
436175
@@ -633,7 +666,7 @@ int print_lldpad_shm()
436175
 	rval = 1;
436175
 
436175
 done:
436175
-	shmdt(shmaddr);
436175
+	munmap(shmaddr, LLDPAD_SHM_SIZE);
436175
 
436175
 	return rval;
436175
 }
436175
-- 
436175
2.1.0
436175