aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-09-27 10:13:08 -0400
committerDavid Howells <dhowells@redhat.com>2018-09-28 05:32:31 -0400
commit403fc2a138457f1071b186786a7589ef7382c8bc (patch)
treea5fe93f58dc7d56d8731c9625df2f1efdc0bf436
parentece64fec164f523bfbe874abdef2a0e6ff376251 (diff)
rxrpc: Improve up-front incoming packet checking
Do more up-front checking on incoming packets to weed out invalid ones and also ones aimed at services that we don't support. Whilst we're at it, replace the clearing of call and skew if we don't find a connection with just initialising the variables to zero at the top of the function. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--net/rxrpc/input.c63
-rw-r--r--net/rxrpc/protocol.h15
2 files changed, 50 insertions, 28 deletions
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index b0f12471f5e7..a569e9e010d1 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -1125,12 +1125,13 @@ void rxrpc_data_ready(struct sock *udp_sk)
1125{ 1125{
1126 struct rxrpc_connection *conn; 1126 struct rxrpc_connection *conn;
1127 struct rxrpc_channel *chan; 1127 struct rxrpc_channel *chan;
1128 struct rxrpc_call *call; 1128 struct rxrpc_call *call = NULL;
1129 struct rxrpc_skb_priv *sp; 1129 struct rxrpc_skb_priv *sp;
1130 struct rxrpc_local *local = udp_sk->sk_user_data; 1130 struct rxrpc_local *local = udp_sk->sk_user_data;
1131 struct rxrpc_sock *rx;
1131 struct sk_buff *skb; 1132 struct sk_buff *skb;
1132 unsigned int channel; 1133 unsigned int channel;
1133 int ret, skew; 1134 int ret, skew = 0;
1134 1135
1135 _enter("%p", udp_sk); 1136 _enter("%p", udp_sk);
1136 1137
@@ -1181,12 +1182,6 @@ void rxrpc_data_ready(struct sock *udp_sk)
1181 1182
1182 trace_rxrpc_rx_packet(sp); 1183 trace_rxrpc_rx_packet(sp);
1183 1184
1184 if (sp->hdr.type >= RXRPC_N_PACKET_TYPES ||
1185 !((RXRPC_SUPPORTED_PACKET_TYPES >> sp->hdr.type) & 1)) {
1186 _proto("Rx Bad Packet Type %u", sp->hdr.type);
1187 goto bad_message;
1188 }
1189
1190 switch (sp->hdr.type) { 1185 switch (sp->hdr.type) {
1191 case RXRPC_PACKET_TYPE_VERSION: 1186 case RXRPC_PACKET_TYPE_VERSION:
1192 if (rxrpc_to_client(sp)) 1187 if (rxrpc_to_client(sp))
@@ -1198,24 +1193,63 @@ void rxrpc_data_ready(struct sock *udp_sk)
1198 if (rxrpc_to_server(sp)) 1193 if (rxrpc_to_server(sp))
1199 goto discard; 1194 goto discard;
1200 /* Fall through */ 1195 /* Fall through */
1196 case RXRPC_PACKET_TYPE_ACK:
1197 case RXRPC_PACKET_TYPE_ACKALL:
1198 if (sp->hdr.callNumber == 0)
1199 goto bad_message;
1200 /* Fall through */
1201 case RXRPC_PACKET_TYPE_ABORT:
1202 break;
1201 1203
1202 case RXRPC_PACKET_TYPE_DATA: 1204 case RXRPC_PACKET_TYPE_DATA:
1203 if (sp->hdr.callNumber == 0) 1205 if (sp->hdr.callNumber == 0 ||
1206 sp->hdr.seq == 0)
1204 goto bad_message; 1207 goto bad_message;
1205 if (sp->hdr.flags & RXRPC_JUMBO_PACKET && 1208 if (sp->hdr.flags & RXRPC_JUMBO_PACKET &&
1206 !rxrpc_validate_jumbo(skb)) 1209 !rxrpc_validate_jumbo(skb))
1207 goto bad_message; 1210 goto bad_message;
1208 break; 1211 break;
1209 1212
1213 case RXRPC_PACKET_TYPE_CHALLENGE:
1214 if (rxrpc_to_server(sp))
1215 goto discard;
1216 break;
1217 case RXRPC_PACKET_TYPE_RESPONSE:
1218 if (rxrpc_to_client(sp))
1219 goto discard;
1220 break;
1221
1210 /* Packet types 9-11 should just be ignored. */ 1222 /* Packet types 9-11 should just be ignored. */
1211 case RXRPC_PACKET_TYPE_PARAMS: 1223 case RXRPC_PACKET_TYPE_PARAMS:
1212 case RXRPC_PACKET_TYPE_10: 1224 case RXRPC_PACKET_TYPE_10:
1213 case RXRPC_PACKET_TYPE_11: 1225 case RXRPC_PACKET_TYPE_11:
1214 goto discard; 1226 goto discard;
1227
1228 default:
1229 _proto("Rx Bad Packet Type %u", sp->hdr.type);
1230 goto bad_message;
1215 } 1231 }
1216 1232
1233 if (sp->hdr.serviceId == 0)
1234 goto bad_message;
1235
1217 rcu_read_lock(); 1236 rcu_read_lock();
1218 1237
1238 if (rxrpc_to_server(sp)) {
1239 /* Weed out packets to services we're not offering. Packets
1240 * that would begin a call are explicitly rejected and the rest
1241 * are just discarded.
1242 */
1243 rx = rcu_dereference(local->service);
1244 if (!rx || (sp->hdr.serviceId != rx->srx.srx_service &&
1245 sp->hdr.serviceId != rx->second_service)) {
1246 if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA &&
1247 sp->hdr.seq == 1)
1248 goto unsupported_service;
1249 goto discard_unlock;
1250 }
1251 }
1252
1219 conn = rxrpc_find_connection_rcu(local, skb); 1253 conn = rxrpc_find_connection_rcu(local, skb);
1220 if (conn) { 1254 if (conn) {
1221 if (sp->hdr.securityIndex != conn->security_ix) 1255 if (sp->hdr.securityIndex != conn->security_ix)
@@ -1297,14 +1331,10 @@ void rxrpc_data_ready(struct sock *udp_sk)
1297 if (!test_bit(RXRPC_CALL_RX_HEARD, &call->flags)) 1331 if (!test_bit(RXRPC_CALL_RX_HEARD, &call->flags))
1298 set_bit(RXRPC_CALL_RX_HEARD, &call->flags); 1332 set_bit(RXRPC_CALL_RX_HEARD, &call->flags);
1299 } 1333 }
1300 } else {
1301 skew = 0;
1302 call = NULL;
1303 } 1334 }
1304 1335
1305 if (!call || atomic_read(&call->usage) == 0) { 1336 if (!call || atomic_read(&call->usage) == 0) {
1306 if (rxrpc_to_client(sp) || 1337 if (rxrpc_to_client(sp) ||
1307 sp->hdr.callNumber == 0 ||
1308 sp->hdr.type != RXRPC_PACKET_TYPE_DATA) 1338 sp->hdr.type != RXRPC_PACKET_TYPE_DATA)
1309 goto bad_message_unlock; 1339 goto bad_message_unlock;
1310 if (sp->hdr.seq != 1) 1340 if (sp->hdr.seq != 1)
@@ -1340,6 +1370,13 @@ wrong_security:
1340 skb->priority = RXKADINCONSISTENCY; 1370 skb->priority = RXKADINCONSISTENCY;
1341 goto post_abort; 1371 goto post_abort;
1342 1372
1373unsupported_service:
1374 rcu_read_unlock();
1375 trace_rxrpc_abort(0, "INV", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
1376 RX_INVALID_OPERATION, EOPNOTSUPP);
1377 skb->priority = RX_INVALID_OPERATION;
1378 goto post_abort;
1379
1343reupgrade: 1380reupgrade:
1344 rcu_read_unlock(); 1381 rcu_read_unlock();
1345 trace_rxrpc_abort(0, "UPG", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, 1382 trace_rxrpc_abort(0, "UPG", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
diff --git a/net/rxrpc/protocol.h b/net/rxrpc/protocol.h
index 93da73bf7098..f9cb83c938f3 100644
--- a/net/rxrpc/protocol.h
+++ b/net/rxrpc/protocol.h
@@ -50,7 +50,6 @@ struct rxrpc_wire_header {
50#define RXRPC_PACKET_TYPE_10 10 /* Ignored */ 50#define RXRPC_PACKET_TYPE_10 10 /* Ignored */
51#define RXRPC_PACKET_TYPE_11 11 /* Ignored */ 51#define RXRPC_PACKET_TYPE_11 11 /* Ignored */
52#define RXRPC_PACKET_TYPE_VERSION 13 /* version string request */ 52#define RXRPC_PACKET_TYPE_VERSION 13 /* version string request */
53#define RXRPC_N_PACKET_TYPES 14 /* number of packet types (incl type 0) */
54 53
55 uint8_t flags; /* packet flags */ 54 uint8_t flags; /* packet flags */
56#define RXRPC_CLIENT_INITIATED 0x01 /* signifies a packet generated by a client */ 55#define RXRPC_CLIENT_INITIATED 0x01 /* signifies a packet generated by a client */
@@ -72,20 +71,6 @@ struct rxrpc_wire_header {
72 71
73} __packed; 72} __packed;
74 73
75#define RXRPC_SUPPORTED_PACKET_TYPES ( \
76 (1 << RXRPC_PACKET_TYPE_DATA) | \
77 (1 << RXRPC_PACKET_TYPE_ACK) | \
78 (1 << RXRPC_PACKET_TYPE_BUSY) | \
79 (1 << RXRPC_PACKET_TYPE_ABORT) | \
80 (1 << RXRPC_PACKET_TYPE_ACKALL) | \
81 (1 << RXRPC_PACKET_TYPE_CHALLENGE) | \
82 (1 << RXRPC_PACKET_TYPE_RESPONSE) | \
83 /*(1 << RXRPC_PACKET_TYPE_DEBUG) | */ \
84 (1 << RXRPC_PACKET_TYPE_PARAMS) | \
85 (1 << RXRPC_PACKET_TYPE_10) | \
86 (1 << RXRPC_PACKET_TYPE_11) | \
87 (1 << RXRPC_PACKET_TYPE_VERSION))
88
89/*****************************************************************************/ 74/*****************************************************************************/
90/* 75/*
91 * jumbo packet secondary header 76 * jumbo packet secondary header