Skip to content

Commit d1b2777

Browse files
committed
Merge branch 'tipc-fixes'
Xin Long says: ==================== tipc: fix the mtu update in link mtu negotiation This patchset fixes a crash caused by a too small MTU carried in the activate msg. Note that as such malicious packet does not exist in the normal env, the fix won't break any application The 1st patch introduces a function to calculate the minimum MTU for the bearer, and the 2nd patch fixes the crash with this helper. While at it, the 3rd patch fixes the udp bearer mtu update by netlink with this helper. ==================== Reviewed-by: Tung Nguyen <[email protected]> Signed-off-by: David S. Miller <[email protected]>
2 parents b48a186 + 35a089b commit d1b2777

File tree

4 files changed

+27
-7
lines changed

4 files changed

+27
-7
lines changed

net/tipc/bearer.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,19 @@ int tipc_bearer_mtu(struct net *net, u32 bearer_id)
541541
return mtu;
542542
}
543543

544+
int tipc_bearer_min_mtu(struct net *net, u32 bearer_id)
545+
{
546+
int mtu = TIPC_MIN_BEARER_MTU;
547+
struct tipc_bearer *b;
548+
549+
rcu_read_lock();
550+
b = bearer_get(net, bearer_id);
551+
if (b)
552+
mtu += b->encap_hlen;
553+
rcu_read_unlock();
554+
return mtu;
555+
}
556+
544557
/* tipc_bearer_xmit_skb - sends buffer to destination over bearer
545558
*/
546559
void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
@@ -1138,8 +1151,8 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
11381151
return -EINVAL;
11391152
}
11401153
#ifdef CONFIG_TIPC_MEDIA_UDP
1141-
if (tipc_udp_mtu_bad(nla_get_u32
1142-
(props[TIPC_NLA_PROP_MTU]))) {
1154+
if (nla_get_u32(props[TIPC_NLA_PROP_MTU]) <
1155+
b->encap_hlen + TIPC_MIN_BEARER_MTU) {
11431156
NL_SET_ERR_MSG(info->extack,
11441157
"MTU value is out-of-range");
11451158
return -EINVAL;

net/tipc/bearer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ struct tipc_media {
146146
* @identity: array index of this bearer within TIPC bearer array
147147
* @disc: ptr to link setup request
148148
* @net_plane: network plane ('A' through 'H') currently associated with bearer
149+
* @encap_hlen: encap headers length
149150
* @up: bearer up flag (bit 0)
150151
* @refcnt: tipc_bearer reference counter
151152
*
@@ -170,6 +171,7 @@ struct tipc_bearer {
170171
u32 identity;
171172
struct tipc_discoverer *disc;
172173
char net_plane;
174+
u16 encap_hlen;
173175
unsigned long up;
174176
refcount_t refcnt;
175177
};
@@ -232,6 +234,7 @@ int tipc_bearer_setup(void);
232234
void tipc_bearer_cleanup(void);
233235
void tipc_bearer_stop(struct net *net);
234236
int tipc_bearer_mtu(struct net *net, u32 bearer_id);
237+
int tipc_bearer_min_mtu(struct net *net, u32 bearer_id);
235238
bool tipc_bearer_bcast_support(struct net *net, u32 bearer_id);
236239
void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
237240
struct sk_buff *skb,

net/tipc/link.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,7 +2200,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
22002200
struct tipc_msg *hdr = buf_msg(skb);
22012201
struct tipc_gap_ack_blks *ga = NULL;
22022202
bool reply = msg_probe(hdr), retransmitted = false;
2203-
u32 dlen = msg_data_sz(hdr), glen = 0;
2203+
u32 dlen = msg_data_sz(hdr), glen = 0, msg_max;
22042204
u16 peers_snd_nxt = msg_next_sent(hdr);
22052205
u16 peers_tol = msg_link_tolerance(hdr);
22062206
u16 peers_prio = msg_linkprio(hdr);
@@ -2239,6 +2239,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
22392239
switch (mtyp) {
22402240
case RESET_MSG:
22412241
case ACTIVATE_MSG:
2242+
msg_max = msg_max_pkt(hdr);
2243+
if (msg_max < tipc_bearer_min_mtu(l->net, l->bearer_id))
2244+
break;
22422245
/* Complete own link name with peer's interface name */
22432246
if_name = strrchr(l->name, ':') + 1;
22442247
if (sizeof(l->name) - (if_name - l->name) <= TIPC_MAX_IF_NAME)
@@ -2283,8 +2286,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
22832286
l->peer_session = msg_session(hdr);
22842287
l->in_session = true;
22852288
l->peer_bearer_id = msg_bearer_id(hdr);
2286-
if (l->mtu > msg_max_pkt(hdr))
2287-
l->mtu = msg_max_pkt(hdr);
2289+
if (l->mtu > msg_max)
2290+
l->mtu = msg_max;
22882291
break;
22892292

22902293
case STATE_MSG:

net/tipc/udp_media.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,8 +738,8 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
738738
udp_conf.local_ip.s_addr = local.ipv4.s_addr;
739739
udp_conf.use_udp_checksums = false;
740740
ub->ifindex = dev->ifindex;
741-
if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
742-
sizeof(struct udphdr))) {
741+
b->encap_hlen = sizeof(struct iphdr) + sizeof(struct udphdr);
742+
if (tipc_mtu_bad(dev, b->encap_hlen)) {
743743
err = -EINVAL;
744744
goto err;
745745
}
@@ -760,6 +760,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
760760
else
761761
udp_conf.local_ip6 = local.ipv6;
762762
ub->ifindex = dev->ifindex;
763+
b->encap_hlen = sizeof(struct ipv6hdr) + sizeof(struct udphdr);
763764
b->mtu = 1280;
764765
#endif
765766
} else {

0 commit comments

Comments
 (0)