Commit cf2157f88a5abf1a64b8c51a737a35e918dc67e5
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
net/tipc/link.c
... | ... | @@ -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 { |
net/tipc/msg.c
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 |
net/tipc/msg.h
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, |