mainline inclusion
from mainline-v6.0
commit d5410ac7b0baeca91cf73ff5241d35998ecc8c9e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5UYT6
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/d…
-----------------------------------------------------------------
In my test, balance-alb bonding with two slaves eth0 and eth1,
and then Bond0.150 is created with vlan id attached bond0.
After adding bond0.150 into one linux bridge, I noted that Bond0,
bond0.150 and bridge were assigned to the same MAC as eth0.
Once bond0.150 receives a packet whose dest IP is bridge's
and dest MAC is eth1's, the linux bridge will not match
eth1's MAC entry in FDB, and not handle it as expected.
The patch fix the issue, and diagram as below:
eth1(mac:eth1_mac)--bond0(balance-alb,mac:eth0_mac)--eth0(mac:eth0_mac)
|
bond0.150(mac:eth0_mac)
|
bridge(ip:br_ip, mac:eth0_mac)--other port
Suggested-by: Hu Yadi <huyd12(a)chinatelecom.cn>
Signed-off-by: Sun Shouxin <sunshouxin(a)chinatelecom.cn>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sun Shouxin <sunshouxin(a)chinatelecom.cn> # openEuler_contributor
Signed-off-by: Ctyun Kernel <ctyuncommiter01(a)chinatelecom.cn> # openEuler_contributor
---
drivers/net/bonding/bond_alb.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 856efe8..f493bcf 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -665,6 +665,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb,
static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
{
struct slave *tx_slave = NULL;
+ struct net_device *dev;
struct arp_pkt *arp;
if (!pskb_network_may_pull(skb, sizeof(*arp)))
@@ -677,6 +678,12 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
if (!bond_slave_has_mac_rx(bond, arp->mac_src))
return NULL;
+ dev = ip_dev_find(dev_net(bond->dev), arp->ip_src);
+ if (dev) {
+ if (netif_is_bridge_master(dev))
+ return NULL;
+ }
+
if (arp->op_code == htons(ARPOP_REPLY)) {
/* the arp must be sent on the selected rx channel */
tx_slave = rlb_choose_channel(skb, bond, arp);
--
1.8.3.1
mainline inclusion
from mainline-v6.0
commit 0da8aa00bfcfeb3f4e6537dd8e2001e0727ba549
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5UY5E
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/dri…
------------------------------------------------------------
Since ipv6 neighbor solicitation and advertisement messages
isn't handled gracefully in bond6 driver, we can see packet
drop due to inconsistency between mac address in the option
message and source MAC .
Another examples is ipv6 neighbor solicitation and advertisement
messages from VM via tap attached to host bridge, the src mac
might be changed through balance-alb mode, but it is not synced
with Link-layer address in the option message.
The patch implements bond6's tx handle for ipv6 neighbor
solicitation and advertisement messages.
Suggested-by: Hu Yadi <huyd12(a)chinatelecom.cn>
Acked-by: Jay Vosburgh <jay.vosburgh(a)canonical.com>
Signed-off-by: Sun Shouxin <sunshouxin(a)chinatelecom.cn>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sun Shouxin <sunshouxin(a)chinatelecom.cn> # openEuler_contributor
Signed-off-by: Ctyun Kernel <ctyuncommiter01(a)chinatelecom.cn> # openEuler_contributor
---
drivers/net/bonding/bond_alb.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index a6a89a0..856efe8 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1281,6 +1281,27 @@ static int alb_set_mac_address(struct bonding *bond, void *addr)
return res;
}
+/* determine if the packet is NA or NS */
+static bool alb_determine_nd(struct sk_buff *skb, struct bonding *bond)
+{
+ struct ipv6hdr *ip6hdr;
+ struct icmp6hdr *hdr;
+
+ if (!pskb_network_may_pull(skb, sizeof(*ip6hdr)))
+ return true;
+
+ ip6hdr = ipv6_hdr(skb);
+ if (ip6hdr->nexthdr != IPPROTO_ICMPV6)
+ return false;
+
+ if (!pskb_network_may_pull(skb, sizeof(*ip6hdr) + sizeof(*hdr)))
+ return true;
+
+ hdr = icmp6_hdr(skb);
+ return hdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT ||
+ hdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION;
+}
+
/************************ exported alb funcions ************************/
int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
@@ -1363,10 +1384,12 @@ netdev_tx_t bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
/* Do not TX balance any multicast or broadcast */
if (!is_multicast_ether_addr(eth_data->h_dest)) {
switch (skb->protocol) {
+ case htons(ETH_P_IPV6):
+ if (alb_determine_nd(skb, bond))
+ break;
case htons(ETH_P_IP):
case htons(ETH_P_IPX):
/* In case of IPX, it will falback to L2 hash */
- case htons(ETH_P_IPV6):
hash_index = bond_xmit_hash(bond, skb);
if (bond->params.tlb_dynamic_lb) {
tx_slave = tlb_choose_channel(bond,
@@ -1440,10 +1463,12 @@ netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
break;
}
- if (!pskb_network_may_pull(skb, sizeof(*ip6hdr))) {
+ if (alb_determine_nd(skb, bond)) {
do_tx_balance = false;
break;
}
+
+ /* The IPv6 header is pulled by alb_determine_nd */
/* Additionally, DAD probes should not be tx-balanced as that
* will lead to false positives for duplicate addresses and
* prevent address configuration from working.
--
1.8.3.1
mainline inclusion
from mainline-v6.0
commit d5410ac7b0baeca91cf73ff5241d35998ecc8c9e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5UYT6
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/d…
---------------------------------------------------------------
In my test, balance-alb bonding with two slaves eth0 and eth1,
and then Bond0.150 is created with vlan id attached bond0.
After adding bond0.150 into one linux bridge, I noted that Bond0,
bond0.150 and bridge were assigned to the same MAC as eth0.
Once bond0.150 receives a packet whose dest IP is bridge's
and dest MAC is eth1's, the linux bridge will not match
eth1's MAC entry in FDB, and not handle it as expected.
The patch fix the issue, and diagram as below:
eth1(mac:eth1_mac)--bond0(balance-alb,mac:eth0_mac)--eth0(mac:eth0_mac)
|
bond0.150(mac:eth0_mac)
|
bridge(ip:br_ip, mac:eth0_mac)--other port
Suggested-by: Hu Yadi <huyd12(a)chinatelecom.cn>
Signed-off-by: Sun Shouxin <sunshouxin(a)chinatelecom.cn>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sun Shouxin <sunshouxin(a)chinatelecom.cn> # openEuler_contributor
Signed-off-by: Ctyun Kernel <ctyuncommiter01(a)chinatelecom.cn> # openEuler_contributor
---
drivers/net/bonding/bond_alb.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 8826380..d9c03a9 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -650,6 +650,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb,
static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
{
struct slave *tx_slave = NULL;
+ struct net_device *dev;
struct arp_pkt *arp;
if (!pskb_network_may_pull(skb, sizeof(*arp)))
@@ -662,6 +663,12 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
if (!bond_slave_has_mac_rx(bond, arp->mac_src))
return NULL;
+ dev = ip_dev_find(dev_net(bond->dev), arp->ip_src);
+ if (dev) {
+ if (netif_is_bridge_master(dev))
+ return NULL;
+ }
+
if (arp->op_code == htons(ARPOP_REPLY)) {
/* the arp must be sent on the selected rx channel */
tx_slave = rlb_choose_channel(skb, bond, arp);
--
1.8.3.1
mainline inclusion
from mainline-v6.0
commit 0da8aa00bfcfeb3f4e6537dd8e2001e0727ba549
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5UY5E
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/dri…
-----------------------------------------------------------
Since ipv6 neighbor solicitation and advertisement messages
isn't handled gracefully in bond6 driver, we can see packet
drop due to inconsistency between mac address in the option
message and source MAC .
Another examples is ipv6 neighbor solicitation and advertisement
messages from VM via tap attached to host bridge, the src mac
might be changed through balance-alb mode, but it is not synced
with Link-layer address in the option message.
The patch implements bond6's tx handle for ipv6 neighbor
solicitation and advertisement messages.
Suggested-by: Hu Yadi <huyd12(a)chinatelecom.cn>
Acked-by: Jay Vosburgh <jay.vosburgh(a)canonical.com>
Signed-off-by: Sun Shouxin <sunshouxin(a)chinatelecom.cn>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sun Shouxin <sunshouxin(a)chinatelecom.cn> # openEuler_contributor
Signed-off-by: Ctyun Kernel <ctyuncommiter01(a)chinatelecom.cn> # openEuler_contributor
---
drivers/net/bonding/bond_alb.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 0436aef9c9ef..882638076355 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1268,6 +1268,27 @@ static int alb_set_mac_address(struct bonding *bond, void *addr)
return res;
}
+/* determine if the packet is NA or NS */
+static bool alb_determine_nd(struct sk_buff *skb, struct bonding *bond)
+{
+ struct ipv6hdr *ip6hdr;
+ struct icmp6hdr *hdr;
+
+ if (!pskb_network_may_pull(skb, sizeof(*ip6hdr)))
+ return true;
+
+ ip6hdr = ipv6_hdr(skb);
+ if (ip6hdr->nexthdr != IPPROTO_ICMPV6)
+ return false;
+
+ if (!pskb_network_may_pull(skb, sizeof(*ip6hdr) + sizeof(*hdr)))
+ return true;
+
+ hdr = icmp6_hdr(skb);
+ return hdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT ||
+ hdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION;
+}
+
/************************ exported alb funcions ************************/
int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
@@ -1347,10 +1368,13 @@ struct slave *bond_xmit_tlb_slave_get(struct bonding *bond,
/* Do not TX balance any multicast or broadcast */
if (!is_multicast_ether_addr(eth_data->h_dest)) {
switch (skb->protocol) {
+ case htons(ETH_P_IPV6):
+ if (alb_determine_nd(skb, bond))
+ break;
+ fallthrough;
case htons(ETH_P_IP):
case htons(ETH_P_IPX):
/* In case of IPX, it will falback to L2 hash */
- case htons(ETH_P_IPV6):
hash_index = bond_xmit_hash(bond, skb);
if (bond->params.tlb_dynamic_lb) {
tx_slave = tlb_choose_channel(bond,
@@ -1433,10 +1457,12 @@ struct slave *bond_xmit_alb_slave_get(struct bonding *bond,
break;
}
- if (!pskb_network_may_pull(skb, sizeof(*ip6hdr))) {
+ if (alb_determine_nd(skb, bond)) {
do_tx_balance = false;
break;
}
+
+ /* The IPv6 header is pulled by alb_determine_nd */
/* Additionally, DAD probes should not be tx-balanced as that
* will lead to false positives for duplicate addresses and
* prevent address configuration from working.
--
2.27.0
From: Lukas Czerner <lczerner(a)redhat.com>
mainline inclusion
from mainline-v6.0-rc1
commit 65f8ea4cd57dbd46ea13b41dc8bac03176b04233
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I58WSQ
CVE: CVE-2022-1184
--------------------------------
Currently ext4 directory handling code implicitly assumes that the
directory blocks are always within the i_size. In fact ext4_append()
will attempt to allocate next directory block based solely on i_size and
the i_size is then appropriately increased after a successful
allocation.
However, for this to work it requires i_size to be correct. If, for any
reason, the directory inode i_size is corrupted in a way that the
directory tree refers to a valid directory block past i_size, we could
end up corrupting parts of the directory tree structure by overwriting
already used directory blocks when modifying the directory.
Fix it by catching the corruption early in __ext4_read_dirblock().
Addresses Red-Hat-Bugzilla: #2070205
CVE: CVE-2022-1184
Signed-off-by: Lukas Czerner <lczerner(a)redhat.com>
Cc: stable(a)vger.kernel.org
Reviewed-by: Andreas Dilger <adilger(a)dilger.ca>
Link: https://lore.kernel.org/r/20220704142721.157985-1-lczerner@redhat.com
Signed-off-by: Theodore Ts'o <tytso(a)mit.edu>
Conflicts:
fs/ext4/namei.c
Signed-off-by: Baokun Li <libaokun1(a)huawei.com>
Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com>
Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com>
---
fs/ext4/namei.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index b2d4fb82e8f4..1a9eda144c7a 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -124,6 +124,13 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
struct ext4_dir_entry *dirent;
int is_dx_block = 0;
+ if (block >= inode->i_size) {
+ ext4_error_inode(inode, func, line, block,
+ "Attempting to read directory block (%u) that is past i_size (%llu)",
+ block, inode->i_size);
+ return ERR_PTR(-EFSCORRUPTED);
+ }
+
bh = ext4_bread(NULL, inode, block, 0);
if (IS_ERR(bh)) {
__ext4_warning(inode->i_sb, func, line,
--
2.25.1