Skip to content

Commit e223d71

Browse files
committed
Merge remote-tracking branch 'stable/linux-4.4.y' into rpi-4.4.y
2 parents 8d1dd63 + c50b74d commit e223d71

29 files changed

+172
-89
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
VERSION = 4
22
PATCHLEVEL = 4
3-
SUBLEVEL = 49
3+
SUBLEVEL = 50
44
EXTRAVERSION =
55
NAME = Blurry Fish Butt
66

drivers/net/ethernet/mellanox/mlx4/en_rx.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,11 @@ void mlx4_en_recover_from_oom(struct mlx4_en_priv *priv)
502502
return;
503503

504504
for (ring = 0; ring < priv->rx_ring_num; ring++) {
505-
if (mlx4_en_is_ring_empty(priv->rx_ring[ring]))
505+
if (mlx4_en_is_ring_empty(priv->rx_ring[ring])) {
506+
local_bh_disable();
506507
napi_reschedule(&priv->rx_cq[ring]->napi);
508+
local_bh_enable();
509+
}
507510
}
508511
}
509512

drivers/net/loopback.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ static void loopback_setup(struct net_device *dev)
164164
{
165165
dev->mtu = 64 * 1024;
166166
dev->hard_header_len = ETH_HLEN; /* 14 */
167+
dev->min_header_len = ETH_HLEN; /* 14 */
167168
dev->addr_len = ETH_ALEN; /* 6 */
168169
dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
169170
dev->flags = IFF_LOOPBACK;

drivers/net/macvtap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
725725
ssize_t n;
726726

727727
if (q->flags & IFF_VNET_HDR) {
728-
vnet_hdr_len = q->vnet_hdr_sz;
728+
vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
729729

730730
err = -EINVAL;
731731
if (len < vnet_hdr_len)
@@ -865,7 +865,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
865865

866866
if (q->flags & IFF_VNET_HDR) {
867867
struct virtio_net_hdr vnet_hdr;
868-
vnet_hdr_len = q->vnet_hdr_sz;
868+
vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
869869
if (iov_iter_count(iter) < vnet_hdr_len)
870870
return -EINVAL;
871871

drivers/net/tun.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,9 +1108,11 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
11081108
}
11091109

11101110
if (tun->flags & IFF_VNET_HDR) {
1111-
if (len < tun->vnet_hdr_sz)
1111+
int vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz);
1112+
1113+
if (len < vnet_hdr_sz)
11121114
return -EINVAL;
1113-
len -= tun->vnet_hdr_sz;
1115+
len -= vnet_hdr_sz;
11141116

11151117
n = copy_from_iter(&gso, sizeof(gso), from);
11161118
if (n != sizeof(gso))
@@ -1122,7 +1124,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
11221124

11231125
if (tun16_to_cpu(tun, gso.hdr_len) > len)
11241126
return -EINVAL;
1125-
iov_iter_advance(from, tun->vnet_hdr_sz - sizeof(gso));
1127+
iov_iter_advance(from, vnet_hdr_sz - sizeof(gso));
11261128
}
11271129

11281130
if ((tun->flags & TUN_TYPE_MASK) == IFF_TAP) {
@@ -1301,7 +1303,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
13011303
vlan_hlen = VLAN_HLEN;
13021304

13031305
if (tun->flags & IFF_VNET_HDR)
1304-
vnet_hdr_sz = tun->vnet_hdr_sz;
1306+
vnet_hdr_sz = READ_ONCE(tun->vnet_hdr_sz);
13051307

13061308
total = skb->len + vlan_hlen + vnet_hdr_sz;
13071309

include/linux/can/core.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@ struct can_proto {
4545
extern int can_proto_register(const struct can_proto *cp);
4646
extern void can_proto_unregister(const struct can_proto *cp);
4747

48-
extern int can_rx_register(struct net_device *dev, canid_t can_id,
49-
canid_t mask,
50-
void (*func)(struct sk_buff *, void *),
51-
void *data, char *ident);
48+
int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
49+
void (*func)(struct sk_buff *, void *),
50+
void *data, char *ident, struct sock *sk);
5251

5352
extern void can_rx_unregister(struct net_device *dev, canid_t can_id,
5453
canid_t mask,

include/linux/netdevice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,7 @@ enum netdev_priv_flags {
13991399
* @mtu: Interface MTU value
14001400
* @type: Interface hardware type
14011401
* @hard_header_len: Maximum hardware header length.
1402+
* @min_header_len: Minimum hardware header length
14021403
*
14031404
* @needed_headroom: Extra headroom the hardware may need, but not in all
14041405
* cases can this be guaranteed
@@ -1619,6 +1620,7 @@ struct net_device {
16191620
unsigned int mtu;
16201621
unsigned short type;
16211622
unsigned short hard_header_len;
1623+
unsigned short min_header_len;
16221624

16231625
unsigned short needed_headroom;
16241626
unsigned short needed_tailroom;
@@ -2541,6 +2543,8 @@ static inline bool dev_validate_header(const struct net_device *dev,
25412543
{
25422544
if (likely(len >= dev->hard_header_len))
25432545
return true;
2546+
if (len < dev->min_header_len)
2547+
return false;
25442548

25452549
if (capable(CAP_SYS_RAWIO)) {
25462550
memset(ll_header + len, 0, dev->hard_header_len - len);

include/net/cipso_ipv4.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,10 @@ static inline int cipso_v4_validate(const struct sk_buff *skb,
309309
}
310310

311311
for (opt_iter = 6; opt_iter < opt_len;) {
312+
if (opt_iter + 1 == opt_len) {
313+
err_offset = opt_iter;
314+
goto out;
315+
}
312316
tag_len = opt[opt_iter + 1];
313317
if ((tag_len == 0) || (tag_len > (opt_len - opt_iter))) {
314318
err_offset = opt_iter + 1;

net/can/af_can.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
445445
* @func: callback function on filter match
446446
* @data: returned parameter for callback function
447447
* @ident: string for calling module identification
448+
* @sk: socket pointer (might be NULL)
448449
*
449450
* Description:
450451
* Invokes the callback function with the received sk_buff and the given
@@ -468,7 +469,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
468469
*/
469470
int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
470471
void (*func)(struct sk_buff *, void *), void *data,
471-
char *ident)
472+
char *ident, struct sock *sk)
472473
{
473474
struct receiver *r;
474475
struct hlist_head *rl;
@@ -496,6 +497,7 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
496497
r->func = func;
497498
r->data = data;
498499
r->ident = ident;
500+
r->sk = sk;
499501

500502
hlist_add_head_rcu(&r->list, rl);
501503
d->entries++;
@@ -520,8 +522,11 @@ EXPORT_SYMBOL(can_rx_register);
520522
static void can_rx_delete_receiver(struct rcu_head *rp)
521523
{
522524
struct receiver *r = container_of(rp, struct receiver, rcu);
525+
struct sock *sk = r->sk;
523526

524527
kmem_cache_free(rcv_cache, r);
528+
if (sk)
529+
sock_put(sk);
525530
}
526531

527532
/**
@@ -596,8 +601,11 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
596601
spin_unlock(&can_rcvlists_lock);
597602

598603
/* schedule the receiver item for deletion */
599-
if (r)
604+
if (r) {
605+
if (r->sk)
606+
sock_hold(r->sk);
600607
call_rcu(&r->rcu, can_rx_delete_receiver);
608+
}
601609
}
602610
EXPORT_SYMBOL(can_rx_unregister);
603611

net/can/af_can.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@
5050

5151
struct receiver {
5252
struct hlist_node list;
53-
struct rcu_head rcu;
5453
canid_t can_id;
5554
canid_t mask;
5655
unsigned long matches;
5756
void (*func)(struct sk_buff *, void *);
5857
void *data;
5958
char *ident;
59+
struct sock *sk;
60+
struct rcu_head rcu;
6061
};
6162

6263
#define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS)

net/can/bcm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
11791179
err = can_rx_register(dev, op->can_id,
11801180
REGMASK(op->can_id),
11811181
bcm_rx_handler, op,
1182-
"bcm");
1182+
"bcm", sk);
11831183

11841184
op->rx_reg_dev = dev;
11851185
dev_put(dev);
@@ -1188,7 +1188,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
11881188
} else
11891189
err = can_rx_register(NULL, op->can_id,
11901190
REGMASK(op->can_id),
1191-
bcm_rx_handler, op, "bcm");
1191+
bcm_rx_handler, op, "bcm", sk);
11921192
if (err) {
11931193
/* this bcm rx op is broken -> remove it */
11941194
list_del(&op->list);

net/can/gw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ static inline int cgw_register_filter(struct cgw_job *gwj)
442442
{
443443
return can_rx_register(gwj->src.dev, gwj->ccgw.filter.can_id,
444444
gwj->ccgw.filter.can_mask, can_can_gw_rcv,
445-
gwj, "gw");
445+
gwj, "gw", NULL);
446446
}
447447

448448
static inline void cgw_unregister_filter(struct cgw_job *gwj)

net/can/raw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ static int raw_enable_filters(struct net_device *dev, struct sock *sk,
190190
for (i = 0; i < count; i++) {
191191
err = can_rx_register(dev, filter[i].can_id,
192192
filter[i].can_mask,
193-
raw_rcv, sk, "raw");
193+
raw_rcv, sk, "raw", sk);
194194
if (err) {
195195
/* clean up successfully registered filters */
196196
while (--i >= 0)
@@ -211,7 +211,7 @@ static int raw_enable_errfilter(struct net_device *dev, struct sock *sk,
211211

212212
if (err_mask)
213213
err = can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG,
214-
raw_rcv, sk, "raw");
214+
raw_rcv, sk, "raw", sk);
215215

216216
return err;
217217
}

net/core/dev.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,37 +1676,32 @@ EXPORT_SYMBOL_GPL(net_dec_ingress_queue);
16761676

16771677
static struct static_key netstamp_needed __read_mostly;
16781678
#ifdef HAVE_JUMP_LABEL
1679-
/* We are not allowed to call static_key_slow_dec() from irq context
1680-
* If net_disable_timestamp() is called from irq context, defer the
1681-
* static_key_slow_dec() calls.
1682-
*/
16831679
static atomic_t netstamp_needed_deferred;
1684-
#endif
1685-
1686-
void net_enable_timestamp(void)
1680+
static void netstamp_clear(struct work_struct *work)
16871681
{
1688-
#ifdef HAVE_JUMP_LABEL
16891682
int deferred = atomic_xchg(&netstamp_needed_deferred, 0);
16901683

1691-
if (deferred) {
1692-
while (--deferred)
1693-
static_key_slow_dec(&netstamp_needed);
1694-
return;
1695-
}
1684+
while (deferred--)
1685+
static_key_slow_dec(&netstamp_needed);
1686+
}
1687+
static DECLARE_WORK(netstamp_work, netstamp_clear);
16961688
#endif
1689+
1690+
void net_enable_timestamp(void)
1691+
{
16971692
static_key_slow_inc(&netstamp_needed);
16981693
}
16991694
EXPORT_SYMBOL(net_enable_timestamp);
17001695

17011696
void net_disable_timestamp(void)
17021697
{
17031698
#ifdef HAVE_JUMP_LABEL
1704-
if (in_interrupt()) {
1705-
atomic_inc(&netstamp_needed_deferred);
1706-
return;
1707-
}
1708-
#endif
1699+
/* net_disable_timestamp() can be called from non process context */
1700+
atomic_inc(&netstamp_needed_deferred);
1701+
schedule_work(&netstamp_work);
1702+
#else
17091703
static_key_slow_dec(&netstamp_needed);
1704+
#endif
17101705
}
17111706
EXPORT_SYMBOL(net_disable_timestamp);
17121707

net/ethernet/eth.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ void ether_setup(struct net_device *dev)
353353
dev->header_ops = &eth_header_ops;
354354
dev->type = ARPHRD_ETHER;
355355
dev->hard_header_len = ETH_HLEN;
356+
dev->min_header_len = ETH_HLEN;
356357
dev->mtu = ETH_DATA_LEN;
357358
dev->addr_len = ETH_ALEN;
358359
dev->tx_queue_len = 1000; /* Ethernet wants good queues */

net/ipv4/cipso_ipv4.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,10 @@ int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option)
16571657
goto validate_return_locked;
16581658
}
16591659

1660+
if (opt_iter + 1 == opt_len) {
1661+
err_offset = opt_iter;
1662+
goto validate_return_locked;
1663+
}
16601664
tag_len = tag[1];
16611665
if (tag_len > (opt_len - opt_iter)) {
16621666
err_offset = opt_iter + 1;

net/ipv4/ip_sockglue.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1192,7 +1192,14 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
11921192
pktinfo->ipi_ifindex = 0;
11931193
pktinfo->ipi_spec_dst.s_addr = 0;
11941194
}
1195-
skb_dst_drop(skb);
1195+
/* We need to keep the dst for __ip_options_echo()
1196+
* We could restrict the test to opt.ts_needtime || opt.srr,
1197+
* but the following is good enough as IP options are not often used.
1198+
*/
1199+
if (unlikely(IPCB(skb)->opt.optlen))
1200+
skb_dst_force(skb);
1201+
else
1202+
skb_dst_drop(skb);
11961203
}
11971204

11981205
int ip_setsockopt(struct sock *sk, int level,

net/ipv4/ping.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,8 @@ static int ping_v4_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
645645
{
646646
struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
647647

648+
if (!skb)
649+
return 0;
648650
pfh->wcheck = csum_partial((char *)&pfh->icmph,
649651
sizeof(struct icmphdr), pfh->wcheck);
650652
pfh->icmph.checksum = csum_fold(pfh->wcheck);

net/ipv4/tcp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,12 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
783783
ret = -EAGAIN;
784784
break;
785785
}
786+
/* if __tcp_splice_read() got nothing while we have
787+
* an skb in receive queue, we do not want to loop.
788+
* This might happen with URG data.
789+
*/
790+
if (!skb_queue_empty(&sk->sk_receive_queue))
791+
break;
786792
sk_wait_data(sk, &timeo, NULL);
787793
if (signal_pending(current)) {
788794
ret = sock_intr_errno(timeo);

net/ipv4/tcp_output.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,9 +2383,11 @@ u32 __tcp_select_window(struct sock *sk)
23832383
int full_space = min_t(int, tp->window_clamp, allowed_space);
23842384
int window;
23852385

2386-
if (mss > full_space)
2386+
if (unlikely(mss > full_space)) {
23872387
mss = full_space;
2388-
2388+
if (mss <= 0)
2389+
return 0;
2390+
}
23892391
if (free_space < (full_space >> 1)) {
23902392
icsk->icsk_ack.quick = 0;
23912393

0 commit comments

Comments
 (0)