Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling misused rte in evbuffer #5002

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions cdb2jdbc/src/test/java/com/bloomberg/comdb2/jdbc/BadRte.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.bloomberg.comdb2.jdbc;

import java.sql.*;
import org.junit.*;
import org.junit.Assert.*;

public class BadRte {
@Test public void testBadRteClient() throws SQLException {
String db = System.getProperty("cdb2jdbc.test.database");
String cluster = System.getProperty("cdb2jdbc.test.cluster");
Connection conn = DriverManager.getConnection(String.format("jdbc:comdb2://%s/%s?allow_pmux_route=1&portmuxport=19000", cluster, db));
Statement stmt = conn.createStatement();
stmt.executeQuery("SELECT 1");
stmt.close();
conn.close();
}
}
1 change: 1 addition & 0 deletions net/net_appsock.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct appsock_handler_arg {
int fd;
int is_readonly;
int secure; /* whether connection is routed from a secure pmux port */
int badrte;
int admin;
struct sockaddr_in addr;
struct evbuffer *rd_buf;
Expand Down
33 changes: 26 additions & 7 deletions net/net_evbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@ static void host_connected_info_free(struct host_connected_info *info)
struct accept_info {
int fd;
int secure; /* whether connection is routed from a secure pmux port */
int badrte;
struct evbuffer *buf;
int to_len;
char *to_host;
Expand Down Expand Up @@ -843,7 +844,8 @@ static int close_oldest_pending_connection(void)
return 0;
}

static struct accept_info *accept_info_new(netinfo_type *netinfo_ptr, struct sockaddr_in *addr, int fd, int secure)
static struct accept_info *accept_info_new(netinfo_type *netinfo_ptr, struct sockaddr_in *addr, int fd, int secure,
int badrte)
{
check_base_thd();
if (pending_connections > max_pending_connections) {
Expand All @@ -855,6 +857,7 @@ static struct accept_info *accept_info_new(netinfo_type *netinfo_ptr, struct soc
a->ss = *addr;
a->fd = fd;
a->secure = secure;
a->badrte = badrte;
a->ev = event_new(base, fd, EV_READ, do_read, a);
event_add(a->ev, NULL);
TAILQ_INSERT_TAIL(&accept_list, a, entry);
Expand Down Expand Up @@ -2844,7 +2847,8 @@ static void rd_connect_msg_len(int fd, short what, void *data)
}
}

static int do_appsock_evbuffer(struct evbuffer *buf, struct sockaddr_in *ss, int fd, int is_readonly, int secure)
static int do_appsock_evbuffer(struct evbuffer *buf, struct sockaddr_in *ss, int fd, int is_readonly, int secure,
int *pbadrte)
{
struct appsock_info *info = NULL;
struct evbuffer_ptr b = evbuffer_search(buf, "\n", 1, NULL);
Expand All @@ -2861,6 +2865,15 @@ static int do_appsock_evbuffer(struct evbuffer *buf, struct sockaddr_in *ss, int
return 1;
}

if (strcmp(key, "rte ") == 0) {
evbuffer_read(buf, fd, -1);
evbuffer_free(buf);
ssize_t rc = write(fd, "0\n", 2);
if (rc == 2 && pbadrte)
*pbadrte = 1;
return 1;
}

info = get_appsock_info(key);
}

Expand All @@ -2873,6 +2886,7 @@ static int do_appsock_evbuffer(struct evbuffer *buf, struct sockaddr_in *ss, int
arg->rd_buf = buf;
arg->is_readonly = is_readonly;
arg->secure = secure;
arg->badrte = *pbadrte;

static int appsock_counter = 0;
arg->base = appsock_base[appsock_counter++];
Expand Down Expand Up @@ -2903,6 +2917,7 @@ static void do_read(int fd, short what, void *data)
netinfo_type *netinfo_ptr = a->netinfo_ptr;
struct sockaddr_in ss = a->ss;
int secure = a->secure;
int badrte = a->badrte;
a->fd = -1;
accept_info_free(a);
a = NULL;
Expand All @@ -2911,8 +2926,12 @@ static void do_read(int fd, short what, void *data)
shutdown_close(fd);
return;
}
if ((do_appsock_evbuffer(buf, &ss, fd, 0, secure)) == 0) return;
handle_appsock(netinfo_ptr, &ss, first_byte, buf, fd);
if ((do_appsock_evbuffer(buf, &ss, fd, 0, secure, &badrte)) == 0)
return;
if (badrte)
accept_info_new(netinfo_ptr, &ss, fd, secure, 1);
else
handle_appsock(netinfo_ptr, &ss, first_byte, buf, fd);
}

static void accept_cb(struct evconnlistener *listener, evutil_socket_t fd,
Expand All @@ -2922,7 +2941,7 @@ static void accept_cb(struct evconnlistener *listener, evutil_socket_t fd,
struct net_info *n = data;
netinfo_type *netinfo_ptr = n->netinfo_ptr;
netinfo_ptr->num_accepts++;
accept_info_new(netinfo_ptr, (struct sockaddr_in *)addr, fd, 0);
accept_info_new(netinfo_ptr, (struct sockaddr_in *)addr, fd, 0, 0);
}

static void accept_secure(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int len,
Expand All @@ -2932,7 +2951,7 @@ static void accept_secure(struct evconnlistener *listener, evutil_socket_t fd, s
struct net_info *n = data;
netinfo_type *netinfo_ptr = n->netinfo_ptr;
netinfo_ptr->num_accepts++;
accept_info_new(netinfo_ptr, (struct sockaddr_in *)addr, fd, 1);
accept_info_new(netinfo_ptr, (struct sockaddr_in *)addr, fd, 1, 0);
}

static void accept_error_cb(struct evconnlistener *listener, void *data)
Expand Down Expand Up @@ -3881,5 +3900,5 @@ void do_revconn_evbuffer(int fd, short what, void *data)
struct sockaddr_in addr;
socklen_t laddr = sizeof(addr);
getsockname(fd, (struct sockaddr *)&addr, &laddr);
do_appsock_evbuffer(buf, &addr, fd, 1, 0);
do_appsock_evbuffer(buf, &addr, fd, 1, 0, NULL);
}
2 changes: 2 additions & 0 deletions plugins/newsql/newsql_evbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,8 @@ static void newsql_setup_clnt_evbuffer(int fd, short what, void *data)
reset_clnt(clnt, 1);
char *origin = arg->origin;
clnt->origin = origin ? origin : intern("???");
if (arg->badrte)
logmsg(LOGMSG_ERROR, "misused rte from host %s\n", clnt->origin);
clnt->appdata = appdata;
clnt->done_cb = newsql_done_cb;

Expand Down