cobalt/kernel: vfile_snapshot: fix seq_file leakage on race detection

vfile_snapshot_open() may re-run the data collection loop in case we
detected a race by checking the revision tag of the data
set. Unfortunately, the seq_file is already open at this point,
causing a leakage as seq_open() will be called again.

The bug triggers after a while running the following commands
concurrently:

$ while : ; do cat /proc/xenomai/sched/stat > /dev/null; done &
$ while : ; do switchtest -T 5; done

As the private_data field of the backing file is not NULL once
seq_open() has run, this bug triggers the following warning splat when
calling it anew for the same file:

[   32.660548] WARNING: CPU: 0 PID: 446 at fs/seq_file.c:55 seq_open.cold+0xc/0x1a
[   32.670934] CPU: 0 PID: 446 Comm: cat Not tainted 4.19.89+ #16
[   32.686078] I-pipe domain: Linux
[   32.689312] RIP: 0010:seq_open.cold+0xc/0x1a
[   32.693592] Code: 48 8b 74 24 08 e8 1e 5e f9 ff 48 8b 5d 18 48 8b 55 08 4c 01 f3 48 89 5d 18 e9 25 fe ff ff 48 c7 c7 00 99 2b 82 e8 32 71 de ff <0f> 0b e9 d3 db ff ff 90 90 90 90 90 90 90 41 57 41 56 41 55 41 54
[   32.712354] RSP: 0018:ffff88815476f9b0 EFLAGS: 00010246
[   32.717588] RAX: 0000000000000024 RBX: ffff888153ec7400 RCX: 0000000000000000
[   32.724728] RDX: 1ffff1102b944a01 RSI: 0000000000000008 RDI: ffffed102a8edf2d
[   32.731873] RBP: ffffffff828c5560 R08: 0000000000000024 R09: ffffffff815d0644
[   32.739016] R10: ffffed102b946f1c R11: ffff88815ca378e7 R12: ffff888153ec74c8
[   32.746156] R13: ffffffff828c75a0 R14: ffff8881544ebb80 R15: ffff888155a2d9c8
[   32.753299] FS:  00007ff225dc3740(0000) GS:ffff88815ca00000(0000) knlGS:0000000000000000
[   32.761395] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   32.767152] CR2: 00007ff225eb8120 CR3: 0000000153d8c000 CR4: 00000000003406f0
[   32.774289] Call Trace:
[   32.776746]  vfile_snapshot_open+0x2a8/0x560
[   32.781022]  proc_reg_open+0x124/0x270
[   32.784782]  ? proc_i_callback+0x20/0x20
[   32.788713]  do_dentry_open+0x2ac/0x750
[   32.792558]  ? proc_i_callback+0x20/0x20
[   32.796492]  ? __x64_sys_fchmod+0x70/0x70
[   32.800507]  ? inode_permission.part.0+0x4f/0x180
[   32.805219]  ? security_inode_permission+0x13/0x60
[   32.810015]  path_openat+0x456/0x1b80
[   32.813681]  ? kmem_cache_alloc+0xd2/0x1c0
[   32.817783]  ? getname_flags+0x35/0x240
[   32.821624]  ? do_syscall_64+0x8a/0x240
[   32.825466]  ? __rcu_read_unlock+0x66/0x80
[   32.829572]  ? path_lookupat+0x430/0x430
[   32.833497]  ? find_get_pages_range_tag+0x3a0/0x3a0
[   32.838381]  ? finish_mkwrite_fault+0x1f0/0x1f0
[   32.842916]  do_filp_open+0x103/0x210
[   32.846586]  ? may_open_dev+0x50/0x50
[   32.850253]  ? __fdget+0xe0/0xe0
[   32.853491]  ? __virt_addr_valid+0xa6/0x100
[   32.857677]  ? check_stack_object+0x1f/0x60
[   32.861864]  ? __check_object_size+0x10c/0x1ce
[   32.866316]  ? _raw_spin_unlock+0x9/0x30
[   32.870245]  ? __alloc_fd+0x115/0x220
[   32.873910]  do_sys_open+0x1c3/0x290
[   32.877489]  ? __do_page_fault+0x494/0x7b0
[   32.881588]  ? file_open_name+0x180/0x180
[   32.885604]  do_syscall_64+0x8a/0x240
[   32.889270]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Fix this by deferring the call to seq_open() until after the data is
fully collected without race, which prevents any seq_file leakage on
race by design.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
11 jobs for next in 30 minutes and 31 seconds (queued for 17 seconds)
latest
Status Job ID Name Coverage
  Build
passed #163617
arm-4.14-release

00:26:48

passed #163616
arm-4.19-release

00:28:32

passed #163618
arm-4.4-cip-head

00:21:36

passed #163620
arm64-4.14-release

00:27:11

passed #163619
arm64-4.19-release

00:30:31

passed #163626
powerpc-4.19-release

00:14:02

passed #163623
x86-4.14-release

00:15:30

passed #163621
x86-4.19-cip-head

00:15:50

passed #163622
x86-4.19-cip-release

00:15:52

passed #163624
x86-4.4-cip-head

00:14:06

passed #163625
x86-4.4-cip-release

00:13:46