aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-29 10:41:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-29 10:41:33 -0400
commitcb1817b37313b4b6c7f8f93c730553dd3cb6ac57 (patch)
tree30c9b246c77ad338f177a5a32a45eb92e5994652 /net
parent89078d572eb9ce8d4c04264b8b0ba86de0d74c8f (diff)
parent02aadf72fe2c83f145e3437734e66be53abae481 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (30 commits) xfrm: Restrict extended sequence numbers to esp xfrm: Check for esn buffer len in xfrm_new_ae xfrm: Assign esn pointers when cloning a state xfrm: Move the test on replay window size into the replay check functions netdev: bfin_mac: document TE setting in RMII modes drivers net: Fix declaration ordering in inline functions. cxgb3: Apply interrupt coalescing settings to all queues net: Always allocate at least 16 skb frags regardless of page size ipv4: Don't ip_rt_put() an error pointer in RAW sockets. net: fix ethtool->set_flags not intended -EINVAL return value mlx4_en: Fix loss of promiscuity tg3: Fix inline keyword usage tg3: use <linux/io.h> and <linux/uaccess.h> instead <asm/io.h> and <asm/uaccess.h> net: use CHECKSUM_NONE instead of magic number Net / jme: Do not use legacy PCI power management myri10ge: small rx_done refactoring bridge: notify applications if address of bridge device changes ipv4: Fix IP timestamp option (IPOPT_TS_PRESPEC) handling in ip_options_echo() can: c_can: Fix tx_bytes accounting can: c_can_platform: fix irq check in probe ...
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_if.c6
-rw-r--r--net/bridge/br_private.h2
-rw-r--r--net/bridge/br_stp_if.c9
-rw-r--r--net/can/af_can.c9
-rw-r--r--net/can/bcm.c4
-rw-r--r--net/can/raw.c4
-rw-r--r--net/core/dev.c55
-rw-r--r--net/core/ethtool.c17
-rw-r--r--net/ipv4/fib_trie.c4
-rw-r--r--net/ipv4/ip_options.c6
-rw-r--r--net/ipv4/raw.c1
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/irda/iriap.c6
-rw-r--r--net/irda/irnet/irnet_ppp.c3
-rw-r--r--net/rose/af_rose.c8
-rw-r--r--net/rose/rose_loopback.c13
-rw-r--r--net/rose/rose_route.c20
-rw-r--r--net/rose/rose_subr.c101
-rw-r--r--net/xfrm/xfrm_input.c4
-rw-r--r--net/xfrm/xfrm_output.c4
-rw-r--r--net/xfrm/xfrm_replay.c17
-rw-r--r--net/xfrm/xfrm_state.c6
-rw-r--r--net/xfrm/xfrm_user.c24
23 files changed, 201 insertions, 124 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index dce8f0009a12..718b60366dfe 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -389,6 +389,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
389{ 389{
390 struct net_bridge_port *p; 390 struct net_bridge_port *p;
391 int err = 0; 391 int err = 0;
392 bool changed_addr;
392 393
393 /* Don't allow bridging non-ethernet like devices */ 394 /* Don't allow bridging non-ethernet like devices */
394 if ((dev->flags & IFF_LOOPBACK) || 395 if ((dev->flags & IFF_LOOPBACK) ||
@@ -446,7 +447,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
446 list_add_rcu(&p->list, &br->port_list); 447 list_add_rcu(&p->list, &br->port_list);
447 448
448 spin_lock_bh(&br->lock); 449 spin_lock_bh(&br->lock);
449 br_stp_recalculate_bridge_id(br); 450 changed_addr = br_stp_recalculate_bridge_id(br);
450 br_features_recompute(br); 451 br_features_recompute(br);
451 452
452 if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && 453 if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
@@ -456,6 +457,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
456 457
457 br_ifinfo_notify(RTM_NEWLINK, p); 458 br_ifinfo_notify(RTM_NEWLINK, p);
458 459
460 if (changed_addr)
461 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
462
459 dev_set_mtu(br->dev, br_min_mtu(br)); 463 dev_set_mtu(br->dev, br_min_mtu(br));
460 464
461 kobject_uevent(&p->kobj, KOBJ_ADD); 465 kobject_uevent(&p->kobj, KOBJ_ADD);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 19e2f46ed086..387013d33745 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -497,7 +497,7 @@ extern void br_stp_disable_bridge(struct net_bridge *br);
497extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val); 497extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val);
498extern void br_stp_enable_port(struct net_bridge_port *p); 498extern void br_stp_enable_port(struct net_bridge_port *p);
499extern void br_stp_disable_port(struct net_bridge_port *p); 499extern void br_stp_disable_port(struct net_bridge_port *p);
500extern void br_stp_recalculate_bridge_id(struct net_bridge *br); 500extern bool br_stp_recalculate_bridge_id(struct net_bridge *br);
501extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); 501extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
502extern void br_stp_set_bridge_priority(struct net_bridge *br, 502extern void br_stp_set_bridge_priority(struct net_bridge *br,
503 u16 newprio); 503 u16 newprio);
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 79372d4a4055..5593f5aec942 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -204,7 +204,7 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
204static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1]; 204static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1];
205 205
206/* called under bridge lock */ 206/* called under bridge lock */
207void br_stp_recalculate_bridge_id(struct net_bridge *br) 207bool br_stp_recalculate_bridge_id(struct net_bridge *br)
208{ 208{
209 const unsigned char *br_mac_zero = 209 const unsigned char *br_mac_zero =
210 (const unsigned char *)br_mac_zero_aligned; 210 (const unsigned char *)br_mac_zero_aligned;
@@ -222,8 +222,11 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br)
222 222
223 } 223 }
224 224
225 if (compare_ether_addr(br->bridge_id.addr, addr)) 225 if (compare_ether_addr(br->bridge_id.addr, addr) == 0)
226 br_stp_change_bridge_id(br, addr); 226 return false; /* no change */
227
228 br_stp_change_bridge_id(br, addr);
229 return true;
227} 230}
228 231
229/* called under bridge lock */ 232/* called under bridge lock */
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 702be5a2c956..733d66f1b05a 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -95,7 +95,7 @@ struct s_pstats can_pstats; /* receive list statistics */
95 * af_can socket functions 95 * af_can socket functions
96 */ 96 */
97 97
98static int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 98int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
99{ 99{
100 struct sock *sk = sock->sk; 100 struct sock *sk = sock->sk;
101 101
@@ -108,6 +108,7 @@ static int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
108 return -ENOIOCTLCMD; 108 return -ENOIOCTLCMD;
109 } 109 }
110} 110}
111EXPORT_SYMBOL(can_ioctl);
111 112
112static void can_sock_destruct(struct sock *sk) 113static void can_sock_destruct(struct sock *sk)
113{ 114{
@@ -698,13 +699,9 @@ int can_proto_register(struct can_proto *cp)
698 printk(KERN_ERR "can: protocol %d already registered\n", 699 printk(KERN_ERR "can: protocol %d already registered\n",
699 proto); 700 proto);
700 err = -EBUSY; 701 err = -EBUSY;
701 } else { 702 } else
702 proto_tab[proto] = cp; 703 proto_tab[proto] = cp;
703 704
704 /* use generic ioctl function if not defined by module */
705 if (!cp->ops->ioctl)
706 cp->ops->ioctl = can_ioctl;
707 }
708 spin_unlock(&proto_tab_lock); 705 spin_unlock(&proto_tab_lock);
709 706
710 if (err < 0) 707 if (err < 0)
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 092dc88a7c64..871a0ad51025 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1569,7 +1569,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
1569 return size; 1569 return size;
1570} 1570}
1571 1571
1572static struct proto_ops bcm_ops __read_mostly = { 1572static const struct proto_ops bcm_ops = {
1573 .family = PF_CAN, 1573 .family = PF_CAN,
1574 .release = bcm_release, 1574 .release = bcm_release,
1575 .bind = sock_no_bind, 1575 .bind = sock_no_bind,
@@ -1578,7 +1578,7 @@ static struct proto_ops bcm_ops __read_mostly = {
1578 .accept = sock_no_accept, 1578 .accept = sock_no_accept,
1579 .getname = sock_no_getname, 1579 .getname = sock_no_getname,
1580 .poll = datagram_poll, 1580 .poll = datagram_poll,
1581 .ioctl = NULL, /* use can_ioctl() from af_can.c */ 1581 .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
1582 .listen = sock_no_listen, 1582 .listen = sock_no_listen,
1583 .shutdown = sock_no_shutdown, 1583 .shutdown = sock_no_shutdown,
1584 .setsockopt = sock_no_setsockopt, 1584 .setsockopt = sock_no_setsockopt,
diff --git a/net/can/raw.c b/net/can/raw.c
index 883e9d74fddf..649acfa7c70a 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -742,7 +742,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
742 return size; 742 return size;
743} 743}
744 744
745static struct proto_ops raw_ops __read_mostly = { 745static const struct proto_ops raw_ops = {
746 .family = PF_CAN, 746 .family = PF_CAN,
747 .release = raw_release, 747 .release = raw_release,
748 .bind = raw_bind, 748 .bind = raw_bind,
@@ -751,7 +751,7 @@ static struct proto_ops raw_ops __read_mostly = {
751 .accept = sock_no_accept, 751 .accept = sock_no_accept,
752 .getname = raw_getname, 752 .getname = raw_getname,
753 .poll = datagram_poll, 753 .poll = datagram_poll,
754 .ioctl = NULL, /* use can_ioctl() from af_can.c */ 754 .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
755 .listen = sock_no_listen, 755 .listen = sock_no_listen,
756 .shutdown = sock_no_shutdown, 756 .shutdown = sock_no_shutdown,
757 .setsockopt = raw_setsockopt, 757 .setsockopt = raw_setsockopt,
diff --git a/net/core/dev.c b/net/core/dev.c
index f453370131a0..563ddc28139d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1140,9 +1140,6 @@ static int __dev_open(struct net_device *dev)
1140 1140
1141 ASSERT_RTNL(); 1141 ASSERT_RTNL();
1142 1142
1143 /*
1144 * Is it even present?
1145 */
1146 if (!netif_device_present(dev)) 1143 if (!netif_device_present(dev))
1147 return -ENODEV; 1144 return -ENODEV;
1148 1145
@@ -1151,9 +1148,6 @@ static int __dev_open(struct net_device *dev)
1151 if (ret) 1148 if (ret)
1152 return ret; 1149 return ret;
1153 1150
1154 /*
1155 * Call device private open method
1156 */
1157 set_bit(__LINK_STATE_START, &dev->state); 1151 set_bit(__LINK_STATE_START, &dev->state);
1158 1152
1159 if (ops->ndo_validate_addr) 1153 if (ops->ndo_validate_addr)
@@ -1162,31 +1156,12 @@ static int __dev_open(struct net_device *dev)
1162 if (!ret && ops->ndo_open) 1156 if (!ret && ops->ndo_open)
1163 ret = ops->ndo_open(dev); 1157 ret = ops->ndo_open(dev);
1164 1158
1165 /*
1166 * If it went open OK then:
1167 */
1168
1169 if (ret) 1159 if (ret)
1170 clear_bit(__LINK_STATE_START, &dev->state); 1160 clear_bit(__LINK_STATE_START, &dev->state);
1171 else { 1161 else {
1172 /*
1173 * Set the flags.
1174 */
1175 dev->flags |= IFF_UP; 1162 dev->flags |= IFF_UP;
1176
1177 /*
1178 * Enable NET_DMA
1179 */
1180 net_dmaengine_get(); 1163 net_dmaengine_get();
1181
1182 /*
1183 * Initialize multicasting status
1184 */
1185 dev_set_rx_mode(dev); 1164 dev_set_rx_mode(dev);
1186
1187 /*
1188 * Wakeup transmit queue engine
1189 */
1190 dev_activate(dev); 1165 dev_activate(dev);
1191 } 1166 }
1192 1167
@@ -1209,22 +1184,13 @@ int dev_open(struct net_device *dev)
1209{ 1184{
1210 int ret; 1185 int ret;
1211 1186
1212 /*
1213 * Is it already up?
1214 */
1215 if (dev->flags & IFF_UP) 1187 if (dev->flags & IFF_UP)
1216 return 0; 1188 return 0;
1217 1189
1218 /*
1219 * Open device
1220 */
1221 ret = __dev_open(dev); 1190 ret = __dev_open(dev);
1222 if (ret < 0) 1191 if (ret < 0)
1223 return ret; 1192 return ret;
1224 1193
1225 /*
1226 * ... and announce new interface.
1227 */
1228 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); 1194 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
1229 call_netdevice_notifiers(NETDEV_UP, dev); 1195 call_netdevice_notifiers(NETDEV_UP, dev);
1230 1196
@@ -1240,10 +1206,6 @@ static int __dev_close_many(struct list_head *head)
1240 might_sleep(); 1206 might_sleep();
1241 1207
1242 list_for_each_entry(dev, head, unreg_list) { 1208 list_for_each_entry(dev, head, unreg_list) {
1243 /*
1244 * Tell people we are going down, so that they can
1245 * prepare to death, when device is still operating.
1246 */
1247 call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); 1209 call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
1248 1210
1249 clear_bit(__LINK_STATE_START, &dev->state); 1211 clear_bit(__LINK_STATE_START, &dev->state);
@@ -1272,15 +1234,7 @@ static int __dev_close_many(struct list_head *head)
1272 if (ops->ndo_stop) 1234 if (ops->ndo_stop)
1273 ops->ndo_stop(dev); 1235 ops->ndo_stop(dev);
1274 1236
1275 /*
1276 * Device is now down.
1277 */
1278
1279 dev->flags &= ~IFF_UP; 1237 dev->flags &= ~IFF_UP;
1280
1281 /*
1282 * Shutdown NET_DMA
1283 */
1284 net_dmaengine_put(); 1238 net_dmaengine_put();
1285 } 1239 }
1286 1240
@@ -1309,9 +1263,6 @@ static int dev_close_many(struct list_head *head)
1309 1263
1310 __dev_close_many(head); 1264 __dev_close_many(head);
1311 1265
1312 /*
1313 * Tell people we are down
1314 */
1315 list_for_each_entry(dev, head, unreg_list) { 1266 list_for_each_entry(dev, head, unreg_list) {
1316 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); 1267 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
1317 call_netdevice_notifiers(NETDEV_DOWN, dev); 1268 call_netdevice_notifiers(NETDEV_DOWN, dev);
@@ -1371,11 +1322,6 @@ EXPORT_SYMBOL(dev_disable_lro);
1371 1322
1372static int dev_boot_phase = 1; 1323static int dev_boot_phase = 1;
1373 1324
1374/*
1375 * Device change register/unregister. These are not inline or static
1376 * as we export them to the world.
1377 */
1378
1379/** 1325/**
1380 * register_netdevice_notifier - register a network notifier block 1326 * register_netdevice_notifier - register a network notifier block
1381 * @nb: notifier 1327 * @nb: notifier
@@ -1477,6 +1423,7 @@ int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
1477 ASSERT_RTNL(); 1423 ASSERT_RTNL();
1478 return raw_notifier_call_chain(&netdev_chain, val, dev); 1424 return raw_notifier_call_chain(&netdev_chain, val, dev);
1479} 1425}
1426EXPORT_SYMBOL(call_netdevice_notifiers);
1480 1427
1481/* When > 0 there are consumers of rx skb time stamps */ 1428/* When > 0 there are consumers of rx skb time stamps */
1482static atomic_t netstamp_needed = ATOMIC_INIT(0); 1429static atomic_t netstamp_needed = ATOMIC_INIT(0);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 24bd57493c0d..74ead9eca126 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -141,9 +141,24 @@ u32 ethtool_op_get_flags(struct net_device *dev)
141} 141}
142EXPORT_SYMBOL(ethtool_op_get_flags); 142EXPORT_SYMBOL(ethtool_op_get_flags);
143 143
144/* Check if device can enable (or disable) particular feature coded in "data"
145 * argument. Flags "supported" describe features that can be toggled by device.
146 * If feature can not be toggled, it state (enabled or disabled) must match
147 * hardcoded device features state, otherwise flags are marked as invalid.
148 */
149bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported)
150{
151 u32 features = dev->features & flags_dup_features;
152 /* "data" can contain only flags_dup_features bits,
153 * see __ethtool_set_flags */
154
155 return (features & ~supported) != (data & ~supported);
156}
157EXPORT_SYMBOL(ethtool_invalid_flags);
158
144int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) 159int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported)
145{ 160{
146 if (data & ~supported) 161 if (ethtool_invalid_flags(dev, data, supported))
147 return -EINVAL; 162 return -EINVAL;
148 163
149 dev->features = ((dev->features & ~flags_dup_features) | 164 dev->features = ((dev->features & ~flags_dup_features) |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 90a3ff605591..b92c86f6e9b3 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1365,9 +1365,9 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
1365 err = fib_props[fa->fa_type].error; 1365 err = fib_props[fa->fa_type].error;
1366 if (err) { 1366 if (err) {
1367#ifdef CONFIG_IP_FIB_TRIE_STATS 1367#ifdef CONFIG_IP_FIB_TRIE_STATS
1368 t->stats.semantic_match_miss++; 1368 t->stats.semantic_match_passed++;
1369#endif 1369#endif
1370 return 1; 1370 return err;
1371 } 1371 }
1372 if (fi->fib_flags & RTNH_F_DEAD) 1372 if (fi->fib_flags & RTNH_F_DEAD)
1373 continue; 1373 continue;
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 1906fa35860c..28a736f3442f 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -140,11 +140,11 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
140 } else { 140 } else {
141 dopt->ts_needtime = 0; 141 dopt->ts_needtime = 0;
142 142
143 if (soffset + 8 <= optlen) { 143 if (soffset + 7 <= optlen) {
144 __be32 addr; 144 __be32 addr;
145 145
146 memcpy(&addr, sptr+soffset-1, 4); 146 memcpy(&addr, dptr+soffset-1, 4);
147 if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL) { 147 if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_UNICAST) {
148 dopt->ts_needtime = 1; 148 dopt->ts_needtime = 1;
149 soffset += 8; 149 soffset += 8;
150 } 150 }
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index e837ffd3edc3..2d3c72e5bbbf 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -569,6 +569,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
569 rt = ip_route_output_flow(sock_net(sk), &fl4, sk); 569 rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
570 if (IS_ERR(rt)) { 570 if (IS_ERR(rt)) {
571 err = PTR_ERR(rt); 571 err = PTR_ERR(rt);
572 rt = NULL;
572 goto done; 573 goto done;
573 } 574 }
574 } 575 }
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 7ff0343e05c7..29e48593bf22 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -663,7 +663,7 @@ static int pim6_rcv(struct sk_buff *skb)
663 skb_pull(skb, (u8 *)encap - skb->data); 663 skb_pull(skb, (u8 *)encap - skb->data);
664 skb_reset_network_header(skb); 664 skb_reset_network_header(skb);
665 skb->protocol = htons(ETH_P_IPV6); 665 skb->protocol = htons(ETH_P_IPV6);
666 skb->ip_summed = 0; 666 skb->ip_summed = CHECKSUM_NONE;
667 skb->pkt_type = PACKET_HOST; 667 skb->pkt_type = PACKET_HOST;
668 668
669 skb_tunnel_rx(skb, reg_dev); 669 skb_tunnel_rx(skb, reg_dev);
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 5b743bdd89ba..36477538cea8 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -656,10 +656,16 @@ static void iriap_getvaluebyclass_indication(struct iriap_cb *self,
656 n = 1; 656 n = 1;
657 657
658 name_len = fp[n++]; 658 name_len = fp[n++];
659
660 IRDA_ASSERT(name_len < IAS_MAX_CLASSNAME + 1, return;);
661
659 memcpy(name, fp+n, name_len); n+=name_len; 662 memcpy(name, fp+n, name_len); n+=name_len;
660 name[name_len] = '\0'; 663 name[name_len] = '\0';
661 664
662 attr_len = fp[n++]; 665 attr_len = fp[n++];
666
667 IRDA_ASSERT(attr_len < IAS_MAX_ATTRIBNAME + 1, return;);
668
663 memcpy(attr, fp+n, attr_len); n+=attr_len; 669 memcpy(attr, fp+n, attr_len); n+=attr_len;
664 attr[attr_len] = '\0'; 670 attr[attr_len] = '\0';
665 671
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index 7c567b8aa89a..2bb2beb6a373 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -105,6 +105,9 @@ irnet_ctrl_write(irnet_socket * ap,
105 while(isspace(start[length - 1])) 105 while(isspace(start[length - 1]))
106 length--; 106 length--;
107 107
108 DABORT(length < 5 || length > NICKNAME_MAX_LEN + 5,
109 -EINVAL, CTRL_ERROR, "Invalid nickname.\n");
110
108 /* Copy the name for later reuse */ 111 /* Copy the name for later reuse */
109 memcpy(ap->rname, start + 5, length - 5); 112 memcpy(ap->rname, start + 5, length - 5);
110 ap->rname[length - 5] = '\0'; 113 ap->rname[length - 5] = '\0';
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 5ee0c62046a0..a80aef6e3d1f 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -978,7 +978,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
978 struct sock *make; 978 struct sock *make;
979 struct rose_sock *make_rose; 979 struct rose_sock *make_rose;
980 struct rose_facilities_struct facilities; 980 struct rose_facilities_struct facilities;
981 int n, len; 981 int n;
982 982
983 skb->sk = NULL; /* Initially we don't know who it's for */ 983 skb->sk = NULL; /* Initially we don't know who it's for */
984 984
@@ -987,9 +987,9 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
987 */ 987 */
988 memset(&facilities, 0x00, sizeof(struct rose_facilities_struct)); 988 memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
989 989
990 len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1; 990 if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
991 len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1; 991 skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
992 if (!rose_parse_facilities(skb->data + len + 4, &facilities)) { 992 &facilities)) {
993 rose_transmit_clear_request(neigh, lci, ROSE_INVALID_FACILITY, 76); 993 rose_transmit_clear_request(neigh, lci, ROSE_INVALID_FACILITY, 76);
994 return 0; 994 return 0;
995 } 995 }
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c
index ae4a9d99aec7..344456206b70 100644
--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -73,9 +73,20 @@ static void rose_loopback_timer(unsigned long param)
73 unsigned int lci_i, lci_o; 73 unsigned int lci_i, lci_o;
74 74
75 while ((skb = skb_dequeue(&loopback_queue)) != NULL) { 75 while ((skb = skb_dequeue(&loopback_queue)) != NULL) {
76 if (skb->len < ROSE_MIN_LEN) {
77 kfree_skb(skb);
78 continue;
79 }
76 lci_i = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); 80 lci_i = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
77 frametype = skb->data[2]; 81 frametype = skb->data[2];
78 dest = (rose_address *)(skb->data + 4); 82 if (frametype == ROSE_CALL_REQUEST &&
83 (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
84 skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
85 ROSE_CALL_REQ_ADDR_LEN_VAL)) {
86 kfree_skb(skb);
87 continue;
88 }
89 dest = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
79 lci_o = ROSE_DEFAULT_MAXVC + 1 - lci_i; 90 lci_o = ROSE_DEFAULT_MAXVC + 1 - lci_i;
80 91
81 skb_reset_transport_header(skb); 92 skb_reset_transport_header(skb);
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 88a77e90e7e8..08dcd2f29cdc 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -861,7 +861,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
861 unsigned int lci, new_lci; 861 unsigned int lci, new_lci;
862 unsigned char cause, diagnostic; 862 unsigned char cause, diagnostic;
863 struct net_device *dev; 863 struct net_device *dev;
864 int len, res = 0; 864 int res = 0;
865 char buf[11]; 865 char buf[11];
866 866
867#if 0 867#if 0
@@ -869,10 +869,17 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
869 return res; 869 return res;
870#endif 870#endif
871 871
872 if (skb->len < ROSE_MIN_LEN)
873 return res;
872 frametype = skb->data[2]; 874 frametype = skb->data[2];
873 lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); 875 lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
874 src_addr = (rose_address *)(skb->data + 9); 876 if (frametype == ROSE_CALL_REQUEST &&
875 dest_addr = (rose_address *)(skb->data + 4); 877 (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
878 skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
879 ROSE_CALL_REQ_ADDR_LEN_VAL))
880 return res;
881 src_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF);
882 dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
876 883
877 spin_lock_bh(&rose_neigh_list_lock); 884 spin_lock_bh(&rose_neigh_list_lock);
878 spin_lock_bh(&rose_route_list_lock); 885 spin_lock_bh(&rose_route_list_lock);
@@ -1010,12 +1017,11 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
1010 goto out; 1017 goto out;
1011 } 1018 }
1012 1019
1013 len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1;
1014 len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1;
1015
1016 memset(&facilities, 0x00, sizeof(struct rose_facilities_struct)); 1020 memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
1017 1021
1018 if (!rose_parse_facilities(skb->data + len + 4, &facilities)) { 1022 if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
1023 skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
1024 &facilities)) {
1019 rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76); 1025 rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76);
1020 goto out; 1026 goto out;
1021 } 1027 }
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index 1734abba26a2..f6c71caa94b9 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -142,7 +142,7 @@ void rose_write_internal(struct sock *sk, int frametype)
142 *dptr++ = ROSE_GFI | lci1; 142 *dptr++ = ROSE_GFI | lci1;
143 *dptr++ = lci2; 143 *dptr++ = lci2;
144 *dptr++ = frametype; 144 *dptr++ = frametype;
145 *dptr++ = 0xAA; 145 *dptr++ = ROSE_CALL_REQ_ADDR_LEN_VAL;
146 memcpy(dptr, &rose->dest_addr, ROSE_ADDR_LEN); 146 memcpy(dptr, &rose->dest_addr, ROSE_ADDR_LEN);
147 dptr += ROSE_ADDR_LEN; 147 dptr += ROSE_ADDR_LEN;
148 memcpy(dptr, &rose->source_addr, ROSE_ADDR_LEN); 148 memcpy(dptr, &rose->source_addr, ROSE_ADDR_LEN);
@@ -246,12 +246,16 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct *
246 do { 246 do {
247 switch (*p & 0xC0) { 247 switch (*p & 0xC0) {
248 case 0x00: 248 case 0x00:
249 if (len < 2)
250 return -1;
249 p += 2; 251 p += 2;
250 n += 2; 252 n += 2;
251 len -= 2; 253 len -= 2;
252 break; 254 break;
253 255
254 case 0x40: 256 case 0x40:
257 if (len < 3)
258 return -1;
255 if (*p == FAC_NATIONAL_RAND) 259 if (*p == FAC_NATIONAL_RAND)
256 facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF); 260 facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF);
257 p += 3; 261 p += 3;
@@ -260,40 +264,61 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct *
260 break; 264 break;
261 265
262 case 0x80: 266 case 0x80:
267 if (len < 4)
268 return -1;
263 p += 4; 269 p += 4;
264 n += 4; 270 n += 4;
265 len -= 4; 271 len -= 4;
266 break; 272 break;
267 273
268 case 0xC0: 274 case 0xC0:
275 if (len < 2)
276 return -1;
269 l = p[1]; 277 l = p[1];
278 if (len < 2 + l)
279 return -1;
270 if (*p == FAC_NATIONAL_DEST_DIGI) { 280 if (*p == FAC_NATIONAL_DEST_DIGI) {
271 if (!fac_national_digis_received) { 281 if (!fac_national_digis_received) {
282 if (l < AX25_ADDR_LEN)
283 return -1;
272 memcpy(&facilities->source_digis[0], p + 2, AX25_ADDR_LEN); 284 memcpy(&facilities->source_digis[0], p + 2, AX25_ADDR_LEN);
273 facilities->source_ndigis = 1; 285 facilities->source_ndigis = 1;
274 } 286 }
275 } 287 }
276 else if (*p == FAC_NATIONAL_SRC_DIGI) { 288 else if (*p == FAC_NATIONAL_SRC_DIGI) {
277 if (!fac_national_digis_received) { 289 if (!fac_national_digis_received) {
290 if (l < AX25_ADDR_LEN)
291 return -1;
278 memcpy(&facilities->dest_digis[0], p + 2, AX25_ADDR_LEN); 292 memcpy(&facilities->dest_digis[0], p + 2, AX25_ADDR_LEN);
279 facilities->dest_ndigis = 1; 293 facilities->dest_ndigis = 1;
280 } 294 }
281 } 295 }
282 else if (*p == FAC_NATIONAL_FAIL_CALL) { 296 else if (*p == FAC_NATIONAL_FAIL_CALL) {
297 if (l < AX25_ADDR_LEN)
298 return -1;
283 memcpy(&facilities->fail_call, p + 2, AX25_ADDR_LEN); 299 memcpy(&facilities->fail_call, p + 2, AX25_ADDR_LEN);
284 } 300 }
285 else if (*p == FAC_NATIONAL_FAIL_ADD) { 301 else if (*p == FAC_NATIONAL_FAIL_ADD) {
302 if (l < 1 + ROSE_ADDR_LEN)
303 return -1;
286 memcpy(&facilities->fail_addr, p + 3, ROSE_ADDR_LEN); 304 memcpy(&facilities->fail_addr, p + 3, ROSE_ADDR_LEN);
287 } 305 }
288 else if (*p == FAC_NATIONAL_DIGIS) { 306 else if (*p == FAC_NATIONAL_DIGIS) {
307 if (l % AX25_ADDR_LEN)
308 return -1;
289 fac_national_digis_received = 1; 309 fac_national_digis_received = 1;
290 facilities->source_ndigis = 0; 310 facilities->source_ndigis = 0;
291 facilities->dest_ndigis = 0; 311 facilities->dest_ndigis = 0;
292 for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) { 312 for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) {
293 if (pt[6] & AX25_HBIT) 313 if (pt[6] & AX25_HBIT) {
314 if (facilities->dest_ndigis >= ROSE_MAX_DIGIS)
315 return -1;
294 memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN); 316 memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN);
295 else 317 } else {
318 if (facilities->source_ndigis >= ROSE_MAX_DIGIS)
319 return -1;
296 memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN); 320 memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN);
321 }
297 } 322 }
298 } 323 }
299 p += l + 2; 324 p += l + 2;
@@ -314,25 +339,38 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
314 do { 339 do {
315 switch (*p & 0xC0) { 340 switch (*p & 0xC0) {
316 case 0x00: 341 case 0x00:
342 if (len < 2)
343 return -1;
317 p += 2; 344 p += 2;
318 n += 2; 345 n += 2;
319 len -= 2; 346 len -= 2;
320 break; 347 break;
321 348
322 case 0x40: 349 case 0x40:
350 if (len < 3)
351 return -1;
323 p += 3; 352 p += 3;
324 n += 3; 353 n += 3;
325 len -= 3; 354 len -= 3;
326 break; 355 break;
327 356
328 case 0x80: 357 case 0x80:
358 if (len < 4)
359 return -1;
329 p += 4; 360 p += 4;
330 n += 4; 361 n += 4;
331 len -= 4; 362 len -= 4;
332 break; 363 break;
333 364
334 case 0xC0: 365 case 0xC0:
366 if (len < 2)
367 return -1;
335 l = p[1]; 368 l = p[1];
369
370 /* Prevent overflows*/
371 if (l < 10 || l > 20)
372 return -1;
373
336 if (*p == FAC_CCITT_DEST_NSAP) { 374 if (*p == FAC_CCITT_DEST_NSAP) {
337 memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN); 375 memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
338 memcpy(callsign, p + 12, l - 10); 376 memcpy(callsign, p + 12, l - 10);
@@ -355,45 +393,44 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
355 return n; 393 return n;
356} 394}
357 395
358int rose_parse_facilities(unsigned char *p, 396int rose_parse_facilities(unsigned char *p, unsigned packet_len,
359 struct rose_facilities_struct *facilities) 397 struct rose_facilities_struct *facilities)
360{ 398{
361 int facilities_len, len; 399 int facilities_len, len;
362 400
363 facilities_len = *p++; 401 facilities_len = *p++;
364 402
365 if (facilities_len == 0) 403 if (facilities_len == 0 || (unsigned)facilities_len > packet_len)
366 return 0; 404 return 0;
367 405
368 while (facilities_len > 0) { 406 while (facilities_len >= 3 && *p == 0x00) {
369 if (*p == 0x00) { 407 facilities_len--;
370 facilities_len--; 408 p++;
371 p++; 409
372 410 switch (*p) {
373 switch (*p) { 411 case FAC_NATIONAL: /* National */
374 case FAC_NATIONAL: /* National */ 412 len = rose_parse_national(p + 1, facilities, facilities_len - 1);
375 len = rose_parse_national(p + 1, facilities, facilities_len - 1); 413 break;
376 facilities_len -= len + 1; 414
377 p += len + 1; 415 case FAC_CCITT: /* CCITT */
378 break; 416 len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1);
379 417 break;
380 case FAC_CCITT: /* CCITT */ 418
381 len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); 419 default:
382 facilities_len -= len + 1; 420 printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p);
383 p += len + 1; 421 len = 1;
384 break; 422 break;
385 423 }
386 default: 424
387 printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p); 425 if (len < 0)
388 facilities_len--; 426 return 0;
389 p++; 427 if (WARN_ON(len >= facilities_len))
390 break; 428 return 0;
391 } 429 facilities_len -= len + 1;
392 } else 430 p += len + 1;
393 break; /* Error in facilities format */
394 } 431 }
395 432
396 return 1; 433 return facilities_len == 0;
397} 434}
398 435
399static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose) 436static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 872065ca7f8c..a026b0ef2443 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -173,7 +173,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
173 goto drop_unlock; 173 goto drop_unlock;
174 } 174 }
175 175
176 if (x->props.replay_window && x->repl->check(x, skb, seq)) { 176 if (x->repl->check(x, skb, seq)) {
177 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR); 177 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
178 goto drop_unlock; 178 goto drop_unlock;
179 } 179 }
@@ -190,6 +190,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
190 XFRM_SKB_CB(skb)->seq.input.low = seq; 190 XFRM_SKB_CB(skb)->seq.input.low = seq;
191 XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; 191 XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
192 192
193 skb_dst_force(skb);
194
193 nexthdr = x->type->input(x, skb); 195 nexthdr = x->type->input(x, skb);
194 196
195 if (nexthdr == -EINPROGRESS) 197 if (nexthdr == -EINPROGRESS)
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 1aba03f449cc..47bacd8c0250 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -78,6 +78,8 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
78 78
79 spin_unlock_bh(&x->lock); 79 spin_unlock_bh(&x->lock);
80 80
81 skb_dst_force(skb);
82
81 err = x->type->output(x, skb); 83 err = x->type->output(x, skb);
82 if (err == -EINPROGRESS) 84 if (err == -EINPROGRESS)
83 goto out_exit; 85 goto out_exit;
@@ -94,7 +96,7 @@ resume:
94 err = -EHOSTUNREACH; 96 err = -EHOSTUNREACH;
95 goto error_nolock; 97 goto error_nolock;
96 } 98 }
97 skb_dst_set(skb, dst_clone(dst)); 99 skb_dst_set(skb, dst);
98 x = dst->xfrm; 100 x = dst->xfrm;
99 } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); 101 } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
100 102
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 2f5be5b15740..f218385950ca 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -118,6 +118,9 @@ static int xfrm_replay_check(struct xfrm_state *x,
118 u32 diff; 118 u32 diff;
119 u32 seq = ntohl(net_seq); 119 u32 seq = ntohl(net_seq);
120 120
121 if (!x->props.replay_window)
122 return 0;
123
121 if (unlikely(seq == 0)) 124 if (unlikely(seq == 0))
122 goto err; 125 goto err;
123 126
@@ -193,9 +196,14 @@ static int xfrm_replay_check_bmp(struct xfrm_state *x,
193{ 196{
194 unsigned int bitnr, nr; 197 unsigned int bitnr, nr;
195 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; 198 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
199 u32 pos;
196 u32 seq = ntohl(net_seq); 200 u32 seq = ntohl(net_seq);
197 u32 diff = replay_esn->seq - seq; 201 u32 diff = replay_esn->seq - seq;
198 u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window; 202
203 if (!replay_esn->replay_window)
204 return 0;
205
206 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
199 207
200 if (unlikely(seq == 0)) 208 if (unlikely(seq == 0))
201 goto err; 209 goto err;
@@ -373,12 +381,17 @@ static int xfrm_replay_check_esn(struct xfrm_state *x,
373 unsigned int bitnr, nr; 381 unsigned int bitnr, nr;
374 u32 diff; 382 u32 diff;
375 struct xfrm_replay_state_esn *replay_esn = x->replay_esn; 383 struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
384 u32 pos;
376 u32 seq = ntohl(net_seq); 385 u32 seq = ntohl(net_seq);
377 u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
378 u32 wsize = replay_esn->replay_window; 386 u32 wsize = replay_esn->replay_window;
379 u32 top = replay_esn->seq; 387 u32 top = replay_esn->seq;
380 u32 bottom = top - wsize + 1; 388 u32 bottom = top - wsize + 1;
381 389
390 if (!wsize)
391 return 0;
392
393 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
394
382 if (unlikely(seq == 0 && replay_esn->seq_hi == 0 && 395 if (unlikely(seq == 0 && replay_esn->seq_hi == 0 &&
383 (replay_esn->seq < replay_esn->replay_window - 1))) 396 (replay_esn->seq < replay_esn->replay_window - 1)))
384 goto err; 397 goto err;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f83a3d1da81b..dd78536d40de 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1181,6 +1181,12 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
1181 goto error; 1181 goto error;
1182 } 1182 }
1183 1183
1184 if (orig->replay_esn) {
1185 err = xfrm_replay_clone(x, orig);
1186 if (err)
1187 goto error;
1188 }
1189
1184 memcpy(&x->mark, &orig->mark, sizeof(x->mark)); 1190 memcpy(&x->mark, &orig->mark, sizeof(x->mark));
1185 1191
1186 err = xfrm_init_state(x); 1192 err = xfrm_init_state(x);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index fc152d28753c..3d15d3e1b2c4 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -127,6 +127,9 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
127 if (!rt) 127 if (!rt)
128 return 0; 128 return 0;
129 129
130 if (p->id.proto != IPPROTO_ESP)
131 return -EINVAL;
132
130 if (p->replay_window != 0) 133 if (p->replay_window != 0)
131 return -EINVAL; 134 return -EINVAL;
132 135
@@ -360,6 +363,23 @@ static int attach_aead(struct xfrm_algo_aead **algpp, u8 *props,
360 return 0; 363 return 0;
361} 364}
362 365
366static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_esn,
367 struct nlattr *rp)
368{
369 struct xfrm_replay_state_esn *up;
370
371 if (!replay_esn || !rp)
372 return 0;
373
374 up = nla_data(rp);
375
376 if (xfrm_replay_state_esn_len(replay_esn) !=
377 xfrm_replay_state_esn_len(up))
378 return -EINVAL;
379
380 return 0;
381}
382
363static int xfrm_alloc_replay_state_esn(struct xfrm_replay_state_esn **replay_esn, 383static int xfrm_alloc_replay_state_esn(struct xfrm_replay_state_esn **replay_esn,
364 struct xfrm_replay_state_esn **preplay_esn, 384 struct xfrm_replay_state_esn **preplay_esn,
365 struct nlattr *rta) 385 struct nlattr *rta)
@@ -1766,6 +1786,10 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
1766 if (x->km.state != XFRM_STATE_VALID) 1786 if (x->km.state != XFRM_STATE_VALID)
1767 goto out; 1787 goto out;
1768 1788
1789 err = xfrm_replay_verify_len(x->replay_esn, rp);
1790 if (err)
1791 goto out;
1792
1769 spin_lock_bh(&x->lock); 1793 spin_lock_bh(&x->lock);
1770 xfrm_update_ae_params(x, attrs); 1794 xfrm_update_ae_params(x, attrs);
1771 spin_unlock_bh(&x->lock); 1795 spin_unlock_bh(&x->lock);