From 5fd282529da85f44836aaba8a0c66f1514484148 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 12 Feb 2018 23:07:39 +0000 Subject: [PATCH] Fix -noauth security handling Fix the handling of -noauth security in the af_rxrpc transport module. Without this, a SEGV can be triggered by: pts examine -nameorid dhowells -noauth -cell my.cell.org Signed-off-by: David Howells --- af_rxrpc/af_rxrpc.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/af_rxrpc/af_rxrpc.c b/af_rxrpc/af_rxrpc.c index faebfe7..724abf9 100644 --- a/af_rxrpc/af_rxrpc.c +++ b/af_rxrpc/af_rxrpc.c @@ -208,7 +208,8 @@ static void af_rxrpc_free_transport(struct kafs_transport_handle *trans) } /* - * Set up a security descriptor + * Set up a security descriptor. Note that cell_name can be NULL (for instance + * if -noauth was passed). */ static struct kafs_security_handle *af_rxrpc_new_security( struct kafs_transport_handle *transport, @@ -216,7 +217,9 @@ static struct kafs_security_handle *af_rxrpc_new_security( enum kafs_connection_auth_level level) { struct kafs_security_handle *security; - size_t namelen = strlen(cell_name); + size_t namelen; + + namelen = cell_name ? strlen(cell_name) : 0; security = calloc(1, sizeof(*security) + namelen + 1); if (!security) @@ -231,22 +234,33 @@ static struct kafs_security_handle *af_rxrpc_new_security( break; case kafs_connection_local_auth: fprintf(stderr, "Local auth not supported by AF_RXRPC transport\n"); - errno = -EINVAL; - free(security); - return NULL; + goto inval; case kafs_connection_clear: + if (!cell_name) + goto inval; security->min_sec_level = RXRPC_SECURITY_PLAIN; break; case kafs_connection_integrity_only: + if (!cell_name) + goto inval; security->min_sec_level = RXRPC_SECURITY_AUTH; break; case kafs_connection_encrypt: + if (!cell_name) + goto inval; security->min_sec_level = RXRPC_SECURITY_ENCRYPT; break; } - memcpy(security->cell_name, cell_name, namelen + 1); + + if (cell_name) + memcpy(security->cell_name, cell_name, namelen + 1); usage_get(&security->transport->usage); return security; + +inval: + errno = -EINVAL; + free(security); + return NULL; } /* @@ -278,7 +292,7 @@ static struct kafs_connection_handle *af_rxrpc_open_connection( errno = EINVAL; return NULL; } - + conn = calloc(1, sizeof(*conn)); if (!conn) return NULL; @@ -291,7 +305,7 @@ static struct kafs_connection_handle *af_rxrpc_open_connection( conn->peer.transport_type = SOCK_DGRAM; conn->peer.transport_len = salen; memcpy(&conn->peer.transport, sa, salen); - + /* Open up a socket for talking to the AF_RXRPC module */ conn->fd = socket(AF_RXRPC, SOCK_DGRAM, PF_INET); if (conn->fd < 0) @@ -305,7 +319,7 @@ static struct kafs_connection_handle *af_rxrpc_open_connection( goto error_conn; } - if (security) { + if (security->level != kafs_connection_no_auth) { ret = setsockopt(conn->fd, SOL_RXRPC, RXRPC_MIN_SECURITY_LEVEL, &security->min_sec_level, sizeof(security->min_sec_level)); @@ -522,7 +536,7 @@ static int af_rxrpc_recv_data(struct kafs_call_handle *call, debug("Detected EOR\n"); call->known_to_kernel = 0; } - + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { unsigned char *p; int n; @@ -635,7 +649,7 @@ static int af_rxrpc_poll_connection(struct kafs_connection_handle *conn, int now int ret; debug("-->poll()\n"); - + fds[0].fd = conn->fd; fds[0].events = POLLIN; fds[0].revents = 0; -- 2.50.1