From 3aa4afeb00d82797c271d37acd7979b1b9b0f0a5 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sat, 2 Aug 2014 17:10:49 +0200 Subject: [PATCH] frontend: Make sure to not read to much from a connection buffer. The current command, as stored in the connection buffer, is not necessarily nil-terminated. That's only the case if there's no further data in the buffer (which will *often* be the case in the current implementation when using 'sysdb' as the client) but the code should never rely on that. In cases where the function operating on the data does not support specifying the length of the string to work on, copy the data to a temporary buffer first. --- src/frontend/connection.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/frontend/connection.c b/src/frontend/connection.c index 7777750..0bdafdc 100644 --- a/src/frontend/connection.c +++ b/src/frontend/connection.c @@ -281,8 +281,11 @@ command_handle(sdb_conn_t *conn) parsetree = sdb_fe_parse(sdb_strbuf_string(conn->buf), (int)conn->cmd_len); if (! parsetree) { + char query[conn->cmd_len + 1]; + strncpy(query, sdb_strbuf_string(conn->buf), conn->cmd_len); + query[sizeof(query) - 1] = '\0'; sdb_log(SDB_LOG_ERR, "frontend: Failed to parse query '%s'", - sdb_strbuf_string(conn->buf)); + query); status = -1; break; } @@ -296,12 +299,17 @@ command_handle(sdb_conn_t *conn) break; default: + { + char query[conn->cmd_len + 1]; + strncpy(query, sdb_strbuf_string(conn->buf), conn->cmd_len); + query[sizeof(query) - 1] = '\0'; sdb_log(SDB_LOG_WARNING, "frontend: Ignoring %d command%s " "in multi-statement query '%s'", sdb_llist_len(parsetree) - 1, sdb_llist_len(parsetree) == 2 ? "" : "s", - sdb_strbuf_string(conn->buf)); + query); node = SDB_CONN_NODE(sdb_llist_get(parsetree, 0)); + } } if (node) { @@ -314,9 +322,13 @@ command_handle(sdb_conn_t *conn) } case CONNECTION_FETCH: - status = sdb_fe_fetch(conn, sdb_strbuf_string(conn->buf), - /* filter = */ NULL); + { + char hostname[conn->cmd_len + 1]; + strncpy(hostname, sdb_strbuf_string(conn->buf), conn->cmd_len); + hostname[sizeof(hostname) - 1] = '\0'; + status = sdb_fe_fetch(conn, hostname, /* filter = */ NULL); break; + } case CONNECTION_LIST: status = sdb_fe_list(conn, /* filter = */ NULL); break; @@ -327,8 +339,11 @@ command_handle(sdb_conn_t *conn) m = sdb_fe_parse_matcher(sdb_strbuf_string(conn->buf), (int)conn->cmd_len); if (! m) { - sdb_log(SDB_LOG_ERR, "frontend: Failed to parse expression '%s'", - sdb_strbuf_string(conn->buf)); + char expr[conn->cmd_len + 1]; + strncpy(expr, sdb_strbuf_string(conn->buf), conn->cmd_len); + expr[sizeof(expr) - 1] = '\0'; + sdb_log(SDB_LOG_ERR, "frontend: Failed to parse " + "lookup condition '%s'", expr); status = -1; break; } -- 2.30.2