Commit cf2157f88a5abf1a64b8c51a737a35e918dc67e5

Authored by Jon Paul Maloy
Committed by David S. Miller
1 parent 7764d6e83d

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 <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 3 changed files with 47 additions and 60 deletions Side-by-side Diff

... ... @@ -1048,61 +1048,6 @@
1048 1048 }
1049 1049  
1050 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   -
1105   -/**
1106 1051 * tipc_rcv - process TIPC packets/messages arriving from off-node
1107 1052 * @net: the applicable net namespace
1108 1053 * @skb: TIPC packet
... ... @@ -1127,7 +1072,7 @@
1127 1072  
1128 1073 while ((skb = __skb_dequeue(&head))) {
1129 1074 /* Ensure message is well-formed */
1130   - if (unlikely(!link_recv_buf_validate(skb)))
  1075 + if (unlikely(!tipc_msg_validate(skb)))
1131 1076 goto discard;
1132 1077  
1133 1078 /* Ensure message data is a single contiguous unit */
... ... @@ -1398,7 +1343,6 @@
1398 1343  
1399 1344 if (tipc_link_defer_pkt(&l_ptr->deferred_queue, buf)) {
1400 1345 l_ptr->stats.deferred_recv++;
1401   - TIPC_SKB_CB(buf)->deferred = true;
1402 1346 if ((skb_queue_len(&l_ptr->deferred_queue) % 16) == 1)
1403 1347 tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
1404 1348 } else {
1 1 /*
2 2 * net/tipc/msg.c: TIPC message header routines
3 3 *
4   - * Copyright (c) 2000-2006, 2014, Ericsson AB
  4 + * Copyright (c) 2000-2006, 2014-2015, Ericsson AB
5 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 6 * All rights reserved.
7 7 *
... ... @@ -181,6 +181,48 @@
181 181 return 0;
182 182 }
183 183  
  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 +}
184 226  
185 227 /**
186 228 * tipc_msg_build - create buffer chain containing specified header and data
1 1 /*
2 2 * net/tipc/msg.h: Include file for TIPC message header routines
3 3 *
4   - * Copyright (c) 2000-2007, 2014, Ericsson AB
  4 + * Copyright (c) 2000-2007, 2014-2015 Ericsson AB
5 5 * Copyright (c) 2005-2008, 2010-2011, Wind River Systems
6 6 * All rights reserved.
7 7 *
... ... @@ -92,7 +92,7 @@
92 92 struct tipc_skb_cb {
93 93 void *handle;
94 94 struct sk_buff *tail;
95   - bool deferred;
  95 + bool validated;
96 96 bool wakeup_pending;
97 97 bool bundling;
98 98 u16 chain_sz;
... ... @@ -758,6 +758,7 @@
758 758 }
759 759  
760 760 struct sk_buff *tipc_buf_acquire(u32 size);
  761 +bool tipc_msg_validate(struct sk_buff *skb);
761 762 bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
762 763 int err);
763 764 void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,