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