[RHEL7,COMMIT] ms/ip6mr: fix stale iterator

Submitted by Vasily Averin on Dec. 3, 2020, 8:58 a.m.

Details

Message ID 202012030858.0B38wmF1001380@vz7build.vvs.sw.ru
State New
Series "ms/ip6mr: fix stale iterator"
Headers show

Commit Message

Vasily Averin Dec. 3, 2020, 8:58 a.m.
The commit is pushed to "branch-rh7-3.10.0-1160.6.1.vz7.171.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.6.1.vz7.171.1
------>
commit 899d82c473521b6ef945679ffa28df91cccc2215
Author: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Date:   Thu Dec 3 11:58:48 2020 +0300

    ms/ip6mr: fix stale iterator
    
    When we dump the ip6mr mfc entries via proc, we initialize an iterator
    with the table to dump but we don't clear the cache pointer which might
    be initialized from a prior read on the same descriptor that ended. This
    can result in lock imbalance (an unnecessary unlock) leading to other
    crashes and hangs. Clear the cache pointer like ipmr does to fix the issue.
    Thanks for the reliable reproducer.
    
    Here's syzbot's trace:
     WARNING: bad unlock balance detected!
     4.15.0-rc3+ #128 Not tainted
     syzkaller971460/3195 is trying to release lock (mrt_lock) at:
     [<000000006898068d>] ipmr_mfc_seq_stop+0xe1/0x130 net/ipv6/ip6mr.c:553
     but there are no more locks to release!
    
     other info that might help us debug this:
     1 lock held by syzkaller971460/3195:
      #0:  (&p->lock){+.+.}, at: [<00000000744a6565>] seq_read+0xd5/0x13d0
     fs/seq_file.c:165
    
     stack backtrace:
     CPU: 1 PID: 3195 Comm: syzkaller971460 Not tainted 4.15.0-rc3+ #128
     Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
     Google 01/01/2011
     Call Trace:
      __dump_stack lib/dump_stack.c:17 [inline]
      dump_stack+0x194/0x257 lib/dump_stack.c:53
      print_unlock_imbalance_bug+0x12f/0x140 kernel/locking/lockdep.c:3561
      __lock_release kernel/locking/lockdep.c:3775 [inline]
      lock_release+0x5f9/0xda0 kernel/locking/lockdep.c:4023
      __raw_read_unlock include/linux/rwlock_api_smp.h:225 [inline]
      _raw_read_unlock+0x1a/0x30 kernel/locking/spinlock.c:255
      ipmr_mfc_seq_stop+0xe1/0x130 net/ipv6/ip6mr.c:553
      traverse+0x3bc/0xa00 fs/seq_file.c:135
      seq_read+0x96a/0x13d0 fs/seq_file.c:189
      proc_reg_read+0xef/0x170 fs/proc/inode.c:217
      do_loop_readv_writev fs/read_write.c:673 [inline]
      do_iter_read+0x3db/0x5b0 fs/read_write.c:897
      compat_readv+0x1bf/0x270 fs/read_write.c:1140
      do_compat_preadv64+0xdc/0x100 fs/read_write.c:1189
      C_SYSC_preadv fs/read_write.c:1209 [inline]
      compat_SyS_preadv+0x3b/0x50 fs/read_write.c:1203
      do_syscall_32_irqs_on arch/x86/entry/common.c:327 [inline]
      do_fast_syscall_32+0x3ee/0xf9d arch/x86/entry/common.c:389
      entry_SYSENTER_compat+0x51/0x60 arch/x86/entry/entry_64_compat.S:125
     RIP: 0023:0xf7f73c79
     RSP: 002b:00000000e574a15c EFLAGS: 00000292 ORIG_RAX: 000000000000014d
     RAX: ffffffffffffffda RBX: 000000000000000f RCX: 0000000020a3afb0
     RDX: 0000000000000001 RSI: 0000000000000067 RDI: 0000000000000000
     RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
     R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
     R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
     BUG: sleeping function called from invalid context at lib/usercopy.c:25
     in_atomic(): 1, irqs_disabled(): 0, pid: 3195, name: syzkaller971460
     INFO: lockdep is turned off.
     CPU: 1 PID: 3195 Comm: syzkaller971460 Not tainted 4.15.0-rc3+ #128
     Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
     Google 01/01/2011
     Call Trace:
      __dump_stack lib/dump_stack.c:17 [inline]
      dump_stack+0x194/0x257 lib/dump_stack.c:53
      ___might_sleep+0x2b2/0x470 kernel/sched/core.c:6060
      __might_sleep+0x95/0x190 kernel/sched/core.c:6013
      __might_fault+0xab/0x1d0 mm/memory.c:4525
      _copy_to_user+0x2c/0xc0 lib/usercopy.c:25
      copy_to_user include/linux/uaccess.h:155 [inline]
      seq_read+0xcb4/0x13d0 fs/seq_file.c:279
      proc_reg_read+0xef/0x170 fs/proc/inode.c:217
      do_loop_readv_writev fs/read_write.c:673 [inline]
      do_iter_read+0x3db/0x5b0 fs/read_write.c:897
      compat_readv+0x1bf/0x270 fs/read_write.c:1140
      do_compat_preadv64+0xdc/0x100 fs/read_write.c:1189
      C_SYSC_preadv fs/read_write.c:1209 [inline]
      compat_SyS_preadv+0x3b/0x50 fs/read_write.c:1203
      do_syscall_32_irqs_on arch/x86/entry/common.c:327 [inline]
      do_fast_syscall_32+0x3ee/0xf9d arch/x86/entry/common.c:389
      entry_SYSENTER_compat+0x51/0x60 arch/x86/entry/entry_64_compat.S:125
     RIP: 0023:0xf7f73c79
     RSP: 002b:00000000e574a15c EFLAGS: 00000292 ORIG_RAX: 000000000000014d
     RAX: ffffffffffffffda RBX: 000000000000000f RCX: 0000000020a3afb0
     RDX: 0000000000000001 RSI: 0000000000000067 RDI: 0000000000000000
     RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
     R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
     R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
     WARNING: CPU: 1 PID: 3195 at lib/usercopy.c:26 _copy_to_user+0xb5/0xc0
     lib/usercopy.c:26
    
    Reported-by: syzbot <bot+eceb3204562c41a438fa1f2335e0fe4f6886d669@syzkaller.appspotmail.com>
    Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    
    (cherry-picked from commit 4adfa79fc254efb7b0eb3cd58f62c2c3f805f1ba)
    https://jira.sw.ru/browse/PSBM-122990
    Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
---
 net/ipv6/ip6mr.c | 1 +
 1 file changed, 1 insertion(+)

Patch hide | download patch | download mbox

diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 00c6c7d..856173b6 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -497,6 +497,7 @@  static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
 		return ERR_PTR(-ENOENT);
 
 	it->mrt = mrt;
+	it->cache = NULL;
 	return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
 		: SEQ_START_TOKEN;
 }