Skip to content

Commit cf2157f

Browse files
Jon Paul Maloydavem330
authored andcommitted
tipc: move message validation function to msg.c
The function link_buf_validate() is in reality re-entrant and context independent, and will in later commits be called from several locations. Therefore, we move it to msg.c, make it outline and rename the it to tipc_msg_validate(). We also redesign the function to make proper use of pskb_may_pull() Signed-off-by: Jon Maloy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7764d6e commit cf2157f

File tree

3 files changed

+47
-60
lines changed

3 files changed

+47
-60
lines changed

net/tipc/link.c

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,61 +1047,6 @@ static void link_retrieve_defq(struct tipc_link *link,
10471047
skb_queue_splice_tail_init(&link->deferred_queue, list);
10481048
}
10491049

1050-
/**
1051-
* link_recv_buf_validate - validate basic format of received message
1052-
*
1053-
* This routine ensures a TIPC message has an acceptable header, and at least
1054-
* as much data as the header indicates it should. The routine also ensures
1055-
* that the entire message header is stored in the main fragment of the message
1056-
* buffer, to simplify future access to message header fields.
1057-
*
1058-
* Note: Having extra info present in the message header or data areas is OK.
1059-
* TIPC will ignore the excess, under the assumption that it is optional info
1060-
* introduced by a later release of the protocol.
1061-
*/
1062-
static int link_recv_buf_validate(struct sk_buff *buf)
1063-
{
1064-
static u32 min_data_hdr_size[8] = {
1065-
SHORT_H_SIZE, MCAST_H_SIZE, NAMED_H_SIZE, BASIC_H_SIZE,
1066-
MAX_H_SIZE, MAX_H_SIZE, MAX_H_SIZE, MAX_H_SIZE
1067-
};
1068-
1069-
struct tipc_msg *msg;
1070-
u32 tipc_hdr[2];
1071-
u32 size;
1072-
u32 hdr_size;
1073-
u32 min_hdr_size;
1074-
1075-
/* If this packet comes from the defer queue, the skb has already
1076-
* been validated
1077-
*/
1078-
if (unlikely(TIPC_SKB_CB(buf)->deferred))
1079-
return 1;
1080-
1081-
if (unlikely(buf->len < MIN_H_SIZE))
1082-
return 0;
1083-
1084-
msg = skb_header_pointer(buf, 0, sizeof(tipc_hdr), tipc_hdr);
1085-
if (msg == NULL)
1086-
return 0;
1087-
1088-
if (unlikely(msg_version(msg) != TIPC_VERSION))
1089-
return 0;
1090-
1091-
size = msg_size(msg);
1092-
hdr_size = msg_hdr_sz(msg);
1093-
min_hdr_size = msg_isdata(msg) ?
1094-
min_data_hdr_size[msg_type(msg)] : INT_H_SIZE;
1095-
1096-
if (unlikely((hdr_size < min_hdr_size) ||
1097-
(size < hdr_size) ||
1098-
(buf->len < size) ||
1099-
(size - hdr_size > TIPC_MAX_USER_MSG_SIZE)))
1100-
return 0;
1101-
1102-
return pskb_may_pull(buf, hdr_size);
1103-
}
1104-
11051050
/**
11061051
* tipc_rcv - process TIPC packets/messages arriving from off-node
11071052
* @net: the applicable net namespace
@@ -1127,7 +1072,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
11271072

11281073
while ((skb = __skb_dequeue(&head))) {
11291074
/* Ensure message is well-formed */
1130-
if (unlikely(!link_recv_buf_validate(skb)))
1075+
if (unlikely(!tipc_msg_validate(skb)))
11311076
goto discard;
11321077

11331078
/* Ensure message data is a single contiguous unit */
@@ -1398,7 +1343,6 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
13981343

13991344
if (tipc_link_defer_pkt(&l_ptr->deferred_queue, buf)) {
14001345
l_ptr->stats.deferred_recv++;
1401-
TIPC_SKB_CB(buf)->deferred = true;
14021346
if ((skb_queue_len(&l_ptr->deferred_queue) % 16) == 1)
14031347
tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
14041348
} else {

net/tipc/msg.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* net/tipc/msg.c: TIPC message header routines
33
*
4-
* Copyright (c) 2000-2006, 2014, Ericsson AB
4+
* Copyright (c) 2000-2006, 2014-2015, Ericsson AB
55
* Copyright (c) 2005, 2010-2011, Wind River Systems
66
* All rights reserved.
77
*
@@ -181,6 +181,48 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
181181
return 0;
182182
}
183183

184+
/* tipc_msg_validate - validate basic format of received message
185+
*
186+
* This routine ensures a TIPC message has an acceptable header, and at least
187+
* as much data as the header indicates it should. The routine also ensures
188+
* that the entire message header is stored in the main fragment of the message
189+
* buffer, to simplify future access to message header fields.
190+
*
191+
* Note: Having extra info present in the message header or data areas is OK.
192+
* TIPC will ignore the excess, under the assumption that it is optional info
193+
* introduced by a later release of the protocol.
194+
*/
195+
bool tipc_msg_validate(struct sk_buff *skb)
196+
{
197+
struct tipc_msg *msg;
198+
int msz, hsz;
199+
200+
if (unlikely(TIPC_SKB_CB(skb)->validated))
201+
return true;
202+
if (unlikely(!pskb_may_pull(skb, MIN_H_SIZE)))
203+
return false;
204+
205+
hsz = msg_hdr_sz(buf_msg(skb));
206+
if (unlikely(hsz < MIN_H_SIZE) || (hsz > MAX_H_SIZE))
207+
return false;
208+
if (unlikely(!pskb_may_pull(skb, hsz)))
209+
return false;
210+
211+
msg = buf_msg(skb);
212+
if (unlikely(msg_version(msg) != TIPC_VERSION))
213+
return false;
214+
215+
msz = msg_size(msg);
216+
if (unlikely(msz < hsz))
217+
return false;
218+
if (unlikely((msz - hsz) > TIPC_MAX_USER_MSG_SIZE))
219+
return false;
220+
if (unlikely(skb->len < msz))
221+
return false;
222+
223+
TIPC_SKB_CB(skb)->validated = true;
224+
return true;
225+
}
184226

185227
/**
186228
* tipc_msg_build - create buffer chain containing specified header and data

net/tipc/msg.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* net/tipc/msg.h: Include file for TIPC message header routines
33
*
4-
* Copyright (c) 2000-2007, 2014, Ericsson AB
4+
* Copyright (c) 2000-2007, 2014-2015 Ericsson AB
55
* Copyright (c) 2005-2008, 2010-2011, Wind River Systems
66
* All rights reserved.
77
*
@@ -92,7 +92,7 @@ struct plist;
9292
struct tipc_skb_cb {
9393
void *handle;
9494
struct sk_buff *tail;
95-
bool deferred;
95+
bool validated;
9696
bool wakeup_pending;
9797
bool bundling;
9898
u16 chain_sz;
@@ -758,6 +758,7 @@ static inline u32 msg_tot_origport(struct tipc_msg *m)
758758
}
759759

760760
struct sk_buff *tipc_buf_acquire(u32 size);
761+
bool tipc_msg_validate(struct sk_buff *skb);
761762
bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
762763
int err);
763764
void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,

0 commit comments

Comments
 (0)