IPC: return CS_ERR_NO_RESOURCES to library when low on fds.

git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@3029 fd59a12c-fef9-0310-b244-a6a79926bd2f
This commit is contained in:
Angus Salkeld 2010-08-25 01:13:14 +00:00
parent f95c4f76c3
commit 3b320c17ae
4 changed files with 61 additions and 20 deletions

View File

@ -85,6 +85,7 @@
#else
#include <sys/sem.h>
#endif
#include "util.h"
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
@ -760,14 +761,14 @@ retry_send:
return (0);
}
static int
static cs_error_t
req_setup_recv (
struct conn_info *conn_info)
{
int res;
struct msghdr msg_recv;
struct iovec iov_recv;
int authenticated = 0;
cs_error_t auth_res = CS_ERR_LIBRARY;
#ifdef COROSYNC_LINUX
struct cmsghdr *cmsg;
@ -803,7 +804,7 @@ retry_recv:
goto retry_recv;
} else
if (res == -1 && errno != EAGAIN) {
return (0);
return (CS_ERR_LIBRARY);
} else
if (res == 0) {
#if defined(COROSYNC_SOLARIS) || defined(COROSYNC_BSD) || defined(COROSYNC_DARWIN)
@ -811,9 +812,9 @@ retry_recv:
* EOF is detected when recvmsg return 0.
*/
ipc_disconnect (conn_info);
return 0;
return (CS_ERR_LIBRARY);
#else
return (-1);
return (CS_ERR_SECURITY);
#endif
}
conn_info->setup_bytes_read += res;
@ -836,7 +837,9 @@ retry_recv:
egid = ucred_getegid (uc);
conn_info->client_pid = ucred_getpid (uc);
if (api->security_valid (euid, egid)) {
authenticated = 1;
auth_res = CS_OK;
} else {
auth_res = hdb_error_to_cs(errno);
}
ucred_free(uc);
}
@ -858,7 +861,9 @@ retry_recv:
egid = -1;
if (getpeereid (conn_info->fd, &euid, &egid) == 0) {
if (api->security_valid (euid, egid)) {
authenticated = 1;
auth_res = CS_OK;
} else {
auth_res = hdb_error_to_cs(errno);
}
}
}
@ -873,29 +878,36 @@ retry_recv:
if (cred) {
conn_info->client_pid = cred->pid;
if (api->security_valid (cred->uid, cred->gid)) {
authenticated = 1;
auth_res = CS_OK;
} else {
auth_res = hdb_error_to_cs(errno);
}
}
#else /* no credentials */
authenticated = 1;
log_printf (LOGSYS_LEVEL_ERROR, "Platform does not support IPC authentication. Using no authentication\n");
auth_res = CS_OK;
log_printf (LOGSYS_LEVEL_ERROR, "Platform does not support IPC authentication. Using no authentication\n");
#endif /* no credentials */
if (authenticated == 0) {
log_printf (LOGSYS_LEVEL_ERROR, "Invalid IPC credentials.\n");
if (auth_res != CS_OK) {
ipc_disconnect (conn_info);
return (-1);
}
if (auth_res == CS_ERR_NO_RESOURCES) {
log_printf (LOGSYS_LEVEL_ERROR,
"Not enough file desciptors for IPC connection.\n");
} else {
log_printf (LOGSYS_LEVEL_ERROR, "Invalid IPC credentials.\n");
}
return auth_res;
}
if (conn_info->setup_bytes_read == sizeof (mar_req_setup_t)) {
#ifdef COROSYNC_LINUX
setsockopt(conn_info->fd, SOL_SOCKET, SO_PASSCRED,
&off, sizeof (off));
#endif
return (1);
return (CS_OK);
}
return (0);
return (CS_ERR_LIBRARY);
}
static void ipc_disconnect (struct conn_info *conn_info)
@ -1575,10 +1587,10 @@ int coroipcs_handler_dispatch (
* send OK
*/
res = req_setup_recv (conn_info);
if (res == -1) {
req_setup_send (conn_info, CS_ERR_SECURITY);
if (res != CS_OK && res != CS_ERR_LIBRARY) {
req_setup_send (conn_info, res);
}
if (res != 1) {
if (res != CS_OK) {
return (0);
}

View File

@ -933,7 +933,8 @@ static int corosync_security_valid (int euid, int egid)
struct list_head *iter;
if (corosync_not_enough_fds_left) {
return 0;
errno = EMFILE;
return (0);
}
if (euid == 0 || egid == 0) {
@ -950,6 +951,7 @@ static int corosync_security_valid (int euid, int egid)
return (1);
}
errno = EACCES;
return (0);
}

View File

@ -65,6 +65,27 @@ enum e_ais_done {
AIS_DONE_ALREADY_RUNNING = 18,
};
static inline cs_error_t hdb_error_to_cs (int res) \
{ \
if (res == 0) { \
return (CS_OK); \
} else { \
if (errno == EBADF) { \
return (CS_ERR_BAD_HANDLE); \
} else \
if (errno == ENOMEM) { \
return (CS_ERR_NO_MEMORY); \
} else \
if (errno == EMFILE) { \
return (CS_ERR_NO_RESOURCES); \
} else \
if (errno == EACCES) { \
return (CS_ERR_SECURITY); \
} \
return (CS_ERR_LIBRARY); \
} \
}
/*
* Compare two names. returns non-zero on match.
*/

View File

@ -48,6 +48,12 @@ static inline cs_error_t hdb_error_to_cs (int res) \
} else \
if (errno == ENOMEM) { \
return (CS_ERR_NO_MEMORY); \
} else \
if (errno == EMFILE) { \
return (CS_ERR_NO_RESOURCES); \
} else \
if (errno == EACCES) { \
return (CS_ERR_SECURITY); \
} \
return (CS_ERR_LIBRARY); \
} \