kernel: bump 4.9 to 4.9.159
Refreshed all patches. Remove upstreamed: - 023-1-smsc95xx-Use-skb_cow_head-to-deal-with-cloned-skbs.patch - 023-6-ch9200-use-skb_cow_head-to-deal-with-cloned-skbs.patch - 023-7-kaweth-use-skb_cow_head-to-deal-with-cloned-skbs.patch - 050-usb-dwc2-Remove-unnecessary-kfree.patch - 092-netfilter-nf_tables-fix-mismatch-in-big-endian-syste.patch - 272-uapi-if_ether.h-prevent-redefinition-of-struct-ethhd.patch Fixes: - CVE-2018-1000026 Compile-tested on: ar7 Runtime-tested on: none Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
This commit is contained in:
		| @@ -3,12 +3,12 @@ | |||||||
| LINUX_RELEASE?=1 | LINUX_RELEASE?=1 | ||||||
|  |  | ||||||
| LINUX_VERSION-3.18 = .135 | LINUX_VERSION-3.18 = .135 | ||||||
| LINUX_VERSION-4.9 = .158 | LINUX_VERSION-4.9 = .159 | ||||||
| LINUX_VERSION-4.14 = .101 | LINUX_VERSION-4.14 = .101 | ||||||
| LINUX_VERSION-4.19 = .23 | LINUX_VERSION-4.19 = .23 | ||||||
|  |  | ||||||
| LINUX_KERNEL_HASH-3.18.135 = d1853eb6e5438abb0b54d11478c0792554e39325d37a3f04b68f6c151ed8f8eb | LINUX_KERNEL_HASH-3.18.135 = d1853eb6e5438abb0b54d11478c0792554e39325d37a3f04b68f6c151ed8f8eb | ||||||
| LINUX_KERNEL_HASH-4.9.158 = 8c8a69f590e6f1103c949b45ff1bfd42c705388321f75e1520be3556f81375ef | LINUX_KERNEL_HASH-4.9.159 = 9f9df13168a090d12314e2e8dac040e71ce3f2ed89eafbece2b14dabb6771742 | ||||||
| LINUX_KERNEL_HASH-4.14.101 = 142ff7c51b001c66e9be134fcec2722f9a47b89879a18e6f65b09b4585cdb69a | LINUX_KERNEL_HASH-4.14.101 = 142ff7c51b001c66e9be134fcec2722f9a47b89879a18e6f65b09b4585cdb69a | ||||||
| LINUX_KERNEL_HASH-4.19.23 = 2d9b25678aac7f3f109c52e6266fb6ee89cc424b597518a2875874bacb8f130a | LINUX_KERNEL_HASH-4.19.23 = 2d9b25678aac7f3f109c52e6266fb6ee89cc424b597518a2875874bacb8f130a | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,40 +0,0 @@ | |||||||
| From e9156cd26a495a18706e796f02a81fee41ec14f4 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: James Hughes <james.hughes@raspberrypi.org> |  | ||||||
| Date: Wed, 19 Apr 2017 11:13:40 +0100 |  | ||||||
| Subject: [PATCH] smsc95xx: Use skb_cow_head to deal with cloned skbs |  | ||||||
|  |  | ||||||
| The driver was failing to check that the SKB wasn't cloned |  | ||||||
| before adding checksum data. |  | ||||||
| Replace existing handling to extend/copy the header buffer |  | ||||||
| with skb_cow_head. |  | ||||||
|  |  | ||||||
| Signed-off-by: James Hughes <james.hughes@raspberrypi.org> |  | ||||||
| Acked-by: Eric Dumazet <edumazet@google.com> |  | ||||||
| Acked-by: Woojung Huh <Woojung.Huh@microchip.com> |  | ||||||
| Signed-off-by: David S. Miller <davem@davemloft.net> |  | ||||||
| --- |  | ||||||
|  drivers/net/usb/smsc95xx.c | 12 ++++++------ |  | ||||||
|  1 file changed, 6 insertions(+), 6 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/usb/smsc95xx.c |  | ||||||
| +++ b/drivers/net/usb/smsc95xx.c |  | ||||||
| @@ -2011,13 +2011,13 @@ static struct sk_buff *smsc95xx_tx_fixup |  | ||||||
|  	/* We do not advertise SG, so skbs should be already linearized */ |  | ||||||
|  	BUG_ON(skb_shinfo(skb)->nr_frags); |  | ||||||
|   |  | ||||||
| -	if (skb_headroom(skb) < overhead) { |  | ||||||
| -		struct sk_buff *skb2 = skb_copy_expand(skb, |  | ||||||
| -			overhead, 0, flags); |  | ||||||
| +	/* Make writable and expand header space by overhead if required */ |  | ||||||
| +	if (skb_cow_head(skb, overhead)) { |  | ||||||
| +		/* Must deallocate here as returning NULL to indicate error |  | ||||||
| +		 * means the skb won't be deallocated in the caller. |  | ||||||
| +		 */ |  | ||||||
|  		dev_kfree_skb_any(skb); |  | ||||||
| -		skb = skb2; |  | ||||||
| -		if (!skb) |  | ||||||
| -			return NULL; |  | ||||||
| +		return NULL; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if (csum) { |  | ||||||
| @@ -1,38 +0,0 @@ | |||||||
| From 6bc6895bdd6744e0136eaa4a11fbdb20a7db4e40 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Eric Dumazet <edumazet@google.com> |  | ||||||
| Date: Wed, 19 Apr 2017 09:59:25 -0700 |  | ||||||
| Subject: [PATCH] ch9200: use skb_cow_head() to deal with cloned skbs |  | ||||||
|  |  | ||||||
| We need to ensure there is enough headroom to push extra header, |  | ||||||
| but we also need to check if we are allowed to change headers. |  | ||||||
|  |  | ||||||
| skb_cow_head() is the proper helper to deal with this. |  | ||||||
|  |  | ||||||
| Fixes: 4a476bd6d1d9 ("usbnet: New driver for QinHeng CH9200 devices") |  | ||||||
| Signed-off-by: Eric Dumazet <edumazet@google.com> |  | ||||||
| Cc: James Hughes <james.hughes@raspberrypi.org> |  | ||||||
| Cc: Matthew Garrett <mjg59@srcf.ucam.org> |  | ||||||
| Signed-off-by: David S. Miller <davem@davemloft.net> |  | ||||||
| --- |  | ||||||
|  drivers/net/usb/ch9200.c | 9 ++------- |  | ||||||
|  1 file changed, 2 insertions(+), 7 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/usb/ch9200.c |  | ||||||
| +++ b/drivers/net/usb/ch9200.c |  | ||||||
| @@ -254,14 +254,9 @@ static struct sk_buff *ch9200_tx_fixup(s |  | ||||||
|  	tx_overhead = 0x40; |  | ||||||
|   |  | ||||||
|  	len = skb->len; |  | ||||||
| -	if (skb_headroom(skb) < tx_overhead) { |  | ||||||
| -		struct sk_buff *skb2; |  | ||||||
| - |  | ||||||
| -		skb2 = skb_copy_expand(skb, tx_overhead, 0, flags); |  | ||||||
| +	if (skb_cow_head(skb, tx_overhead)) { |  | ||||||
|  		dev_kfree_skb_any(skb); |  | ||||||
| -		skb = skb2; |  | ||||||
| -		if (!skb) |  | ||||||
| -			return NULL; |  | ||||||
| +		return NULL; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	__skb_push(skb, tx_overhead); |  | ||||||
| @@ -1,43 +0,0 @@ | |||||||
| From 39fba7835aacda65284a86e611774cbba71dac20 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Eric Dumazet <edumazet@google.com> |  | ||||||
| Date: Wed, 19 Apr 2017 09:59:26 -0700 |  | ||||||
| Subject: [PATCH] kaweth: use skb_cow_head() to deal with cloned skbs |  | ||||||
|  |  | ||||||
| We can use skb_cow_head() to properly deal with clones, |  | ||||||
| especially the ones coming from TCP stack that allow their head being |  | ||||||
| modified. This avoids a copy. |  | ||||||
|  |  | ||||||
| Signed-off-by: Eric Dumazet <edumazet@google.com> |  | ||||||
| Cc: James Hughes <james.hughes@raspberrypi.org> |  | ||||||
| Signed-off-by: David S. Miller <davem@davemloft.net> |  | ||||||
| --- |  | ||||||
|  drivers/net/usb/kaweth.c | 18 ++++++------------ |  | ||||||
|  1 file changed, 6 insertions(+), 12 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/net/usb/kaweth.c |  | ||||||
| +++ b/drivers/net/usb/kaweth.c |  | ||||||
| @@ -803,18 +803,12 @@ static netdev_tx_t kaweth_start_xmit(str |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	/* We now decide whether we can put our special header into the sk_buff */ |  | ||||||
| -	if (skb_cloned(skb) || skb_headroom(skb) < 2) { |  | ||||||
| -		/* no such luck - we make our own */ |  | ||||||
| -		struct sk_buff *copied_skb; |  | ||||||
| -		copied_skb = skb_copy_expand(skb, 2, 0, GFP_ATOMIC); |  | ||||||
| -		dev_kfree_skb_irq(skb); |  | ||||||
| -		skb = copied_skb; |  | ||||||
| -		if (!copied_skb) { |  | ||||||
| -			kaweth->stats.tx_errors++; |  | ||||||
| -			netif_start_queue(net); |  | ||||||
| -			spin_unlock_irq(&kaweth->device_lock); |  | ||||||
| -			return NETDEV_TX_OK; |  | ||||||
| -		} |  | ||||||
| +	if (skb_cow_head(skb, 2)) { |  | ||||||
| +		kaweth->stats.tx_errors++; |  | ||||||
| +		netif_start_queue(net); |  | ||||||
| +		spin_unlock_irq(&kaweth->device_lock); |  | ||||||
| +		dev_kfree_skb_any(skb); |  | ||||||
| +		return NETDEV_TX_OK; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	private_header = (__le16 *)__skb_push(skb, 2); |  | ||||||
| @@ -1,24 +0,0 @@ | |||||||
| From cd4b1e34655d46950c065d9284b596cd8d7b28cd Mon Sep 17 00:00:00 2001 |  | ||||||
| From: John Youn <johnyoun@synopsys.com> |  | ||||||
| Date: Thu, 3 Nov 2016 17:55:45 -0700 |  | ||||||
| Subject: [PATCH] usb: dwc2: Remove unnecessary kfree |  | ||||||
|  |  | ||||||
| This shouldn't be freed by the HCD as it is owned by the core and |  | ||||||
| allocated with devm_kzalloc. |  | ||||||
|  |  | ||||||
| Signed-off-by: John Youn <johnyoun@synopsys.com> |  | ||||||
| Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> |  | ||||||
| --- |  | ||||||
|  drivers/usb/dwc2/hcd.c | 1 - |  | ||||||
|  1 file changed, 1 deletion(-) |  | ||||||
|  |  | ||||||
| --- a/drivers/usb/dwc2/hcd.c |  | ||||||
| +++ b/drivers/usb/dwc2/hcd.c |  | ||||||
| @@ -5202,7 +5202,6 @@ error3: |  | ||||||
|  error2: |  | ||||||
|  	usb_put_hcd(hcd); |  | ||||||
|  error1: |  | ||||||
| -	kfree(hsotg->core_params); |  | ||||||
|   |  | ||||||
|  #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS |  | ||||||
|  	kfree(hsotg->last_frame_num_array); |  | ||||||
| @@ -1,323 +0,0 @@ | |||||||
| From 0bc01df3df7a88258148518eb9ce7f88c16a6106 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Liping Zhang <zlpnobody@gmail.com> |  | ||||||
| Date: Wed, 8 Mar 2017 22:54:18 +0800 |  | ||||||
| Subject: netfilter: nf_tables: fix mismatch in big-endian system |  | ||||||
|  |  | ||||||
| Currently, there are two different methods to store an u16 integer to |  | ||||||
| the u32 data register. For example: |  | ||||||
|   u32 *dest = ®s->data[priv->dreg]; |  | ||||||
|   1. *dest = 0; *(u16 *) dest = val_u16; |  | ||||||
|   2. *dest = val_u16; |  | ||||||
|  |  | ||||||
| For method 1, the u16 value will be stored like this, either in |  | ||||||
| big-endian or little-endian system: |  | ||||||
|   0          15           31 |  | ||||||
|   +-+-+-+-+-+-+-+-+-+-+-+-+ |  | ||||||
|   |   Value   |     0     | |  | ||||||
|   +-+-+-+-+-+-+-+-+-+-+-+-+ |  | ||||||
|  |  | ||||||
| For method 2, in little-endian system, the u16 value will be the same |  | ||||||
| as listed above. But in big-endian system, the u16 value will be stored |  | ||||||
| like this: |  | ||||||
|   0          15           31 |  | ||||||
|   +-+-+-+-+-+-+-+-+-+-+-+-+ |  | ||||||
|   |     0     |   Value   | |  | ||||||
|   +-+-+-+-+-+-+-+-+-+-+-+-+ |  | ||||||
|  |  | ||||||
| So later we use "memcmp(®s->data[priv->sreg], data, 2);" to do |  | ||||||
| compare in nft_cmp, nft_lookup expr ..., method 2 will get the wrong |  | ||||||
| result in big-endian system, as 0~15 bits will always be zero. |  | ||||||
|  |  | ||||||
| For the similar reason, when loading an u16 value from the u32 data |  | ||||||
| register, we should use "*(u16 *) sreg;" instead of "(u16)*sreg;", |  | ||||||
| the 2nd method will get the wrong value in the big-endian system. |  | ||||||
|  |  | ||||||
| So introduce some wrapper functions to store/load an u8 or u16 |  | ||||||
| integer to/from the u32 data register, and use them in the right |  | ||||||
| place. |  | ||||||
|  |  | ||||||
| Signed-off-by: Liping Zhang <zlpnobody@gmail.com> |  | ||||||
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |  | ||||||
| --- |  | ||||||
|  include/net/netfilter/nf_tables.h   | 29 +++++++++++++++++++++++++ |  | ||||||
|  net/ipv4/netfilter/nft_masq_ipv4.c  |  8 +++---- |  | ||||||
|  net/ipv4/netfilter/nft_redir_ipv4.c |  8 +++---- |  | ||||||
|  net/ipv6/netfilter/nft_masq_ipv6.c  |  8 +++---- |  | ||||||
|  net/ipv6/netfilter/nft_redir_ipv6.c |  8 +++---- |  | ||||||
|  net/netfilter/nft_ct.c              | 10 ++++----- |  | ||||||
|  net/netfilter/nft_meta.c            | 42 +++++++++++++++++++------------------ |  | ||||||
|  net/netfilter/nft_nat.c             |  8 +++---- |  | ||||||
|  8 files changed, 76 insertions(+), 45 deletions(-) |  | ||||||
|  |  | ||||||
| --- a/include/net/netfilter/nf_tables.h |  | ||||||
| +++ b/include/net/netfilter/nf_tables.h |  | ||||||
| @@ -87,6 +87,35 @@ struct nft_regs { |  | ||||||
|  	}; |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +/* Store/load an u16 or u8 integer to/from the u32 data register. |  | ||||||
| + * |  | ||||||
| + * Note, when using concatenations, register allocation happens at 32-bit |  | ||||||
| + * level. So for store instruction, pad the rest part with zero to avoid |  | ||||||
| + * garbage values. |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +static inline void nft_reg_store16(u32 *dreg, u16 val) |  | ||||||
| +{ |  | ||||||
| +	*dreg = 0; |  | ||||||
| +	*(u16 *)dreg = val; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void nft_reg_store8(u32 *dreg, u8 val) |  | ||||||
| +{ |  | ||||||
| +	*dreg = 0; |  | ||||||
| +	*(u8 *)dreg = val; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline u16 nft_reg_load16(u32 *sreg) |  | ||||||
| +{ |  | ||||||
| +	return *(u16 *)sreg; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline u8 nft_reg_load8(u32 *sreg) |  | ||||||
| +{ |  | ||||||
| +	return *(u8 *)sreg; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
|  static inline void nft_data_copy(u32 *dst, const struct nft_data *src, |  | ||||||
|  				 unsigned int len) |  | ||||||
|  { |  | ||||||
| --- a/net/ipv4/netfilter/nft_masq_ipv4.c |  | ||||||
| +++ b/net/ipv4/netfilter/nft_masq_ipv4.c |  | ||||||
| @@ -26,10 +26,10 @@ static void nft_masq_ipv4_eval(const str |  | ||||||
|  	memset(&range, 0, sizeof(range)); |  | ||||||
|  	range.flags = priv->flags; |  | ||||||
|  	if (priv->sreg_proto_min) { |  | ||||||
| -		range.min_proto.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_min]; |  | ||||||
| -		range.max_proto.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_max]; |  | ||||||
| +		range.min_proto.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_min]); |  | ||||||
| +		range.max_proto.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_max]); |  | ||||||
|  	} |  | ||||||
|  	regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb, pkt->hook, |  | ||||||
|  						    &range, pkt->out); |  | ||||||
| --- a/net/ipv4/netfilter/nft_redir_ipv4.c |  | ||||||
| +++ b/net/ipv4/netfilter/nft_redir_ipv4.c |  | ||||||
| @@ -26,10 +26,10 @@ static void nft_redir_ipv4_eval(const st |  | ||||||
|   |  | ||||||
|  	memset(&mr, 0, sizeof(mr)); |  | ||||||
|  	if (priv->sreg_proto_min) { |  | ||||||
| -		mr.range[0].min.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_min]; |  | ||||||
| -		mr.range[0].max.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_max]; |  | ||||||
| +		mr.range[0].min.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_min]); |  | ||||||
| +		mr.range[0].max.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_max]); |  | ||||||
|  		mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| --- a/net/ipv6/netfilter/nft_masq_ipv6.c |  | ||||||
| +++ b/net/ipv6/netfilter/nft_masq_ipv6.c |  | ||||||
| @@ -27,10 +27,10 @@ static void nft_masq_ipv6_eval(const str |  | ||||||
|  	memset(&range, 0, sizeof(range)); |  | ||||||
|  	range.flags = priv->flags; |  | ||||||
|  	if (priv->sreg_proto_min) { |  | ||||||
| -		range.min_proto.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_min]; |  | ||||||
| -		range.max_proto.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_max]; |  | ||||||
| +		range.min_proto.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_min]); |  | ||||||
| +		range.max_proto.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_max]); |  | ||||||
|  	} |  | ||||||
|  	regs->verdict.code = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out); |  | ||||||
|  } |  | ||||||
| --- a/net/ipv6/netfilter/nft_redir_ipv6.c |  | ||||||
| +++ b/net/ipv6/netfilter/nft_redir_ipv6.c |  | ||||||
| @@ -26,10 +26,10 @@ static void nft_redir_ipv6_eval(const st |  | ||||||
|   |  | ||||||
|  	memset(&range, 0, sizeof(range)); |  | ||||||
|  	if (priv->sreg_proto_min) { |  | ||||||
| -		range.min_proto.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_min], |  | ||||||
| -		range.max_proto.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_max], |  | ||||||
| +		range.min_proto.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_min]); |  | ||||||
| +		range.max_proto.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_max]); |  | ||||||
|  		range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| --- a/net/netfilter/nft_ct.c |  | ||||||
| +++ b/net/netfilter/nft_ct.c |  | ||||||
| @@ -77,7 +77,7 @@ static void nft_ct_get_eval(const struct |  | ||||||
|   |  | ||||||
|  	switch (priv->key) { |  | ||||||
|  	case NFT_CT_DIRECTION: |  | ||||||
| -		*dest = CTINFO2DIR(ctinfo); |  | ||||||
| +		nft_reg_store8(dest, CTINFO2DIR(ctinfo)); |  | ||||||
|  		return; |  | ||||||
|  	case NFT_CT_STATUS: |  | ||||||
|  		*dest = ct->status; |  | ||||||
| @@ -129,10 +129,10 @@ static void nft_ct_get_eval(const struct |  | ||||||
|  		return; |  | ||||||
|  	} |  | ||||||
|  	case NFT_CT_L3PROTOCOL: |  | ||||||
| -		*dest = nf_ct_l3num(ct); |  | ||||||
| +		nft_reg_store8(dest, nf_ct_l3num(ct)); |  | ||||||
|  		return; |  | ||||||
|  	case NFT_CT_PROTOCOL: |  | ||||||
| -		*dest = nf_ct_protonum(ct); |  | ||||||
| +		nft_reg_store8(dest, nf_ct_protonum(ct)); |  | ||||||
|  		return; |  | ||||||
|  	default: |  | ||||||
|  		break; |  | ||||||
| @@ -149,10 +149,10 @@ static void nft_ct_get_eval(const struct |  | ||||||
|  		       nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); |  | ||||||
|  		return; |  | ||||||
|  	case NFT_CT_PROTO_SRC: |  | ||||||
| -		*dest = (__force __u16)tuple->src.u.all; |  | ||||||
| +		nft_reg_store16(dest, (__force u16)tuple->src.u.all); |  | ||||||
|  		return; |  | ||||||
|  	case NFT_CT_PROTO_DST: |  | ||||||
| -		*dest = (__force __u16)tuple->dst.u.all; |  | ||||||
| +		nft_reg_store16(dest, (__force u16)tuple->dst.u.all); |  | ||||||
|  		return; |  | ||||||
|  	default: |  | ||||||
|  		break; |  | ||||||
| --- a/net/netfilter/nft_meta.c |  | ||||||
| +++ b/net/netfilter/nft_meta.c |  | ||||||
| @@ -45,16 +45,15 @@ void nft_meta_get_eval(const struct nft_ |  | ||||||
|  		*dest = skb->len; |  | ||||||
|  		break; |  | ||||||
|  	case NFT_META_PROTOCOL: |  | ||||||
| -		*dest = 0; |  | ||||||
| -		*(__be16 *)dest = skb->protocol; |  | ||||||
| +		nft_reg_store16(dest, (__force u16)skb->protocol); |  | ||||||
|  		break; |  | ||||||
|  	case NFT_META_NFPROTO: |  | ||||||
| -		*dest = pkt->pf; |  | ||||||
| +		nft_reg_store8(dest, pkt->pf); |  | ||||||
|  		break; |  | ||||||
|  	case NFT_META_L4PROTO: |  | ||||||
|  		if (!pkt->tprot_set) |  | ||||||
|  			goto err; |  | ||||||
| -		*dest = pkt->tprot; |  | ||||||
| +		nft_reg_store8(dest, pkt->tprot); |  | ||||||
|  		break; |  | ||||||
|  	case NFT_META_PRIORITY: |  | ||||||
|  		*dest = skb->priority; |  | ||||||
| @@ -85,14 +84,12 @@ void nft_meta_get_eval(const struct nft_ |  | ||||||
|  	case NFT_META_IIFTYPE: |  | ||||||
|  		if (in == NULL) |  | ||||||
|  			goto err; |  | ||||||
| -		*dest = 0; |  | ||||||
| -		*(u16 *)dest = in->type; |  | ||||||
| +		nft_reg_store16(dest, in->type); |  | ||||||
|  		break; |  | ||||||
|  	case NFT_META_OIFTYPE: |  | ||||||
|  		if (out == NULL) |  | ||||||
|  			goto err; |  | ||||||
| -		*dest = 0; |  | ||||||
| -		*(u16 *)dest = out->type; |  | ||||||
| +		nft_reg_store16(dest, out->type); |  | ||||||
|  		break; |  | ||||||
|  	case NFT_META_SKUID: |  | ||||||
|  		sk = skb_to_full_sk(skb); |  | ||||||
| @@ -142,22 +139,22 @@ void nft_meta_get_eval(const struct nft_ |  | ||||||
|  #endif |  | ||||||
|  	case NFT_META_PKTTYPE: |  | ||||||
|  		if (skb->pkt_type != PACKET_LOOPBACK) { |  | ||||||
| -			*dest = skb->pkt_type; |  | ||||||
| +			nft_reg_store8(dest, skb->pkt_type); |  | ||||||
|  			break; |  | ||||||
|  		} |  | ||||||
|   |  | ||||||
|  		switch (pkt->pf) { |  | ||||||
|  		case NFPROTO_IPV4: |  | ||||||
|  			if (ipv4_is_multicast(ip_hdr(skb)->daddr)) |  | ||||||
| -				*dest = PACKET_MULTICAST; |  | ||||||
| +				nft_reg_store8(dest, PACKET_MULTICAST); |  | ||||||
|  			else |  | ||||||
| -				*dest = PACKET_BROADCAST; |  | ||||||
| +				nft_reg_store8(dest, PACKET_BROADCAST); |  | ||||||
|  			break; |  | ||||||
|  		case NFPROTO_IPV6: |  | ||||||
|  			if (ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF) |  | ||||||
| -				*dest = PACKET_MULTICAST; |  | ||||||
| +				nft_reg_store8(dest, PACKET_MULTICAST); |  | ||||||
|  			else |  | ||||||
| -				*dest = PACKET_BROADCAST; |  | ||||||
| +				nft_reg_store8(dest, PACKET_BROADCAST); |  | ||||||
|  			break; |  | ||||||
|  		case NFPROTO_NETDEV: |  | ||||||
|  			switch (skb->protocol) { |  | ||||||
| @@ -171,14 +168,14 @@ void nft_meta_get_eval(const struct nft_ |  | ||||||
|  					goto err; |  | ||||||
|   |  | ||||||
|  				if (ipv4_is_multicast(iph->daddr)) |  | ||||||
| -					*dest = PACKET_MULTICAST; |  | ||||||
| +					nft_reg_store8(dest, PACKET_MULTICAST); |  | ||||||
|  				else |  | ||||||
| -					*dest = PACKET_BROADCAST; |  | ||||||
| +					nft_reg_store8(dest, PACKET_BROADCAST); |  | ||||||
|   |  | ||||||
|  				break; |  | ||||||
|  			} |  | ||||||
|  			case htons(ETH_P_IPV6): |  | ||||||
| -				*dest = PACKET_MULTICAST; |  | ||||||
| +				nft_reg_store8(dest, PACKET_MULTICAST); |  | ||||||
|  				break; |  | ||||||
|  			default: |  | ||||||
|  				WARN_ON_ONCE(1); |  | ||||||
| @@ -233,7 +230,9 @@ void nft_meta_set_eval(const struct nft_ |  | ||||||
|  { |  | ||||||
|  	const struct nft_meta *meta = nft_expr_priv(expr); |  | ||||||
|  	struct sk_buff *skb = pkt->skb; |  | ||||||
| -	u32 value = regs->data[meta->sreg]; |  | ||||||
| +	u32 *sreg = ®s->data[meta->sreg]; |  | ||||||
| +	u32 value = *sreg; |  | ||||||
| +	u8 pkt_type; |  | ||||||
|   |  | ||||||
|  	switch (meta->key) { |  | ||||||
|  	case NFT_META_MARK: |  | ||||||
| @@ -243,9 +242,12 @@ void nft_meta_set_eval(const struct nft_ |  | ||||||
|  		skb->priority = value; |  | ||||||
|  		break; |  | ||||||
|  	case NFT_META_PKTTYPE: |  | ||||||
| -		if (skb->pkt_type != value && |  | ||||||
| -		    skb_pkt_type_ok(value) && skb_pkt_type_ok(skb->pkt_type)) |  | ||||||
| -			skb->pkt_type = value; |  | ||||||
| +		pkt_type = nft_reg_load8(sreg); |  | ||||||
| + |  | ||||||
| +		if (skb->pkt_type != pkt_type && |  | ||||||
| +		    skb_pkt_type_ok(pkt_type) && |  | ||||||
| +		    skb_pkt_type_ok(skb->pkt_type)) |  | ||||||
| +			skb->pkt_type = pkt_type; |  | ||||||
|  		break; |  | ||||||
|  	case NFT_META_NFTRACE: |  | ||||||
|  		skb->nf_trace = !!value; |  | ||||||
| --- a/net/netfilter/nft_nat.c |  | ||||||
| +++ b/net/netfilter/nft_nat.c |  | ||||||
| @@ -65,10 +65,10 @@ static void nft_nat_eval(const struct nf |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
|  	if (priv->sreg_proto_min) { |  | ||||||
| -		range.min_proto.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_min]; |  | ||||||
| -		range.max_proto.all = |  | ||||||
| -			*(__be16 *)®s->data[priv->sreg_proto_max]; |  | ||||||
| +		range.min_proto.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_min]); |  | ||||||
| +		range.max_proto.all = (__force __be16)nft_reg_load16( |  | ||||||
| +			®s->data[priv->sreg_proto_max]); |  | ||||||
|  		range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; |  | ||||||
|  	} |  | ||||||
|   |  | ||||||
| @@ -1,55 +0,0 @@ | |||||||
| From 649affd04813c43e0a72886517fcfccd63230981 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Hauke Mehrtens <hauke@hauke-m.de> |  | ||||||
| Date: Mon, 29 Jun 2015 16:53:03 +0200 |  | ||||||
| Subject: uapi/if_ether.h: prevent redefinition of struct ethhdr |  | ||||||
|  |  | ||||||
| Musl provides its own ethhdr struct definition. Add a guard to prevent |  | ||||||
| its definition of the appropriate musl header has already been included. |  | ||||||
|  |  | ||||||
| glibc does not implement this header, but when glibc will implement this |  | ||||||
| they can just define __UAPI_DEF_ETHHDR 0 to make it work with the |  | ||||||
| kernel. |  | ||||||
|  |  | ||||||
| Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> |  | ||||||
| --- |  | ||||||
|  include/uapi/linux/if_ether.h    | 3 +++ |  | ||||||
|  include/uapi/linux/libc-compat.h | 6 ++++++ |  | ||||||
|  2 files changed, 9 insertions(+) |  | ||||||
|  |  | ||||||
| --- a/include/uapi/linux/if_ether.h |  | ||||||
| +++ b/include/uapi/linux/if_ether.h |  | ||||||
| @@ -22,6 +22,7 @@ |  | ||||||
|  #define _UAPI_LINUX_IF_ETHER_H |  | ||||||
|   |  | ||||||
|  #include <linux/types.h> |  | ||||||
| +#include <linux/libc-compat.h> |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
|   *	IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble |  | ||||||
| @@ -139,11 +140,13 @@ |  | ||||||
|   *	This is an Ethernet frame header. |  | ||||||
|   */ |  | ||||||
|   |  | ||||||
| +#if __UAPI_DEF_ETHHDR |  | ||||||
|  struct ethhdr { |  | ||||||
|  	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/ |  | ||||||
|  	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/ |  | ||||||
|  	__be16		h_proto;		/* packet type ID field	*/ |  | ||||||
|  } __attribute__((packed)); |  | ||||||
| +#endif |  | ||||||
|   |  | ||||||
|   |  | ||||||
|  #endif /* _UAPI_LINUX_IF_ETHER_H */ |  | ||||||
| --- a/include/uapi/linux/libc-compat.h |  | ||||||
| +++ b/include/uapi/linux/libc-compat.h |  | ||||||
| @@ -263,4 +263,10 @@ |  | ||||||
|   |  | ||||||
|  #endif /* __GLIBC__ */ |  | ||||||
|   |  | ||||||
| +/* Definitions for if_ether.h */ |  | ||||||
| +/* allow libcs like musl to deactivate this, glibc does not implement this. */ |  | ||||||
| +#ifndef __UAPI_DEF_ETHHDR |  | ||||||
| +#define __UAPI_DEF_ETHHDR		1 |  | ||||||
| +#endif |  | ||||||
| + |  | ||||||
|  #endif /* _UAPI_LIBC_COMPAT_H */ |  | ||||||
		Reference in New Issue
	
	Block a user
	 Koen Vandeputte
					Koen Vandeputte