Attached patch is Whitetank support for: - mmaped shared memory - POSIX semaphores - hardening patch
mmaped shm + posix sem are allowed by uncommenting OPENAIS_POSIX_IPC define in Makefile.inc (by default uncommented). Also please note, that this is supported only on Linux (nether FreeBSD or Darwin has shared semaphores support). I choose definition of OPENAIS_POSIX_IPC rather then testing of _POSIX_THREAD_PROCESS_SHARED simply because it is currently very easy to just recompile code and get old/new version on Linux (and of course, patch can be easily transformed by simple sed script). Regards, Honza
>From 2e0357991169728667b317ffe933751e278348e9 Mon Sep 17 00:00:00 2001 From: Jan Friesse <[email protected]> Date: Thu, 27 May 2010 15:48:43 +0200 Subject: [PATCH 1/3] Support for MMAPed shared memory --- branches/whitetank/Makefile.inc | 6 +++ branches/whitetank/exec/ipc.c | 58 +++++++++++++++++++++++++++++ branches/whitetank/include/ipc_gen.h | 8 ++++ branches/whitetank/lib/util.c | 66 +++++++++++++++++++++++++++++++++- 4 files changed, 137 insertions(+), 1 deletions(-) diff --git a/branches/whitetank/Makefile.inc b/branches/whitetank/Makefile.inc index c94e820..5d3add9 100644 --- a/branches/whitetank/Makefile.inc +++ b/branches/whitetank/Makefile.inc @@ -64,6 +64,9 @@ endif # OPENAIS_PROFILE +# Use POSIX IPC (sem_post, mmaped shm) instead of SYS V IPC (semop, shm) +OPENAIS_POSIX_IPC=1 + # default CFLAGS, LDFLAGS # CFLAGS = @@ -101,6 +104,9 @@ ifeq (${OPENAIS_COMPAT}, LINUX) override CFLAGS += -DOPENAIS_LINUX override LDFLAGS += -ldl -lpthread override DYFLAGS += -rdynamic +ifdef OPENAIS_POSIX_IPC + override CFLAGS += -DOPENAIS_POSIX_IPC +endif endif ifeq (${OPENAIS_COMPAT}, BSD) override CFLAGS += -DOPENAIS_BSD diff --git a/branches/whitetank/exec/ipc.c b/branches/whitetank/exec/ipc.c index 5337d25..1456fcc 100644 --- a/branches/whitetank/exec/ipc.c +++ b/branches/whitetank/exec/ipc.c @@ -89,6 +89,12 @@ #include "util.h" +#ifdef OPENAIS_POSIX_IPC +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#endif + #ifdef OPENAIS_SOLARIS #define MSG_NOSIGNAL 0 #endif @@ -138,9 +144,13 @@ struct conn_info { enum conn_state state; int notify_flow_control_enabled; int refcount; +#ifndef OPENAIS_POSIX_IPC key_t shmkey; +#endif key_t semkey; +#ifndef OPENAIS_POSIX_IPC int shmid; +#endif int semid; unsigned int pending_semops; pthread_mutex_t mutex; @@ -246,8 +256,12 @@ static inline int conn_info_destroy (struct conn_info *conn_info) /* * Destroy shared memory segment and semaphore */ +#ifndef OPENAIS_POSIX_IPC shmdt (conn_info->mem); res = shmctl (conn_info->shmid, IPC_RMID, NULL); +#else + munmap (conn_info->mem, sizeof (struct shared_memory)); +#endif semctl (conn_info->semid, 0, IPC_RMID); /* @@ -541,6 +555,40 @@ retry_recv: return (0); } +#ifdef OPENAIS_POSIX_IPC +static int +memory_map (const char *path, size_t bytes, void **buf) +{ + int fd; + void *addr; + int res; + + fd = open (path, O_RDWR, 0600); + + unlink (path); + + if (fd == -1) { + return (-1); + } + + res = ftruncate (fd, bytes); + if (res == -1) { + close (fd); + return (-1); + } + + addr = mmap (NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + res = close (fd); + if (res) { + return (-1); + } + + *buf = addr; + return (0); +} +#endif + static int poll_handler_connection ( poll_handle handle, int fd, @@ -585,16 +633,22 @@ static int poll_handler_connection ( pthread_mutex_init (&conn_info->mutex, NULL); req_setup = (mar_req_setup_t *)conn_info->setup_msg; +#ifndef OPENAIS_POSIX_IPC conn_info->shmkey = req_setup->shmkey; +#endif conn_info->semkey = req_setup->semkey; conn_info->service = req_setup->service; conn_info->refcount = 0; conn_info->notify_flow_control_enabled = 0; conn_info->setup_bytes_read = 0; +#ifndef OPENAIS_POSIX_IPC conn_info->shmid = shmget (conn_info->shmkey, sizeof (struct shared_memory), 0600); conn_info->mem = shmat (conn_info->shmid, NULL, 0); +#else + res = memory_map (req_setup->shm_file, sizeof (struct shared_memory), (void *)&conn_info->mem); +#endif conn_info->semid = semget (conn_info->semkey, 3, 0600); conn_info->pending_semops = 0; @@ -899,8 +953,12 @@ void openais_ipc_exit (void) conn_info = list_entry (list, struct conn_info, list); +#ifndef OPENAIS_POSIX_IPC shmdt (conn_info->mem); shmctl (conn_info->shmid, IPC_RMID, NULL); +#else + munmap (conn_info->mem, sizeof (struct shared_memory)); +#endif semctl (conn_info->semid, 0, IPC_RMID); pthread_kill (conn_info->thread, SIGUSR1); diff --git a/branches/whitetank/include/ipc_gen.h b/branches/whitetank/include/ipc_gen.h index a6235ee..c81d9c7 100644 --- a/branches/whitetank/include/ipc_gen.h +++ b/branches/whitetank/include/ipc_gen.h @@ -37,6 +37,10 @@ #include "mar_gen.h" +#ifdef OPENAIS_POSIX_IPC +#include <semaphore.h> +#endif + enum service_types { EVS_SERVICE = 0, CLM_SERVICE = 1, @@ -81,7 +85,11 @@ typedef struct { typedef struct { int service __attribute__((aligned(8))); +#ifndef OPENAIS_POSIX_IPC unsigned long long shmkey __attribute__((aligned(8))); +#else + char shm_file[128] __attribute__((aligned(8))); +#endif unsigned long long semkey __attribute__((aligned(8))); } mar_req_setup_t __attribute__((aligned(8))); diff --git a/branches/whitetank/lib/util.c b/branches/whitetank/lib/util.c index f285eb5..7dfbc86 100644 --- a/branches/whitetank/lib/util.c +++ b/branches/whitetank/lib/util.c @@ -70,6 +70,10 @@ #define IPC_SEMWAIT_TIMEOUT 2 #endif +#ifdef OPENAIS_POSIX_IPC +#include <sys/mman.h> +#endif + enum SA_HANDLE_STATE { SA_HANDLE_STATE_EMPTY, SA_HANDLE_STATE_PENDINGREMOVAL, @@ -85,7 +89,9 @@ struct saHandle { struct ipc_segment { int fd; +#ifndef OPENAIS_POSIX_IPC int shmid; +#endif int semid; int flow_control_state; struct shared_memory *shared_memory; @@ -285,6 +291,43 @@ union semun { }; #endif +#ifdef OPENAIS_POSIX_IPC +static int +memory_map (char *path, const char *file, void **buf, size_t bytes) +{ + int fd; + void *addr; + int res; + + sprintf (path, "/dev/shm/%s", file); + + fd = mkstemp (path); + if (fd == -1) { + sprintf (path, "/var/run/%s", file); + fd = mkstemp (path); + if (fd == -1) { + return (-1); + } + } + + res = ftruncate (fd, bytes); + if (res == -1) { + close (fd); + return (-1); + } + + addr = mmap (NULL, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + res = close (fd); + if (res) { + return (-1); + } + + *buf = addr; + return (0); +} +#endif + SaAisErrorT openais_service_connect ( enum service_types service, @@ -294,7 +337,11 @@ openais_service_connect ( struct sockaddr_un address; SaAisErrorT error; struct ipc_segment *ipc_segment; +#ifndef OPENAIS_POSIX_IPC key_t shmkey = 0; +#else + char shm_path[128]; +#endif key_t semkey = 0; int res; mar_req_setup_t req_setup; @@ -335,11 +382,13 @@ openais_service_connect ( /* * Allocate a shared memory segment */ +#ifndef OPENAIS_POSIX_IPC do { shmkey = random(); ipc_segment->shmid = shmget (shmkey, sizeof (struct shared_memory), IPC_CREAT|IPC_EXCL|0600); } while (ipc_segment->shmid == -1); +#endif /* * Allocate a semaphore segment @@ -353,11 +402,18 @@ openais_service_connect ( /* * Attach to shared memory segment */ +#ifndef OPENAIS_POSIX_IPC ipc_segment->shared_memory = shmat (ipc_segment->shmid, NULL, 0); if (ipc_segment->shared_memory == (void *)-1) { goto error_exit; } - +#else + res = memory_map (shm_path, "openais_shm-XXXXXX", (void *)&ipc_segment->shared_memory, + sizeof (struct shared_memory)); + if (res == -1) { + return (-1); + } +#endif semun.val = 0; res = semctl (ipc_segment->semid, 0, SETVAL, semun); if (res != 0) { @@ -374,7 +430,11 @@ openais_service_connect ( goto error_exit; } +#ifndef OPENAIS_POSIX_IPC req_setup.shmkey = shmkey; +#else + strcpy (req_setup.shm_file, shm_path); +#endif req_setup.semkey = semkey; req_setup.service = service; @@ -403,8 +463,12 @@ openais_service_connect ( error_exit: close (request_fd); +#ifndef OPENAIS_POSIX_IPC if (ipc_segment->shmid > 0) shmctl (ipc_segment->shmid, IPC_RMID, NULL); +#else + munmap (ipc_segment->shared_memory, sizeof (struct shared_memory)); +#endif if (ipc_segment->semid > 0) semctl (ipc_segment->semid, 0, IPC_RMID); return (res_setup.error); -- 1.5.5.6
>From 3cdfb579645439eb5d729ed7e270c717ada257c2 Mon Sep 17 00:00:00 2001 From: Jan Friesse <[email protected]> Date: Mon, 31 May 2010 10:02:03 +0200 Subject: [PATCH 2/3] Support for POSIX semaphores --- branches/whitetank/exec/ipc.c | 65 +++++++++++++++++--- branches/whitetank/include/ipc_gen.h | 7 ++- branches/whitetank/lib/util.c | 111 +++++++++++++++++++++++----------- 3 files changed, 138 insertions(+), 45 deletions(-) diff --git a/branches/whitetank/exec/ipc.c b/branches/whitetank/exec/ipc.c index 1456fcc..b890825 100644 --- a/branches/whitetank/exec/ipc.c +++ b/branches/whitetank/exec/ipc.c @@ -146,12 +146,10 @@ struct conn_info { int refcount; #ifndef OPENAIS_POSIX_IPC key_t shmkey; -#endif key_t semkey; -#ifndef OPENAIS_POSIX_IPC int shmid; -#endif int semid; +#endif unsigned int pending_semops; pthread_mutex_t mutex; struct shared_memory *mem; @@ -167,7 +165,9 @@ static int shared_mem_dispatch_bytes_left (struct conn_info *conn_info); static void outq_flush (struct conn_info *conn_info); +#ifndef OPENAIS_POSIX_IPC static int priv_change (struct conn_info *conn_info); +#endif static void ipc_disconnect (struct conn_info *conn_info); @@ -259,10 +259,13 @@ static inline int conn_info_destroy (struct conn_info *conn_info) #ifndef OPENAIS_POSIX_IPC shmdt (conn_info->mem); res = shmctl (conn_info->shmid, IPC_RMID, NULL); + semctl (conn_info->semid, 0, IPC_RMID); #else + sem_destroy (&conn_info->mem->sem0); + sem_destroy (&conn_info->mem->sem1); + sem_destroy (&conn_info->mem->sem2); munmap (conn_info->mem, sizeof (struct shared_memory)); #endif - semctl (conn_info->semid, 0, IPC_RMID); /* * Free allocated data needed to retry exiting library IPC connection @@ -313,7 +316,9 @@ record_proc_state(const char *file, const char *function, int line, const char * static void *pthread_ipc_consumer (void *conn) { struct conn_info *conn_info = (struct conn_info *)conn; +#ifndef OPENAIS_POSIX_IPC struct sembuf sop; +#endif int res; mar_req_header_t *header; struct res_overlay res_overlay; @@ -323,14 +328,17 @@ static void *pthread_ipc_consumer (void *conn) int flow_control = 0; for (;;) { +#ifndef OPENAIS_POSIX_IPC sop.sem_num = 0; sop.sem_op = -1; sop.sem_flg = 0; +#endif retry_semop: if (ipc_thread_active (conn_info) == 0) { openais_conn_refcount_dec (conn_info); pthread_exit (0); } +#ifndef OPENAIS_POSIX_IPC res = semop (conn_info->semid, &sop, 1); if ((res == -1) && (errno == EINTR || errno == EAGAIN)) { goto retry_semop; @@ -339,7 +347,12 @@ retry_semop: openais_conn_refcount_dec (conn_info); pthread_exit (0); } - +#else + res = sem_wait (&conn_info->mem->sem0); + if (res == -1 && errno == EINTR) { + goto retry_semop; + } +#endif openais_conn_refcount_inc (conn_info); header = (mar_req_header_t *)conn_info->mem->req_buffer; @@ -635,8 +648,8 @@ static int poll_handler_connection ( req_setup = (mar_req_setup_t *)conn_info->setup_msg; #ifndef OPENAIS_POSIX_IPC conn_info->shmkey = req_setup->shmkey; -#endif conn_info->semkey = req_setup->semkey; +#endif conn_info->service = req_setup->service; conn_info->refcount = 0; conn_info->notify_flow_control_enabled = 0; @@ -646,10 +659,10 @@ static int poll_handler_connection ( conn_info->shmid = shmget (conn_info->shmkey, sizeof (struct shared_memory), 0600); conn_info->mem = shmat (conn_info->shmid, NULL, 0); + conn_info->semid = semget (conn_info->semkey, 3, 0600); #else res = memory_map (req_setup->shm_file, sizeof (struct shared_memory), (void *)&conn_info->mem); #endif - conn_info->semid = semget (conn_info->semkey, 3, 0600); conn_info->pending_semops = 0; /* @@ -696,11 +709,13 @@ static int poll_handler_connection ( case MESSAGE_REQ_OUTQ_FLUSH: outq_flush (conn_info); break; +#ifndef OPENAIS_POSIX_IPC case MESSAGE_REQ_CHANGE_EUID: if (priv_change (conn_info) == -1) { ipc_disconnect (conn_info); } break; +#endif default: res = 0; break; @@ -956,11 +971,14 @@ void openais_ipc_exit (void) #ifndef OPENAIS_POSIX_IPC shmdt (conn_info->mem); shmctl (conn_info->shmid, IPC_RMID, NULL); + semctl (conn_info->semid, 0, IPC_RMID); #else + sem_destroy (&conn_info->mem->sem0); + sem_destroy (&conn_info->mem->sem1); + sem_destroy (&conn_info->mem->sem2); munmap (conn_info->mem, sizeof (struct shared_memory)); #endif - semctl (conn_info->semid, 0, IPC_RMID); - + pthread_kill (conn_info->thread, SIGUSR1); } } @@ -978,10 +996,13 @@ void *openais_conn_private_data_get (void *conn) int openais_response_send (void *conn, void *msg, int mlen) { struct conn_info *conn_info = (struct conn_info *)conn; +#ifndef OPENAIS_POSIX_IPC struct sembuf sop; +#endif int res; memcpy (conn_info->mem->res_buffer, msg, mlen); +#ifndef OPENAIS_POSIX_IPC sop.sem_num = 1; sop.sem_op = 1; sop.sem_flg = 0; @@ -994,13 +1015,21 @@ retry_semop: if ((res == -1) && (errno == EINVAL || errno == EIDRM)) { return (0); } +#else + res = sem_post (&conn_info->mem->sem1); + if (res == -1) { + return (-1); + } +#endif return (0); } int openais_response_iov_send (void *conn, struct iovec *iov, int iov_len) { struct conn_info *conn_info = (struct conn_info *)conn; +#ifndef OPENAIS_POSIX_IPC struct sembuf sop; +#endif int res; int write_idx = 0; int i; @@ -1010,6 +1039,7 @@ int openais_response_iov_send (void *conn, struct iovec *iov, int iov_len) write_idx += iov[i].iov_len; } +#ifndef OPENAIS_POSIX_IPC sop.sem_num = 1; sop.sem_op = 1; sop.sem_flg = 0; @@ -1022,6 +1052,12 @@ retry_semop: if ((res == -1) && (errno == EINVAL || errno == EIDRM)) { return (0); } +#else + res = sem_post (&conn_info->mem->sem1); + if (res == -1) { + return (-1); + } +#endif return (0); } @@ -1069,7 +1105,9 @@ int memcpy_dwrap (struct conn_info *conn_info, void *msg, int len) void msg_send (void *conn, struct iovec *iov, int iov_len, int locked) { struct conn_info *conn_info = (struct conn_info *)conn; +#ifndef OPENAIS_POSIX_IPC struct sembuf sop; +#endif int res; int i; char buf; @@ -1094,6 +1132,7 @@ void msg_send (void *conn, struct iovec *iov, int iov_len, int locked) if (res == -1) { ipc_disconnect (conn_info); } +#ifndef OPENAIS_POSIX_IPC sop.sem_num = 2; sop.sem_op = 1; sop.sem_flg = 0; @@ -1106,6 +1145,12 @@ retry_semop: if ((res == -1) && (errno == EINVAL || errno == EIDRM)) { return; } +#else + res = sem_post (&conn_info->mem->sem2); + if (res == -1) { + return ; + } +#endif } static void outq_flush (struct conn_info *conn_info) { @@ -1143,6 +1188,7 @@ static void outq_flush (struct conn_info *conn_info) { pthread_mutex_unlock (&conn_info->mutex); } +#ifndef OPENAIS_POSIX_IPC static int priv_change (struct conn_info *conn_info) { mar_req_priv_change req_priv_change; @@ -1186,6 +1232,7 @@ retry_recv: } return (0); } +#endif static void msg_send_or_queue (void *conn, struct iovec *iov, int iov_len) { diff --git a/branches/whitetank/include/ipc_gen.h b/branches/whitetank/include/ipc_gen.h index c81d9c7..251de1f 100644 --- a/branches/whitetank/include/ipc_gen.h +++ b/branches/whitetank/include/ipc_gen.h @@ -72,6 +72,11 @@ struct shared_memory { unsigned char dispatch_buffer[DISPATCH_SIZE]; unsigned int read; unsigned int write; +#ifdef OPENAIS_POSIX_IPC + sem_t sem0; + sem_t sem1; + sem_t sem2; +#endif }; enum res_init_types { @@ -87,10 +92,10 @@ typedef struct { int service __attribute__((aligned(8))); #ifndef OPENAIS_POSIX_IPC unsigned long long shmkey __attribute__((aligned(8))); + unsigned long long semkey __attribute__((aligned(8))); #else char shm_file[128] __attribute__((aligned(8))); #endif - unsigned long long semkey __attribute__((aligned(8))); } mar_req_setup_t __attribute__((aligned(8))); typedef struct { diff --git a/branches/whitetank/lib/util.c b/branches/whitetank/lib/util.c index 7dfbc86..e111557 100644 --- a/branches/whitetank/lib/util.c +++ b/branches/whitetank/lib/util.c @@ -91,8 +91,8 @@ struct ipc_segment { int fd; #ifndef OPENAIS_POSIX_IPC int shmid; -#endif int semid; +#endif int flow_control_state; struct shared_memory *shared_memory; uid_t euid; @@ -249,6 +249,7 @@ error_exit: return (0); } +#ifndef OPENAIS_POSIX_IPC static int priv_change_send (struct ipc_segment *ipc_segment) { @@ -280,7 +281,7 @@ priv_change_send (struct ipc_segment *ipc_segment) ipc_segment->euid = req_priv_change.euid; return (0); } - +#endif #if defined(_SEM_SEMUN_UNDEFINED) union semun { @@ -339,14 +340,14 @@ openais_service_connect ( struct ipc_segment *ipc_segment; #ifndef OPENAIS_POSIX_IPC key_t shmkey = 0; + key_t semkey = 0; + union semun semun; #else char shm_path[128]; #endif - key_t semkey = 0; int res; mar_req_setup_t req_setup; mar_res_setup_t res_setup; - union semun semun; res_setup.error = SA_AIS_ERR_LIBRARY; @@ -379,16 +380,15 @@ openais_service_connect ( } bzero (ipc_segment, sizeof (struct ipc_segment)); +#ifndef OPENAIS_POSIX_IPC /* * Allocate a shared memory segment */ -#ifndef OPENAIS_POSIX_IPC do { shmkey = random(); ipc_segment->shmid = shmget (shmkey, sizeof (struct shared_memory), IPC_CREAT|IPC_EXCL|0600); } while (ipc_segment->shmid == -1); -#endif /* * Allocate a semaphore segment @@ -402,18 +402,11 @@ openais_service_connect ( /* * Attach to shared memory segment */ -#ifndef OPENAIS_POSIX_IPC ipc_segment->shared_memory = shmat (ipc_segment->shmid, NULL, 0); if (ipc_segment->shared_memory == (void *)-1) { goto error_exit; } -#else - res = memory_map (shm_path, "openais_shm-XXXXXX", (void *)&ipc_segment->shared_memory, - sizeof (struct shared_memory)); - if (res == -1) { - return (-1); - } -#endif + semun.val = 0; res = semctl (ipc_segment->semid, 0, SETVAL, semun); if (res != 0) { @@ -429,13 +422,36 @@ openais_service_connect ( if (res != 0) { goto error_exit; } +#else + /* + * Attach to shared memory segment + */ + res = memory_map (shm_path, "openais_shm-XXXXXX", (void *)&ipc_segment->shared_memory, + sizeof (struct shared_memory)); + if (res == -1) { + return (-1); + } + + /* + * Initialize semaphores + */ + if (sem_init (&ipc_segment->shared_memory->sem0, 1, 0) == -1) { + return (-1); + } + if (sem_init (&ipc_segment->shared_memory->sem1, 1, 0) == -1) { + return (-1); + } + if (sem_init (&ipc_segment->shared_memory->sem2, 1, 0) == -1) { + return (-1); + } +#endif #ifndef OPENAIS_POSIX_IPC req_setup.shmkey = shmkey; + req_setup.semkey = semkey; #else strcpy (req_setup.shm_file, shm_path); #endif - req_setup.semkey = semkey; req_setup.service = service; error = openais_send (request_fd, &req_setup, sizeof (mar_req_setup_t)); @@ -466,11 +482,14 @@ error_exit: #ifndef OPENAIS_POSIX_IPC if (ipc_segment->shmid > 0) shmctl (ipc_segment->shmid, IPC_RMID, NULL); + if (ipc_segment->semid > 0) + semctl (ipc_segment->semid, 0, IPC_RMID); #else + sem_destroy (&ipc_segment->shared_memory->sem0); + sem_destroy (&ipc_segment->shared_memory->sem1); + sem_destroy (&ipc_segment->shared_memory->sem2); munmap (ipc_segment->shared_memory, sizeof (struct shared_memory)); #endif - if (ipc_segment->semid > 0) - semctl (ipc_segment->semid, 0, IPC_RMID); return (res_setup.error); } @@ -535,23 +554,22 @@ ipc_sem_wait ( struct ipc_segment *ipc_segment, int sem_num) { +#ifndef OPENAIS_POSIX_IPC struct sembuf sop; -#if defined(OPENAIS_LINUX) +#else struct timespec timeout; struct pollfd pfd; + sem_t *sem; #endif int res; +#ifndef OPENAIS_POSIX_IPC sop.sem_num = sem_num; sop.sem_op = -1; sop.sem_flg = 0; retry_semop: -#if defined(OPENAIS_LINUX) - timeout.tv_sec = IPC_SEMWAIT_TIMEOUT; - timeout.tv_nsec = 0; - - res = semtimedop (ipc_segment->semid, &sop, 1, &timeout); + res = semop (ipc_segment->semid, &sop, 1); if (res == -1 && errno == EINTR) { goto retry_semop; } else @@ -559,7 +577,28 @@ retry_semop: priv_change_send (ipc_segment); goto retry_semop; } else - if (res == -1 && errno == EAGAIN) { + if (res == -1) { + return (SA_AIS_ERR_LIBRARY); + } +#else + switch (sem_num) { + case 0: + sem = &ipc_segment->shared_memory->sem0; + break; + case 1: + sem = &ipc_segment->shared_memory->sem1; + break; + case 2: + sem = &ipc_segment->shared_memory->sem2; + break; + } + +retry_semwait: + timeout.tv_sec = time (NULL) + IPC_SEMWAIT_TIMEOUT; + timeout.tv_nsec = 0; + + res = sem_timedwait (sem, &timeout); + if (res == -1 && errno == ETIMEDOUT) { pfd.fd = ipc_segment->fd; pfd.events = 0; @@ -575,19 +614,10 @@ retry_semop: } } - goto retry_semop; + goto retry_semwait; } else - if (res == -1) { - return (SA_AIS_ERR_LIBRARY); - } -#else - res = semop (ipc_segment->semid, &sop, 1); if (res == -1 && errno == EINTR) { - goto retry_semop; - } else - if (res == -1 && errno == EACCES) { - priv_change_send (ipc_segment); - goto retry_semop; + goto retry_semwait; } else if (res == -1) { return (SA_AIS_ERR_LIBRARY); @@ -697,7 +727,9 @@ openais_msg_send ( int iov_len) { struct ipc_segment *ipc_segment = (struct ipc_segment *)ipc_context; +#ifndef OPENAIS_POSIX_IPC struct sembuf sop; +#endif int i; int res; int req_buffer_idx = 0; @@ -711,6 +743,8 @@ openais_msg_send ( iov[i].iov_len); req_buffer_idx += iov[i].iov_len; } + +#ifndef OPENAIS_POSIX_IPC /* * Signal semaphore #0 indicting a new message from client * to server request queue @@ -731,6 +765,13 @@ retry_semop: if (res == -1) { return (SA_AIS_ERR_LIBRARY); } +#else + res = sem_post (&ipc_segment->shared_memory->sem0); + if (res == -1) { + return (-1); + } +#endif + return (SA_AIS_OK); } -- 1.5.5.6
>From 45077b237e1f0431af8ddcf54ca897f62d42b14a Mon Sep 17 00:00:00 2001 From: Jan Friesse <[email protected]> Date: Mon, 31 May 2010 15:06:43 +0200 Subject: [PATCH 3/3] IPC hardening Backport of almost same patch as in corosync for solve a segfault issue in openais on exit. Semop implementation doesn't has this problem because semop is little more clever and doesn't segfault on uninitialized semaphore. --- branches/whitetank/exec/ipc.c | 14 ++++++++++++-- 1 files changed, 12 insertions(+), 2 deletions(-) diff --git a/branches/whitetank/exec/ipc.c b/branches/whitetank/exec/ipc.c index b890825..ba920a5 100644 --- a/branches/whitetank/exec/ipc.c +++ b/branches/whitetank/exec/ipc.c @@ -962,6 +962,9 @@ void openais_ipc_exit (void) { struct list_head *list; struct conn_info *conn_info; +#ifdef OPENAIS_POSIX_IPC + void *retval; +#endif for (list = conn_info_list_head.next; list != &conn_info_list_head; list = list->next) { @@ -972,14 +975,21 @@ void openais_ipc_exit (void) shmdt (conn_info->mem); shmctl (conn_info->shmid, IPC_RMID, NULL); semctl (conn_info->semid, 0, IPC_RMID); + + pthread_kill (conn_info->thread, SIGUSR1); #else + if (conn_info->state != CONN_STATE_THREAD_ACTIVE && conn_info->state != CONN_STATE_THREAD_REQUEST_EXIT) + continue; + + ipc_disconnect (conn_info); + + pthread_join (conn_info->thread, &retval); + sem_destroy (&conn_info->mem->sem0); sem_destroy (&conn_info->mem->sem1); sem_destroy (&conn_info->mem->sem2); munmap (conn_info->mem, sizeof (struct shared_memory)); #endif - - pthread_kill (conn_info->thread, SIGUSR1); } } -- 1.5.5.6
_______________________________________________ Openais mailing list [email protected] https://lists.linux-foundation.org/mailman/listinfo/openais
