PERFORCE change 83906 for review
soc-bushman
soc-bushman at FreeBSD.org
Mon Sep 19 07:01:23 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=83906
Change 83906 by soc-bushman at soc-bushman_stinger on 2005/09/19 14:01:11
some minor fixes - preparing to start a new branch
Affected files ...
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/cached.c#6 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_rs_query.c#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_rs_query.h#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_ws_query.c#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_ws_query.h#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/protocol.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/query.c#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/query.h#5 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/nsdispatch_test/nsdispatch_test.c#7 edit
Differences ...
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/cached.c#6 (text+ko) ====
@@ -207,6 +207,7 @@
memset(retval, 0, sizeof(struct runtime_env));
retval->sockfd = socket(PF_LOCAL, SOCK_STREAM, 0);
+ TRACE_INT(retval->sockfd);
if (config->force_unlink == 1)
unlink(config->socket_path);
@@ -227,8 +228,13 @@
TRACE_OUT(init_runtime_env);
return (NULL);
}
+
+ /*
+ * Here we're marking socket as non-blocking and setting its backlog
+ * to the maximum value
+ */
chmod(config->socket_path, config->socket_mode);
- listen(retval->sockfd, 100);
+ listen(retval->sockfd, -1);
fcntl(retval->sockfd, F_SETFL, O_NONBLOCK);
retval->queue = kqueue();
@@ -262,26 +268,40 @@
struct query_state *qstate;
struct sockaddr addr;
- size_t addr_len;
+ socklen_t addr_len;
int fd;
int res;
+
+ uid_t euid;
+ gid_t egid;
TRACE_IN(accept_connection);
addr_len = sizeof(struct sockaddr);
fd = accept(event_data->ident, &addr, &addr_len);
if (fd == -1) {
- /* do something */
- TRACE_POINT();
+ /* TODO: do something */
+ TRACE_OUT(accept_connection);
+ return;
+ }
+
+ if (getpeereid(fd, &euid, &egid) != 0) {
+ /* TODO: do something */
+ TRACE_OUT(accept_connection);
return;
}
- qstate = init_query_state(fd, sizeof(int));
- memset(&timeout, 0, sizeof(struct timespec));
+ qstate = init_query_state(fd, sizeof(int), euid, egid);
+ if (qstate == NULL) {
+ /* TODO: do something */
+ TRACE_OUT(accept_connection);
+ return;
+ }
+ memset(&timeout, 0, sizeof(struct timespec));
+ EV_SET(&eventlist[0], fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
+ 0, qstate->timeout.tv_sec * 1000, qstate);
EV_SET(&eventlist[1], fd, EVFILT_READ, EV_ADD | EV_ONESHOT,
NOTE_LOWAT, qstate->kevent_watermark, qstate);
- EV_SET(&eventlist[0], fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
- 0, qstate->timeout.tv_sec * 1000, qstate);
res = kevent(env->queue, eventlist, 2, NULL, 0, &timeout);
TRACE_INT(res);
TRACE_INT(fd);
@@ -418,7 +438,7 @@
qstate->use_alternate_io = 0;
if (qstate->use_alternate_io == 0) {
- if (qstate->kevent_watermark > MAX_SOCKET_IO_SIZE) {
+ if (qstate->kevent_watermark > MAX_SOCKET_IO_SIZE) {
if (qstate->io_buffer != NULL)
free(qstate->io_buffer);
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_rs_query.c#5 (text+ko) ====
@@ -92,7 +92,7 @@
return (-1);
}
- if (c_mp_rs_request->entry_length == 0) {
+ if (BUFSIZE_INVALID(c_mp_rs_request->entry_length)) {
TRACE_OUT(on_mp_read_session_request_read1);
return (-1);
}
@@ -158,7 +158,7 @@
return (-1);
}
- asprintf(&dec_cache_entry_name, "%s%s", qstate->euid_str,
+ asprintf(&dec_cache_entry_name, "%s%s", qstate->eid_str,
qstate->config_entry->c_params->entry_name);
assert(dec_cache_entry_name != NULL);
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_rs_query.h#5 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_ws_query.c#5 (text+ko) ====
@@ -94,7 +94,7 @@
return (-1);
}
- if (c_mp_ws_request->entry_length == 0) {
+ if (BUFSIZE_INVALID(c_mp_ws_request->entry_length)) {
TRACE_OUT(on_mp_write_session_request_read1);
return (-1);
}
@@ -161,7 +161,7 @@
return (-1);
}
- asprintf(&dec_cache_entry_name, "%s%s", qstate->euid_str,
+ asprintf(&dec_cache_entry_name, "%s%s", qstate->eid_str,
qstate->config_entry->c_params->entry_name);
assert(dec_cache_entry_name != NULL);
@@ -303,6 +303,11 @@
TRACE_OUT(on_mp_write_session_write_request_read1);
return (-1);
}
+
+ if (BUFSIZE_INVALID(write_request->data_size)) {
+ TRACE_OUT(on_mp_write_session_write_request_read1);
+ return (-1);
+ }
write_request->data = (char *)malloc(write_request->data_size);
assert(write_request->data != NULL);
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_ws_query.h#5 (text+ko) ====
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/protocol.h#4 (text+ko) ====
@@ -30,6 +30,13 @@
#include <stdlib.h>
+/* maximum buffer size to receive - larger buffers are not allowed */
+#define MAX_BUFFER_SIZE (1 << 20)
+
+/* buffer size correctness checking routine */
+#define BUFSIZE_CORRECT(x) (((x) > 0) && ((x) < MAX_BUFFER_SIZE))
+#define BUFSIZE_INVALID(x) (!BUFSIZE_CORRECT(x))
+
struct cache_write_request
{
char *entry;
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/query.c#5 (text+ko) ====
@@ -67,16 +67,15 @@
{
struct msghdr cred_hdr;
struct iovec iov;
- int elem_type;
+ int elem_type;
struct {
struct cmsghdr hdr;
struct cmsgcred creds;
- } cmsg;
+ } cmsg;
TRACE_IN(on_query_startup);
assert(qstate != NULL);
- assert(qstate != NULL);
memset(&cred_hdr, 0, sizeof(struct msghdr));
cred_hdr.msg_iov = &iov;
@@ -88,6 +87,7 @@
iov.iov_base = &elem_type;
iov.iov_len = sizeof(int);
+ TRACE_INT(qstate->sockfd);
if (recvmsg(qstate->sockfd, &cred_hdr, 0) == -1) {
TRACE_OUT(on_query_startup);
return (-1);
@@ -101,19 +101,25 @@
}
qstate->uid = cmsg.creds.cmcred_uid;
- qstate->euid = cmsg.creds.cmcred_euid;
- qstate->pid = cmsg.creds.cmcred_pid;
-
- if (asprintf(&qstate->euid_str, "%d_", qstate->euid) == -1) {
- TRACE_OUT(on_query_startup);
- return (-1);
- }
- qstate->euid_str_length = strlen(qstate->euid_str);
+ qstate->gid = cmsg.creds.cmcred_gid;
TRACE_INT(qstate->uid);
+ TRACE_INT(qstate->gid);
TRACE_INT(qstate->euid);
- TRACE_INT(qstate->pid);
+ TRACE_INT(qstate->egid);
+/*
+ This check is probably a bit redundant - per-user cache is always separated by
+ the euid/egid pair
+*/
+#ifndef NO_STRICT_EID_CHECKING
+ if ((qstate->uid != qstate->euid) ||
+ (qstate->gid != qstate->egid)) {
+ TRACE_OUT(on_query_startup);
+ return (-1);
+ }
+#endif
+
switch (elem_type) {
case CET_WRITE_REQUEST:
qstate->process_func = on_write_request_read1;
@@ -131,8 +137,8 @@
qstate->process_func = on_mp_read_session_request_read1;
break;
default:
- elem_type = -1;
- break;
+ TRACE_OUT(on_query_startup);
+ return (-1);
}
qstate->kevent_watermark = 0;
@@ -211,9 +217,9 @@
return (-1);
}
- if ((write_request->entry_length == 0) ||
- (write_request->cache_key_length == 0) ||
- (write_request->data_size == 0)) {
+ if (BUFSIZE_INVALID(write_request->entry_length) ||
+ BUFSIZE_INVALID(write_request->cache_key_length) ||
+ BUFSIZE_INVALID(write_request->data_size)) {
TRACE_OUT(on_write_request_read1);
return (-1);
}
@@ -225,11 +231,11 @@
write_request->cache_key = (char *)malloc(
write_request->cache_key_length +
- qstate->euid_str_length + 1);
+ qstate->eid_str_length + 1);
assert(write_request->cache_key != NULL);
- memcpy(write_request->cache_key, qstate->euid_str,
- qstate->euid_str_length);
- memset(write_request->cache_key + qstate->euid_str_length, 0,
+ memcpy(write_request->cache_key, qstate->eid_str,
+ qstate->eid_str_length);
+ memset(write_request->cache_key + qstate->eid_str_length, 0,
write_request->cache_key_length + 1);
write_request->data = (char *)malloc(write_request->data_size);
@@ -258,7 +264,7 @@
result = qstate->read_func(qstate, write_request->entry,
write_request->entry_length);
result += qstate->read_func(qstate, write_request->cache_key +
- qstate->euid_str_length, write_request->cache_key_length);
+ qstate->eid_str_length, write_request->cache_key_length);
result += qstate->read_func(qstate, write_request->data,
write_request->data_size);
@@ -345,7 +351,7 @@
if (result != sizeof(int)) {
TRACE_OUT(on_write_response_write1);
return (-1);
- }
+ }
finalize_comm_element(&qstate->request);
finalize_comm_element(&qstate->response);
@@ -381,8 +387,8 @@
return (-1);
}
- if ((read_request->entry_length == 0) ||
- (read_request->cache_key_length == 0)) {
+ if (BUFSIZE_INVALID(read_request->entry_length) ||
+ BUFSIZE_INVALID(read_request->cache_key_length)) {
TRACE_OUT(on_read_request_read1);
return (-1);
}
@@ -394,11 +400,11 @@
read_request->cache_key = (char *)malloc(
read_request->cache_key_length +
- qstate->euid_str_length + 1);
+ qstate->eid_str_length + 1);
assert(read_request->cache_key != NULL);
- memcpy(read_request->cache_key, qstate->euid_str,
- qstate->euid_str_length);
- memset(read_request->cache_key + qstate->euid_str_length, 0,
+ memcpy(read_request->cache_key, qstate->eid_str,
+ qstate->eid_str_length);
+ memset(read_request->cache_key + qstate->eid_str_length, 0,
read_request->cache_key_length + 1);
qstate->kevent_watermark = read_request->entry_length +
@@ -422,7 +428,7 @@
result = qstate->read_func(qstate, read_request->entry,
read_request->entry_length);
result += qstate->read_func(qstate,
- read_request->cache_key + qstate->euid_str_length,
+ read_request->cache_key + qstate->eid_str_length,
read_request->cache_key_length);
if (result != qstate->kevent_watermark) {
@@ -685,9 +691,18 @@
ssize_t result;
TRACE_IN(query_socket_read);
+ if (qstate->socket_failed != 0) {
+ TRACE_POINT();
+ return (-1);
+ }
+
result = read(qstate->sockfd, buf, nbytes);
- TRACE_OUT(query_socket_read);
+ if ((result == -1) || (result < nbytes)) {
+ qstate->socket_failed = 1;
+ TRACE_POINT();
+ }
+ TRACE_OUT(query_socket_read);
return (result);
}
@@ -697,21 +712,23 @@
ssize_t result;
TRACE_IN(query_socket_write);
+ if (qstate->socket_failed != 0) {
+ TRACE_POINT();
+ return (-1);
+ }
+
result = write(qstate->sockfd, buf, nbytes);
- if (result == -1) {
- TRACE_INT(qstate->sockfd);
- TRACE_PTR(buf);
- TRACE_INT(nbytes);
- TRACE_INT(errno);
+ if ((result == -1) || (result < nbytes)) {
+ qstate->socket_failed = 1;
+ TRACE_POINT();
}
- TRACE_OUT(query_socket_write);
-
+ TRACE_OUT(query_socket_write);
return (result);
}
struct query_state *
-init_query_state(int sockfd, size_t kevent_watermark)
+init_query_state(int sockfd, size_t kevent_watermark, uid_t euid, gid_t egid)
{
struct query_state *retval;
@@ -724,6 +741,18 @@
retval->kevent_filter = EVFILT_READ;
retval->kevent_watermark = kevent_watermark;
+ retval->euid = euid;
+ retval->egid = egid;
+ retval->uid = retval->gid = -1;
+
+ if (asprintf(&retval->eid_str, "%d_%d_", retval->euid,
+ retval->egid) == -1) {
+ free(retval);
+ TRACE_OUT(init_query_state);
+ return (NULL);
+ }
+ retval->eid_str_length = strlen(retval->eid_str);
+
init_comm_element(&retval->request, CET_UNDEFINED);
init_comm_element(&retval->response, CET_UNDEFINED);
retval->process_func = on_query_startup;
@@ -744,8 +773,8 @@
destroy_query_state(struct query_state *qstate)
{
TRACE_IN(destroy_query_state);
- if (qstate->euid_str != NULL)
- free(qstate->euid_str);
+ if (qstate->eid_str != NULL)
+ free(qstate->eid_str);
if (qstate->io_buffer != NULL)
free(qstate->io_buffer);
==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/query.h#5 (text+ko) ====
@@ -64,18 +64,20 @@
query_write_func write_func; /* data write function */
query_read_func read_func; /* data read function */
- char *euid_str; /* string version of the euid */
- size_t euid_str_length;
+ char *eid_str; /* the user-identifying string (euid_egid_) */
+ size_t eid_str_length;
- uid_t euid; /* euid of the caller, recevied via credentials */
- uid_t uid; /* uid of the caller, recevied via credentials */
- pid_t pid; /* pid of the caller, recevied via credentials */
+ uid_t euid; /* euid of the caller, received via getpeereid */
+ uid_t uid; /* uid of the caller, received via credentials */
+ gid_t egid; /* egid of the caller, received via getpeereid */
+ gid_t gid; /* gid of the caller received via credentials */
size_t io_buffer_size;
size_t io_buffer_watermark;
size_t kevent_watermark; /* bytes to be sent/received */
int sockfd; /* the unix socket to read/write */
- int kevent_filter; /* EVFILT_READ or EVFILT_WRITE */
+ int kevent_filter; /* EVFILT_READ or EVFILT_WRITE */
+ int socket_failed; /* set to 1 if the socket doesn't work correctly */
char *io_buffer;
char *io_buffer_p;
@@ -91,7 +93,7 @@
extern ssize_t query_socket_write(struct query_state *, const void *,
size_t);
-extern struct query_state *init_query_state(int, size_t);
+extern struct query_state *init_query_state(int, size_t, uid_t, gid_t);
extern void destroy_query_state(struct query_state *);
extern struct configuration_entry *find_config_entry_by_name_and_euid(
==== //depot/projects/soc2005/nsswitch_cached/tests/nsdispatch_test/nsdispatch_test.c#7 (text+ko) ====
@@ -411,17 +411,17 @@
tsystem = __init_test_system("testing system testing :)");
assert(tsystem != NULL);
-/* tinfo = __create_test_info("getservbyname_test", getservbyname_test, 1);
+ tinfo = __create_test_info("getservbyname_test", getservbyname_test, 1);
assert(tinfo != NULL);
- __register_test_info(tsystem, tinfo);*/
+ __register_test_info(tsystem, tinfo);
tinfo = __create_test_info("getpwnam_test", getpwnam_test, 1);
assert(tinfo != NULL);
__register_test_info(tsystem, tinfo);
-/* tinfo = __create_test_info("getgrnam_test", getgrnam_test, 1);
+ tinfo = __create_test_info("getgrnam_test", getgrnam_test, 1);
assert(tinfo != NULL);
- __register_test_info(tsystem, tinfo);*/
+ __register_test_info(tsystem, tinfo);
/* tinfo = __create_test_info("getaddrinfo_test", getaddrinfo_test, 1);
assert(tinfo != NULL);
@@ -435,13 +435,13 @@
assert(tinfo != NULL);
__register_test_info(tsystem, tinfo); */
-/* tinfo = __create_test_info("getprotoent_test", getprotoent_test, 1);
+ tinfo = __create_test_info("getprotoent_test", getprotoent_test, 1);
assert(tinfo != NULL);
- __register_test_info(tsystem, tinfo);*/
+ __register_test_info(tsystem, tinfo);
-/* tinfo = __create_test_info("getrpcent_test", getrpcent_test, 1);
+ tinfo = __create_test_info("getrpcent_test", getrpcent_test, 1);
assert(tinfo != NULL);
- __register_test_info(tsystem, tinfo);*/
+ __register_test_info(tsystem, tinfo);
__process_tests(tsystem, &passed, &failed);
__test_log1("__process_tests returned, %d passed, %d failed\n", passed, failed);
More information about the p4-projects
mailing list