Author: mturk
Date: Thu Mar 15 04:11:20 2007
New Revision: 518581
URL: http://svn.apache.org/viewvc?view=rev&rev=518581
Log:
Fix shared memory lock by using temporary file instead
adding extension to shared memory file. This allows to
have higher security for shared memory
Modified:
tomcat/connectors/trunk/jk/native/common/jk_shm.c
Modified: tomcat/connectors/trunk/jk/native/common/jk_shm.c
URL:
http://svn.apache.org/viewvc/tomcat/connectors/trunk/jk/native/common/jk_shm.c?view=diff&rev=518581&r1=518580&r2=518581
==============================================================================
--- tomcat/connectors/trunk/jk/native/common/jk_shm.c (original)
+++ tomcat/connectors/trunk/jk/native/common/jk_shm.c Thu Mar 15 04:11:20 2007
@@ -59,6 +59,7 @@
{
size_t size;
const char *filename;
+ const char *lockname;
int fd;
int fd_lock;
int attached;
@@ -69,7 +70,7 @@
typedef struct jk_shm jk_shm_t;
static const char shm_signature[] = { JK_SHM_MAGIC };
-static jk_shm_t jk_shmem = { 0, NULL, -1, -1, 0, NULL};
+static jk_shm_t jk_shmem = { 0, NULL, NULL, -1, -1, 0, NULL};
static time_t jk_workers_modified_time = 0;
static time_t jk_workers_access_time = 0;
#if defined (WIN32)
@@ -227,44 +228,68 @@
#define MAP_FILE (0)
#endif
-static int do_shm_open_lock(const char *fname, int attached, jk_logger_t *l)
+static int do_shm_open_lock(int attached, jk_logger_t *l)
{
int rc;
- int fd;
- int flags = O_RDWR;
char flkname[256];
JK_TRACE_ENTER(l);
- jk_shmem.fd_lock = -1;
- strcpy(flkname, fname);
- strcat(flkname, ".lock");
- if (!attached)
- flags |= (O_CREAT|O_TRUNC);
- fd = open(flkname, flags, 0666);
- if (fd == -1) {
+ if (!jk_shmem.lockname) {
+ int i;
+ jk_shmem.fd_lock = -1;
+ for (i = 0; i < 8) {
+ strcpy(flkname, "/tmp/jkshmlock.XXXXXX");
+ if (mktemp(flkname)) {
+ jk_shmem.fd_lock = open(flkname, O_RDWR|O_CREAT|O_TRUNC, 0666);
+ if (jk_shmem.fd_lock >= 0)
+ break;
+ }
+ }
+ if (jk_shmem.fd_lock == -1) {
+ rc = errno;
+ JK_TRACE_EXIT(l);
+ return rc;
+ }
+ jk_shmem.lockname = strdup(flkname);
+ unlink(jk_shmem.lockname);
+ }
+ else if (attached) {
+ jk_shmem.fd_lock = open(jk_shmem.lockname, O_RDWR, 0666);
+ if (jk_shmem.fd_lock == -1) {
+ rc = errno;
+ JK_TRACE_EXIT(l);
+ return rc;
+ }
+ if (JK_IS_DEBUG_LEVEL(l))
+ jk_log(l, JK_LOG_DEBUG,
+ "Duplicated shared memory lock %s", jk_shmem.lockname);
JK_TRACE_EXIT(l);
- return errno;
+ return 0;
+ }
+ else {
+
+
}
if (!attached) {
- if (ftruncate(fd, 1)) {
+ if (ftruncate(jk_shmem.fd_lock, 1)) {
rc = errno;
- close(fd);
+ close(jk_shmem.fd_lock);
+ jk_shmem.fd_lock = -1;
JK_TRACE_EXIT(l);
return rc;
}
}
- if (lseek(fd, 0, SEEK_SET) != 0) {
+ if (lseek(jk_shmem.fd_lock, 0, SEEK_SET) != 0) {
rc = errno;
- close(fd);
+ close(jk_shmem.fd_lock);
+ jk_shmem.fd_lock = -1;
JK_TRACE_EXIT(l);
return rc;
}
- jk_shmem.fd_lock = fd;
-
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
- "Opened shared memory lock %s", flkname);
+ "Opened shared memory lock %s", jk_shmem.lockname);
JK_TRACE_EXIT(l);
return 0;
}
@@ -274,7 +299,6 @@
{
int rc;
int fd;
- int flags = O_RDWR;
void *base;
JK_TRACE_ENTER(l);
@@ -283,12 +307,14 @@
if (!attached)
attached = 1;
}
+ else if (attached) {
+ /* We should already have a header
+ * Use memory if we don't
+ */
+ JK_TRACE_EXIT(l);
+ return 0;
+ }
jk_shmem.filename = fname;
- if (attached)
- jk_shmem.attached = (int)getpid();
- else
- jk_shmem.attached = 0;
-
jk_shmem.size = JK_SHM_ALIGN(sizeof(jk_shm_header_t) + sz);
/* Use plain memory in case there is no file name */
@@ -301,17 +327,16 @@
return 0;
}
- if (!attached)
- flags |= (O_CREAT|O_TRUNC);
- fd = open(fname, flags, 0666);
- if (fd == -1) {
- jk_shmem.size = 0;
- JK_TRACE_EXIT(l);
- return errno;
- }
-
if (!attached) {
- size_t size = lseek(fd, 0, SEEK_END);
+ size_t size;
+ jk_shmem.attached = 0;
+ fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666);
+ if (fd == -1) {
+ jk_shmem.size = 0;
+ JK_TRACE_EXIT(l);
+ return errno;
+ }
+ size = lseek(fd, 0, SEEK_END);
if (size < jk_shmem.size) {
size = jk_shmem.size;
if (ftruncate(fd, jk_shmem.size)) {
@@ -325,31 +350,27 @@
jk_log(l, JK_LOG_DEBUG,
"Truncated shared memory to %u", size);
}
- }
- if (lseek(fd, 0, SEEK_SET) != 0) {
- rc = errno;
- close(fd);
- jk_shmem.size = 0;
- JK_TRACE_EXIT(l);
- return rc;
- }
-
- base = mmap((caddr_t)0, jk_shmem.size,
- PROT_READ | PROT_WRITE,
- MAP_FILE | MAP_SHARED,
- fd, 0);
- if (base == (caddr_t)MAP_FAILED || base == (caddr_t)0) {
- rc = errno;
- close(fd);
- jk_shmem.size = 0;
- JK_TRACE_EXIT(l);
- return rc;
- }
- jk_shmem.hdr = base;
- jk_shmem.fd = fd;
+ if (lseek(fd, 0, SEEK_SET) != 0) {
+ rc = errno;
+ close(fd);
+ jk_shmem.size = 0;
+ JK_TRACE_EXIT(l);
+ return rc;
+ }
- /* Clear shared memory */
- if (!attached) {
+ base = mmap((caddr_t)0, jk_shmem.size,
+ PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED,
+ fd, 0);
+ if (base == (caddr_t)MAP_FAILED || base == (caddr_t)0) {
+ rc = errno;
+ close(fd);
+ jk_shmem.size = 0;
+ JK_TRACE_EXIT(l);
+ return rc;
+ }
+ jk_shmem.hdr = base;
+ jk_shmem.fd = fd;
memset(jk_shmem.hdr, 0, jk_shmem.size);
memcpy(jk_shmem.hdr->h.data.magic, shm_signature, JK_SHM_MAGIC_SIZ);
jk_shmem.hdr->h.data.size = sz;
@@ -360,11 +381,12 @@
jk_shmem.size, jk_shmem.hdr->h.data.size, jk_shmem.hdr);
}
else {
- jk_shmem.hdr->h.data.childs++;
+ unsigned int nchild = jk_shmem.hdr->h.data.childs + 1;
+ jk_shmem.attached = (int)getpid();
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_INFO,
"Attached shared memory [%d] size=%u free=%u addr=%#lx",
- jk_shmem.hdr->h.data.childs, jk_shmem.hdr->h.data.size,
+ nchild, jk_shmem.hdr->h.data.size,
jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos,
jk_shmem.hdr);
/*
@@ -374,20 +396,23 @@
* if the number of workers change between
* open and attach or between two attach operations.
*/
- if (jk_shmem.hdr->h.data.childs > 1) {
+ if (nchild > 1) {
if (JK_IS_DEBUG_LEVEL(l)) {
jk_log(l, JK_LOG_DEBUG,
"Reseting the shared memory for child %d",
- jk_shmem.hdr->h.data.childs);
+ nchild);
}
}
+ jk_shmem.hdr->h.data.childs = nchild;
jk_shmem.hdr->h.data.pos = 0;
jk_shmem.hdr->h.data.workers = 0;
}
JK_INIT_CS(&(jk_shmem.cs), rc);
- if ((rc = do_shm_open_lock(fname, attached, l))) {
- munmap((void *)jk_shmem.hdr, jk_shmem.size);
- close(jk_shmem.fd);
+ if ((rc = do_shm_open_lock(attached, l))) {
+ if (!attached) {
+ munmap((void *)jk_shmem.hdr, jk_shmem.size);
+ close(jk_shmem.fd);
+ }
jk_shmem.hdr = NULL;
jk_shmem.fd = -1;
JK_TRACE_EXIT(l);
@@ -413,27 +438,32 @@
if (jk_shmem.hdr) {
--jk_shmem.hdr->h.data.childs;
+ if (jk_shmem.fd_lock >= 0) {
+ close(jk_shmem.fd_lock);
+ jk_shmem.fd_lock = -1;
+ }
+ JK_DELETE_CS(&(jk_shmem.cs), rc);
if (jk_shmem.attached) {
int p = (int)getpid();
- if (p != jk_shmem.attached) {
+ if (p == jk_shmem.attached) {
/* In case this is a forked child
* do not close the shared memory.
* It will be closed by the parent.
*/
- return;
+ jk_shmem.size = 0;
+ jk_shmem.hdr = NULL;
+ jk_shmem.fd = -1;
+ return;
}
}
- if (jk_shmem.fd_lock >= 0) {
- close(jk_shmem.fd_lock);
- }
if (jk_shmem.fd >= 0) {
munmap((void *)jk_shmem.hdr, jk_shmem.size);
close(jk_shmem.fd);
+ if (jk_shmem.lockname) {
+ free(jk_shmem.lockname);
+ jk_shmem.lockname = NULL;
+ }
}
- jk_shmem.fd_lock = -1;
- }
- if (jk_shmem.size) {
- JK_DELETE_CS(&(jk_shmem.cs), rc);
}
jk_shmem.size = 0;
jk_shmem.hdr = NULL;