Skip to content
Snippets Groups Projects
Commit 06da776e authored by Leif Johansson's avatar Leif Johansson
Browse files

Merge pull request #6 from fredrikt/fix_zero_sized_buffers

Fix zero sized buffers
parents 2f6f9d20 95c3d844
Branches
No related tags found
No related merge requests found
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <signal.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <pthread.h> #include <pthread.h>
...@@ -66,18 +67,52 @@ static int install_syscall_filter(void) ...@@ -66,18 +67,52 @@ static int install_syscall_filter(void)
ALLOW_SYSCALL(futex), ALLOW_SYSCALL(futex),
ALLOW_SYSCALL(brk), ALLOW_SYSCALL(brk),
ALLOW_SYSCALL(open), ALLOW_SYSCALL(open),
#ifdef __NR_fstat64
ALLOW_SYSCALL(fstat64), ALLOW_SYSCALL(fstat64),
#else
ALLOW_SYSCALL(fstat),
#endif
#ifdef __NR_mmap2
ALLOW_SYSCALL(mmap2), ALLOW_SYSCALL(mmap2),
#else
ALLOW_SYSCALL(mmap),
#endif
ALLOW_SYSCALL(mprotect), ALLOW_SYSCALL(mprotect),
ALLOW_SYSCALL(close), ALLOW_SYSCALL(close),
ALLOW_SYSCALL(access), ALLOW_SYSCALL(access),
ALLOW_SYSCALL(munmap), ALLOW_SYSCALL(munmap),
ALLOW_SYSCALL(time), ALLOW_SYSCALL(time),
#ifdef __NR__llseek
ALLOW_SYSCALL(_llseek), ALLOW_SYSCALL(_llseek),
#else
ALLOW_SYSCALL(lseek),
#endif
#ifdef __NR_stat64
ALLOW_SYSCALL(stat64), ALLOW_SYSCALL(stat64),
#else
ALLOW_SYSCALL(stat),
#endif
#ifdef __NR_fcntl64
ALLOW_SYSCALL(fcntl64), ALLOW_SYSCALL(fcntl64),
#else
ALLOW_SYSCALL(fcntl),
#endif
ALLOW_SYSCALL(mlock), ALLOW_SYSCALL(mlock),
ALLOW_SYSCALL(munlock), ALLOW_SYSCALL(munlock),
ALLOW_SYSCALL(socket),
ALLOW_SYSCALL(setsockopt),
ALLOW_SYSCALL(bind),
ALLOW_SYSCALL(listen),
ALLOW_SYSCALL(getsockname),
ALLOW_SYSCALL(connect),
ALLOW_SYSCALL(sendto),
ALLOW_SYSCALL(select),
ALLOW_SYSCALL(accept),
ALLOW_SYSCALL(clone),
ALLOW_SYSCALL(set_robust_list),
ALLOW_SYSCALL(recvfrom),
ALLOW_SYSCALL(madvise),
ALLOW_SYSCALL(rt_sigaction),
KILL_PROCESS, KILL_PROCESS,
}; };
struct sock_fprog prog = { struct sock_fprog prog = {
...@@ -121,6 +156,11 @@ static int usage(void) ...@@ -121,6 +156,11 @@ static int usage(void)
exit(2); exit(2);
} }
void termination_handler (int signum)
{
is_running = 0;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
CK_C_GetFunctionList func_get_list; CK_C_GetFunctionList func_get_list;
...@@ -192,6 +232,10 @@ int main(int argc, char *argv[]) ...@@ -192,6 +232,10 @@ int main(int argc, char *argv[])
if (sock == -1) if (sock == -1)
exit(1); exit(1);
/* Shut down gracefully on SIGTERM. */
if (signal (SIGTERM, termination_handler) == SIG_IGN)
signal (SIGTERM, SIG_IGN);
is_running = 1; is_running = 1;
while (is_running) { while (is_running) {
FD_ZERO(&read_fds); FD_ZERO(&read_fds);
......
...@@ -72,7 +72,6 @@ typedef struct _DispatchState { ...@@ -72,7 +72,6 @@ typedef struct _DispatchState {
struct _DispatchState *next; struct _DispatchState *next;
pthread_t thread; pthread_t thread;
CallState cs; CallState cs;
int socket;
} DispatchState; } DispatchState;
/* A linked list of dispatcher threads */ /* A linked list of dispatcher threads */
...@@ -105,10 +104,10 @@ void gck_rpc_log(const char *msg, ...) ...@@ -105,10 +104,10 @@ void gck_rpc_log(const char *msg, ...)
va_start(ap, msg); va_start(ap, msg);
#if DEBUG_OUTPUT #if DEBUG_OUTPUT
vfprintf(stderr, msg, ap); vfprintf(stderr, msg, ap);
fprintf(stderr, "\n");
#else #else
vsyslog(LOG_INFO,msg,ap); vsyslog(LOG_INFO,msg,ap);
#endif #endif
printf("\n");
va_end(ap); va_end(ap);
} }
...@@ -215,9 +214,11 @@ proto_read_byte_buffer(CallState * cs, CK_BYTE_PTR * buffer, ...@@ -215,9 +214,11 @@ proto_read_byte_buffer(CallState * cs, CK_BYTE_PTR * buffer,
*n_buffer = length; *n_buffer = length;
*buffer = NULL; *buffer = NULL;
/* If set to zero, then they just want the length */ /* We go ahead and allocate a buffer even if length is zero. The code used
if (!length) * to just return CKR_OK without allocating a buffer, but that breaks a
return CKR_OK; * test case in pkcs11-tool for C_GenerateRandom of 0 bytes. Best to be as
* transparent as possible and let the p11 module decide how to handle it.
*/
*buffer = call_alloc(cs, length * sizeof(CK_BYTE)); *buffer = call_alloc(cs, length * sizeof(CK_BYTE));
if (!*buffer) if (!*buffer)
...@@ -884,11 +885,12 @@ static CK_RV rpc_C_Finalize(CallState * cs) ...@@ -884,11 +885,12 @@ static CK_RV rpc_C_Finalize(CallState * cs)
if (c->sock == cs->sock) if (c->sock == cs->sock)
continue ; continue ;
if (c->req && if (c->req &&
c->req->call_id == GCK_RPC_CALL_C_WaitForSlotEvent) { (c->req->call_id == GCK_RPC_CALL_C_WaitForSlotEvent)) {
gck_rpc_log("Sending interuption signal to %d\n", gck_rpc_log("Sending interuption signal to %i\n",
ds->socket); c->sock);
if (ds->socket) if (c->sock != -1)
shutdown(ds->socket, SHUT_RDWR); if (shutdown(c->sock, SHUT_RDWR) == 0)
c->sock = -1;
//pthread_kill(ds->thread, SIGINT); //pthread_kill(ds->thread, SIGINT);
} }
} }
...@@ -2203,7 +2205,8 @@ void gck_rpc_layer_accept(void) ...@@ -2203,7 +2205,8 @@ void gck_rpc_layer_accept(void)
/* Cleanup any completed dispatch threads */ /* Cleanup any completed dispatch threads */
pthread_mutex_lock(&pkcs11_dispatchers_mutex); pthread_mutex_lock(&pkcs11_dispatchers_mutex);
for (here = &pkcs11_dispatchers, ds = *here; ds != NULL; ds = *here) { for (here = &pkcs11_dispatchers, ds = *here; ds != NULL; ds = *here) {
if (ds->socket == -1) { CallState *c = &ds->cs;
if (c && c->sock == -1) {
pthread_join(ds->thread, NULL); pthread_join(ds->thread, NULL);
*here = ds->next; *here = ds->next;
free(ds); free(ds);
...@@ -2227,7 +2230,6 @@ void gck_rpc_layer_accept(void) ...@@ -2227,7 +2230,6 @@ void gck_rpc_layer_accept(void)
return; return;
} }
ds->socket = new_fd;
ds->cs.sock = new_fd; ds->cs.sock = new_fd;
ds->cs.read = &read_all; ds->cs.read = &read_all;
ds->cs.write = &write_all; ds->cs.write = &write_all;
...@@ -2295,18 +2297,16 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module) ...@@ -2295,18 +2297,16 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module)
if (!strncmp("tcp://", prefix, 6)) { if (!strncmp("tcp://", prefix, 6)) {
int one = 1, port; int one = 1, port;
char *p = NULL; char *p = NULL;
const char *ip; char *ip;
ip = strdup(prefix + 6); ip = strdup(prefix + 6);
if (ip) if (ip == NULL) {
p = strchr(ip, ':'); gck_rpc_warn("out of memory");
if (!ip) {
gck_rpc_warn("invalid syntax for pkcs11 socket : %s",
prefix);
return -1; return -1;
} }
p = strchr(ip, ':');
if (p) { if (p) {
*p = '\0'; *p = '\0';
port = strtol(p + 1, NULL, 0); port = strtol(p + 1, NULL, 0);
...@@ -2323,7 +2323,7 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module) ...@@ -2323,7 +2323,7 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module)
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof (one)) == -1) { (char *)&one, sizeof (one)) == -1) {
gck_rpc_warn("couldn't create set pkcs11 " gck_rpc_warn("couldn't set pkcs11 "
"socket options : %s", strerror (errno)); "socket options : %s", strerror (errno));
return -1; return -1;
} }
...@@ -2331,7 +2331,7 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module) ...@@ -2331,7 +2331,7 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module)
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&one, sizeof(one)) == -1) { (char *)&one, sizeof(one)) == -1) {
gck_rpc_warn gck_rpc_warn
("couldn't create set pkcs11 socket options : %s", ("couldn't set pkcs11 socket options : %s",
strerror(errno)); strerror(errno));
return -1; return -1;
} }
...@@ -2346,6 +2346,8 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module) ...@@ -2346,6 +2346,8 @@ int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module)
snprintf(pkcs11_socket_path, sizeof(pkcs11_socket_path), snprintf(pkcs11_socket_path, sizeof(pkcs11_socket_path),
"%s", prefix); "%s", prefix);
free(ip);
} else { } else {
snprintf(pkcs11_socket_path, sizeof(pkcs11_socket_path), snprintf(pkcs11_socket_path, sizeof(pkcs11_socket_path),
"%s/socket.pkcs11", prefix); "%s/socket.pkcs11", prefix);
...@@ -2421,15 +2423,19 @@ void gck_rpc_layer_uninitialize(void) ...@@ -2421,15 +2423,19 @@ void gck_rpc_layer_uninitialize(void)
/* Stop all of the dispatch threads */ /* Stop all of the dispatch threads */
pthread_mutex_lock(&pkcs11_dispatchers_mutex); pthread_mutex_lock(&pkcs11_dispatchers_mutex);
for (ds = pkcs11_dispatchers; ds; ds = next) { for (ds = pkcs11_dispatchers; ds; ds = next) {
CallState *c = &ds->cs;
next = ds->next; next = ds->next;
/* Forcibly shutdown the connection */ /* Forcibly shutdown the connection */
if (ds->socket) if (c && c->sock != -1)
shutdown(ds->socket, SHUT_RDWR); if (shutdown(c->sock, SHUT_RDWR) == 0)
c->sock = -1;
pthread_join(ds->thread, NULL); pthread_join(ds->thread, NULL);
/* This is always closed by dispatch thread */ /* This is always closed by dispatch thread */
assert(ds->socket == -1); if (c)
assert(c->sock == -1);
free(ds); free(ds);
} }
pthread_mutex_unlock(&pkcs11_dispatchers_mutex); pthread_mutex_unlock(&pkcs11_dispatchers_mutex);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment