The commit is pushed to "branch-rh9-5.14.0-427.44.1.vz9.80.x-ovz" and will 
appear at g...@bitbucket.org:openvz/vzkernel.git
after rh9-5.14.0-427.44.1.vz9.80.19
------>
commit e3a186b220eac01b476c6281d266174e5c29cc34
Author: Sabrina Dubroca <sdubr...@redhat.com>
Date:   Thu Apr 11 10:04:27 2024 +0200

    ms/xfrm: annotate data-race around use_time
    
    JIRA: https://issues.redhat.com/browse/RHEL-31751
    
    commit 0a9e5794b21e2d1303759ff8fe5f9215db7757ba
    Author: Eric Dumazet <eduma...@google.com>
    Date:   Thu Jan 26 11:21:30 2023 +0000
    
        xfrm: annotate data-race around use_time
    
        KCSAN reported multiple cpus can update use_time
        at the same time.
    
        Adds READ_ONCE()/WRITE_ONCE() annotations.
    
        Note that 32bit arches are not fully protected,
        but they will probably no longer be supported/used in 2106.
    
        BUG: KCSAN: data-race in __xfrm_policy_check / __xfrm_policy_check
    
        write to 0xffff88813e7ec108 of 8 bytes by interrupt on cpu 0:
        __xfrm_policy_check+0x6ae/0x17f0 net/xfrm/xfrm_policy.c:3664
        __xfrm_policy_check2 include/net/xfrm.h:1174 [inline]
        xfrm_policy_check include/net/xfrm.h:1179 [inline]
        xfrm6_policy_check+0x2e9/0x320 include/net/xfrm.h:1189
        udpv6_queue_rcv_one_skb+0x48/0xa30 net/ipv6/udp.c:703
        udpv6_queue_rcv_skb+0x2d6/0x310 net/ipv6/udp.c:792
        udp6_unicast_rcv_skb+0x16b/0x190 net/ipv6/udp.c:935
        __udp6_lib_rcv+0x84b/0x9b0 net/ipv6/udp.c:1020
        udpv6_rcv+0x4b/0x50 net/ipv6/udp.c:1133
        ip6_protocol_deliver_rcu+0x99e/0x1020 net/ipv6/ip6_input.c:439
        ip6_input_finish net/ipv6/ip6_input.c:484 [inline]
        NF_HOOK include/linux/netfilter.h:302 [inline]
        ip6_input+0xca/0x180 net/ipv6/ip6_input.c:493
        dst_input include/net/dst.h:454 [inline]
        ip6_rcv_finish+0x1e9/0x2d0 net/ipv6/ip6_input.c:79
        NF_HOOK include/linux/netfilter.h:302 [inline]
        ipv6_rcv+0x85/0x140 net/ipv6/ip6_input.c:309
        __netif_receive_skb_one_core net/core/dev.c:5482 [inline]
        __netif_receive_skb+0x8b/0x1b0 net/core/dev.c:5596
        process_backlog+0x23f/0x3b0 net/core/dev.c:5924
        __napi_poll+0x65/0x390 net/core/dev.c:6485
        napi_poll net/core/dev.c:6552 [inline]
        net_rx_action+0x37e/0x730 net/core/dev.c:6663
        __do_softirq+0xf2/0x2c7 kernel/softirq.c:571
        do_softirq+0xb1/0xf0 kernel/softirq.c:472
        __local_bh_enable_ip+0x6f/0x80 kernel/softirq.c:396
        __raw_read_unlock_bh include/linux/rwlock_api_smp.h:257 [inline]
        _raw_read_unlock_bh+0x17/0x20 kernel/locking/spinlock.c:284
        wg_socket_send_skb_to_peer+0x107/0x120 
drivers/net/wireguard/socket.c:184
        wg_packet_create_data_done drivers/net/wireguard/send.c:251 [inline]
        wg_packet_tx_worker+0x142/0x360 drivers/net/wireguard/send.c:276
        process_one_work+0x3d3/0x720 kernel/workqueue.c:2289
        worker_thread+0x618/0xa70 kernel/workqueue.c:2436
        kthread+0x1a9/0x1e0 kernel/kthread.c:376
        ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308
    
        write to 0xffff88813e7ec108 of 8 bytes by interrupt on cpu 1:
        __xfrm_policy_check+0x6ae/0x17f0 net/xfrm/xfrm_policy.c:3664
        __xfrm_policy_check2 include/net/xfrm.h:1174 [inline]
        xfrm_policy_check include/net/xfrm.h:1179 [inline]
        xfrm6_policy_check+0x2e9/0x320 include/net/xfrm.h:1189
        udpv6_queue_rcv_one_skb+0x48/0xa30 net/ipv6/udp.c:703
        udpv6_queue_rcv_skb+0x2d6/0x310 net/ipv6/udp.c:792
        udp6_unicast_rcv_skb+0x16b/0x190 net/ipv6/udp.c:935
        __udp6_lib_rcv+0x84b/0x9b0 net/ipv6/udp.c:1020
        udpv6_rcv+0x4b/0x50 net/ipv6/udp.c:1133
        ip6_protocol_deliver_rcu+0x99e/0x1020 net/ipv6/ip6_input.c:439
        ip6_input_finish net/ipv6/ip6_input.c:484 [inline]
        NF_HOOK include/linux/netfilter.h:302 [inline]
        ip6_input+0xca/0x180 net/ipv6/ip6_input.c:493
        dst_input include/net/dst.h:454 [inline]
        ip6_rcv_finish+0x1e9/0x2d0 net/ipv6/ip6_input.c:79
        NF_HOOK include/linux/netfilter.h:302 [inline]
        ipv6_rcv+0x85/0x140 net/ipv6/ip6_input.c:309
        __netif_receive_skb_one_core net/core/dev.c:5482 [inline]
        __netif_receive_skb+0x8b/0x1b0 net/core/dev.c:5596
        process_backlog+0x23f/0x3b0 net/core/dev.c:5924
        __napi_poll+0x65/0x390 net/core/dev.c:6485
        napi_poll net/core/dev.c:6552 [inline]
        net_rx_action+0x37e/0x730 net/core/dev.c:6663
        __do_softirq+0xf2/0x2c7 kernel/softirq.c:571
        do_softirq+0xb1/0xf0 kernel/softirq.c:472
        __local_bh_enable_ip+0x6f/0x80 kernel/softirq.c:396
        __raw_read_unlock_bh include/linux/rwlock_api_smp.h:257 [inline]
        _raw_read_unlock_bh+0x17/0x20 kernel/locking/spinlock.c:284
        wg_socket_send_skb_to_peer+0x107/0x120 
drivers/net/wireguard/socket.c:184
        wg_packet_create_data_done drivers/net/wireguard/send.c:251 [inline]
        wg_packet_tx_worker+0x142/0x360 drivers/net/wireguard/send.c:276
        process_one_work+0x3d3/0x720 kernel/workqueue.c:2289
        worker_thread+0x618/0xa70 kernel/workqueue.c:2436
        kthread+0x1a9/0x1e0 kernel/kthread.c:376
        ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308
    
        value changed: 0x0000000063c62d6f -> 0x0000000063c62d70
    
        Reported by Kernel Concurrency Sanitizer on:
        CPU: 1 PID: 4185 Comm: kworker/1:2 Tainted: G W 
6.2.0-rc4-syzkaller-00009-gd532dd102151-dirty #0
        Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS 
Google 10/26/2022
        Workqueue: wg-crypt-wg0 wg_packet_tx_worker
    
        Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
        Reported-by: syzbot <syzkal...@googlegroups.com>
        Signed-off-by: Eric Dumazet <eduma...@google.com>
        Cc: Steffen Klassert <steffen.klass...@secunet.com>
        Cc: Arnd Bergmann <a...@arndb.de>
        Acked-by: Arnd Bergmann <a...@arndb.de>
        Signed-off-by: Steffen Klassert <steffen.klass...@secunet.com>
    
    Signed-off-by: Sabrina Dubroca <sdubr...@redhat.com>
    
    https://virtuozzo.atlassian.net/browse/VSTOR-101702
    (cherry picked from CentOS Stream commit 
c137a781a237e3be2fb178b0d65d1385ac6d5068)
    Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com>
    
    Feature: fix ms/xfrm
---
 net/xfrm/xfrm_policy.c | 11 +++++++----
 net/xfrm/xfrm_state.c  | 10 +++++-----
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 2f615a3cc70b..52d45c5a7fb0 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -336,7 +336,7 @@ static void xfrm_policy_timer(struct timer_list *t)
        }
        if (xp->lft.hard_use_expires_seconds) {
                time64_t tmo = xp->lft.hard_use_expires_seconds +
-                       (xp->curlft.use_time ? : xp->curlft.add_time) - now;
+                       (READ_ONCE(xp->curlft.use_time) ? : 
xp->curlft.add_time) - now;
                if (tmo <= 0)
                        goto expired;
                if (tmo < next)
@@ -354,7 +354,7 @@ static void xfrm_policy_timer(struct timer_list *t)
        }
        if (xp->lft.soft_use_expires_seconds) {
                time64_t tmo = xp->lft.soft_use_expires_seconds +
-                       (xp->curlft.use_time ? : xp->curlft.add_time) - now;
+                       (READ_ONCE(xp->curlft.use_time) ? : 
xp->curlft.add_time) - now;
                if (tmo <= 0) {
                        warn = 1;
                        tmo = XFRM_KM_TIMEOUT;
@@ -3670,7 +3670,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct 
sk_buff *skb,
                return 1;
        }
 
-       pol->curlft.use_time = ktime_get_real_seconds();
+       /* This lockless write can happen from different cpus. */
+       WRITE_ONCE(pol->curlft.use_time, ktime_get_real_seconds());
 
        pols[0] = pol;
        npols++;
@@ -3685,7 +3686,9 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct 
sk_buff *skb,
                                xfrm_pol_put(pols[0]);
                                return 0;
                        }
-                       pols[1]->curlft.use_time = ktime_get_real_seconds();
+                       /* This write can happen from different cpus. */
+                       WRITE_ONCE(pols[1]->curlft.use_time,
+                                  ktime_get_real_seconds());
                        npols++;
                }
        }
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 821e4ea52f3f..f9e56d481562 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -595,7 +595,7 @@ static enum hrtimer_restart xfrm_timer_handler(struct 
hrtimer *me)
        }
        if (x->lft.hard_use_expires_seconds) {
                time64_t tmo = x->lft.hard_use_expires_seconds +
-                       (x->curlft.use_time ? : now) - now;
+                       (READ_ONCE(x->curlft.use_time) ? : now) - now;
                if (tmo <= 0)
                        goto expired;
                if (tmo < next)
@@ -617,7 +617,7 @@ static enum hrtimer_restart xfrm_timer_handler(struct 
hrtimer *me)
        }
        if (x->lft.soft_use_expires_seconds) {
                time64_t tmo = x->lft.soft_use_expires_seconds +
-                       (x->curlft.use_time ? : now) - now;
+                       (READ_ONCE(x->curlft.use_time) ? : now) - now;
                if (tmo <= 0)
                        warn = 1;
                else if (tmo < next)
@@ -1902,7 +1902,7 @@ int xfrm_state_update(struct xfrm_state *x)
 
                hrtimer_start(&x1->mtimer, ktime_set(1, 0),
                              HRTIMER_MODE_REL_SOFT);
-               if (x1->curlft.use_time)
+               if (READ_ONCE(x1->curlft.use_time))
                        xfrm_state_check_expire(x1);
 
                if (x->props.smark.m || x->props.smark.v || x->if_id) {
@@ -1936,8 +1936,8 @@ int xfrm_state_check_expire(struct xfrm_state *x)
 {
        xfrm_dev_state_update_curlft(x);
 
-       if (!x->curlft.use_time)
-               x->curlft.use_time = ktime_get_real_seconds();
+       if (!READ_ONCE(x->curlft.use_time))
+               WRITE_ONCE(x->curlft.use_time, ktime_get_real_seconds());
 
        if (x->curlft.bytes >= x->lft.hard_byte_limit ||
            x->curlft.packets >= x->lft.hard_packet_limit) {
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to