Skip to contentSkip to conversation

linux 5.14.3: free_user_ns causes NULL pointer dereference

PATCH Superseded Jordan Glover 8 participants 54 messages Sep 15, 2021 – Nov 6, 2021

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

Hi, recently I hit system freeze after I was closing few containerized apps on my system. As for now it occurred only once on linux 5.14.3. I think it maybe be related to "Count rlimits in each user namespace" patchset merged during 5.14 window

https://lore.kernel.org/all/257aa5fb1a7d81cf0f4c34f39ada2320c4284771.1619094428.git.legion@kernel.org/T/#u

Logs below:

------------[ cut here ]------------
WARNING: CPU: 1 PID: 26546 at kernel/ucount.c:253 dec_ucount+0x43/0x50
Modules linked in: nft_ct nft_fib_ipv4 nft_fib wireguard curve25519_x86_64 libcurve25519_generic libchacha20poly1305 chacha_x86_64 poly1305_x86_64 udp_tunnel libblake2s blake2s_x86_64 libblake2s_generic libchacha ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg hid_sensor_custom_intel_hinge hid_sensor_als hid_sensor_magn_3d hid_sensor_rotation hid_sensor_accel_3d hid_sensor_gyro_3d hid_sensor_trigger industrialio_triggered_buffer hid_sensor_iio_common kfifo_buf industrialio hid_sensor_custom hid_sensor_hub cros_ec_ishtp cros_ec intel_ishtp_loader nft_counter intel_ishtp_hid snd_hda_codec_hdmi intel_rapl_msr xt_mark ipt_REJECT nf_reject_ipv4 snd_ctl_led xt_LOG snd_hda_codec_conexant nf_log_syslog snd_hda_codec_generic xt_addrtype xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv4 mei_hdcp snd_hda_intel nft_compat wmi_bmof nf_tables intel_rapl_common libcrc32c think_lmi intel_tcc_cooling snd_intel_dspcfg firmware_attributes_class nfnetlink iwlmvm
 intel_wmi_thunderbolt mac80211 x86_pkg_temp_thermal snd_hda_codec intel_powerclamp coretemp libarc4 vfat fat kvm_intel rapl intel_cstate snd_hwdep intel_uncore iwlwifi snd_hda_core mousedev joydev snd_pcm psmouse cfg80211 snd_timer mei_me ucsi_acpi wacom intel_ish_ipc intel_xhci_usb_role_switch mei intel_pch_thermal typec_ucsi roles typec intel_ishtp wmi thinkpad_acpi ledtrig_audio platform_profile snd soundcore rfkill tpm_crb i2c_hid_acpi i2c_hid acpi_pad tpm_tis mac_hid tpm_tis_core pkcs8_key_parser fuse zram ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 usbhid dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core dm_mod rtsx_pci_sdmmc mmc_core serio_raw atkbd libps2 crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd xhci_pci rtsx_pci xhci_pci_renesas i8042 serio kvmgt mdev vfio_iommu_type1 vfio i915 i2c_algo_bit intel_gtt ttm agpgart video drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec
 drm kvm irqbypass
CPU: 1 PID: 26546 Comm: kworker/1:1 Not tainted 5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x43/0x50
Code: 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 48 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff <0f> 0b eb e7 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 f8 48
RSP: 0018:ffffa82cc2bd7e60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa2f53298ee50 RCX: ffffa2f3c0061000
RDX: ffffa2f3c0061020 RSI: ffffffffffffffff RDI: ffffa2f3c0061000
RBP: ffffa2f53298ebe0 R08: 0000000000000020 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: ffffa2f3c0061000
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffffa2f599680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000628f892be9f8 CR3: 000000002880e004 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
---[ end trace eb7a8d38b64b2d3a ]---
BUG: kernel NULL pointer dereference, address: 00000000000001e8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
Oops: 0000 [#1] SMP PTI
CPU: 1 PID: 26546 Comm: kworker/1:1 Tainted: G        W         5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff 0f 0b eb e7 66
RSP: 0018:ffffa82cc2bd7e60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa2f53298ee50 RCX: ffffa2f3c0061000
RDX: ffffa2f3c0061020 RSI: ffffffffffffffff RDI: ffffa2f3c0061000
RBP: ffffa2f53298ebe0 R08: 0000000000000020 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: ffffa2f3c0061000
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffffa2f599680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 000000002880e004 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
#1 lore raw
Quoted 3 lines · Jordan Glover

Hi, recently I hit system freeze after I was closing few containerized apps on my system. As for now it occurred only once on linux 5.14.3. I think it maybe be related to "Count rlimits in each user namespace" patchset merged during 5.14 window

https://lore.kernel.org/all/257aa5fb1a7d81cf0f4c34f39ada2320c4284771.1619094428.git.legion@kernel.org/T/#u

So that warning comes from:

void dec_ucount(struct ucounts *ucounts, enum ucount_type type)

{
	struct ucounts *iter;
	for (iter = ucounts; iter; iter = iter->ns->ucounts) {
		long dec = atomic_long_dec_if_positive(&iter->ucount[type]);
		WARN_ON_ONCE(dec < 0);
	}
	put_ucounts(ucounts);
}

Which certainly looks like a reference count bug. It could also be a memory stomp somewhere close.

Do you have any idea what else was going on? This location is the symptom but not the actual cause.

Eric

Quoted 6 lines

Logs below:

------------[ cut here ]------------
WARNING: CPU: 1 PID: 26546 at kernel/ucount.c:253 dec_ucount+0x43/0x50
Modules linked in: nft_ct nft_fib_ipv4 nft_fib wireguard curve25519_x86_64 libcurve25519_generic libchacha20poly1305 chacha_x86_64 poly1305_x86_64 udp_tunnel libblake2s blake2s_x86_64 libblake2s_generic libchacha ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg hid_sensor_custom_intel_hinge hid_sensor_als hid_sensor_magn_3d hid_sensor_rotation hid_sensor_accel_3d hid_sensor_gyro_3d hid_sensor_trigger industrialio_triggered_buffer hid_sensor_iio_common kfifo_buf industrialio hid_sensor_custom hid_sensor_hub cros_ec_ishtp cros_ec intel_ishtp_loader nft_counter intel_ishtp_hid snd_hda_codec_hdmi intel_rapl_msr xt_mark ipt_REJECT nf_reject_ipv4 snd_ctl_led xt_LOG snd_hda_codec_conexant nf_log_syslog snd_hda_codec_generic xt_addrtype xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv4 mei_hdcp snd_hda_intel nft_compat wmi_bmof nf_tables intel_rapl_common libcrc32c think_lmi intel_tcc_cooling snd_intel_dspcfg firmware_attributes_class nfnetlink iwlmv

m

Quoted 53 lines

intel_wmi_thunderbolt mac80211 x86_pkg_temp_thermal snd_hda_codec intel_powerclamp coretemp libarc4 vfat fat kvm_intel rapl intel_cstate snd_hwdep intel_uncore iwlwifi snd_hda_core mousedev joydev snd_pcm psmouse cfg80211 snd_timer mei_me ucsi_acpi wacom intel_ish_ipc intel_xhci_usb_role_switch mei intel_pch_thermal typec_ucsi roles typec intel_ishtp wmi thinkpad_acpi ledtrig_audio platform_profile snd soundcore rfkill tpm_crb i2c_hid_acpi i2c_hid acpi_pad tpm_tis mac_hid tpm_tis_core pkcs8_key_parser fuse zram ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 usbhid dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core dm_mod rtsx_pci_sdmmc mmc_core serio_raw atkbd libps2 crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd xhci_pci rtsx_pci xhci_pci_renesas i8042 serio kvmgt mdev vfio_iommu_type1 vfio i915 i2c_algo_bit intel_gtt ttm agpgart video drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec drm kvm irqbypass

CPU: 1 PID: 26546 Comm: kworker/1:1 Not tainted 5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x43/0x50
Code: 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 48 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff <0f> 0b eb e7 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 f8 48
RSP: 0018:ffffa82cc2bd7e60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa2f53298ee50 RCX: ffffa2f3c0061000
RDX: ffffa2f3c0061020 RSI: ffffffffffffffff RDI: ffffa2f3c0061000
RBP: ffffa2f53298ebe0 R08: 0000000000000020 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: ffffa2f3c0061000
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffffa2f599680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000628f892be9f8 CR3: 000000002880e004 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
---[ end trace eb7a8d38b64b2d3a ]---
BUG: kernel NULL pointer dereference, address: 00000000000001e8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
Oops: 0000 [#1] SMP PTI
CPU: 1 PID: 26546 Comm: kworker/1:1 Tainted: G        W         5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff 0f 0b eb e7 66
RSP: 0018:ffffa82cc2bd7e60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa2f53298ee50 RCX: ffffa2f3c0061000
RDX: ffffa2f3c0061020 RSI: ffffffffffffffff RDI: ffffa2f3c0061000
RBP: ffffa2f53298ebe0 R08: 0000000000000020 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: ffffa2f3c0061000
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffffa2f599680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 000000002880e004 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
#2 lore raw
Quoted 27 lines · On Wednesday, September 15th, 2021 at 9:02 PM, <[email protected]> wrote:
Quoted 3 lines · Jordan Glover [email protected] writes:

Hi, recently I hit system freeze after I was closing few containerized apps on my system. As for now it occurred only once on linux 5.14.3. I think it maybe be related to "Count rlimits in each user namespace" patchset merged during 5.14 window

https://lore.kernel.org/all/257aa5fb1a7d81cf0f4c34f39ada2320c4284771.1619094428.git.legion@kernel.org/T/#u

So that warning comes from:

void dec_ucount(struct ucounts *ucounts, enum ucount_type type)

{

struct ucounts *iter;

for (iter = ucounts; iter; iter = iter->ns->ucounts) {

    	long dec = atomic_long_dec_if_positive(&iter->ucount[type]);

    	WARN_ON_ONCE(dec < 0);
    }
    put_ucounts(ucounts);

}

Which certainly looks like a reference count bug. It could also be a

Quoted 7 lines

memory stomp somewhere close.

Do you have any idea what else was going on? This location is the

symptom but not the actual cause.

Eric

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

Jordan

#3 lore raw
Quoted 34 lines · Jordan Glover
Quoted 31 lines · On Wednesday, September 15th, 2021 at 9:02 PM, <[email protected]> wrote:
Quoted 3 lines · Jordan Glover [email protected] writes:

Hi, recently I hit system freeze after I was closing few containerized apps on my system. As for now it occurred only once on linux 5.14.3. I think it maybe be related to "Count rlimits in each user namespace" patchset merged during 5.14 window

https://lore.kernel.org/all/257aa5fb1a7d81cf0f4c34f39ada2320c4284771.1619094428.git.legion@kernel.org/T/#u

So that warning comes from:

void dec_ucount(struct ucounts *ucounts, enum ucount_type type)

{

struct ucounts *iter;

for (iter = ucounts; iter; iter = iter->ns->ucounts) {

      long dec = atomic_long_dec_if_positive(&iter->ucount[type]);

      WARN_ON_ONCE(dec < 0);
    }
    put_ucounts(ucounts);

}

Which certainly looks like a reference count bug. It could also be a

memory stomp somewhere close.

Do you have any idea what else was going on? This location is the

Quoted 7 lines
Quoted 3 lines

symptom but not the actual cause.

Eric

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

I have been able to steadily reproduce this for a while. But I haven't had time to look into it. I'd appreciate any help.

[ 1324.741762] ==================================================================
[ 1324.749200] BUG: KASAN: use-after-free in dec_ucount+0x50/0xd8
[ 1324.755198] Write of size 8 at addr ffffff808f2f0120 by task kworker/7:2/1817
[ 1324.762523]
[ 1324.764063] CPU: 7 PID: 1817 Comm: kworker/7:2 Not tainted 5.14.0-lockdep+ #7
[ 1324.771396] Hardware name: Google Lazor (rev3+) with KB Backlight (DT)
[ 1324.778098] Workqueue: events free_user_ns
[ 1324.782320] Call trace:
[ 1324.784845]  dump_backtrace+0x0/0x42c
[ 1324.788614]  show_stack+0x24/0x30
[ 1324.792026]  dump_stack_lvl+0xd0/0x100
[ 1324.795884]  print_address_description+0x30/0x304
[ 1324.800725]  kasan_report+0x190/0x1d8
[ 1324.804494]  kasan_check_range+0x1ac/0x1bc
[ 1324.808708]  __kasan_check_write+0x44/0x54
[ 1324.812923]  dec_ucount+0x50/0xd8
[ 1324.816334]  free_user_ns+0x1b0/0x288
[ 1324.820102]  process_one_work+0x7b4/0x10ec
[ 1324.824318]  worker_thread+0x800/0xcf4
[ 1324.828176]  kthread+0x2a8/0x358
[ 1324.831500]  ret_from_fork+0x10/0x18
[ 1324.835182]
[ 1324.836720] Allocated by task 5167:
[ 1324.840312]  kasan_save_stack+0x38/0x68
[ 1324.844261]  __kasan_slab_alloc+0x6c/0x88
[ 1324.848387]  kmem_cache_alloc+0x234/0x47c
[ 1324.852505]  getname_flags+0xb4/0x3b8
[ 1324.856273]  __arm64_sys_unlink+0x4c/0x68
[ 1324.860400]  invoke_syscall+0xd4/0x2c8
[ 1324.864258]  el0_svc_common+0x124/0x200
[ 1324.868199]  do_el0_svc_compat+0x54/0x64
[ 1324.872235]  el0_svc_compat+0x24/0x34
[ 1324.876003]  el0t_32_sync_handler+0xc0/0xf0
[ 1324.880307]  el0t_32_sync+0x19c/0x1a0
[ 1324.884078]
[ 1324.885616] Freed by task 5167:
[ 1324.888848]  kasan_save_stack+0x38/0x68
[ 1324.892797]  kasan_set_track+0x28/0x3c
[ 1324.896653]  kasan_set_free_info+0x28/0x4c
[ 1324.900865]  ____kasan_slab_free+0x118/0x164
[ 1324.905259]  __kasan_slab_free+0x18/0x28
[ 1324.909296]  kmem_cache_free+0x1c0/0x4b8
[ 1324.913325]  putname+0xd0/0x140
[ 1324.916554]  do_unlinkat+0x518/0x57c
[ 1324.920233]  __arm64_sys_unlink+0x58/0x68
[ 1324.924359]  invoke_syscall+0xd4/0x2c8
[ 1324.928215]  el0_svc_common+0x124/0x200
[ 1324.932164]  do_el0_svc_compat+0x54/0x64
[ 1324.936195]  el0_svc_compat+0x24/0x34
[ 1324.939963]  el0t_32_sync_handler+0xc0/0xf0
[ 1324.944259]  el0t_32_sync+0x19c/0x1a0
[ 1324.948029]
[ 1324.949567] The buggy address belongs to the object at ffffff808f2f0040
[ 1324.949567]  which belongs to the cache names_cache of size 4096
[ 1324.962498] The buggy address is located 224 bytes inside of
[ 1324.962498]  4096-byte region [ffffff808f2f0040, ffffff808f2f1040)
[ 1324.974635] The buggy address belongs to the page:
[ 1324.979561] page:fffffffe023cbc00 refcount:1 mapcount:0
mapping:0000000000000000 index:0xffffff808f2f23c0 pfn:0x10f2f0
[ 1324.990536] head:fffffffe023cbc00 order:3 compound_mapcount:0
compound_pincount:0
[ 1324.998220] flags: 0x8000000000010200(slab|head|zone=2)
[ 1325.003596] raw: 8000000000010200 fffffffe02b59a08 fffffffe0247a208
ffffff808036ad80
[ 1325.011549] raw: ffffff808f2f23c0 0000000000070006 00000001ffffffff
0000000000000000
[ 1325.019494] page dumped because: kasan: bad access detected
[ 1325.025214]
[ 1325.026751] Memory state around the buggy address:
[ 1325.031680]  ffffff808f2f0000: fc fc fc fc fc fc fc fc fa fb fb fb
fb fb fb fb
[ 1325.039093]  ffffff808f2f0080: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 1325.046506] >ffffff808f2f0100: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 1325.053920]                                ^
[ 1325.058311]  ffffff808f2f0180: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 1325.065725]  ffffff808f2f0200: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 1325.073153] ==================================================================
[ 7358.532846] ==================================================================
[ 7358.540369] BUG: KASAN: use-after-free in dec_ucount+0x50/0xd8
[ 7358.546429] Write of size 8 at addr ffffff800af71120 by task
kworker/3:1/27623
[ 7358.553880]
[ 7358.555458] CPU: 3 PID: 27623 Comm: kworker/3:1 Not tainted
5.14.0-lockdep+ #13
[ 7358.563013] Hardware name: Google Lazor (rev3+) with KB Backlight (DT)
[ 7358.569761] Workqueue: events free_user_ns
[ 7358.574039] Call trace:
[ 7358.576595]  dump_backtrace+0x0/0x42c
[ 7358.580402]  show_stack+0x24/0x30
[ 7358.583842]  dump_stack_lvl+0xd0/0x100
[ 7358.587732]  print_address_description+0x30/0x304
[ 7358.592608]  kasan_report+0x190/0x1d8
[ 7358.596405]  kasan_check_range+0x1ac/0x1bc
[ 7358.600643]  __kasan_check_write+0x44/0x54
[ 7358.604876]  dec_ucount+0x50/0xd8
[ 7358.608317]  free_user_ns+0x1b0/0x288
[ 7358.612106]  process_one_work+0x7b4/0x10ec
[ 7358.616354]  worker_thread+0x800/0xcf4
[ 7358.620234]  kthread+0x2a8/0x358
[ 7358.623585]  ret_from_fork+0x10/0x18
[ 7358.627297]
[ 7358.628861] Allocated by task 26538:
[ 7358.632556]  kasan_save_stack+0x38/0x68
[ 7358.636537]  __kasan_kmalloc+0x9c/0xb8
[ 7358.640424]  kmem_cache_alloc_trace+0x2a4/0x370
[ 7358.645104]  fscrypt_setup_filename+0x3bc/0x754
[ 7358.649793]  ext4_find_entry+0x80/0x240
[ 7358.653774]  __ext4_unlink+0x88/0x594
[ 7358.657563]  ext4_unlink+0x458/0x99c
[ 7358.661263]  vfs_unlink+0x22c/0x340
[ 7358.664877]  do_unlinkat+0x358/0x57c
[ 7358.668586]  __arm64_sys_unlinkat+0xa8/0xc4
[ 7358.672920]  invoke_syscall+0xd4/0x2c8
[ 7358.676808]  el0_svc_common+0x124/0x200
[ 7358.680781]  do_el0_svc_compat+0x54/0x64
[ 7358.684835]  el0_svc_compat+0x24/0x34
[ 7358.688640]  el0t_32_sync_handler+0xc0/0xf0
[ 7358.692973]  el0t_32_sync+0x19c/0x1a0
[ 7358.696772]
[ 7358.698331] Freed by task 26538:
[ 7358.701668]  kasan_save_stack+0x38/0x68
[ 7358.705646]  kasan_set_track+0x28/0x3c
[ 7358.709533]  kasan_set_free_info+0x28/0x4c
[ 7358.713772]  ____kasan_slab_free+0x118/0x164
[ 7358.718186]  __kasan_slab_free+0x18/0x28
[ 7358.722240]  kfree+0x2f8/0x500
[ 7358.725403]  ext4_find_entry+0x19c/0x240
[ 7358.729469]  __ext4_unlink+0x88/0x594
[ 7358.733265]  ext4_unlink+0x458/0x99c
[ 7358.736968]  vfs_unlink+0x22c/0x340
[ 7358.740587]  do_unlinkat+0x358/0x57c
[ 7358.744285]  __arm64_sys_unlinkat+0xa8/0xc4
[ 7358.748610]  invoke_syscall+0xd4/0x2c8
[ 7358.752495]  el0_svc_common+0x124/0x200
[ 7358.756464]  do_el0_svc_compat+0x54/0x64
[ 7358.760522]  el0_svc_compat+0x24/0x34
[ 7358.764320]  el0t_32_sync_handler+0xc0/0xf0
[ 7358.768653]  el0t_32_sync+0x19c/0x1a0
[ 7358.772453]
[ 7358.774015] Last potentially related work creation:
[ 7358.779053]  kasan_save_stack+0x38/0x68
[ 7358.783025]  kasan_record_aux_stack+0xdc/0x108
[ 7358.787619]  call_rcu+0x180/0xed4
[ 7358.791061]  __ip6_del_rt+0xfc/0x130
[ 7358.794771]  ip6_route_del+0xa74/0xb74
[ 7358.798653]  inet6_rtm_delroute+0x31c/0x3e4
[ 7358.802986]  rtnetlink_rcv_msg+0x3d0/0x928
[ 7358.807242]  netlink_rcv_skb+0x164/0x2ac
[ 7358.811311]  rtnetlink_rcv+0x24/0x30
[ 7358.815025]  netlink_unicast+0x328/0x518
[ 7358.819083]  netlink_sendmsg+0x5c0/0x934
[ 7358.823142]  sock_sendmsg+0xb8/0xdc
[ 7358.826764]  __sys_sendto+0x218/0x3e4
[ 7358.830557]  __arm64_sys_send+0xac/0xc8
[ 7358.834526]  invoke_syscall+0xd4/0x2c8
[ 7358.838413]  el0_svc_common+0x124/0x200
[ 7358.842382]  do_el0_svc_compat+0x54/0x64
[ 7358.846443]  el0_svc_compat+0x24/0x34
[ 7358.850245]  el0t_32_sync_handler+0xc0/0xf0
[ 7358.854578]  el0t_32_sync+0x19c/0x1a0
[ 7358.858382]
[ 7358.859941] Second to last potentially related work creation:
[ 7358.865862]  kasan_save_stack+0x38/0x68
[ 7358.869850]  kasan_record_aux_stack+0xdc/0x108
[ 7358.874452]  insert_work+0x60/0x22c
[ 7358.878072]  __queue_work+0xae8/0xe74
[ 7358.881866]  queue_work_on+0x100/0x148
[ 7358.885752]  drm_atomic_helper_commit+0x18c/0x1f4
[ 7358.890615]  drm_atomic_nonblocking_commit+0xc4/0xdc
[ 7358.895749]  drm_mode_atomic_ioctl+0x89c/0xaa0
[ 7358.900353]  drm_ioctl_kernel+0x15c/0x260
[ 7358.904505]  drm_ioctl+0x460/0x828
[ 7358.908029]  drm_compat_ioctl+0x1bc/0x230
[ 7358.912176]  __arm64_compat_sys_ioctl+0x1b0/0x1c4
[ 7358.917037]  invoke_syscall+0xd4/0x2c8
[ 7358.920919]  el0_svc_common+0x124/0x200
[ 7358.924887]  do_el0_svc_compat+0x54/0x64
[ 7358.928946]  el0_svc_compat+0x24/0x34
[ 7358.932735]  el0t_32_sync_handler+0xc0/0xf0
[ 7358.937065]  el0t_32_sync+0x19c/0x1a0
[ 7358.940853]
[ 7358.942408] The buggy address belongs to the object at ffffff800af71100
[ 7358.942408]  which belongs to the cache kmalloc-256 of size 256
[ 7358.955282] The buggy address is located 32 bytes inside of
[ 7358.955282]  256-byte region [ffffff800af71100, ffffff800af71200)
[ 7358.967268] The buggy address belongs to the page:
[ 7358.972209] page:fffffffe002bdc00 refcount:1 mapcount:0
mapping:0000000000000000 index:0x0 pfn:0x8af70
[ 7358.981790] head:fffffffe002bdc00 order:3 compound_mapcount:0
compound_pincount:0
[ 7358.989493] flags: 0x10200(slab|head|zone=0)
[ 7358.993922] raw: 0000000000010200 fffffffe021e0c08 fffffffe02960008
ffffff808000c980
[ 7359.001898] raw: 0000000000000000 0000000000200020 00000001ffffffff
0000000000000000
[ 7359.009867] page dumped because: kasan: bad access detected
[ 7359.015607]
[ 7359.017162] Memory state around the buggy address:
[ 7359.022105]  ffffff800af71000: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7359.029543]  ffffff800af71080: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7359.036981] >ffffff800af71100: fa fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7359.044414]                                ^
[ 7359.048818]  ffffff800af71180: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7359.056256]  ffffff800af71200: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7359.063695] ==================================================================
#4 lore raw
Quoted 38 lines · Yu Zhao
Quoted 36 lines · Jordan Glover
Quoted 33 lines · On Wednesday, September 15th, 2021 at 9:02 PM, <[email protected]> wrote:
Quoted 3 lines · Jordan Glover [email protected] writes:

Hi, recently I hit system freeze after I was closing few containerized apps on my system. As for now it occurred only once on linux 5.14.3. I think it maybe be related to "Count rlimits in each user namespace" patchset merged during 5.14 window

https://lore.kernel.org/all/257aa5fb1a7d81cf0f4c34f39ada2320c4284771.1619094428.git.legion@kernel.org/T/#u

So that warning comes from:

void dec_ucount(struct ucounts *ucounts, enum ucount_type type)

{

struct ucounts *iter;

for (iter = ucounts; iter; iter = iter->ns->ucounts) {

      long dec = atomic_long_dec_if_positive(&iter->ucount[type]);

      WARN_ON_ONCE(dec < 0);
    }
    put_ucounts(ucounts);

}

Which certainly looks like a reference count bug. It could also be a

memory stomp somewhere close.

Do you have any idea what else was going on? This location is the

symptom but not the actual cause.

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Eric

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

I have been able to steadily reproduce this for a while. But I haven't had time to look into it. I'd appreciate any help.

It would be very helpful if you could look farther back in your logs and see if you can also see:

WARNING: CPU: 1 PID: 351 at kernel/ucount.c:253 dec_ucount+0x43/0x5

Or anything else preceding the use-after-free.

I am inclined to think they are the same issue but without seeing the WARN_ON_ONCE I can't safely conclude that.

Eric

#5 lore raw
Quoted 50 lines · Eric W. Biederman
Quoted 38 lines · Yu Zhao
Quoted 36 lines · Jordan Glover
Quoted 33 lines · On Wednesday, September 15th, 2021 at 9:02 PM, <[email protected]> wrote:
Quoted 3 lines · Jordan Glover [email protected] writes:

Hi, recently I hit system freeze after I was closing few containerized apps on my system. As for now it occurred only once on linux 5.14.3. I think it maybe be related to "Count rlimits in each user namespace" patchset merged during 5.14 window

https://lore.kernel.org/all/257aa5fb1a7d81cf0f4c34f39ada2320c4284771.1619094428.git.legion@kernel.org/T/#u

So that warning comes from:

void dec_ucount(struct ucounts *ucounts, enum ucount_type type)

{

struct ucounts *iter;

for (iter = ucounts; iter; iter = iter->ns->ucounts) {

      long dec = atomic_long_dec_if_positive(&iter->ucount[type]);

      WARN_ON_ONCE(dec < 0);
    }
    put_ucounts(ucounts);

}

Which certainly looks like a reference count bug. It could also be a

memory stomp somewhere close.

Do you have any idea what else was going on? This location is the

symptom but not the actual cause.

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Eric

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

I have been able to steadily reproduce this for a while. But I haven't had time to look into it. I'd appreciate any help.

Quoted 8 lines

It would be very helpful if you could look farther back in your logs and see if you can also see:

WARNING: CPU: 1 PID: 351 at kernel/ucount.c:253 dec_ucount+0x43/0x5

Or anything else preceding the use-after-free.

I am inclined to think they are the same issue but without seeing the WARN_ON_ONCE I can't safely conclude that.

It was either the WARN_ON_ONCE or the KASAN before my kernel crashed. (KASAN is on for both cases.)

[ 3049.540734] ------------[ cut here ]------------^M
[ 3049.545557] WARNING: CPU: 0 PID: 8369 at kernel/ucount.c:253
dec_ucount+0xb0/0xd8^M
[ 3049.553293] Modules linked in: vhost_vsock vhost vhost_iotlb

vmw_vsock_virtio_transport_common vsock rfcomm algif_hash algif_skcipher af_alg uinput uvcvideo videobuf2_vmalloc venus_enc venus_dec videobuf2_dma_contig videobuf2_memops cros_ec_typec typec hci_uart btqca bluetooth ecdh_generic ecc venus_core v4l2_mem2mem videobuf2_v4l2 videobuf2_common qcom_q6v5_mss ipa qcom_pil_info qcom_q6v5 qcom_common xt_MASQUERADE rmtfs_mem fuse ath10k_snoc qmi_helpers ath10k_core ath mac80211 lzo_rle lzo_compress cfg80211 zram smsc smsc95xx usbnet mii joydev^M

[ 3049.603135] CPU: 0 PID: 8369 Comm: kworker/0:2 Not tainted
5.14.0-lockdep+ #4^M
[ 3049.610506] Hardware name: Google Lazor (rev3+) with KB Backlight (DT)^M
[ 3049.617230] Workqueue: events free_user_ns^M
[ 3049.621494] pstate: a0400009 (NzCv daif +PAN -UAO -TCO BTYPE=--)^M
[ 3049.627694] pc : dec_ucount+0xb0/0xd8^M
[ 3049.631489] lr : dec_ucount+0x50/0xd8^M
[ 3049.635280] sp : ffffffc019ff7b50^M
[ 3049.638707] x29: ffffffc019ff7b50 x28: ffffffd5b5d8b710 x27:
ffffff80884cae90^M
[ 3049.646083] x26: dfffffc000000000 x25: ffffffd5b5de98a0 x24:
0000000000000001^M
[ 3049.653460] x23: ffffff80d2597100 x22: 0000000000000000 x21:
dfffffc000000000^M
[ 3049.660838] x20: ffffff80d2597120 x19: ffffff80d2597100 x18:
1ffffff01b4b3f48^M
[ 3049.668210] x17: 1ffffff01b4b3f47 x16: 0000000000000000 x15:
0000000000000000^M
[ 3049.675585] x14: 0000000000000000 x13: 000000002b0cc34b x12:
0000000024966d0f^M
[ 3049.682960] x11: 0000000000000000 x10: dfffffc000000001 x9 :
0000000000000000^M
[ 3049.690334] x8 : ffffff80d259791f x7 : 0000000000000000 x6 :
ffffffd5b3de71c4^M
[ 3049.697709] x5 : 0000000000000000 x4 : 0000000000000000 x3 :
ffffffd5b3391ca4^M
[ 3049.705086] x2 : 0000000000000001 x1 : 0000000000000008 x0 :
0000000000000001^M
[ 3049.712459] Call trace:^M
[ 3049.715003]  dec_ucount+0xb0/0xd8^M
[ 3049.718443]  free_user_ns+0x1b0/0x288^M
[ 3049.722242]  process_one_work+0x7b4/0x10ec^M
[ 3049.726485]  worker_thread+0x800/0xcf4^M
[ 3049.730377]  kthread+0x2a8/0x358^M
[ 3049.733736]  ret_from_fork+0x10/0x18^M
[ 3049.737445] irq event stamp: 0^M
[ 3049.740612] hardirqs last  enabled at (0): [<0000000000000000>] 0x0^M
[ 3049.747092] hardirqs last disabled at (0): [<ffffffd5b331413c>]
copy_process+0xcb0/0x2a54^M
[ 3049.755521] softirqs last  enabled at (0): [<ffffffd5b3314164>]
copy_process+0xcd8/0x2a54^M
[ 3049.763954] softirqs last disabled at (0): [<0000000000000000>] 0x0^M
[ 3049.770432] ---[ end trace fa55518c981c0c5d ]---^M
#6 lore raw
In reply to Jordan Glover
Quoted 4 lines · Jordan Glover

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

Heh, it jut happened again. This time closing firefox alone had such effect:

------------[ cut here ]------------
WARNING: CPU: 1 PID: 351 at kernel/ucount.c:253 dec_ucount+0x43/0x50
Modules linked in: nft_ct nft_fib_ipv4 nft_fib wireguard curve25519_x86_64 libcurve25519_generic libchacha20poly1305 chacha_x86_64 poly1305_x86_64 udp_tunnel libblake2s blake2s_x86_64 libblake2s_generic libchacha ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg hid_sensor_custom_intel_hinge hid_sensor_als hid_sensor_gyro_3d hid_sensor_accel_3d hid_sensor_rotation hid_sensor_magn_3d hid_sensor_trigger industrialio_triggered_buffer hid_sensor_iio_common kfifo_buf industrialio hid_sensor_custom hid_sensor_hub cros_ec_ishtp cros_ec intel_ishtp_loader intel_ishtp_hid intel_rapl_msr nft_counter xt_mark ipt_REJECT nf_reject_ipv4 mei_hdcp intel_rapl_common xt_LOG nf_log_syslog intel_tcc_cooling x86_pkg_temp_thermal think_lmi wmi_bmof xt_addrtype firmware_attributes_class xt_tcpudp intel_powerclamp xt_conntrack nf_conntrack nf_defrag_ipv4 snd_hda_codec_hdmi nft_compat intel_wmi_thunderbolt nf_tables libcrc32c coretemp iwlmvm snd_ctl_led nfnetlink
 snd_hda_codec_conexant mac80211 snd_hda_codec_generic libarc4 vfat snd_hda_intel kvm_intel fat iwlwifi snd_intel_dspcfg rapl intel_cstate joydev snd_hda_codec mousedev intel_uncore snd_hwdep snd_hda_core psmouse snd_pcm snd_timer cfg80211 mei_me wacom ucsi_acpi typec_ucsi mei intel_pch_thermal intel_xhci_usb_role_switch intel_ish_ipc roles intel_ishtp typec wmi thinkpad_acpi ledtrig_audio platform_profile snd soundcore tpm_crb rfkill i2c_hid_acpi tpm_tis tpm_tis_core i2c_hid mac_hid acpi_pad pkcs8_key_parser fuse zram ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 usbhid dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core dm_mod rtsx_pci_sdmmc mmc_core serio_raw atkbd libps2 crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd rtsx_pci xhci_pci xhci_pci_renesas i8042 serio kvmgt mdev vfio_iommu_type1 vfio i915 i2c_algo_bit intel_gtt ttm agpgart video drm_kms_helper syscopyarea sysfillrect sysimgblt
 fb_sys_fops cec drm kvm irqbypass
CPU: 1 PID: 351 Comm: kworker/1:3 Not tainted 5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x43/0x50
Code: 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 48 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff <0f> 0b eb e7 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 f8 48
RSP: 0018:ffffaa06c08bbe60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffff894ecb0c35a0 RCX: ffff894e25cdfcc0
RDX: ffff894e25cdfce0 RSI: ffffffffffffffff RDI: ffff894e25cdfcc0
RBP: ffff894ee393d380 R08: 0000000000000020 R09: ffff894ee393d5f0
R10: ffff894f617fd000 R11: 0000000000031678 R12: ffff894e25cdfcc0
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff894f59680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000056ffceff6b10 CR3: 0000000147a0e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
---[ end trace ff45ac39689f43c1 ]---
BUG: kernel NULL pointer dereference, address: 00000000000001e8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
Oops: 0000 [#1] SMP PTI
CPU: 1 PID: 351 Comm: kworker/1:3 Tainted: G        W         5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff 0f 0b eb e7 66
RSP: 0018:ffffaa06c08bbe60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffff894ecb0c35a0 RCX: ffff894e25cdfcc0
RDX: ffff894e25cdfce0 RSI: ffffffffffffffff RDI: ffff894e25cdfcc0
RBP: ffff894ee393d380 R08: 0000000000000020 R09: ffff894ee393d5f0
R10: ffff894f617fd000 R11: 0000000000031678 R12: ffff894e25cdfcc0
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff894f59680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 0000000147a0e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
Modules linked in: nft_ct nft_fib_ipv4 nft_fib wireguard curve25519_x86_64 libcurve25519_generic libchacha20poly1305 chacha_x86_64 poly1305_x86_64 udp_tunnel libblake2s blake2s_x86_64 libblake2s_generic libchacha ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg hid_sensor_custom_intel_hinge hid_sensor_als hid_sensor_gyro_3d hid_sensor_accel_3d hid_sensor_rotation hid_sensor_magn_3d hid_sensor_trigger industrialio_triggered_buffer hid_sensor_iio_common kfifo_buf industrialio hid_sensor_custom hid_sensor_hub cros_ec_ishtp cros_ec intel_ishtp_loader intel_ishtp_hid intel_rapl_msr nft_counter xt_mark ipt_REJECT nf_reject_ipv4 mei_hdcp intel_rapl_common xt_LOG nf_log_syslog intel_tcc_cooling x86_pkg_temp_thermal think_lmi wmi_bmof xt_addrtype firmware_attributes_class xt_tcpudp intel_powerclamp xt_conntrack nf_conntrack nf_defrag_ipv4 snd_hda_codec_hdmi nft_compat intel_wmi_thunderbolt nf_tables libcrc32c coretemp iwlmvm snd_ctl_led nfnetlink
 snd_hda_codec_conexant mac80211 snd_hda_codec_generic libarc4 vfat snd_hda_intel kvm_intel fat iwlwifi snd_intel_dspcfg rapl intel_cstate joydev snd_hda_codec mousedev intel_uncore snd_hwdep snd_hda_core psmouse snd_pcm snd_timer cfg80211 mei_me wacom ucsi_acpi typec_ucsi mei intel_pch_thermal intel_xhci_usb_role_switch intel_ish_ipc roles intel_ishtp typec wmi thinkpad_acpi ledtrig_audio platform_profile snd soundcore tpm_crb rfkill i2c_hid_acpi tpm_tis tpm_tis_core i2c_hid mac_hid acpi_pad pkcs8_key_parser fuse zram ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 usbhid dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core dm_mod rtsx_pci_sdmmc mmc_core serio_raw atkbd libps2 crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd rtsx_pci xhci_pci xhci_pci_renesas i8042 serio kvmgt mdev vfio_iommu_type1 vfio i915 i2c_algo_bit intel_gtt ttm agpgart video drm_kms_helper syscopyarea sysfillrect sysimgblt
 fb_sys_fops cec drm kvm irqbypass
CR2: 00000000000001e8
---[ end trace ff45ac39689f43c2 ]---
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff 0f 0b eb e7 66
RSP: 0018:ffffaa06c08bbe60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffff894ecb0c35a0 RCX: ffff894e25cdfcc0
RDX: ffff894e25cdfce0 RSI: ffffffffffffffff RDI: ffff894e25cdfcc0
RBP: ffff894ee393d380 R08: 0000000000000020 R09: ffff894ee393d5f0
R10: ffff894f617fd000 R11: 0000000000031678 R12: ffff894e25cdfcc0
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff894f59680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 0000000147a0e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
#7 lore raw
Quoted 8 lines · Jordan Glover
Quoted 4 lines · Jordan Glover

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

Heh, it jut happened again. This time closing firefox alone had such effect:

Ok. It looks like he have a couple of folks seeing issues here.

I thought we had all of the issues sorted out for the release of v5.14, but it looks like there is still some little bug left.

If Alex doesn't beat me to it I will see if I can come up with a debugging patch to make it easy to help track down where the reference
count is going wrong. It will be a little bit as my brain is mush at
the moment.

Eric

Quoted 74 lines
------------[ cut here ]------------
WARNING: CPU: 1 PID: 351 at kernel/ucount.c:253 dec_ucount+0x43/0x50
Modules linked in: nft_ct nft_fib_ipv4 nft_fib wireguard curve25519_x86_64 libcurve25519_generic libchacha20poly1305 chacha_x86_64 poly1305_x86_64 udp_tunnel libblake2s blake2s_x86_64 libblake2s_generic libchacha ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg hid_sensor_custom_intel_hinge hid_sensor_als hid_sensor_gyro_3d hid_sensor_accel_3d hid_sensor_rotation hid_sensor_magn_3d hid_sensor_trigger industrialio_triggered_buffer hid_sensor_iio_common kfifo_buf industrialio hid_sensor_custom hid_sensor_hub cros_ec_ishtp cros_ec intel_ishtp_loader intel_ishtp_hid intel_rapl_msr nft_counter xt_mark ipt_REJECT nf_reject_ipv4 mei_hdcp intel_rapl_common xt_LOG nf_log_syslog intel_tcc_cooling x86_pkg_temp_thermal think_lmi wmi_bmof xt_addrtype firmware_attributes_class xt_tcpudp intel_powerclamp xt_conntrack nf_conntrack nf_defrag_ipv4 snd_hda_codec_hdmi nft_compat intel_wmi_thunderbolt nf_tables libcrc32c coretemp iwlmvm snd_ctl_led nfnetlink
 snd_hda_codec_conexant mac80211 snd_hda_codec_generic libarc4 vfat snd_hda_intel kvm_intel fat iwlwifi snd_intel_dspcfg rapl intel_cstate joydev snd_hda_codec mousedev intel_uncore snd_hwdep snd_hda_core psmouse snd_pcm snd_timer cfg80211 mei_me wacom ucsi_acpi typec_ucsi mei intel_pch_thermal intel_xhci_usb_role_switch intel_ish_ipc roles intel_ishtp typec wmi thinkpad_acpi ledtrig_audio platform_profile snd soundcore tpm_crb rfkill i2c_hid_acpi tpm_tis tpm_tis_core i2c_hid mac_hid acpi_pad pkcs8_key_parser fuse zram ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 usbhid dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core dm_mod rtsx_pci_sdmmc mmc_core serio_raw atkbd libps2 crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd rtsx_pci xhci_pci xhci_pci_renesas i8042 serio kvmgt mdev vfio_iommu_type1 vfio i915 i2c_algo_bit intel_gtt ttm agpgart video drm_kms_helper syscopyarea sysfillrect sysimgblt
 fb_sys_fops cec drm kvm irqbypass
CPU: 1 PID: 351 Comm: kworker/1:3 Not tainted 5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x43/0x50
Code: 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 48 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff <0f> 0b eb e7 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 f8 48
RSP: 0018:ffffaa06c08bbe60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffff894ecb0c35a0 RCX: ffff894e25cdfcc0
RDX: ffff894e25cdfce0 RSI: ffffffffffffffff RDI: ffff894e25cdfcc0
RBP: ffff894ee393d380 R08: 0000000000000020 R09: ffff894ee393d5f0
R10: ffff894f617fd000 R11: 0000000000031678 R12: ffff894e25cdfcc0
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff894f59680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000056ffceff6b10 CR3: 0000000147a0e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
---[ end trace ff45ac39689f43c1 ]---
BUG: kernel NULL pointer dereference, address: 00000000000001e8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
Oops: 0000 [#1] SMP PTI
CPU: 1 PID: 351 Comm: kworker/1:3 Tainted: G        W         5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff 0f 0b eb e7 66
RSP: 0018:ffffaa06c08bbe60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffff894ecb0c35a0 RCX: ffff894e25cdfcc0
RDX: ffff894e25cdfce0 RSI: ffffffffffffffff RDI: ffff894e25cdfcc0
RBP: ffff894ee393d380 R08: 0000000000000020 R09: ffff894ee393d5f0
R10: ffff894f617fd000 R11: 0000000000031678 R12: ffff894e25cdfcc0
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff894f59680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 0000000147a0e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
Modules linked in: nft_ct nft_fib_ipv4 nft_fib wireguard curve25519_x86_64 libcurve25519_generic libchacha20poly1305 chacha_x86_64 poly1305_x86_64 udp_tunnel libblake2s blake2s_x86_64 libblake2s_generic libchacha ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg hid_sensor_custom_intel_hinge hid_sensor_als hid_sensor_gyro_3d hid_sensor_accel_3d hid_sensor_rotation hid_sensor_magn_3d hid_sensor_trigger industrialio_triggered_buffer hid_sensor_iio_common kfifo_buf industrialio hid_sensor_custom hid_sensor_hub cros_ec_ishtp cros_ec intel_ishtp_loader intel_ishtp_hid intel_rapl_msr nft_counter xt_mark ipt_REJECT nf_reject_ipv4 mei_hdcp intel_rapl_common xt_LOG nf_log_syslog intel_tcc_cooling x86_pkg_temp_thermal think_lmi wmi_bmof xt_addrtype firmware_attributes_class xt_tcpudp intel_powerclamp xt_conntrack nf_conntrack nf_defrag_ipv4 snd_hda_codec_hdmi nft_compat intel_wmi_thunderbolt nf_tables libcrc32c coretemp iwlmvm snd_ctl_led nfnetlink
 snd_hda_codec_conexant mac80211 snd_hda_codec_generic libarc4 vfat snd_hda_intel kvm_intel fat iwlwifi snd_intel_dspcfg rapl intel_cstate joydev snd_hda_codec mousedev intel_uncore snd_hwdep snd_hda_core psmouse snd_pcm snd_timer cfg80211 mei_me wacom ucsi_acpi typec_ucsi mei intel_pch_thermal intel_xhci_usb_role_switch intel_ish_ipc roles intel_ishtp typec wmi thinkpad_acpi ledtrig_audio platform_profile snd soundcore tpm_crb rfkill i2c_hid_acpi tpm_tis tpm_tis_core i2c_hid mac_hid acpi_pad pkcs8_key_parser fuse zram ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 usbhid dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core dm_mod rtsx_pci_sdmmc mmc_core serio_raw atkbd libps2 crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd rtsx_pci xhci_pci xhci_pci_renesas i8042 serio kvmgt mdev vfio_iommu_type1 vfio i915 i2c_algo_bit intel_gtt ttm agpgart video drm_kms_helper syscopyarea sysfillrect sysimgblt
 fb_sys_fops cec drm kvm irqbypass
CR2: 00000000000001e8
---[ end trace ff45ac39689f43c2 ]---
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff 0f 0b eb e7 66
RSP: 0018:ffffaa06c08bbe60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffff894ecb0c35a0 RCX: ffff894e25cdfcc0
RDX: ffff894e25cdfce0 RSI: ffffffffffffffff RDI: ffff894e25cdfcc0
RBP: ffff894ee393d380 R08: 0000000000000020 R09: ffff894ee393d5f0
R10: ffff894f617fd000 R11: 0000000000031678 R12: ffff894e25cdfcc0
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff894f59680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 0000000147a0e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
#8 lore raw
Quoted 13 lines · Eric W. Biederman
Quoted 8 lines · Jordan Glover
Quoted 4 lines · Jordan Glover

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

Heh, it jut happened again. This time closing firefox alone had such effect:

Ok. It looks like he have a couple of folks seeing issues here.

Quoted 7 lines

I thought we had all of the issues sorted out for the release of v5.14, but it looks like there is still some little bug left.

If Alex doesn't beat me to it I will see if I can come up with a debugging patch to make it easy to help track down where the reference
count is going wrong. It will be a little bit as my brain is mush at
the moment.

I'm poking it right now, but so far without much success.

The dec_ucount() happened free_user_ns(). There we only decrease the UCOUNT_USER_NAMESPACES in the user_ns tree. Perhaps somewhere someone forgot to do create_user_ns() ?

Quoted 77 lines

Eric

Quoted 74 lines
------------[ cut here ]------------
WARNING: CPU: 1 PID: 351 at kernel/ucount.c:253 dec_ucount+0x43/0x50
Modules linked in: nft_ct nft_fib_ipv4 nft_fib wireguard curve25519_x86_64 libcurve25519_generic libchacha20poly1305 chacha_x86_64 poly1305_x86_64 udp_tunnel libblake2s blake2s_x86_64 libblake2s_generic libchacha ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg hid_sensor_custom_intel_hinge hid_sensor_als hid_sensor_gyro_3d hid_sensor_accel_3d hid_sensor_rotation hid_sensor_magn_3d hid_sensor_trigger industrialio_triggered_buffer hid_sensor_iio_common kfifo_buf industrialio hid_sensor_custom hid_sensor_hub cros_ec_ishtp cros_ec intel_ishtp_loader intel_ishtp_hid intel_rapl_msr nft_counter xt_mark ipt_REJECT nf_reject_ipv4 mei_hdcp intel_rapl_common xt_LOG nf_log_syslog intel_tcc_cooling x86_pkg_temp_thermal think_lmi wmi_bmof xt_addrtype firmware_attributes_class xt_tcpudp intel_powerclamp xt_conntrack nf_conntrack nf_defrag_ipv4 snd_hda_codec_hdmi nft_compat intel_wmi_thunderbolt nf_tables libcrc32c coretemp iwlmvm snd_ctl_led nfnetlink
 snd_hda_codec_conexant mac80211 snd_hda_codec_generic libarc4 vfat snd_hda_intel kvm_intel fat iwlwifi snd_intel_dspcfg rapl intel_cstate joydev snd_hda_codec mousedev intel_uncore snd_hwdep snd_hda_core psmouse snd_pcm snd_timer cfg80211 mei_me wacom ucsi_acpi typec_ucsi mei intel_pch_thermal intel_xhci_usb_role_switch intel_ish_ipc roles intel_ishtp typec wmi thinkpad_acpi ledtrig_audio platform_profile snd soundcore tpm_crb rfkill i2c_hid_acpi tpm_tis tpm_tis_core i2c_hid mac_hid acpi_pad pkcs8_key_parser fuse zram ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 usbhid dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core dm_mod rtsx_pci_sdmmc mmc_core serio_raw atkbd libps2 crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd rtsx_pci xhci_pci xhci_pci_renesas i8042 serio kvmgt mdev vfio_iommu_type1 vfio i915 i2c_algo_bit intel_gtt ttm agpgart video drm_kms_helper syscopyarea sysfillrect sysimgblt
 fb_sys_fops cec drm kvm irqbypass
CPU: 1 PID: 351 Comm: kworker/1:3 Not tainted 5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x43/0x50
Code: 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 48 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff <0f> 0b eb e7 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 f8 48
RSP: 0018:ffffaa06c08bbe60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffff894ecb0c35a0 RCX: ffff894e25cdfcc0
RDX: ffff894e25cdfce0 RSI: ffffffffffffffff RDI: ffff894e25cdfcc0
RBP: ffff894ee393d380 R08: 0000000000000020 R09: ffff894ee393d5f0
R10: ffff894f617fd000 R11: 0000000000031678 R12: ffff894e25cdfcc0
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff894f59680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000056ffceff6b10 CR3: 0000000147a0e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
---[ end trace ff45ac39689f43c1 ]---
BUG: kernel NULL pointer dereference, address: 00000000000001e8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
Oops: 0000 [#1] SMP PTI
CPU: 1 PID: 351 Comm: kworker/1:3 Tainted: G        W         5.14.3 #1 c719caf0c6c208968387ed83e3061ac05d0faf2f
Workqueue: events free_user_ns
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff 0f 0b eb e7 66
RSP: 0018:ffffaa06c08bbe60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffff894ecb0c35a0 RCX: ffff894e25cdfcc0
RDX: ffff894e25cdfce0 RSI: ffffffffffffffff RDI: ffff894e25cdfcc0
RBP: ffff894ee393d380 R08: 0000000000000020 R09: ffff894ee393d5f0
R10: ffff894f617fd000 R11: 0000000000031678 R12: ffff894e25cdfcc0
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff894f59680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 0000000147a0e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 free_user_ns+0x73/0x110
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
Modules linked in: nft_ct nft_fib_ipv4 nft_fib wireguard curve25519_x86_64 libcurve25519_generic libchacha20poly1305 chacha_x86_64 poly1305_x86_64 udp_tunnel libblake2s blake2s_x86_64 libblake2s_generic libchacha ccm algif_aead des_generic libdes ecb algif_skcipher cmac md4 algif_hash af_alg hid_sensor_custom_intel_hinge hid_sensor_als hid_sensor_gyro_3d hid_sensor_accel_3d hid_sensor_rotation hid_sensor_magn_3d hid_sensor_trigger industrialio_triggered_buffer hid_sensor_iio_common kfifo_buf industrialio hid_sensor_custom hid_sensor_hub cros_ec_ishtp cros_ec intel_ishtp_loader intel_ishtp_hid intel_rapl_msr nft_counter xt_mark ipt_REJECT nf_reject_ipv4 mei_hdcp intel_rapl_common xt_LOG nf_log_syslog intel_tcc_cooling x86_pkg_temp_thermal think_lmi wmi_bmof xt_addrtype firmware_attributes_class xt_tcpudp intel_powerclamp xt_conntrack nf_conntrack nf_defrag_ipv4 snd_hda_codec_hdmi nft_compat intel_wmi_thunderbolt nf_tables libcrc32c coretemp iwlmvm snd_ctl_led nfnetlink
 snd_hda_codec_conexant mac80211 snd_hda_codec_generic libarc4 vfat snd_hda_intel kvm_intel fat iwlwifi snd_intel_dspcfg rapl intel_cstate joydev snd_hda_codec mousedev intel_uncore snd_hwdep snd_hda_core psmouse snd_pcm snd_timer cfg80211 mei_me wacom ucsi_acpi typec_ucsi mei intel_pch_thermal intel_xhci_usb_role_switch intel_ish_ipc roles intel_ishtp typec wmi thinkpad_acpi ledtrig_audio platform_profile snd soundcore tpm_crb rfkill i2c_hid_acpi tpm_tis tpm_tis_core i2c_hid mac_hid acpi_pad pkcs8_key_parser fuse zram ip_tables x_tables ext4 crc32c_generic crc16 mbcache jbd2 usbhid dm_crypt cbc encrypted_keys trusted asn1_encoder tee tpm rng_core dm_mod rtsx_pci_sdmmc mmc_core serio_raw atkbd libps2 crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel crypto_simd cryptd rtsx_pci xhci_pci xhci_pci_renesas i8042 serio kvmgt mdev vfio_iommu_type1 vfio i915 i2c_algo_bit intel_gtt ttm agpgart video drm_kms_helper syscopyarea sysfillrect sysimgblt
 fb_sys_fops cec drm kvm irqbypass
CR2: 00000000000001e8
---[ end trace ff45ac39689f43c2 ]---
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 0d fd ff ff 0f 0b eb e7 66
RSP: 0018:ffffaa06c08bbe60 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffff894ecb0c35a0 RCX: ffff894e25cdfcc0
RDX: ffff894e25cdfce0 RSI: ffffffffffffffff RDI: ffff894e25cdfcc0
RBP: ffff894ee393d380 R08: 0000000000000020 R09: ffff894ee393d5f0
R10: ffff894f617fd000 R11: 0000000000031678 R12: ffff894e25cdfcc0
R13: 00000000ffffffff R14: 0000000000000000 R15: 0000000000000001
FS:  0000000000000000(0000) GS:ffff894f59680000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 0000000147a0e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Signature · 1 line
Rgrds, legion
#9 lore raw
In reply to Eric W. Biederman
Quoted 15 lines · On Thursday, September 16th, 2021 at 5:30 PM, <[email protected]> wrote:
Quoted 8 lines · Jordan Glover [email protected] writes:
Quoted 3 lines · On Wednesday, September 15th, 2021 at 10:42 PM, Jordan Glover…

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

Heh, it jut happened again. This time closing firefox alone had such effect:

Ok. It looks like he have a couple of folks seeing issues here. I thought we had all of the issues sorted out for the release of v5.14, but it looks like there is still some little bug left.

Quoted 6 lines

If Alex doesn't beat me to it I will see if I can come up with a debugging patch to make it easy to help track down where the reference count is going wrong. It will be a little bit as my brain is mush at the moment.

Eric

As the issue persist in 5.14.7 I would be very interested in such patch.

For now the thing is mostly reproducible when I close several tabs in ff then close the browser in short period of time. When I close tabs then wait out a bit then close the browser it doesn't happen so I guess some interrupted cleanup triggers it.

Jordan

#10 lore raw
Quoted 22 lines · Jordan Glover
Quoted 20 lines · On Thursday, September 16th, 2021 at 5:30 PM, <[email protected]> wrote:
Quoted 8 lines · Jordan Glover [email protected] writes:
Quoted 3 lines · On Wednesday, September 15th, 2021 at 10:42 PM, Jordan Glover…

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

Heh, it jut happened again. This time closing firefox alone had such effect:

Ok. It looks like he have a couple of folks seeing issues here. I thought we had all of the issues sorted out for the release of v5.14, but it looks like there is still some little bug left.

If Alex doesn't beat me to it I will see if I can come up with a debugging patch to make it easy to help track down where the reference count is going wrong. It will be a little bit as my brain is mush at the moment.

Quoted 8 lines
Quoted 1 line

Eric

As the issue persist in 5.14.7 I would be very interested in such patch.

For now the thing is mostly reproducible when I close several tabs in ff then close the browser in short period of time. When I close tabs then wait out a bit then close the browser it doesn't happen so I guess some interrupted cleanup triggers it.

I'm still investigating, but I would like to rule out one option. Could you check out the patch?

kernel/ucount.c +4 -1
index bb51849e6375..f23f906f4f62 100644
@@ -201,11 +201,14 @@ void put_ucounts(struct ucounts *ucounts)
 {
        unsigned long flags;
 
-       if (atomic_dec_and_lock_irqsave(&ucounts->count, &ucounts_lock, flags)) {
+       spin_lock_irqsave(&ucounts_lock, flags);
+       if (atomic_dec_and_test(&ucounts->count)) {
                hlist_del_init(&ucounts->node);
                spin_unlock_irqrestore(&ucounts_lock, flags);
                kfree(ucounts);
+               return;
        }
+       spin_unlock_irqrestore(&ucounts_lock, flags);
 }
 
 static inline bool atomic_long_inc_below(atomic_long_t *v, int u)
Signature · 1 line
Rgrds, legion
#11 lore raw
Quoted 38 lines · Alexey Gladkov
Quoted 36 lines · Jordan Glover
Quoted 20 lines · On Thursday, September 16th, 2021 at 5:30 PM, [email protected] wrote:
Quoted 9 lines · Jordan Glover [email protected] writes:
Quoted 3 lines · On Wednesday, September 15th, 2021 at 10:42 PM, Jordan Glover…

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

Heh, it jut happened again. This time closing firefox alone had such

effect:

Ok. It looks like he have a couple of folks seeing issues here.

I thought we had all of the issues sorted out for the release of v5.14,

but it looks like there is still some little bug left.

If Alex doesn't beat me to it I will see if I can come up with a

Quoted 7 lines

debugging patch to make it easy to help track down where the reference

count is going wrong. It will be a little bit as my brain is mush at

the moment.

Eric

As the issue persist in 5.14.7 I would be very interested in such patch.

For now the thing is mostly reproducible when I close several tabs in ff then

close the browser in short period of time. When I close tabs then wait out

Quoted 7 lines
Quoted 3 lines

a bit then close the browser it doesn't happen so I guess some interrupted

cleanup triggers it.

I'm still investigating, but I would like to rule out one option.

Could you check out the patch?

Thx, I added it to my kernel and will report in few days. Does this patch try to fix the issue or make it easier to track?

Jordan

Quoted 44 lines
kernel/ucount.c +0 -0

index bb51849e6375..f23f906f4f62 100644

--- a/kernel/ucount.c

+++ b/kernel/ucount.c

kernel/ucount.c +0 -5
@@ -201,11 +201,14 @@ void put_ucounts(struct ucounts *ucounts)
 
 {
 
 unsigned long flags;
 
-         if (atomic_dec_and_lock_irqsave(&ucounts->count, &ucounts_lock, flags)) {
 
 
 
-         spin_lock_irqsave(&ucounts_lock, flags);
 
 
-         if (atomic_dec_and_test(&ucounts->count)) {
 
                  hlist_del_init(&ucounts->node);
 
                  spin_unlock_irqrestore(&ucounts_lock, flags);
                  kfree(ucounts);
 
 
-                 return;
          }
 
 
-         spin_unlock_irqrestore(&ucounts_lock, flags);

}

static inline bool atomic_long_inc_below(atomic_long_t *v, int u)

---------------------------------------------------------------------

Rgrds, legion

#12 lore raw
Quoted 7 lines · Jordan Glover
Quoted 3 lines

I'm still investigating, but I would like to rule out one option.

Could you check out the patch?

Thx, I added it to my kernel and will report in few days. Does this patch try to fix the issue or make it easier to track?

I suspect the error is caused by a race between allow_ucounts() and put_ucounts(). I think this patch could solve the problem.

Signature · 1 line
Rgrds, legion
#13 lore raw
Quoted 4 lines · Alexey Gladkov
Quoted 2 lines · Jordan Glover
Quoted 2 lines

I'm still investigating, but I would like to rule out one option.

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Could you check out the patch?

Thx, I added it to my kernel and will report in few days. Does this patch try to fix the issue or make it easier to track?

I suspect the error is caused by a race between allow_ucounts() and put_ucounts(). I think this patch could solve the problem.

Thanks for your help. Still can reproduce the problem with the change suggested.

[ 7761.885966] ==================================================================
[ 7761.893462] BUG: KASAN: use-after-free in dec_ucount+0x50/0xd8
[ 7761.899491] Write of size 8 at addr ffffff80c537b140 by task
kworker/u16:3/10303
[ 7761.907110]
[ 7761.908668] CPU: 0 PID: 10303 Comm: kworker/u16:3 Not tainted
5.14.0-lockdep+ #1
[ 7761.916289] Hardware name: Google Lazor (rev3+) with KB Backlight (DT)
[ 7761.923021] Workqueue: netns cleanup_net
[ 7761.927106] Call trace:
[ 7761.929648]  dump_backtrace+0x0/0x42c
[ 7761.933442]  show_stack+0x24/0x30
[ 7761.936878]  dump_stack_lvl+0xd0/0x100
[ 7761.940763]  print_address_description+0x30/0x304
[ 7761.945628]  kasan_report+0x190/0x1d8
[ 7761.949418]  kasan_check_range+0x1ac/0x1bc
[ 7761.953655]  __kasan_check_write+0x44/0x54
[ 7761.957891]  dec_ucount+0x50/0xd8
[ 7761.961334]  cleanup_net+0x630/0x718
[ 7761.965036]  process_one_work+0x7b4/0x10ec
[ 7761.969274]  worker_thread+0x800/0xcf4
[ 7761.973152]  kthread+0x2a8/0x358
[ 7761.976496]  ret_from_fork+0x10/0x18
[ 7761.980201]
[ 7761.981761] Allocated by task 4840:
[ 7761.985366]  kasan_save_stack+0x38/0x68
[ 7761.989342]  __kasan_kmalloc+0x9c/0xb8
[ 7761.993222]  kmem_cache_alloc_trace+0x2a4/0x370
[ 7761.997905]  alloc_ucounts+0x150/0x374
[ 7762.001787]  set_cred_ucounts+0x198/0x248
[ 7762.005935]  __sys_setresuid+0x31c/0x4f8
[ 7762.009993]  __arm64_sys_setresuid+0x84/0x98
[ 7762.014410]  invoke_syscall+0xd4/0x2c8
[ 7762.018292]  el0_svc_common+0x124/0x200
[ 7762.022265]  do_el0_svc_compat+0x54/0x64
[ 7762.026325]  el0_svc_compat+0x24/0x34
[ 7762.030124]  el0t_32_sync_handler+0xc0/0xf0
[ 7762.034451]  el0t_32_sync+0x19c/0x1a0
[ 7762.038241]
[ 7762.039799] Freed by task 0:
[ 7762.042778]  kasan_save_stack+0x38/0x68
[ 7762.046747]  kasan_set_track+0x28/0x3c
[ 7762.050625]  kasan_set_free_info+0x28/0x4c
[ 7762.054857]  ____kasan_slab_free+0x118/0x164
[ 7762.059277]  __kasan_slab_free+0x18/0x28
[ 7762.063339]  kfree+0x2f8/0x500
[ 7762.066505]  put_ucounts+0x11c/0x134
[ 7762.070209]  put_cred_rcu+0x1bc/0x35c
[ 7762.074006]  rcu_core+0xa68/0x1b20
[ 7762.077538]  rcu_core_si+0x1c/0x28
[ 7762.081061]  __do_softirq+0x4bc/0xedc
[ 7762.084851]
[ 7762.086401] The buggy address belongs to the object at ffffff80c537b100
[ 7762.086401]  which belongs to the cache kmalloc-256 of size 256
[ 7762.099267] The buggy address is located 64 bytes inside of
[ 7762.099267]  256-byte region [ffffff80c537b100, ffffff80c537b200)
[ 7762.111248] The buggy address belongs to the page:
[ 7762.116185] page:fffffffe0314de00 refcount:1 mapcount:0
mapping:0000000000000000 index:0xffffff80c537ad00 pfn:0x145378
[ 7762.127180] head:fffffffe0314de00 order:3 compound_mapcount:0
compound_pincount:0
[ 7762.134881] flags: 0x8000000000010200(slab|head|zone=2)
[ 7762.140286] raw: 8000000000010200 fffffffe02799408 fffffffe02020808
ffffff808000c980
[ 7762.148263] raw: ffffff80c537ad00 0000000000200004 00000001ffffffff
0000000000000000
[ 7762.156228] page dumped because: kasan: bad access detected
[ 7762.161974]
[ 7762.163532] Memory state around the buggy address:
[ 7762.168475]  ffffff80c537b000: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7762.175915]  ffffff80c537b080: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7762.183346] >ffffff80c537b100: fa fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7762.190774]                                            ^
[ 7762.196258]  ffffff80c537b180: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7762.203689]  ffffff80c537b200: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7762.211125] ==================================================================
#14 lore raw

Adding Rune Kleveland to the discussion as he also seems to have reproduced the issue.

Alex and I have been starring at the code and the reports and this bug is hiding well. Here is what we have figured out so far.

Both the warning from free_user_ns calling dec_ucount that Jordan Glover reported and the KASAN error that Yu Zhao has reported appear to have the same cause. Using a ucounts structure after it has been freed and reallocated as something else.

I have just skimmed through the recent report from Rune Kleveland and it appears also to be a use after free. Especially since the second failure in the log is slub complaining about trying to free the ucounts data structure.

We looked through the users of put_ucounts and we don't see any obvious buggy users that would be freeing the data structure early.

Alex has tried to reproduce this so far is not having any luck. Folks can you tell what compiler versions you are using and share your kernel config with us? That might help.

The little debug diff below is my guess of what is happening. If the folks who can reproduce this issue can try the patch below and let me know if the warnings fire that would be appreciated. It is still not enough to track down the bug but at least it will confirm my current hypothesis about how things look before there is a use of memory after it is freed.

Thank you,
Eric

kernel/cred.c +6 -0
index f784e08c2fbd..e7ffaa3cf5a6 100644
@@ -120,6 +120,12 @@ static void put_cred_rcu(struct rcu_head *rcu)
 	if (cred->group_info)
 		put_group_info(cred->group_info);
 	free_uid(cred->user);
+#if 1
+	if ((cred->ucounts == cred->user_ns->ucounts) &&
+	    (atomic_read(&cred->ucounts->count) == 1)) {
+		WARN_ONCE(1, "put_cred_rcu: ucount count 1\n");
+	}
+#endif
 	if (cred->ucounts)
 		put_ucounts(cred->ucounts);
 	put_user_ns(cred->user_ns);
kernel/exit.c +7 -0
index 91a43e57a32e..60fd88b34c1a 100644
@@ -743,6 +743,13 @@ void __noreturn do_exit(long code)
 	if (unlikely(!tsk->pid))
 		panic("Attempted to kill the idle task!");
 
+#if 1
+	if ((tsk->cred->ucounts == tsk->cred->user_ns->ucounts) &&
+	    (atomic_read(tsk->cred->ucounts->count) == 1)) {
+		WARN_ONCE(1, "do_exit: ucount count 1\n");
+	}
+#endif
+
 	/*
 	 * If do_exit is called because this processes oopsed, it's possible
 	 * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
#15 lore raw
Quoted 23 lines · [email protected] (Eric W. Biederman) writes:

Adding Rune Kleveland to the discussion as he also seems to have reproduced the issue.

Alex and I have been starring at the code and the reports and this bug is hiding well. Here is what we have figured out so far.

Both the warning from free_user_ns calling dec_ucount that Jordan Glover reported and the KASAN error that Yu Zhao has reported appear to have the same cause. Using a ucounts structure after it has been freed and reallocated as something else.

I have just skimmed through the recent report from Rune Kleveland and it appears also to be a use after free. Especially since the second failure in the log is slub complaining about trying to free the ucounts data structure.

We looked through the users of put_ucounts and we don't see any obvious buggy users that would be freeing the data structure early.

Alex has tried to reproduce this so far is not having any luck. Folks can you tell what compiler versions you are using and share your kernel config with us? That might help.

Quoted 6 lines

The little debug diff below is my guess of what is happening. If the folks who can reproduce this issue can try the patch below and let me know if the warnings fire that would be appreciated. It is still not enough to track down the bug but at least it will confirm my current hypothesis about how things look before there is a use of memory after it is freed.

Bah. Scratch that test patch. I just double checked myself and cred->ucounts and cred->user_ns->ucounts should never be equal, as the user namespace is counted in it's parent user namespace.

That observation now tells me I have a parent user namespace that went corrupt.

Back to the drawing board.

Quoted 38 lines

Thank you,
Eric

kernel/cred.c +6 -0
index f784e08c2fbd..e7ffaa3cf5a6 100644
@@ -120,6 +120,12 @@ static void put_cred_rcu(struct rcu_head *rcu)
 	if (cred->group_info)
 		put_group_info(cred->group_info);
 	free_uid(cred->user);
+#if 1
+	if ((cred->ucounts == cred->user_ns->ucounts) &&
+	    (atomic_read(&cred->ucounts->count) == 1)) {
+		WARN_ONCE(1, "put_cred_rcu: ucount count 1\n");
+	}
+#endif
 	if (cred->ucounts)
 		put_ucounts(cred->ucounts);
 	put_user_ns(cred->user_ns);
kernel/exit.c +7 -0
index 91a43e57a32e..60fd88b34c1a 100644
@@ -743,6 +743,13 @@ void __noreturn do_exit(long code)
 	if (unlikely(!tsk->pid))
 		panic("Attempted to kill the idle task!");
 
+#if 1
+	if ((tsk->cred->ucounts == tsk->cred->user_ns->ucounts) &&
+	    (atomic_read(tsk->cred->ucounts->count) == 1)) {
+		WARN_ONCE(1, "do_exit: ucount count 1\n");
+	}
+#endif
+
 	/*
 	 * If do_exit is called because this processes oopsed, it's possible
 	 * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
#16 lore raw
Quoted 19 lines · Eric W. Biederman
Quoted 16 lines · [email protected] (Eric W. Biederman) writes:

Adding Rune Kleveland to the discussion as he also seems to have reproduced the issue.

Alex and I have been starring at the code and the reports and this bug is hiding well. Here is what we have figured out so far.

Both the warning from free_user_ns calling dec_ucount that Jordan Glover reported and the KASAN error that Yu Zhao has reported appear to have the same cause. Using a ucounts structure after it has been freed and reallocated as something else.

I have just skimmed through the recent report from Rune Kleveland and it appears also to be a use after free. Especially since the second failure in the log is slub complaining about trying to free the ucounts data structure.

Quoted 6 lines
Quoted 6 lines

We looked through the users of put_ucounts and we don't see any obvious buggy users that would be freeing the data structure early.

Alex has tried to reproduce this so far is not having any luck. Folks can you tell what compiler versions you are using and share your kernel config with us? That might help.

Thanks. Per your request:

$ aarch64-cros-linux-gnu-clang -v
Chromium OS 12.0_pre422132_p20210405-r9 clang version 13.0.0
(/var/tmp/portage/sys-devel/llvm-12.0_pre422132_p20210405-r9/work/llvm-12.0_pre422132_p20210405/clang
cd442157cff4aad209ae532cbf031abbe10bc1df)
Target: aarch64-cros-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation:
/usr/bin/../lib/gcc/aarch64-cros-linux-gnu/10.2.0
Found candidate GCC installation:
/usr/bin/../lib64/gcc/aarch64-cros-linux-gnu/10.2.0
Selected GCC installation: /usr/bin/../lib64/gcc/aarch64-cros-linux-gnu/10.2.0
Candidate multilib: .;@m64
Selected multilib: .;@m64

Kernel config attached.

#17 lore raw
In reply to Eric W. Biederman

Hi!

Thank you for all your efforts with this issue!

I am using the stock Fedora 34 kernel. The failures happen quite frequently. It varies from an hour to a couple of days before the hang, and it appens on all the IBM blades and less frequently on HP DL380 G7.

The servers run selenimm-controlled Google Chrome compiled by Google, and that produces some traps. They It's quite high load on them.

Here is a new trace looking a bit different. Maybe some clues in there?

Oct 06 08:12:17.709377 kant4.opoint.com kernel: BUG: kernel NULL pointer dereference, address: 0000000000000251
Oct 06 08:12:17.709641 kant4.opoint.com kernel: #PF: supervisor read access in kernel mode
Oct 06 08:12:17.889197 kant4.opoint.com kernel: #PF: error_code(0x0000) - not-present page
Oct 06 08:12:17.967596 kant4.opoint.com kernel: PGD 0 P4D 0
Oct 06 08:12:18.051776 kant4.opoint.com kernel: Oops: 0000 [#1] SMP PTI
Oct 06 08:12:18.051895 kant4.opoint.com kernel: CPU: 9 PID: 3337825 Comm: chrome Not tainted 5.14.9-200.fc34.x86_64 #1
Oct 06 08:12:18.051962 kant4.opoint.com kernel: Hardware name: IBM BladeCenter HS22 -[7870TKN]-/68Y8163, BIOS -[P9E164CUS-1.28]- 04/17/2018
Oct 06 08:12:18.052022 kant4.opoint.com kernel: RIP: 0010:is_ucounts_overlimit+0x42/0x60
Oct 06 08:12:18.052080 kant4.opoint.com kernel: Code: 8d 14 07 48 8b 0a 4c 39 c9 77 30 48 85 ff 74 2c 48 83 c6 3e eb 10 48 8b b8 e8 01 00 00 48 85 ff 74 1a 4a 8d 14 07 48 8b 47 10 <48> 8b 0c f0 48 8b 12 48 39 ca 76 e0 b8 01 00 00 00 c3 3>
Oct 06 08:12:18.052154 kant4.opoint.com kernel: RSP: 0018:ffffb8118f9ffdc8 EFLAGS: 00010212
Oct 06 08:12:18.052227 kant4.opoint.com kernel: RAX: 0000000000000001 RBX: ffff994b86f77bc0 RCX: 0000000000000000
Oct 06 08:12:18.052344 kant4.opoint.com kernel: RDX: ffff994b86f77c40 RSI: 000000000000004a RDI: ffff994b86f77bc0
Oct 06 08:12:18.052452 kant4.opoint.com kernel: RBP: ffffb8118f9ffe60 R08: 0000000000000080 R09: 0000000000075f6b
Oct 06 08:12:18.052523 kant4.opoint.com kernel: R10: 00007f2bacbb3910 R11: 0000000000000000 R12: ffffb8118f9ffed0
Oct 06 08:12:18.052613 kant4.opoint.com kernel: R13: 0000000000000000 R14: 00000000003d0f00 R15: ffff995f0d0e8000
Oct 06 08:12:18.052701 kant4.opoint.com kernel: FS: 00007f2bc6c01d80(0000) GS:ffff99689fac0000(0000) knlGS:0000000000000000
Oct 06 08:12:18.052774 kant4.opoint.com kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Oct 06 08:12:18.052850 kant4.opoint.com kernel: CR2: 0000000000000251 CR3: 0000000a98dae005 CR4: 00000000000206e0
Oct 06 08:12:18.052923 kant4.opoint.com kernel: Call Trace:
Oct 06 08:12:18.052989 kant4.opoint.com kernel: copy_process+0x444/0x1c20
Oct 06 08:12:18.053116 kant4.opoint.com kernel: kernel_clone+0x87/0x380
Oct 06 08:12:18.053185 kant4.opoint.com kernel: __do_sys_clone+0x52/0x60
Oct 06 08:12:18.053251 kant4.opoint.com kernel: do_syscall_64+0x3b/0x90
Oct 06 08:12:18.053366 kant4.opoint.com kernel: entry_SYSCALL_64_after_hwframe+0x44/0xae
Oct 06 08:12:18.053450 kant4.opoint.com kernel: RIP: 0033:0x7f2bc8288345
Oct 06 08:12:18.053536 kant4.opoint.com kernel: Code: 48 85 ff 74 3d 48 85 f6 74 38 48 83 ee 10 48 89 4e 08 48 89 3e 48 89 d7 4c 89 c2 4d 89 c8 4c 8b 54 24 08 b8 38 00 00 00 0f 05 <48> 85 c0 7c 13 74 01 c3 31 ed 58 5f ff d0 48 89 c7 b8 3>
Oct 06 08:12:18.053640 kant4.opoint.com kernel: RSP: 002b:00007ffc07a6d8e8 EFLAGS: 00000202 ORIG_RAX: 0000000000000038
Oct 06 08:12:18.053743 kant4.opoint.com kernel: RAX: ffffffffffffffda RBX: 00007f2bacbb3640 RCX: 00007f2bc8288345
Oct 06 08:12:18.053888 kant4.opoint.com kernel: RDX: 00007f2bacbb3910 RSI: 00007f2bacbb28b0 RDI: 00000000003d0f00
Oct 05 16:08:07.573709 kant4.opoint.com kernel: traps: chrome[1578552] trap invalid opcode ip:557906685910 sp:7ffcbd31bde0 error:0 in chrome[55790650a000+857b000]
Oct 05 16:53:44.208521 kant4.opoint.com kernel: traps: chrome[1849193] trap invalid opcode ip:55c1a0bb7910 sp:7ffd510ac860 error:0 in chrome[55c1a0a3c000+857b000]
Oct 05 17:25:37.631729 kant4.opoint.com kernel: traps: chrome[2023334] trap invalid opcode ip:55dea0728910 sp:7ffefcec5300 error:0 in chrome[55dea05ad000+857b000]
Oct 05 20:21:30.226448 kant4.opoint.com kernel: traps: chrome[3288200] trap invalid opcode ip:55d913483b9f sp:7ffcedbf57f0 error:0 in chrome[55d90ea9a000+857b000]
Oct 05 21:21:12.211391 kant4.opoint.com kernel: traps: chrome[3659878] trap invalid opcode ip:56503e2a0910 sp:7ffca7949460 error:0 in chrome[56503e125000+857b000]
Oct 05 22:16:34.325471 kant4.opoint.com kernel: traps: chrome[3954333] trap invalid opcode ip:55ac2f16b910 sp:7fffd3621fe0 error:0 in chrome[55ac2eff0000+857b000]
Oct 05 22:52:28.831375 kant4.opoint.com kernel: traps: chrome[4165973] trap invalid opcode ip:55bb31ccc910 sp:7fff26662d80 error:0 in chrome[55bb31b51000+857b000]
Oct 06 08:02:07.417376 kant4.opoint.com kernel: getlink4[3251694]: segfault at 0 ip 00007f2bdbabc0c0 sp 00007fffff169a38 error 4 in libc-2.33.so[7f2bdb98b000+14d000]
Oct 06 08:02:07.417455 kant4.opoint.com kernel: Code: d2 0f 84 b7 0f 00 00 48 83 fa 01 0f 84 b9 0f 00 00 49 89 d3 89 f1 89 f8 48 83 e1 3f 48 83 e0 3f 83 f9 30 77 45 83 f8 30 77 40 <f3> 0f 6f 0f f3 0f 6f 16 66 0f ef c0 66 0f 74 c1 66 0f 7>
Oct 06 08:07:31.375414 kant4.opoint.com kernel: getlink8[3251723]: segfault at 0 ip 00007fb8ee8de0c0 sp 00007ffe9eae5898 error 4 in libc-2.33.so[7fb8ee7ad000+14d000]
Oct 06 08:07:31.375744 kant4.opoint.com kernel: Code: d2 0f 84 b7 0f 00 00 48 83 fa 01 0f 84 b9 0f 00 00 49 89 d3 89 f1 89 f8 48 83 e1 3f 48 83 e0 3f 83 f9 30 77 45 83 f8 30 77 40 <f3> 0f 6f 0f f3 0f 6f 16 66 0f ef c0 66 0f 74 c1 66 0f 7>
Oct 06 08:11:44.148749 kant4.opoint.com kernel: getlink8[3310785]: segfault at 0 ip 00007f30262810c0 sp 00007ffd8d263db8 error 4 in libc-2.33.so[7f3026150000+14d000]
Oct 06 08:11:44.148859 kant4.opoint.com kernel: Code: d2 0f 84 b7 0f 00 00 48 83 fa 01 0f 84 b9 0f 00 00 49 89 d3 89 f1 89 f8 48 83 e1 3f 48 83 e0 3f 83 f9 30 77 45 83 f8 30 77 40 <f3> 0f 6f 0f f3 0f 6f 16 66 0f ef c0 66 0f 74 c1 66 0f 7>
Oct 06 08:12:17.709377 kant4.opoint.com kernel: BUG: kernel NULL pointer dereference, address: 0000000000000251
Oct 06 08:11:44.148749 kant4.opoint.com kernel: getlink8[3310785]: segfault at 0 ip 00007f30262810c0 sp 00007ffd8d263db8 error 4 in libc-2.33.so[7f3026150000+14d000]
Oct 06 08:11:44.148859 kant4.opoint.com kernel: Code: d2 0f 84 b7 0f 00 00 48 83 fa 01 0f 84 b9 0f 00 00 49 89 d3 89 f1 89 f8 48 83 e1 3f 48 83 e0 3f 83 f9 30 77 45 83 f8 30 77 40 <f3> 0f 6f 0f f3 0f 6f 16 66 0f ef c0 66 0f 74 c1 66 0f 7>
Oct 06 08:11:44.148749 kant4.opoint.com kernel: getlink8[3310785]: segfault at 0 ip 00007f30262810c0 sp 00007ffd8d263db8 error 4 in libc-2.33.so[7f3026150000+14d000]
Oct 06 08:11:44.148859 kant4.opoint.com kernel: Code: d2 0f 84 b7 0f 00 00 48 83 fa 01 0f 84 b9 0f 00 00 49 89 d3 89 f1 89 f8 48 83 e1 3f 48 83 e0 3f 83 f9 30 77 45 83 f8 30 77 40 <f3> 0f 6f 0f f3 0f 6f 16 66 0f ef c0 66 0f 74 c1 66 0f 7>
Oct 06 08:12:17.709377 kant4.opoint.com kernel: BUG: kernel NULL pointer dereference, address: 0000000000000251
Oct 06 08:12:17.709641 kant4.opoint.com kernel: #PF: supervisor read access in kernel mode
Oct 06 08:12:17.889197 kant4.opoint.com kernel: #PF: error_code(0x0000) - not-present page
Oct 06 08:12:17.967596 kant4.opoint.com kernel: PGD 0 P4D 0
Oct 06 08:12:18.051776 kant4.opoint.com kernel: Oops: 0000 [#1] SMP PTI
Oct 06 08:12:18.051895 kant4.opoint.com kernel: CPU: 9 PID: 3337825 Comm: chrome Not tainted 5.14.9-200.fc34.x86_64 #1
Oct 06 08:12:18.051962 kant4.opoint.com kernel: Hardware name: IBM BladeCenter HS22 -[7870TKN]-/68Y8163, BIOS -[P9E164CUS-1.28]- 04/17/2018
Oct 06 08:12:18.052022 kant4.opoint.com kernel: RIP: 0010:is_ucounts_overlimit+0x42/0x60
Oct 06 08:12:18.052080 kant4.opoint.com kernel: Code: 8d 14 07 48 8b 0a 4c 39 c9 77 30 48 85 ff 74 2c 48 83 c6 3e eb 10 48 8b b8 e8 01 00 00 48 85 ff 74 1a 4a 8d 14 07 48 8b 47 10 <48> 8b 0c f0 48 8b 12 48 39 ca 76 e0 b8 01 00 00 00 c3 3>
Oct 06 08:12:18.052154 kant4.opoint.com kernel: RSP: 0018:ffffb8118f9ffdc8 EFLAGS: 00010212
Oct 06 08:12:18.052227 kant4.opoint.com kernel: RAX: 0000000000000001 RBX: ffff994b86f77bc0 RCX: 0000000000000000
Oct 06 08:12:18.052344 kant4.opoint.com kernel: RDX: ffff994b86f77c40 RSI: 000000000000004a RDI: ffff994b86f77bc0
Oct 06 08:12:18.052452 kant4.opoint.com kernel: RBP: ffffb8118f9ffe60 R08: 0000000000000080 R09: 0000000000075f6b
Oct 06 08:12:18.052523 kant4.opoint.com kernel: R10: 00007f2bacbb3910 R11: 0000000000000000 R12: ffffb8118f9ffed0
Oct 06 08:12:18.052613 kant4.opoint.com kernel: R13: 0000000000000000 R14: 00000000003d0f00 R15: ffff995f0d0e8000
Oct 06 08:12:18.052701 kant4.opoint.com kernel: FS: 00007f2bc6c01d80(0000) GS:ffff99689fac0000(0000) knlGS:0000000000000000
Oct 06 08:12:18.052774 kant4.opoint.com kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Oct 06 08:12:18.052850 kant4.opoint.com kernel: CR2: 0000000000000251 CR3: 0000000a98dae005 CR4: 00000000000206e0
Oct 06 08:12:18.052923 kant4.opoint.com kernel: Call Trace:
Oct 06 08:12:18.052989 kant4.opoint.com kernel: copy_process+0x444/0x1c20
Oct 06 08:12:18.053116 kant4.opoint.com kernel: kernel_clone+0x87/0x380
Oct 06 08:12:18.053185 kant4.opoint.com kernel: __do_sys_clone+0x52/0x60
Oct 06 08:12:18.053251 kant4.opoint.com kernel: do_syscall_64+0x3b/0x90
Oct 06 08:12:18.053366 kant4.opoint.com kernel: entry_SYSCALL_64_after_hwframe+0x44/0xae
Oct 06 08:12:18.053450 kant4.opoint.com kernel: RIP: 0033:0x7f2bc8288345
Oct 06 08:12:18.053536 kant4.opoint.com kernel: Code: 48 85 ff 74 3d 48 85 f6 74 38 48 83 ee 10 48 89 4e 08 48 89 3e 48 89 d7 4c 89 c2 4d 89 c8 4c 8b 54 24 08 b8 38 00 00 00 0f 05 <48> 85 c0 7c 13 74 01 c3 31 ed 58 5f ff d0 48 89 c7 b8 3>
Oct 06 08:12:18.053640 kant4.opoint.com kernel: RSP: 002b:00007ffc07a6d8e8 EFLAGS: 00000202 ORIG_RAX: 0000000000000038
Oct 06 08:12:18.053743 kant4.opoint.com kernel: RAX: ffffffffffffffda RBX: 00007f2bacbb3640 RCX: 00007f2bc8288345
Oct 06 08:12:18.053888 kant4.opoint.com kernel: RDX: 00007f2bacbb3910 RSI: 00007f2bacbb28b0 RDI: 00000000003d0f00
Oct 06 08:12:18.053955 kant4.opoint.com kernel: RBP: 00007ffc07a6dc10 R08: 00007f2bacbb3640 R09: 00007f2bacbb3640
Oct 06 08:12:18.054025 kant4.opoint.com kernel: R10: 00007f2bacbb3910 R11: 0000000000000202 R12: 00007ffc07a6d9ae
Oct 06 08:12:18.054091 kant4.opoint.com kernel: R13: 00007ffc07a6d9af R14: 0000000000000000 R15: 00007f2bacbb3640
Oct 06 08:12:18.054162 kant4.opoint.com kernel: Modules linked in: binfmt_misc rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace sunrpc fscache netfs nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_i>
Oct 06 08:12:18.054308 kant4.opoint.com kernel: CR2: 0000000000000251
Oct 06 08:12:18.054386 kant4.opoint.com kernel: ---[ end trace 08aecc7d786b859c ]---
Oct 06 08:12:18.054450 kant4.opoint.com kernel: RIP: 0010:is_ucounts_overlimit+0x42/0x60
Oct 06 08:12:18.054509 kant4.opoint.com kernel: Code: 8d 14 07 48 8b 0a 4c 39 c9 77 30 48 85 ff 74 2c 48 83 c6 3e eb 10 48 8b b8 e8 01 00 00 48 85 ff 74 1a 4a 8d 14 07 48 8b 47 10 <48> 8b 0c f0 48 8b 12 48 39 ca 76 e0 b8 01 00 00 00 c3 3>
Oct 06 08:12:18.054578 kant4.opoint.com kernel: RSP: 0018:ffffb8118f9ffdc8 EFLAGS: 00010212
Oct 06 08:12:18.054637 kant4.opoint.com kernel: RAX: 0000000000000001 RBX: ffff994b86f77bc0 RCX: 0000000000000000
Oct 06 08:12:18.054680 kant4.opoint.com kernel: RDX: ffff994b86f77c40 RSI: 000000000000004a RDI: ffff994b86f77bc0
Oct 06 08:12:18.054729 kant4.opoint.com kernel: RBP: ffffb8118f9ffe60 R08: 0000000000000080 R09: 0000000000075f6b
Oct 06 08:12:18.054769 kant4.opoint.com kernel: R10: 00007f2bacbb3910 R11: 0000000000000000 R12: ffffb8118f9ffed0
Oct 06 08:12:18.054806 kant4.opoint.com kernel: R13: 0000000000000000 R14: 00000000003d0f00 R15: ffff995f0d0e8000
Oct 06 08:12:18.054841 kant4.opoint.com kernel: FS: 00007f2bc6c01d80(0000) GS:ffff99689fac0000(0000) knlGS:0000000000000000
Oct 06 08:12:18.054876 kant4.opoint.com kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Oct 06 08:12:18.054922 kant4.opoint.com kernel: CR2: 0000000000000251 CR3: 0000000a98dae005 CR4: 00000000000206e0
Oct 06 08:12:20.369065 kant4.opoint.com kernel: traps: chrome[3242064] trap invalid opcode ip:55a5975a8910 sp:7ffe43768e20 error:0 in chrome[55a59742d000+857b000]
Oct 06 08:12:24.954402 kant4.opoint.com kernel: BUG: kernel NULL pointer dereference, address: 0000000000000251
Oct 06 08:12:24.954696 kant4.opoint.com kernel: #PF: supervisor read access in kernel mode
Oct 06 08:12:25.230724 kant4.opoint.com kernel: #PF: error_code(0x0000) - not-present page
Oct 06 08:12:25.234392 kant4.opoint.com kernel: PGD 0 P4D 0
Oct 06 08:12:25.234606 kant4.opoint.com kernel: Oops: 0000 [#2] SMP PTI
Oct 06 08:12:25.234686 kant4.opoint.com kernel: CPU: 4 PID: 3337732 Comm: ThreadPoolForeg Tainted: G      D 5.14.9-200.fc34.x86_64 #1
Oct 06 08:12:25.234756 kant4.opoint.com kernel: Hardware name: IBM BladeCenter HS22 -[7870TKN]-/68Y8163, BIOS -[P9E164CUS-1.28]- 04/17/2018
 ^X
Oct 06 08:11:44.148859 kant4.opoint.com kernel: Code: d2 0f 84 b7 0f 00 00 48 83 fa 01 0f 84 b9 0f 00 00 49 89 d3 89 f1 89 f8 48 83 e1 3f 48 83 e0 3f 83 f9 30 77 45 83 f8 30 77 40 <f3> 0f 6f 0f f3 0f 6f 16 66 0f ef c0 66 0f 74 c1 66 0f 74 ca 66 0f
Oct 06 08:12:17.709377 kant4.opoint.com kernel: BUG: kernel NULL pointer dereference, address: 0000000000000251
Oct 06 08:12:17.709641 kant4.opoint.com kernel: #PF: supervisor read access in kernel mode
Oct 06 08:12:17.889197 kant4.opoint.com kernel: #PF: error_code(0x0000) - not-present page
Oct 06 08:12:17.967596 kant4.opoint.com kernel: PGD 0 P4D 0
Oct 06 08:12:18.051776 kant4.opoint.com kernel: Oops: 0000 [#1] SMP PTI
Oct 06 08:12:18.051895 kant4.opoint.com kernel: CPU: 9 PID: 3337825 Comm: chrome Not tainted 5.14.9-200.fc34.x86_64 #1
Oct 06 08:12:18.051962 kant4.opoint.com kernel: Hardware name: IBM BladeCenter HS22 -[7870TKN]-/68Y8163, BIOS -[P9E164CUS-1.28]- 04/17/2018
Oct 06 08:12:18.052022 kant4.opoint.com kernel: RIP: 0010:is_ucounts_overlimit+0x42/0x60
Oct 06 08:12:18.052080 kant4.opoint.com kernel: Code: 8d 14 07 48 8b 0a 4c 39 c9 77 30 48 85 ff 74 2c 48 83 c6 3e eb 10 48 8b b8 e8 01 00 00 48 85 ff 74 1a 4a 8d 14 07 48 8b 47 10 <48> 8b 0c f0 48 8b 12 48 39 ca 76 e0 b8 01 00 00 00 c3 31 c0 c3 cc
Oct 06 08:12:18.052154 kant4.opoint.com kernel: RSP: 0018:ffffb8118f9ffdc8 EFLAGS: 00010212
Oct 06 08:12:18.052227 kant4.opoint.com kernel: RAX: 0000000000000001 RBX: ffff994b86f77bc0 RCX: 0000000000000000
Oct 06 08:12:18.052344 kant4.opoint.com kernel: RDX: ffff994b86f77c40 RSI: 000000000000004a RDI: ffff994b86f77bc0
Oct 06 08:12:18.052452 kant4.opoint.com kernel: RBP: ffffb8118f9ffe60 R08: 0000000000000080 R09: 0000000000075f6b
Oct 06 08:12:18.052523 kant4.opoint.com kernel: R10: 00007f2bacbb3910 R11: 0000000000000000 R12: ffffb8118f9ffed0
Oct 06 08:12:18.052613 kant4.opoint.com kernel: R13: 0000000000000000 R14: 00000000003d0f00 R15: ffff995f0d0e8000
Oct 06 08:12:18.052701 kant4.opoint.com kernel: FS: 00007f2bc6c01d80(0000) GS:ffff99689fac0000(0000) knlGS:0000000000000000
Oct 06 08:12:18.052774 kant4.opoint.com kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Oct 06 08:12:18.052850 kant4.opoint.com kernel: CR2: 0000000000000251 CR3: 0000000a98dae005 CR4: 00000000000206e0
Oct 06 08:12:18.052923 kant4.opoint.com kernel: Call Trace:
Oct 06 08:12:18.052989 kant4.opoint.com kernel: copy_process+0x444/0x1c20
Oct 06 08:12:18.053116 kant4.opoint.com kernel: kernel_clone+0x87/0x380
Oct 06 08:12:18.053185 kant4.opoint.com kernel: __do_sys_clone+0x52/0x60
Oct 06 08:12:18.053251 kant4.opoint.com kernel: do_syscall_64+0x3b/0x90
Oct 06 08:12:18.053366 kant4.opoint.com kernel: entry_SYSCALL_64_after_hwframe+0x44/0xae
Oct 06 08:12:18.053450 kant4.opoint.com kernel: RIP: 0033:0x7f2bc8288345
Oct 06 08:12:18.053536 kant4.opoint.com kernel: Code: 48 85 ff 74 3d 48 85 f6 74 38 48 83 ee 10 48 89 4e 08 48 89 3e 48 89 d7 4c 89 c2 4d 89 c8 4c 8b 54 24 08 b8 38 00 00 00 0f 05 <48> 85 c0 7c 13 74 01 c3 31 ed 58 5f ff d0 48 89 c7 b8 3c 00 00 00
Oct 06 08:12:18.053640 kant4.opoint.com kernel: RSP: 002b:00007ffc07a6d8e8 EFLAGS: 00000202 ORIG_RAX: 0000000000000038
Oct 06 08:12:18.053743 kant4.opoint.com kernel: RAX: ffffffffffffffda RBX: 00007f2bacbb3640 RCX: 00007f2bc8288345
Oct 06 08:12:18.053888 kant4.opoint.com kernel: RDX: 00007f2bacbb3910 RSI: 00007f2bacbb28b0 RDI: 00000000003d0f00
Oct 06 08:12:18.053955 kant4.opoint.com kernel: RBP: 00007ffc07a6dc10 R08: 00007f2bacbb3640 R09: 00007f2bacbb3640
Oct 06 08:12:18.054025 kant4.opoint.com kernel: R10: 00007f2bacbb3910 R11: 0000000000000202 R12: 00007ffc07a6d9ae
Oct 06 08:12:18.054091 kant4.opoint.com kernel: R13: 00007ffc07a6d9af R14: 0000000000000000 R15: 00007f2bacbb3640
Oct 06 08:12:18.054162 kant4.opoint.com kernel: Modules linked in: binfmt_misc rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace sunrpc fscache netfs nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_>
Oct 06 08:12:18.054308 kant4.opoint.com kernel: CR2: 0000000000000251
Oct 06 08:12:18.054386 kant4.opoint.com kernel: ---[ end trace 08aecc7d786b859c ]---
Oct 06 08:12:18.054450 kant4.opoint.com kernel: RIP: 0010:is_ucounts_overlimit+0x42/0x60
Oct 06 08:12:18.054509 kant4.opoint.com kernel: Code: 8d 14 07 48 8b 0a 4c 39 c9 77 30 48 85 ff 74 2c 48 83 c6 3e eb 10 48 8b b8 e8 01 00 00 48 85 ff 74 1a 4a 8d 14 07 48 8b 47 10 <48> 8b 0c f0 48 8b 12 48 39 ca 76 e0 b8 01 00 00 00 c3 31 c0 c3 cc
Oct 06 08:12:18.054578 kant4.opoint.com kernel: RSP: 0018:ffffb8118f9ffdc8 EFLAGS: 00010212
Oct 06 08:12:18.054637 kant4.opoint.com kernel: RAX: 0000000000000001 RBX: ffff994b86f77bc0 RCX: 0000000000000000
Oct 06 08:12:18.054680 kant4.opoint.com kernel: RDX: ffff994b86f77c40 RSI: 000000000000004a RDI: ffff994b86f77bc0
Oct 06 08:12:18.054729 kant4.opoint.com kernel: RBP: ffffb8118f9ffe60 R08: 0000000000000080 R09: 0000000000075f6b
Oct 06 08:12:18.054769 kant4.opoint.com kernel: R10: 00007f2bacbb3910 R11: 0000000000000000 R12: ffffb8118f9ffed0
Oct 06 08:12:18.054806 kant4.opoint.com kernel: R13: 0000000000000000 R14: 00000000003d0f00 R15: ffff995f0d0e8000
Oct 06 08:12:18.054841 kant4.opoint.com kernel: FS: 00007f2bc6c01d80(0000) GS:ffff99689fac0000(0000) knlGS:0000000000000000
Oct 06 08:12:18.054876 kant4.opoint.com kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Oct 06 08:12:18.054922 kant4.opoint.com kernel: CR2: 0000000000000251 CR3: 0000000a98dae005 CR4: 00000000000206e0
Oct 06 08:12:20.369065 kant4.opoint.com kernel: traps: chrome[3242064] trap invalid opcode ip:55a5975a8910 sp:7ffe43768e20 error:0 in chrome[55a59742d000+857b000]
Oct 06 08:12:24.954402 kant4.opoint.com kernel: BUG: kernel NULL pointer dereference, address: 0000000000000251
Oct 06 08:12:24.954696 kant4.opoint.com kernel: #PF: supervisor read access in kernel mode
Oct 06 08:12:25.230724 kant4.opoint.com kernel: #PF: error_code(0x0000) - not-present page
Oct 06 08:12:25.234392 kant4.opoint.com kernel: PGD 0 P4D 0
Oct 06 08:12:25.234606 kant4.opoint.com kernel: Oops: 0000 [#2] SMP PTI
Oct 06 08:12:25.234686 kant4.opoint.com kernel: CPU: 4 PID: 3337732 Comm: ThreadPoolForeg Tainted: G      D 5.14.9-200.fc34.x86_64 #1
Oct 06 08:12:25.234756 kant4.opoint.com kernel: Hardware name: IBM BladeCenter HS22 -[7870TKN]-/68Y8163, BIOS -[P9E164CUS-1.28]- 04/17/2018
Oct 06 08:12:25.234818 kant4.opoint.com kernel: RIP: 0010:is_ucounts_overlimit+0x42/0x60
Oct 06 08:12:25.234881 kant4.opoint.com kernel: Code: 8d 14 07 48 8b 0a 4c 39 c9 77 30 48 85 ff 74 2c 48 83 c6 3e eb 10 48 8b b8 e8 01 00 00 48 85 ff 74 1a 4a 8d 14 07 48 8b 47 10 <48> 8b 0c f0 48 8b 12 48 39 ca 76 e0 b8 01 00 00 00 c3 31 c0 c3 cc
Oct 06 08:12:25.234949 kant4.opoint.com kernel: RSP: 0018:ffffb81189d5fdc8 EFLAGS: 00010212
Oct 06 08:12:25.235017 kant4.opoint.com kernel: RAX: 0000000000000001 RBX: ffff994b86f77bc0 RCX: 0000000000000000
Oct 06 08:12:25.235079 kant4.opoint.com kernel: RDX: ffff994b86f77c40 RSI: 000000000000004a RDI: ffff994b86f77bc0
Oct 06 08:12:25.235142 kant4.opoint.com kernel: RBP: ffffb81189d5fe60 R08: 0000000000000080 R09: 0000000000075f6b
Oct 06 08:12:25.235227 kant4.opoint.com kernel: R10: 00000000e846208d R11: 0000000075572f44 R12: ffffb81189d5fed0
Oct 06 08:12:25.235307 kant4.opoint.com kernel: R13: 0000000000000000 R14: 00000000003d0f00 R15: ffff994be4dc2680
Oct 06 08:12:25.235420 kant4.opoint.com kernel: FS: 00007fea1f676640(0000) GS:ffff9950e7b00000(0000) knlGS:0000000000000000
Oct 06 08:12:25.235491 kant4.opoint.com kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Oct 06 08:12:25.235571 kant4.opoint.com kernel: CR2: 0000000000000251 CR3: 0000000692ffc003 CR4: 00000000000206e0
Oct 06 08:12:25.235654 kant4.opoint.com kernel: Call Trace:
lines 1191-1257/1834 62%
Oct 06 08:11:44.148859 kant4.opoint.com kernel: Code: d2 0f 84 b7 0f 00 00 48 83 fa 01 0f 84 b9 0f 00 00 49 89 d3 89 f1 89 f8 48 83 e1 3f 48 83 e0 3f 83 f9 30 77 45 83 f8 30 77 40 <f3> 0f 6f 0f f3 0f 6f 16 66 0f ef c0 66 0f 74 c1 66 0f 74 ca 66 0f
Oct 06 08:12:17.709377 kant4.opoint.com kernel: BUG: kernel NULL pointer dereference, address: 0000000000000251
Oct 06 08:12:17.709641 kant4.opoint.com kernel: #PF: supervisor read access in kernel mode
Oct 06 08:12:17.889197 kant4.opoint.com kernel: #PF: error_code(0x0000) - not-present page
Oct 06 08:12:17.967596 kant4.opoint.com kernel: PGD 0 P4D 0
Oct 06 08:12:18.051776 kant4.opoint.com kernel: Oops: 0000 [#1] SMP PTI
Oct 06 08:12:18.051895 kant4.opoint.com kernel: CPU: 9 PID: 3337825 Comm: chrome Not tainted 5.14.9-200.fc34.x86_64 #1
Oct 06 08:12:18.051962 kant4.opoint.com kernel: Hardware name: IBM BladeCenter HS22 -[7870TKN]-/68Y8163, BIOS -[P9E164CUS-1.28]- 04/17/2018
Oct 06 08:12:18.052022 kant4.opoint.com kernel: RIP: 0010:is_ucounts_overlimit+0x42/0x60
Oct 06 08:12:18.052080 kant4.opoint.com kernel: Code: 8d 14 07 48 8b 0a 4c 39 c9 77 30 48 85 ff 74 2c 48 83 c6 3e eb 10 48 8b b8 e8 01 00 00 48 85 ff 74 1a 4a 8d 14 07 48 8b 47 10 <48> 8b 0c f0 48 8b 12 48 39 ca 76 e0 b8 01 00 00 00 c3 31 c0 c3 cc
Oct 06 08:12:18.052154 kant4.opoint.com kernel: RSP: 0018:ffffb8118f9ffdc8 EFLAGS: 00010212
Oct 06 08:12:18.052227 kant4.opoint.com kernel: RAX: 0000000000000001 RBX: ffff994b86f77bc0 RCX: 0000000000000000
Oct 06 08:12:18.052344 kant4.opoint.com kernel: RDX: ffff994b86f77c40 RSI: 000000000000004a RDI: ffff994b86f77bc0
Oct 06 08:12:18.052452 kant4.opoint.com kernel: RBP: ffffb8118f9ffe60 R08: 0000000000000080 R09: 0000000000075f6b
Oct 06 08:12:18.052523 kant4.opoint.com kernel: R10: 00007f2bacbb3910 R11: 0000000000000000 R12: ffffb8118f9ffed0
Oct 06 08:12:18.052613 kant4.opoint.com kernel: R13: 0000000000000000 R14: 00000000003d0f00 R15: ffff995f0d0e8000
Oct 06 08:12:18.052701 kant4.opoint.com kernel: FS: 00007f2bc6c01d80(0000) GS:ffff99689fac0000(0000) knlGS:0000000000000000
Oct 06 08:12:18.052774 kant4.opoint.com kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Oct 06 08:12:18.052850 kant4.opoint.com kernel: CR2: 0000000000000251 CR3: 0000000a98dae005 CR4: 00000000000206e0
Oct 06 08:12:18.052923 kant4.opoint.com kernel: Call Trace:
Oct 06 08:12:18.052989 kant4.opoint.com kernel: copy_process+0x444/0x1c20
Oct 06 08:12:18.053116 kant4.opoint.com kernel: kernel_clone+0x87/0x380
Oct 06 08:12:18.053185 kant4.opoint.com kernel: __do_sys_clone+0x52/0x60
Oct 06 08:12:18.053251 kant4.opoint.com kernel: do_syscall_64+0x3b/0x90
Oct 06 08:12:18.053366 kant4.opoint.com kernel: entry_SYSCALL_64_after_hwframe+0x44/0xae
Oct 06 08:12:18.053450 kant4.opoint.com kernel: RIP: 0033:0x7f2bc8288345
Oct 06 08:12:18.053536 kant4.opoint.com kernel: Code: 48 85 ff 74 3d 48 85 f6 74 38 48 83 ee 10 48 89 4e 08 48 89 3e 48 89 d7 4c 89 c2 4d 89 c8 4c 8b 54 24 08 b8 38 00 00 00 0f 05 <48> 85 c0 7c 13 74 01 c3 31 ed 58 5f ff d0 48 89 c7 b8 3c 00 00 00
Oct 06 08:12:18.053640 kant4.opoint.com kernel: RSP: 002b:00007ffc07a6d8e8 EFLAGS: 00000202 ORIG_RAX: 0000000000000038
Oct 06 08:12:18.053743 kant4.opoint.com kernel: RAX: ffffffffffffffda RBX: 00007f2bacbb3640 RCX: 00007f2bc8288345
Oct 06 08:12:18.053888 kant4.opoint.com kernel: RDX: 00007f2bacbb3910 RSI: 00007f2bacbb28b0 RDI: 00000000003d0f00
Oct 06 08:12:18.053955 kant4.opoint.com kernel: RBP: 00007ffc07a6dc10 R08: 00007f2bacbb3640 R09: 00007f2bacbb3640
Oct 06 08:12:18.054025 kant4.opoint.com kernel: R10: 00007f2bacbb3910 R11: 0000000000000202 R12: 00007ffc07a6d9ae
Oct 06 08:12:18.054091 kant4.opoint.com kernel: R13: 00007ffc07a6d9af R14: 0000000000000000 R15: 00007f2bacbb3640
Oct 06 08:12:18.054162 kant4.opoint.com kernel: Modules linked in: binfmt_misc rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace sunrpc fscache netfs nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_tables ebtable_nat ebtabl>
Oct 06 08:12:18.054308 kant4.opoint.com kernel: CR2: 0000000000000251
Oct 06 08:12:18.054386 kant4.opoint.com kernel: ---[ end trace 08aecc7d786b859c ]
Signature · 6 lines
Best regards / Med vennlig hilsen

*Rune Kleveland*
CTO, Opoint Technology Part of Infomedia
Mob: +47 95 08 89 25
[email protected] <mailto:[email protected]>
#18 lore raw
In reply to Eric W. Biederman

Hi!

Just wanted to let you know that I still get these on stock Fedora kernel 5.14.10 on the IBM blades. But it took 10 hours before the first server crashed. The other 4 still runs fine since 15 hours ago. So for me it seems more stable now, but that could just be a coincidence.

Best regards,

Rune

------------[ cut here ]------------
kernel BUG at mm/slub.c:321!
invalid opcode: 0000 [#1] SMP PTI
CPU: 22 PID: 1838853 Comm: python3 Not tainted 5.14.10-200.fc34.x86_64 #1
Hardware name: IBM BladeCenter HS22 -[7870TKN]-/68Y8161, BIOS -[P9E164CUS-1.28]- 04/17/2018
RIP: 0010:__slab_free+0x245/0x4a0
Code: 0f b6 5c 24 1b 44 8b 44 24 1c 48 89 44 24 08 48 8b 54 24 20 4c 8b 4c 24 28 e9 8a fe ff ff 41 f7 45 08 00 0d 21 00 75 98 eb 8d <0f> 0b 49 3b 54 24 28 0f 85 53 ff ff ff 49 8b 44 24 08 4>
RSP: 0018:ffffb71dcfd6fda0 EFLAGS: 00010246
RAX: ffff9c5480d35860 RBX: ffff9c5480d35800 RCX: ffff9c5480d35800
RDX: 00000000802a0029 RSI: ffffeb41da034d00 RDI: ffff9c4f00042800
RBP: ffffb71dcfd6fe50 R08: 0000000000000001 R09: ffffffff9210b6a5
R10: ffff9c548102e000 R11: 0000000062667658 R12: ffffeb41da034d00
R13: ffff9c4f00042800 R14: ffff9c5480d35800 R15: ffff9c5480d35800
FS:  00007f7a89765740(0000) GS:ffff9c6c1fc80000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f7a7ad7f4b0 CR3: 0000000564af4002 CR4: 00000000000206e0
Call Trace:
 ? filename_lookup+0x135/0x1b0
 ? put_ucounts+0x65/0x70
 kfree+0x369/0x3c0
 put_ucounts+0x65/0x70
 put_cred_rcu+0x70/0xd0
 do_faccessat+0x113/0x240
 do_syscall_64+0x3b/0x90
 entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7f7a899cc44b
Code: 77 05 c3 0f 1f 40 00 48 8b 15 29 1a 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff c3 0f 1f 40 00 f3 0f 1e fa b8 15 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 05 c3 0f 1f 40 00 48 8b 15 f9 19 0>
RSP: 002b:00007ffd01fa9ce8 EFLAGS: 00000202 ORIG_RAX: 0000000000000015
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7a899cc44b
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 00007f79a96d6e10
RBP: 0000000000000001 R08: 0000000000000000 R09: 00007f7a7c1fb930
R10: 00007f79a96d6000 R11: 0000000000000202 R12: 00007ffd01fa9d00
R13: 0000000000000001 R14: 0000556841045c90 R15: 00000000ffffff9c
Modules linked in: rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace sunrpc fscache netfs nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_rejec>
---[ end trace 0a81b150eacde1d5 ]---
RIP: 0010:__slab_free+0x245/0x4a0
Code: 0f b6 5c 24 1b 44 8b 44 24 1c 48 89 44 24 08 48 8b 54 24 20 4c 8b 4c 24 28 e9 8a fe ff ff 41 f7 45 08 00 0d 21 00 75 98 eb 8d <0f> 0b 49 3b 54 24 28 0f 85 53 ff ff ff 49 8b 44 24 08 4>
RSP: 0018:ffffb71dcfd6fda0 EFLAGS: 00010246
RAX: ffff9c5480d35860 RBX: ffff9c5480d35800 RCX: ffff9c5480d35800
RDX: 00000000802a0029 RSI: ffffeb41da034d00 RDI: ffff9c4f00042800
RBP: ffffb71dcfd6fe50 R08: 0000000000000001 R09: ffffffff9210b6a5
R10: ffff9c548102e000 R11: 0000000062667658 R12: ffffeb41da034d00
R13: ffff9c4f00042800 R14: ffff9c5480d35800 R15: ffff9c5480d35800
FS:  00007f7a89765740(0000) GS:ffff9c6c1fc80000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f7a7ad7f4b0 CR3: 0000000564af4002 CR4: 00000000000206e0
------------[ cut here ]------------
Quoted 79 lines · Eric W. Biederman
Quoted 23 lines · [email protected] (Eric W. Biederman) writes:

Adding Rune Kleveland to the discussion as he also seems to have reproduced the issue.

Alex and I have been starring at the code and the reports and this bug is hiding well. Here is what we have figured out so far.

Both the warning from free_user_ns calling dec_ucount that Jordan Glover reported and the KASAN error that Yu Zhao has reported appear to have the same cause. Using a ucounts structure after it has been freed and reallocated as something else.

I have just skimmed through the recent report from Rune Kleveland and it appears also to be a use after free. Especially since the second failure in the log is slub complaining about trying to free the ucounts data structure.

We looked through the users of put_ucounts and we don't see any obvious buggy users that would be freeing the data structure early.

Alex has tried to reproduce this so far is not having any luck. Folks can you tell what compiler versions you are using and share your kernel config with us? That might help.

Quoted 6 lines

The little debug diff below is my guess of what is happening. If the folks who can reproduce this issue can try the patch below and let me know if the warnings fire that would be appreciated. It is still not enough to track down the bug but at least it will confirm my current hypothesis about how things look before there is a use of memory after it is freed.

Bah. Scratch that test patch. I just double checked myself and cred->ucounts and cred->user_ns->ucounts should never be equal, as the user namespace is counted in it's parent user namespace.

That observation now tells me I have a parent user namespace that went corrupt.

Back to the drawing board.

Quoted 38 lines

Thank you,
Eric

kernel/cred.c +6 -0
index f784e08c2fbd..e7ffaa3cf5a6 100644
@@ -120,6 +120,12 @@ static void put_cred_rcu(struct rcu_head *rcu)
  	if (cred->group_info)
  		put_group_info(cred->group_info);
  	free_uid(cred->user);
+#if 1
+	if ((cred->ucounts == cred->user_ns->ucounts) &&
+	    (atomic_read(&cred->ucounts->count) == 1)) {
+		WARN_ONCE(1, "put_cred_rcu: ucount count 1\n");
+	}
+#endif
  	if (cred->ucounts)
  		put_ucounts(cred->ucounts);
  	put_user_ns(cred->user_ns);
kernel/exit.c +7 -0
index 91a43e57a32e..60fd88b34c1a 100644
@@ -743,6 +743,13 @@ void __noreturn do_exit(long code)
  	if (unlikely(!tsk->pid))
  		panic("Attempted to kill the idle task!");
 
+#if 1
+	if ((tsk->cred->ucounts == tsk->cred->user_ns->ucounts) &&
+	    (atomic_read(tsk->cred->ucounts->count) == 1)) {
+		WARN_ONCE(1, "do_exit: ucount count 1\n");
+	}
+#endif
+
  	/*
  	 * If do_exit is called because this processes oopsed, it's possible
  	 * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
#19 lore raw
Quoted 2 lines · On Sun, 10 Oct 2021 10:59:10 +0200 Rune Kleveland wrote:

Just wanted to let you know that I still get these on stock Fedora kernel 5.14.10 on the IBM blades. But it took 10 hours before the first

Thanks for your report.

Quoted 9 lines

server crashed. The other 4 still runs fine since 15 hours ago. So for me it seems more stable now, but that could just be a coincidence.

Best regards,

Rune

------------[ cut here ]------------
kernel BUG at mm/slub.c:321!

We did not see this before.

Quoted 53 lines

invalid opcode: 0000 [#1] SMP PTI

CPU: 22 PID: 1838853 Comm: python3 Not tainted 5.14.10-200.fc34.x86_64 #1
Hardware name: IBM BladeCenter HS22 -[7870TKN]-/68Y8161, BIOS 
-[P9E164CUS-1.28]- 04/17/2018
RIP: 0010:__slab_free+0x245/0x4a0
Code: 0f b6 5c 24 1b 44 8b 44 24 1c 48 89 44 24 08 48 8b 54 24 20 4c 8b 

4c 24 28 e9 8a fe ff ff 41 f7 45 08 00 0d 21 00 75 98 eb 8d <0f> 0b 49 3b 54 24 28 0f 85 53 ff ff ff 49 8b 44 24 08 4>
RSP: 0018:ffffb71dcfd6fda0 EFLAGS: 00010246
RAX: ffff9c5480d35860 RBX: ffff9c5480d35800 RCX: ffff9c5480d35800
RDX: 00000000802a0029 RSI: ffffeb41da034d00 RDI: ffff9c4f00042800
RBP: ffffb71dcfd6fe50 R08: 0000000000000001 R09: ffffffff9210b6a5
R10: ffff9c548102e000 R11: 0000000062667658 R12: ffffeb41da034d00
R13: ffff9c4f00042800 R14: ffff9c5480d35800 R15: ffff9c5480d35800 FS:  00007f7a89765740(0000) GS:ffff9c6c1fc80000(0000) knlGS:0000000000000000 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f7a7ad7f4b0 CR3: 0000000564af4002 CR4: 00000000000206e0

Call Trace:
  ? filename_lookup+0x135/0x1b0
  ? put_ucounts+0x65/0x70
  kfree+0x369/0x3c0
  put_ucounts+0x65/0x70
  put_cred_rcu+0x70/0xd0
  do_faccessat+0x113/0x240
  do_syscall_64+0x3b/0x90
  entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7f7a899cc44b
Code: 77 05 c3 0f 1f 40 00 48 8b 15 29 1a 0d 00 f7 d8 64 89 02 48 c7 c0 

ff ff ff ff c3 0f 1f 40 00 f3 0f 1e fa b8 15 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 05 c3 0f 1f 40 00 48 8b 15 f9 19 0>
RSP: 002b:00007ffd01fa9ce8 EFLAGS: 00000202 ORIG_RAX: 0000000000000015
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7a899cc44b
RDX: 0000000000000000 RSI: 0000000000000001 RDI: 00007f79a96d6e10
RBP: 0000000000000001 R08: 0000000000000000 R09: 00007f7a7c1fb930
R10: 00007f79a96d6000 R11: 0000000000000202 R12: 00007ffd01fa9d00
R13: 0000000000000001 R14: 0000556841045c90 R15: 00000000ffffff9c

Modules linked in: rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs 
lockd grace sunrpc fscache netfs nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 
nft_fib nft_reject_inet nf_reject_ipv4 nf_rejec>
---[ end trace 0a81b150eacde1d5 ]---
RIP: 0010:__slab_free+0x245/0x4a0
Code: 0f b6 5c 24 1b 44 8b 44 24 1c 48 89 44 24 08 48 8b 54 24 20 4c 8b 

4c 24 28 e9 8a fe ff ff 41 f7 45 08 00 0d 21 00 75 98 eb 8d <0f> 0b 49 3b 54 24 28 0f 85 53 ff ff ff 49 8b 44 24 08 4>
RSP: 0018:ffffb71dcfd6fda0 EFLAGS: 00010246
RAX: ffff9c5480d35860 RBX: ffff9c5480d35800 RCX: ffff9c5480d35800
RDX: 00000000802a0029 RSI: ffffeb41da034d00 RDI: ffff9c4f00042800
RBP: ffffb71dcfd6fe50 R08: 0000000000000001 R09: ffffffff9210b6a5
R10: ffff9c548102e000 R11: 0000000062667658 R12: ffffeb41da034d00
R13: ffff9c4f00042800 R14: ffff9c5480d35800 R15: ffff9c5480d35800 FS:  00007f7a89765740(0000) GS:ffff9c6c1fc80000(0000) knlGS:0000000000000000 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f7a7ad7f4b0 CR3: 0000000564af4002 CR4: 00000000000206e0

Quoted 1 line
------------[ cut here ]------------

Although the chance for double free is not zero, corruption can not be ruled out today yet because reports [1,2] in this thread caught no count underflow.

Want to know what this DF looks like with kasan enabled.

Hillf

	CPU 1			CPU 2
	-----			-----
	put_ucounts 

	atomic_dec_and_lock_irqsave

				get_ucounts

	hlist_del_init(&ucounts->node);
	spin_unlock_irqrestore(&ucounts_lock, flags);

				put_ucounts 
				atomic_dec_and_lock_irqsave
				hlist_del_init(&ucounts->node);
				spin_unlock_irqrestore(&ucounts_lock, flags);
	kfree(ucounts);		kfree(ucounts);

[1] https://lore.kernel.org/linux-mm/CAOUHufaaPoTOCML+v8FomeWtN_PncmaHT9d6-XJG8RPzTcFZug@mail.gmail.com/

[2] https://lore.kernel.org/linux-mm/BCdQdQjRHZ9CJwIhmvKGfnFtMBJuatrZUX5In1gLlPswtrs4HwNONAbJleaeSfOOenMIdc_FPi0wwPIdW5Vodm4Aj-0iCqQY57288M5WFuY=@protonmail.ch/

#20 lore raw
In reply to Rune Kleveland
Quoted 6 lines · Rune Kleveland

Hi!

Just wanted to let you know that I still get these on stock Fedora kernel 5.14.10 on the IBM blades. But it took 10 hours before the first server crashed. The other 4 still runs fine since 15 hours ago. So for me it seems more stable now, but that could just be a coincidence.

Alex and I have been working on this and we are still tracking down whatever is going on.

While we haven't found the issue yet we have found a trivially correct change that allows us to reproduce the issue faster.

Hopefully this will allow us to narrow down on whatever it is soon.

kernel/ucount.c +1 -0
index bb51849e6375..3b7e176cf7a2 100644
@@ -203,6 +203,7 @@ void put_ucounts(struct ucounts *ucounts)
 
 	if (atomic_dec_and_lock_irqsave(&ucounts->count, &ucounts_lock, flags)) {
 		hlist_del_init(&ucounts->node);
+		ucounts->ns = NULL;
 		spin_unlock_irqrestore(&ucounts_lock, flags);
 		kfree(ucounts);
 	}

Eric

#21 lore raw

PATCH 1/1 ucounts: Fix signal ucount refcounting

In reply to Rune Kleveland

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

I wish we had a single user across all of the threads whose rlimit could be charged so we did not need this complexity.

Fixes d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts")

---

With a lot of help from Alex who found a way I could reproduce this I believe I have found the issue.

Could people who are seeing this issue test and verify this solves the problem for them?

 include/linux/user_namespace.h |  2 ++
 kernel/signal.c                | 25 +++++----------------
 kernel/ucount.c                | 41 ++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 19 deletions(-)
include/linux/user_namespace.h +2 -0
index eb70cabe6e7f..33a4240e6a6f 100644
@@ -127,6 +127,8 @@ static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type t
 
 long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
 bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type);
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type);
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max);
 
 static inline void set_rlimit_ucount_max(struct user_namespace *ns,
kernel/signal.c +6 -19
index a3229add4455..762de58c6e76 100644
@@ -425,22 +425,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	 */
 	rcu_read_lock();
 	ucounts = task_ucounts(t);
-	sigpending = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-	switch (sigpending) {
-	case 1:
-		if (likely(get_ucounts(ucounts)))
-			break;
-		fallthrough;
-	case LONG_MAX:
-		/*
-		 * we need to decrease the ucount in the userns tree on any
-		 * failure to avoid counts leaking.
-		 */
-		dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-		rcu_read_unlock();
-		return NULL;
-	}
+	sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	rcu_read_unlock();
+	if (sigpending == LONG_MAX)
+		return NULL;
 
 	if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
 		q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
@@ -449,8 +437,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	}
 
 	if (unlikely(q == NULL)) {
-		if (dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1))
-			put_ucounts(ucounts);
+		dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	} else {
 		INIT_LIST_HEAD(&q->list);
 		q->flags = sigqueue_flags;
@@ -463,8 +450,8 @@ static void __sigqueue_free(struct sigqueue *q)
 {
 	if (q->flags & SIGQUEUE_PREALLOC)
 		return;
-	if (q->ucounts && dec_rlimit_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING, 1)) {
-		put_ucounts(q->ucounts);
+	if (q->ucounts) {
+		dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING);
 		q->ucounts = NULL;
 	}
 	kmem_cache_free(sigqueue_cachep, q);
kernel/ucount.c +41 -0

47 lines not on this page · raw message

Signature · 1 line
2.20.1
#22 lore raw

Re: [CFT][PATCH] ucounts: Fix signal ucount refcounting

Quoted 129 lines · Eric W. Biederman

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

I wish we had a single user across all of the threads whose rlimit could be charged so we did not need this complexity.

Fixes d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts")

---

With a lot of help from Alex who found a way I could reproduce this I believe I have found the issue.

Could people who are seeing this issue test and verify this solves the problem for them?

 include/linux/user_namespace.h |  2 ++
 kernel/signal.c                | 25 +++++----------------
 kernel/ucount.c                | 41 ++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 19 deletions(-)
include/linux/user_namespace.h +2 -0
index eb70cabe6e7f..33a4240e6a6f 100644
@@ -127,6 +127,8 @@ static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type t
 
 long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
 bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type);
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type);
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max);
 
 static inline void set_rlimit_ucount_max(struct user_namespace *ns,
kernel/signal.c +6 -19
index a3229add4455..762de58c6e76 100644
@@ -425,22 +425,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	 */
 	rcu_read_lock();
 	ucounts = task_ucounts(t);
-	sigpending = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-	switch (sigpending) {
-	case 1:
-		if (likely(get_ucounts(ucounts)))
-			break;
-		fallthrough;
-	case LONG_MAX:
-		/*
-		 * we need to decrease the ucount in the userns tree on any
-		 * failure to avoid counts leaking.
-		 */
-		dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-		rcu_read_unlock();
-		return NULL;
-	}
+	sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	rcu_read_unlock();
+	if (sigpending == LONG_MAX)
+		return NULL;
 
 	if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
 		q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
@@ -449,8 +437,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	}
 
 	if (unlikely(q == NULL)) {
-		if (dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1))
-			put_ucounts(ucounts);
+		dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	} else {
 		INIT_LIST_HEAD(&q->list);
 		q->flags = sigqueue_flags;
@@ -463,8 +450,8 @@ static void __sigqueue_free(struct sigqueue *q)
 {
 	if (q->flags & SIGQUEUE_PREALLOC)
 		return;
-	if (q->ucounts && dec_rlimit_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING, 1)) {
-		put_ucounts(q->ucounts);
+	if (q->ucounts) {
+		dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING);
 		q->ucounts = NULL;
 	}
 	kmem_cache_free(sigqueue_cachep, q);
kernel/ucount.c +20 -0
index 3b7e176cf7a2..687d77aa66bb 100644
@@ -285,6 +285,47 @@ bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
 	return (new == 0);
 }
 
+static void do_dec_rlimit_put_ucounts(struct ucounts *ucounts,
+				struct ucounts *last, enum ucount_type type)
+{
+	struct ucounts *iter;
+	for (iter = ucounts; iter != last; iter = iter->ns->ucounts) {
+		long dec = atomic_long_add_return(-1, &iter->ucount[type]);
+		WARN_ON_ONCE(dec < 0);
+		if (dec == 0)
+			put_ucounts(iter);
+	}
+}
+
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+	do_dec_rlimit_put_ucounts(ucounts, NULL, type);
+}
+
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+	struct ucounts *iter;

kernel/ucount.c bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) · line 317

Quoted 10 lines
kernel/ucount.c +10 -0
+	long dec, ret = 0;
+
+	for (iter = ucounts; iter; iter = iter->ns->ucounts) {
+		long max = READ_ONCE(iter->ns->ucount_max[type]);
+		long new = atomic_long_add_return(1, &iter->ucount[type]);
+		if (new < 0 || new > max)
+			goto unwind;
+		else if (iter == ucounts)
+			ret = new;
+		if ((new == 1) && (get_ucounts(iter) != iter))

get_ucounts can do put_ucounts. Are you sure it's correct to use get_ucounts here?

kernel/ucount.c bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) · line 322

Quoted 5 lines
kernel/ucount.c +5 -0
+			goto dec_unwind;
+	}
+	return ret;
+dec_unwind:
+	dec = atomic_long_add_return(1, &iter->ucount[type]);

Should be -1 ?

Quoted 12 lines
kernel/ucount.c +6 -0
+	WARN_ON_ONCE(dec < 0);
+unwind:
+	do_dec_rlimit_put_ucounts(ucounts, iter, type);
+	return LONG_MAX;
+}
+
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max)
 {
 	struct ucounts *iter;
Signature · 1 line
2.20.1
Signature · 1 line
Rgrds, legion
#23 lore raw

Re: [CFT][PATCH] ucounts: Fix signal ucount refcounting

Quoted 135 lines · Alexey Gladkov
Quoted 134 lines · Eric W. Biederman

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

I wish we had a single user across all of the threads whose rlimit could be charged so we did not need this complexity.

Fixes d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts")

---

With a lot of help from Alex who found a way I could reproduce this I believe I have found the issue.

Could people who are seeing this issue test and verify this solves the problem for them?

 include/linux/user_namespace.h |  2 ++
 kernel/signal.c                | 25 +++++----------------
 kernel/ucount.c                | 41 ++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 19 deletions(-)
include/linux/user_namespace.h +2 -0
index eb70cabe6e7f..33a4240e6a6f 100644
@@ -127,6 +127,8 @@ static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type t
 
 long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
 bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type);
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type);
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max);
 
 static inline void set_rlimit_ucount_max(struct user_namespace *ns,
kernel/signal.c +6 -19
index a3229add4455..762de58c6e76 100644
@@ -425,22 +425,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	 */
 	rcu_read_lock();
 	ucounts = task_ucounts(t);
-	sigpending = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-	switch (sigpending) {
-	case 1:
-		if (likely(get_ucounts(ucounts)))
-			break;
-		fallthrough;
-	case LONG_MAX:
-		/*
-		 * we need to decrease the ucount in the userns tree on any
-		 * failure to avoid counts leaking.
-		 */
-		dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-		rcu_read_unlock();
-		return NULL;
-	}
+	sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	rcu_read_unlock();
+	if (sigpending == LONG_MAX)
+		return NULL;
 
 	if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
 		q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
@@ -449,8 +437,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	}
 
 	if (unlikely(q == NULL)) {
-		if (dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1))
-			put_ucounts(ucounts);
+		dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	} else {
 		INIT_LIST_HEAD(&q->list);
 		q->flags = sigqueue_flags;
@@ -463,8 +450,8 @@ static void __sigqueue_free(struct sigqueue *q)
 {
 	if (q->flags & SIGQUEUE_PREALLOC)
 		return;
-	if (q->ucounts && dec_rlimit_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING, 1)) {
-		put_ucounts(q->ucounts);
+	if (q->ucounts) {
+		dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING);
 		q->ucounts = NULL;
 	}
 	kmem_cache_free(sigqueue_cachep, q);
kernel/ucount.c +25 -0
index 3b7e176cf7a2..687d77aa66bb 100644
@@ -285,6 +285,47 @@ bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
 	return (new == 0);
 }
 
+static void do_dec_rlimit_put_ucounts(struct ucounts *ucounts,
+				struct ucounts *last, enum ucount_type type)
+{
+	struct ucounts *iter;
+	for (iter = ucounts; iter != last; iter = iter->ns->ucounts) {
+		long dec = atomic_long_add_return(-1, &iter->ucount[type]);
+		WARN_ON_ONCE(dec < 0);
+		if (dec == 0)
+			put_ucounts(iter);
+	}
+}
+
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+	do_dec_rlimit_put_ucounts(ucounts, NULL, type);
+}
+
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+	struct ucounts *iter;
+	long dec, ret = 0;
+
+	for (iter = ucounts; iter; iter = iter->ns->ucounts) {
+		long max = READ_ONCE(iter->ns->ucount_max[type]);
+		long new = atomic_long_add_return(1, &iter->ucount[type]);
Quoted 8 lines

kernel/ucount.c bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) · line 317

Quoted 5 lines
kernel/ucount.c +5 -0
+		if (new < 0 || new > max)
+			goto unwind;
+		else if (iter == ucounts)
+			ret = new;
+		if ((new == 1) && (get_ucounts(iter) != iter))

get_ucounts can do put_ucounts. Are you sure it's correct to use get_ucounts here?

My only concern would be if we could not run inc_rlimit_get_ucounts would not be safe to call under rcu_read_lock(). I don't see anything in get_ucounts or put_ucounts that would not be safe under rcu_read_lock().

For get_ucounts we do need to test to see if it fails. Either by testing for NULL or testing to see if it does not return the expected ucount.

Does that make sense or do you have another concern?

Quoted 7 lines

kernel/ucount.c bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) · line 322

Quoted 5 lines
kernel/ucount.c +5 -0
+			goto dec_unwind;
+	}
+	return ret;
+dec_unwind:
+	dec = atomic_long_add_return(1, &iter->ucount[type]);

Should be -1 ?

Yes it should. I will fix and resend.

Quoted 4 lines
Quoted 4 lines
kernel/ucount.c +4 -0
+	WARN_ON_ONCE(dec < 0);
+unwind:
+	do_dec_rlimit_put_ucounts(ucounts, iter, type);
+	return LONG_MAX;
Quoted 8 lines
Quoted 8 lines
kernel/ucount.c +2 -0
+}
+
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max)
 {
 	struct ucounts *iter;
Signature · 1 line
2.20.1

Eric

#24 lore raw

Re: [CFT][PATCH] ucounts: Fix signal ucount refcounting

Quoted 165 lines · Eric W. Biederman
Quoted 135 lines · Alexey Gladkov
Quoted 134 lines · Eric W. Biederman

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

I wish we had a single user across all of the threads whose rlimit could be charged so we did not need this complexity.

Fixes d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts")

---

With a lot of help from Alex who found a way I could reproduce this I believe I have found the issue.

Could people who are seeing this issue test and verify this solves the problem for them?

 include/linux/user_namespace.h |  2 ++
 kernel/signal.c                | 25 +++++----------------
 kernel/ucount.c                | 41 ++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 19 deletions(-)
include/linux/user_namespace.h +2 -0
index eb70cabe6e7f..33a4240e6a6f 100644
@@ -127,6 +127,8 @@ static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type t
 
 long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
 bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type);
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type);
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max);
 
 static inline void set_rlimit_ucount_max(struct user_namespace *ns,
kernel/signal.c +6 -19
index a3229add4455..762de58c6e76 100644
@@ -425,22 +425,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
      */
     rcu_read_lock();
     ucounts = task_ucounts(t);
-    sigpending = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-    switch (sigpending) {
-    case 1:
-            if (likely(get_ucounts(ucounts)))
-                    break;
-            fallthrough;
-    case LONG_MAX:
-            /*
-             * we need to decrease the ucount in the userns tree on any
-             * failure to avoid counts leaking.
-             */
-            dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-            rcu_read_unlock();
-            return NULL;
-    }
+    sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
     rcu_read_unlock();
+    if (sigpending == LONG_MAX)
+            return NULL;
 
     if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
             q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
@@ -449,8 +437,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
     }
 
     if (unlikely(q == NULL)) {
-            if (dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1))
-                    put_ucounts(ucounts);
+            dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
     } else {
             INIT_LIST_HEAD(&q->list);
             q->flags = sigqueue_flags;
@@ -463,8 +450,8 @@ static void __sigqueue_free(struct sigqueue *q)
 {
     if (q->flags & SIGQUEUE_PREALLOC)
             return;
-    if (q->ucounts && dec_rlimit_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING, 1)) {
-            put_ucounts(q->ucounts);
+    if (q->ucounts) {
+            dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING);
             q->ucounts = NULL;
     }
     kmem_cache_free(sigqueue_cachep, q);
kernel/ucount.c +25 -0
index 3b7e176cf7a2..687d77aa66bb 100644
@@ -285,6 +285,47 @@ bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
     return (new == 0);
 }
 
+static void do_dec_rlimit_put_ucounts(struct ucounts *ucounts,
+                            struct ucounts *last, enum ucount_type type)
+{
+    struct ucounts *iter;
+    for (iter = ucounts; iter != last; iter = iter->ns->ucounts) {
+            long dec = atomic_long_add_return(-1, &iter->ucount[type]);
+            WARN_ON_ONCE(dec < 0);
+            if (dec == 0)
+                    put_ucounts(iter);
+    }
+}
+
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+    do_dec_rlimit_put_ucounts(ucounts, NULL, type);
+}
+
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+    struct ucounts *iter;
+    long dec, ret = 0;
+
+    for (iter = ucounts; iter; iter = iter->ns->ucounts) {
+            long max = READ_ONCE(iter->ns->ucount_max[type]);
+            long new = atomic_long_add_return(1, &iter->ucount[type]);
Quoted 8 lines

kernel/ucount.c bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) · line 317

Quoted 5 lines
kernel/ucount.c +5 -0
+            if (new < 0 || new > max)
+                    goto unwind;
+            else if (iter == ucounts)
+                    ret = new;
+            if ((new == 1) && (get_ucounts(iter) != iter))

get_ucounts can do put_ucounts. Are you sure it's correct to use get_ucounts here?

My only concern would be if we could not run inc_rlimit_get_ucounts would not be safe to call under rcu_read_lock(). I don't see anything in get_ucounts or put_ucounts that would not be safe under rcu_read_lock().

For get_ucounts we do need to test to see if it fails. Either by testing for NULL or testing to see if it does not return the expected ucount.

Does that make sense or do you have another concern?

Quoted 6 lines
Quoted 5 lines
kernel/ucount.c +5 -0
+                    goto dec_unwind;
+    }
+    return ret;
+dec_unwind:
+    dec = atomic_long_add_return(1, &iter->ucount[type]);
Quoted 3 lines
Quoted 1 line

Should be -1 ?

Yes it should. I will fix and resend.

Or just atomic_long_dec_return().

Quoted 14 lines
Quoted 4 lines
Quoted 4 lines
kernel/ucount.c +4 -0
+    WARN_ON_ONCE(dec < 0);
+unwind:
+    do_dec_rlimit_put_ucounts(ucounts, iter, type);
+    return LONG_MAX;
Quoted 8 lines
Quoted 8 lines
kernel/ucount.c +2 -1
+}
+
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max)
 {
     struct ucounts *iter;
--

2.20.1

Eric

#25 lore raw

Re: [CFT][PATCH] ucounts: Fix signal ucount refcounting

Quoted 12 lines · Yu Zhao
Quoted 10 lines · Eric W. Biederman
Quoted 7 lines · Alexey Gladkov
Quoted 5 lines · Eric W. Biederman
kernel/ucount.c +5 -0
+                    goto dec_unwind;
+    }
+    return ret;
+dec_unwind:
+    dec = atomic_long_add_return(1, &iter->ucount[type]);
Quoted 5 lines
Quoted 3 lines
Quoted 1 line

Should be -1 ?

Yes it should. I will fix and resend.

Or just atomic_long_dec_return().

It would have to be atomic_long_sub_return().

Even then I would want to change all of kernel/ucount.c to use the same helper function so discrepancies can easily be spotted.

It is a good idea, just not I think for this particular patch.

Eric

#26 lore raw

Re: [CFT][PATCH] ucounts: Fix signal ucount refcounting

In reply to Eric W. Biederman
Quoted 109 lines · On Fri, 15 Oct 2021 17:10:58 -0500 Eric W. Biederman wrote:

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

I wish we had a single user across all of the threads whose rlimit could be charged so we did not need this complexity.

Fixes d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts")

---

With a lot of help from Alex who found a way I could reproduce this I believe I have found the issue.

Could people who are seeing this issue test and verify this solves the problem for them?

 include/linux/user_namespace.h |  2 ++
 kernel/signal.c                | 25 +++++----------------
 kernel/ucount.c                | 41 ++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 19 deletions(-)
include/linux/user_namespace.h +2 -0
index eb70cabe6e7f..33a4240e6a6f 100644
@@ -127,6 +127,8 @@ static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type t
 
 long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
 bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type);
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type);
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max);
 
 static inline void set_rlimit_ucount_max(struct user_namespace *ns,
kernel/signal.c +6 -19
index a3229add4455..762de58c6e76 100644
@@ -425,22 +425,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	 */
 	rcu_read_lock();
 	ucounts = task_ucounts(t);
-	sigpending = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-	switch (sigpending) {
-	case 1:
-		if (likely(get_ucounts(ucounts)))
-			break;
-		fallthrough;
-	case LONG_MAX:
-		/*
-		 * we need to decrease the ucount in the userns tree on any
-		 * failure to avoid counts leaking.
-		 */
-		dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-		rcu_read_unlock();
-		return NULL;
-	}
+	sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	rcu_read_unlock();
+	if (sigpending == LONG_MAX)
+		return NULL;
 
 	if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
 		q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
@@ -449,8 +437,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	}
 
 	if (unlikely(q == NULL)) {
-		if (dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1))
-			put_ucounts(ucounts);
+		dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	} else {
 		INIT_LIST_HEAD(&q->list);
 		q->flags = sigqueue_flags;
@@ -463,8 +450,8 @@ static void __sigqueue_free(struct sigqueue *q)
 {
 	if (q->flags & SIGQUEUE_PREALLOC)
 		return;
-	if (q->ucounts && dec_rlimit_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING, 1)) {
-		put_ucounts(q->ucounts);
+	if (q->ucounts) {
+		dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING);
 		q->ucounts = NULL;
 	}
 	kmem_cache_free(sigqueue_cachep, q);
kernel/ucount.c +0 -0
index 3b7e176cf7a2..687d77aa66bb 100644
@@ -285,6 +285,47 @@ bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
 	return (new == 0);
 }
 

kernel/ucount.c bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) · line 297

Quoted 10 lines
kernel/ucount.c +10 -0
+static void do_dec_rlimit_put_ucounts(struct ucounts *ucounts,
+				struct ucounts *last, enum ucount_type type)
+{
+	struct ucounts *iter;
+	for (iter = ucounts; iter != last; iter = iter->ns->ucounts) {
+		long dec = atomic_long_add_return(-1, &iter->ucount[type]);
+		WARN_ON_ONCE(dec < 0);
+		if (dec == 0)
+			put_ucounts(iter);
+	}

Given kfree in put_ucounts(), this has difficulty surviving tests like kasan if the put pairs with the get in the below inc_rlimit_get_ucounts().

Quoted 11 lines
kernel/ucount.c +11 -0
+}
+
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+	do_dec_rlimit_put_ucounts(ucounts, NULL, type);
+}
+
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+	struct ucounts *iter;
+	long dec, ret = 0;

kernel/ucount.c bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) · line 318

Quoted 10 lines
kernel/ucount.c +10 -0
+
+	for (iter = ucounts; iter; iter = iter->ns->ucounts) {
+		long max = READ_ONCE(iter->ns->ucount_max[type]);
+		long new = atomic_long_add_return(1, &iter->ucount[type]);
+		if (new < 0 || new > max)
+			goto unwind;
+		else if (iter == ucounts)
+			ret = new;
+		if ((new == 1) && (get_ucounts(iter) != iter))
+			goto dec_unwind;

Add a line of comment for get to ease readers.

Hillf

Quoted 15 lines
kernel/ucount.c +10 -0
+	}
+	return ret;
+dec_unwind:
+	dec = atomic_long_add_return(1, &iter->ucount[type]);
+	WARN_ON_ONCE(dec < 0);
+unwind:
+	do_dec_rlimit_put_ucounts(ucounts, iter, type);
+	return LONG_MAX;
+}
+
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max)
 {
 	struct ucounts *iter;
Signature · 1 line
2.20.1
#27 lore raw

Re: [CFT][PATCH] ucounts: Fix signal ucount refcounting

Quoted 110 lines · Hillf Danton
Quoted 109 lines · On Fri, 15 Oct 2021 17:10:58 -0500 Eric W. Biederman wrote:

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

I wish we had a single user across all of the threads whose rlimit could be charged so we did not need this complexity.

Fixes d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts")

---

With a lot of help from Alex who found a way I could reproduce this I believe I have found the issue.

Could people who are seeing this issue test and verify this solves the problem for them?

 include/linux/user_namespace.h |  2 ++
 kernel/signal.c                | 25 +++++----------------
 kernel/ucount.c                | 41 ++++++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 19 deletions(-)
include/linux/user_namespace.h +2 -0
index eb70cabe6e7f..33a4240e6a6f 100644
@@ -127,6 +127,8 @@ static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type t
 
 long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
 bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type);
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type);
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max);
 
 static inline void set_rlimit_ucount_max(struct user_namespace *ns,
kernel/signal.c +6 -19
index a3229add4455..762de58c6e76 100644
@@ -425,22 +425,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	 */
 	rcu_read_lock();
 	ucounts = task_ucounts(t);
-	sigpending = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-	switch (sigpending) {
-	case 1:
-		if (likely(get_ucounts(ucounts)))
-			break;
-		fallthrough;
-	case LONG_MAX:
-		/*
-		 * we need to decrease the ucount in the userns tree on any
-		 * failure to avoid counts leaking.
-		 */
-		dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-		rcu_read_unlock();
-		return NULL;
-	}
+	sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	rcu_read_unlock();
+	if (sigpending == LONG_MAX)
+		return NULL;
 
 	if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
 		q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
@@ -449,8 +437,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	}
 
 	if (unlikely(q == NULL)) {
-		if (dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1))
-			put_ucounts(ucounts);
+		dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	} else {
 		INIT_LIST_HEAD(&q->list);
 		q->flags = sigqueue_flags;
@@ -463,8 +450,8 @@ static void __sigqueue_free(struct sigqueue *q)
 {
 	if (q->flags & SIGQUEUE_PREALLOC)
 		return;
-	if (q->ucounts && dec_rlimit_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING, 1)) {
-		put_ucounts(q->ucounts);
+	if (q->ucounts) {
+		dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING);
 		q->ucounts = NULL;
 	}
 	kmem_cache_free(sigqueue_cachep, q);
kernel/ucount.c +0 -0
index 3b7e176cf7a2..687d77aa66bb 100644
@@ -285,6 +285,47 @@ bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
 	return (new == 0);
 }
 
Quoted 14 lines

kernel/ucount.c bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) · line 297

Quoted 10 lines
kernel/ucount.c +10 -0
+static void do_dec_rlimit_put_ucounts(struct ucounts *ucounts,
+				struct ucounts *last, enum ucount_type type)
+{
+	struct ucounts *iter;
+	for (iter = ucounts; iter != last; iter = iter->ns->ucounts) {
+		long dec = atomic_long_add_return(-1, &iter->ucount[type]);
+		WARN_ON_ONCE(dec < 0);
+		if (dec == 0)
+			put_ucounts(iter);
+	}

Given kfree in put_ucounts(), this has difficulty surviving tests like kasan if the put pairs with the get in the below inc_rlimit_get_ucounts().

I don't know if this is what you are thinking about but there is indeed a bug in that loop caused by kfree.

The problem is that iter->ns->ucounts is read after put_ucounts. It just needs to be read before hand.

Quoted 15 lines
Quoted 15 lines
kernel/ucount.c +15 -0
+}
+
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+	do_dec_rlimit_put_ucounts(ucounts, NULL, type);
+}
+
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+	struct ucounts *iter;
+	long dec, ret = 0;
+
+	for (iter = ucounts; iter; iter = iter->ns->ucounts) {
+		long max = READ_ONCE(iter->ns->ucount_max[type]);
+		long new = atomic_long_add_return(1, &iter->ucount[type]);
Quoted 8 lines

kernel/ucount.c bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v) · line 318

Quoted 6 lines
kernel/ucount.c +6 -0
+		if (new < 0 || new > max)
+			goto unwind;
+		else if (iter == ucounts)
+			ret = new;
+		if ((new == 1) && (get_ucounts(iter) != iter))
+			goto dec_unwind;

Add a line of comment for get to ease readers.

/* you are not expected to understand this */

I think that is the classic comment from unix source. Seriously I can't think of any comment that will make the situation more comprehensible.

Quoted 17 lines

Hillf

Quoted 15 lines
kernel/ucount.c +10 -0
+	}
+	return ret;
+dec_unwind:
+	dec = atomic_long_add_return(1, &iter->ucount[type]);
+	WARN_ON_ONCE(dec < 0);
+unwind:
+	do_dec_rlimit_put_ucounts(ucounts, iter, type);
+	return LONG_MAX;
+}
+
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max)
 {
 	struct ucounts *iter;
Signature · 1 line
2.20.1

Eric

#28 lore raw

Re: [CFT][PATCH] ucounts: Fix signal ucount refcounting

In reply to Eric W. Biederman

Hi!

After applying the below patch, the 5 most problematic servers have run without any issues for 23 hours. That never happened before the patch on 5.14, so the patch seems to have fixed the issue for me.

On Monday there will be more load on the servers, which caused them to crash faster without the patch. I will let you know if it happens again.

Best regards,
Rune

Quoted 20 lines · Eric W. Biederman

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

I wish we had a single user across all of the threads whose rlimit could be charged so we did not need this complexity.

#29 lore raw

Re: [CFT][PATCH] ucounts: Fix signal ucount refcounting

Quoted 6 lines · Rune Kleveland

Hi!

After applying the below patch, the 5 most problematic servers have run without any issues for 23 hours. That never happened before the patch on 5.14, so the patch seems to have fixed the issue for me.

Confirm. I couldn't reproduce the problem on 5.14 either.

Quoted 27 lines

On Monday there will be more load on the servers, which caused them to crash faster without the patch. I will let you know if it happens again.

Best regards,
Rune

Quoted 20 lines · Eric W. Biederman

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

I wish we had a single user across all of the threads whose rlimit could be charged so we did not need this complexity.

#30 lore raw

Re: [CFT][PATCH] ucounts: Fix signal ucount refcounting

Quoted 6 lines · Yu Zhao

On Sun, Oct 17, 2021 at 10:47 AM Rune Kleveland

Quoted 2 lines · [email protected] wrote:

Hi!

Quoted 8 lines
Quoted 5 lines

After applying the below patch, the 5 most problematic servers have run

without any issues for 23 hours. That never happened before the patch on

5.14, so the patch seems to have fixed the issue for me.

Confirm. I couldn't reproduce the problem on 5.14 either.

I'm also unable to reproduce the crash as for now. Thx for the patch.

Jordan

Quoted 41 lines
Quoted 41 lines

On Monday there will be more load on the servers, which caused them to

crash faster without the patch. I will let you know if it happens again.

Best regards,

Rune

Quoted 31 lines · Eric W. Biederman

In commit fda31c50292a ("signal: avoid double atomic counter

increments for user accounting") Linus made a clever optimization to

how rlimits and the struct user_struct. Unfortunately that

optimization does not work in the obvious way when moved to nested

rlimits. The problem is that the last decrement of the per user

namespace per user sigpending counter might also be the last decrement

of the sigpending counter in the parent user namespace as well. Which

means that simply freeing the leaf ucount in __free_sigqueue is not

enough.

Maintain the optimization and handle the tricky cases by introducing

inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of

the work it becomes possible to ensure that every level is handled

properly.

I wish we had a single user across all of the threads whose rlimit

could be charged so we did not need this complexity.

#31 lore raw

PATCH v2 1/1 ucounts: Fix signal ucount refcounting

In reply to Eric W. Biederman

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

The new function inc_rlimit_get_ucounts returns 0 on failure to increment the ucount. This is different than inc_rlimit_ucounts which increments the ucounts and returns LONG_MAX if the ucount counter has exceeded it's maximum or it wrapped (to indicate the counter needs to decremented).

I wish we had a single user to account all pending signals to across all of the threads of a process so this complexity was not necessary

Fixes d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts")

v1: https://lkml.kernel.org/r/87mtnavszx.fsf_-_@disp2133

---

This is my version of the fix with all of the feedback rolled in. I have tested it and believe this is ready to send out.

If folks code take a once over and see if I have spotted things.

For the people who are testing or have tested this I have added your tested-by's please let me know if you mind.

Eric

 include/linux/user_namespace.h |  2 ++
 kernel/signal.c                | 25 +++++------------
 kernel/ucount.c                | 49 ++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 19 deletions(-)
include/linux/user_namespace.h +2 -0
index eb70cabe6e7f..33a4240e6a6f 100644
@@ -127,6 +127,8 @@ static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type t
 
 long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
 bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type);
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type);
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max);
 
 static inline void set_rlimit_ucount_max(struct user_namespace *ns,
kernel/signal.c +6 -19
index a3229add4455..13d2505a14a0 100644
@@ -425,22 +425,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	 */
 	rcu_read_lock();
 	ucounts = task_ucounts(t);
-	sigpending = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-	switch (sigpending) {
-	case 1:
-		if (likely(get_ucounts(ucounts)))
-			break;
-		fallthrough;
-	case LONG_MAX:
-		/*
-		 * we need to decrease the ucount in the userns tree on any
-		 * failure to avoid counts leaking.
-		 */
-		dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-		rcu_read_unlock();
-		return NULL;
-	}
+	sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	rcu_read_unlock();
+	if (!sigpending)
+		return NULL;
 
 	if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
 		q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
@@ -449,8 +437,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
 	}
 
 	if (unlikely(q == NULL)) {
-		if (dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1))
-			put_ucounts(ucounts);
+		dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
 	} else {
 		INIT_LIST_HEAD(&q->list);
 		q->flags = sigqueue_flags;
@@ -463,8 +450,8 @@ static void __sigqueue_free(struct sigqueue *q)
 {
 	if (q->flags & SIGQUEUE_PREALLOC)
 		return;
-	if (q->ucounts && dec_rlimit_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING, 1)) {
-		put_ucounts(q->ucounts);
+	if (q->ucounts) {
+		dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING);
 		q->ucounts = NULL;
 	}
 	kmem_cache_free(sigqueue_cachep, q);
kernel/ucount.c +49 -0

55 lines not on this page · raw message

Signature · 1 line
2.20.1
#32 lore raw

cover ucounts: misc fixes

While digging into the previous ucount kernel crashes I found some minor bugs in the ucount code. When hit these bugs all result in a ucount either being counted in the wrong location or leak of a struct ucounts.

Nothing particularly serious but certainly things that should be fixed.

Eric W. Biederman (3):
ucounts: Pair inc_rlimit_ucounts with dec_rlimit_ucoutns in commit_creds
ucounts: Proper error handling in set_cred_ucounts
ucounts: Move get_ucounts from cred_alloc_blank to key_change_session_keyring

 kernel/cred.c                | 9 ++++-----
 security/keys/process_keys.c | 8 ++++++++
 2 files changed, 12 insertions(+), 5 deletions(-)

Eric

#33 lore raw

PATCH 1/3 ucounts: Pair inc_rlimit_ucounts with dec_rlimit_ucoutns in commit_creds

The purpose of inc_rlimit_ucounts and dec_rlimit_ucounts in commit_creds is to change which rlimit counter is used to track a process when the credentials changes.

Use the same test for both to guarantee the tracking is correct.

Fixes 21d1c5e386bc ("Reimplement RLIMIT_NPROC on top of ucounts")
---
 kernel/cred.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/cred.c +1 -1
index f784e08c2fbd..3d163bfd64a9 100644
@@ -501,7 +501,7 @@ int commit_creds(struct cred *new)
 		inc_rlimit_ucounts(new->ucounts, UCOUNT_RLIMIT_NPROC, 1);
 	rcu_assign_pointer(task->real_cred, new);
 	rcu_assign_pointer(task->cred, new);
-	if (new->user != old->user)
+	if (new->user != old->user || new->user_ns != old->user_ns)
 		dec_rlimit_ucounts(old->ucounts, UCOUNT_RLIMIT_NPROC, 1);
 	alter_cred_subscribers(old, -2);
 
Signature · 1 line
2.20.1
#34 lore raw

PATCH 2/3 ucounts: Proper error handling in set_cred_ucounts

In reply to Eric W. Biederman

Instead of leaking the ucounts in new if alloc_ucounts fails, store the result of alloc_ucounts into a temporary variable, which is later assigned to new->ucounts.

Fixes 905ae01c4ae2 ("Add a reference to ucounts for each cred")
---
 kernel/cred.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/cred.c +3 -2
index 3d163bfd64a9..16c05dfbec4d 100644
@@ -669,7 +669,7 @@ int set_cred_ucounts(struct cred *new)
 {
 	struct task_struct *task = current;
 	const struct cred *old = task->real_cred;
-	struct ucounts *old_ucounts = new->ucounts;
+	struct ucounts *new_ucounts, *old_ucounts = new->ucounts;
 
 	if (new->user == old->user && new->user_ns == old->user_ns)
 		return 0;
@@ -681,9 +681,10 @@ int set_cred_ucounts(struct cred *new)
 	if (old_ucounts && old_ucounts->ns == new->user_ns && uid_eq(old_ucounts->uid, new->euid))
 		return 0;
 
-	if (!(new->ucounts = alloc_ucounts(new->user_ns, new->euid)))
+	if (!(new_ucounts = alloc_ucounts(new->user_ns, new->euid)))
 		return -EAGAIN;
 
+	new->ucounts = new_ucounts;
 	if (old_ucounts)
 		put_ucounts(old_ucounts);
 
Signature · 1 line
2.20.1
#35 lore raw

PATCH 3/3 ucounts: Move get_ucounts from cred_alloc_blank to key_change_session_keyring

In reply to Eric W. Biederman

Setting cred->ucounts in cred_alloc_blank does not make sense. The uid and user_ns are deliberately not set in cred_alloc_blank but instead the setting is delayed until key_change_session_keyring.

So move dealing with ucounts into key_change_session_keyring as well.

Unfortunately that movement of get_ucounts adds a new failure mode to key_change_session_keyring. I do not see anything stopping the parent process from calling setuid and changing the relevant part of it's cred while keyctl_session_to_parent is running making it fundamentally necessary to call get_ucounts in key_change_session_keyring. Which means that the new failure mode cannot be avoided.

A failure of key_change_session_keyring results in a single threaded parent keeping it's existing credentials. Which results in the parent process not being able to access the session keyring and whichever keys are in the new keyring.

Further get_ucounts is only expected to fail if the number of bits in the refernece count for the structure is too few.

Since the code has no other way to report the failure of get_ucounts and because such failures are not expected to be common add a WARN_ONCE to report this problem to userspace.

Between the WARN_ONCE and the parent process not having access to the keys in the new session keyring I expect any failure of get_ucounts will be noticed and reported and we can find another way to handle this condition. (Possibly by just making ucounts->count an atomic_long_t).

Fixes 905ae01c4ae2 ("Add a reference to ucounts for each cred")
---
 kernel/cred.c                | 2 --
 security/keys/process_keys.c | 8 ++++++++
 2 files changed, 8 insertions(+), 2 deletions(-)
kernel/cred.c +0 -2
index 16c05dfbec4d..1ae0b4948a5a 100644
@@ -225,8 +225,6 @@ struct cred *cred_alloc_blank(void)
 #ifdef CONFIG_DEBUG_CREDENTIALS
 	new->magic = CRED_MAGIC;
 #endif
-	new->ucounts = get_ucounts(&init_ucounts);
-
 	if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0)
 		goto error;
 
security/keys/process_keys.c +8 -0
index e3d79a7b6db6..20cc5a9a05fd 100644
@@ -918,6 +918,13 @@ void key_change_session_keyring(struct callback_head *twork)
 		return;
 	}
 
+	/* If get_ucounts fails more bits are needed in the refcount */
+	if (unlikely(!get_ucounts(old->ucounts))) {
+		WARN_ONCE(1, "In %s get_ucounts failed\n");
+		put_cred(new);
+		return;
+	}
+
 	new->  uid	= old->  uid;
 	new-> euid	= old-> euid;
 	new-> suid	= old-> suid;
@@ -927,6 +934,7 @@ void key_change_session_keyring(struct callback_head *twork)
 	new-> sgid	= old-> sgid;
 	new->fsgid	= old->fsgid;
 	new->user	= get_uid(old->user);
+	new->ucounts	= old->ucounts;
 	new->user_ns	= get_user_ns(old->user_ns);
 	new->group_info	= get_group_info(old->group_info);
 
Signature · 1 line
2.20.1
#36 lore raw

Re: [PATCH 3/3] ucounts: Move get_ucounts from cred_alloc_blank to key_change_session_keyring

Thank you for the patch! Yet something to improve:

Hi "Eric,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linux/master]
[also build test ERROR on v5.15-rc6]
[cannot apply to linus/master jmorris-security/next-testing next-20211022] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Eric-W-Biederman/ucounts-Pair-inc_rlimit_ucounts-with-dec_rlimit_ucoutns-in-commit_creds/20211019-022345
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ec681c53f8d2d0ee362ff67f5b98dd8263c15002
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/78e52b4abddecd7a6666f768874ee737c292830d
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Eric-W-Biederman/ucounts-Pair-inc_rlimit_ucounts-with-dec_rlimit_ucoutns-in-commit_creds/20211019-022345 git checkout 78e52b4abddecd7a6666f768874ee737c292830d
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

In file included from arch/arc/include/asm/bug.h:30,
from include/linux/bug.h:5,
from include/linux/thread_info.h:13,
from include/asm-generic/preempt.h:5,
from ./arch/arc/include/generated/asm/preempt.h:1, from include/linux/preempt.h:78,
from include/linux/rcupdate.h:27,
from include/linux/rculist.h:11,
from include/linux/pid.h:5,
from include/linux/sched.h:14,
from security/keys/process_keys.c:9:
security/keys/process_keys.c: In function 'key_change_session_keyring':

>> security/keys/process_keys.c:923:30: error: format '%s' expects a matching 'char *' argument [-Werror=format=]
     923 |                 WARN_ONCE(1, "In %s get_ucounts failed\n");
         |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/asm-generic/bug.h:91:62: note: in definition of macro '__WARN_printf'
      91 |                 warn_slowpath_fmt(__FILE__, __LINE__, taint, arg);      \
         |                                                              ^~~
   include/linux/once_lite.h:19:25: note: in expansion of macro 'WARN'
      19 |                         func(__VA_ARGS__);                              \
         |                         ^~~~
   include/asm-generic/bug.h:150:9: note: in expansion of macro 'DO_ONCE_LITE_IF'
     150 |         DO_ONCE_LITE_IF(condition, WARN, 1, format)
         |         ^~~~~~~~~~~~~~~
   security/keys/process_keys.c:923:17: note: in expansion of macro 'WARN_ONCE'
     923 |                 WARN_ONCE(1, "In %s get_ucounts failed\n");
         |                 ^~~~~~~~~
   security/keys/process_keys.c:923:35: note: format string is defined here
     923 |                 WARN_ONCE(1, "In %s get_ucounts failed\n");
         |                                  ~^
         |                                   |
         |                                   char *

cc1: all warnings being treated as errors

vim +923 security/keys/process_keys.c

906
907 /*
908 * Replace a process's session keyring on behalf of one of its children when
909 * the target process is about to resume userspace execution.
910 */
911 void key_change_session_keyring(struct callback_head *twork)
912 {
913 const struct cred *old = current_cred();
914 struct cred *new = container_of(twork, struct cred, rcu);
915
916 if (unlikely(current->flags & PF_EXITING)) {
917 put_cred(new);
918 return;
919 }
920
921 /* If get_ucounts fails more bits are needed in the refcount */
922 if (unlikely(!get_ucounts(old->ucounts))) {

 > 923			WARN_ONCE(1, "In %s get_ucounts failed\n");

924 put_cred(new);
925 return;
926 }
927
928 new-> uid = old-> uid;
929 new-> euid = old-> euid;
930 new-> suid = old-> suid;
931 new->fsuid = old->fsuid;
932 new-> gid = old-> gid;
933 new-> egid = old-> egid;
934 new-> sgid = old-> sgid;
935 new->fsgid = old->fsgid;
936 new->user = get_uid(old->user);
937 new->ucounts = old->ucounts;
938 new->user_ns = get_user_ns(old->user_ns);
939 new->group_info = get_group_info(old->group_info);
940
941 new->securebits = old->securebits;
942 new->cap_inheritable = old->cap_inheritable;
943 new->cap_permitted = old->cap_permitted;
944 new->cap_effective = old->cap_effective;
945 new->cap_ambient = old->cap_ambient;
946 new->cap_bset = old->cap_bset;
947
948 new->jit_keyring = old->jit_keyring;
949 new->thread_keyring = key_get(old->thread_keyring);
950 new->process_keyring = key_get(old->process_keyring);
951
952 security_transfer_creds(new, old);
953
954 commit_creds(new);
955 }
956

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#37 lore raw

Re: [PATCH 3/3] ucounts: Move get_ucounts from cred_alloc_blank to key_change_session_keyring

Quoted 3 lines · kernel test robot

Hi "Eric,

Thank you for the patch! Yet something to improve:

Fixed already. Thank you for noticing as well.

Eric

Quoted 118 lines

[auto build test ERROR on linux/master]
[also build test ERROR on v5.15-rc6]
[cannot apply to linus/master jmorris-security/next-testing next-20211022] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Eric-W-Biederman/ucounts-Pair-inc_rlimit_ucounts-with-dec_rlimit_ucoutns-in-commit_creds/20211019-022345
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ec681c53f8d2d0ee362ff67f5b98dd8263c15002
config: arc-allyesconfig (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/78e52b4abddecd7a6666f768874ee737c292830d
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Eric-W-Biederman/ucounts-Pair-inc_rlimit_ucounts-with-dec_rlimit_ucoutns-in-commit_creds/20211019-022345 git checkout 78e52b4abddecd7a6666f768874ee737c292830d
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arc

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

In file included from arch/arc/include/asm/bug.h:30,
from include/linux/bug.h:5,
from include/linux/thread_info.h:13,
from include/asm-generic/preempt.h:5,
from ./arch/arc/include/generated/asm/preempt.h:1, from include/linux/preempt.h:78,
from include/linux/rcupdate.h:27,
from include/linux/rculist.h:11,
from include/linux/pid.h:5,
from include/linux/sched.h:14,
from security/keys/process_keys.c:9:
security/keys/process_keys.c: In function 'key_change_session_keyring':

Quoted 1 line
Quoted 1 line

security/keys/process_keys.c:923:30: error: format '%s' expects a matching 'char *' argument [-Werror=format=]

     923 |                 WARN_ONCE(1, "In %s get_ucounts failed\n");
         |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/asm-generic/bug.h:91:62: note: in definition of macro '__WARN_printf'
      91 |                 warn_slowpath_fmt(__FILE__, __LINE__, taint, arg);      \
         |                                                              ^~~
   include/linux/once_lite.h:19:25: note: in expansion of macro 'WARN'
      19 |                         func(__VA_ARGS__);                              \
         |                         ^~~~
   include/asm-generic/bug.h:150:9: note: in expansion of macro 'DO_ONCE_LITE_IF'
     150 |         DO_ONCE_LITE_IF(condition, WARN, 1, format)
         |         ^~~~~~~~~~~~~~~
   security/keys/process_keys.c:923:17: note: in expansion of macro 'WARN_ONCE'
     923 |                 WARN_ONCE(1, "In %s get_ucounts failed\n");
         |                 ^~~~~~~~~
   security/keys/process_keys.c:923:35: note: format string is defined here
     923 |                 WARN_ONCE(1, "In %s get_ucounts failed\n");
         |                                  ~^
         |                                   |
         |                                   char *

cc1: all warnings being treated as errors

vim +923 security/keys/process_keys.c

   906	
   907	/*
   908	 * Replace a process's session keyring on behalf of one of its children when
   909	 * the target  process is about to resume userspace execution.
   910	 */
   911	void key_change_session_keyring(struct callback_head *twork)
   912	{
   913		const struct cred *old = current_cred();
   914		struct cred *new = container_of(twork, struct cred, rcu);
   915	
   916		if (unlikely(current->flags & PF_EXITING)) {
   917			put_cred(new);
   918			return;
   919		}
   920	
   921		/* If get_ucounts fails more bits are needed in the refcount */
   922		if (unlikely(!get_ucounts(old->ucounts))) {
Quoted 1 line

923 WARN_ONCE(1, "In %s get_ucounts failed\n");

   924			put_cred(new);
   925			return;
   926		}
   927	
   928		new->  uid	= old->  uid;
   929		new-> euid	= old-> euid;
   930		new-> suid	= old-> suid;
   931		new->fsuid	= old->fsuid;
   932		new->  gid	= old->  gid;
   933		new-> egid	= old-> egid;
   934		new-> sgid	= old-> sgid;
   935		new->fsgid	= old->fsgid;
   936		new->user	= get_uid(old->user);
   937		new->ucounts	= old->ucounts;
   938		new->user_ns	= get_user_ns(old->user_ns);
   939		new->group_info	= get_group_info(old->group_info);
   940	
   941		new->securebits	= old->securebits;
   942		new->cap_inheritable	= old->cap_inheritable;
   943		new->cap_permitted	= old->cap_permitted;
   944		new->cap_effective	= old->cap_effective;
   945		new->cap_ambient	= old->cap_ambient;
   946		new->cap_bset		= old->cap_bset;
   947	
   948		new->jit_keyring	= old->jit_keyring;
   949		new->thread_keyring	= key_get(old->thread_keyring);
   950		new->process_keyring	= key_get(old->process_keyring);
   951	
   952		security_transfer_creds(new, old);
   953	
   954		commit_creds(new);
   955	}
   956	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#38 lore raw

Re: [PATCH 3/3] ucounts: Move get_ucounts from cred_alloc_blank to key_change_session_keyring

In reply to Eric W. Biederman
Thank you for the patch! Yet something to improve:

Hi "Eric,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linux/master]
[cannot apply to linus/master jmorris-security/next-testing v5.15 next-20211106] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Eric-W-Biederman/ucounts-Pair-inc_rlimit_ucounts-with-dec_rlimit_ucoutns-in-commit_creds/20211019-022345
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ec681c53f8d2d0ee362ff67f5b98dd8263c15002
config: i386-buildonly-randconfig-r003-20211021 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 3cea2505fd8d99a9ba0cb625aecfe28a47c4e3f8)

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/78e52b4abddecd7a6666f768874ee737c292830d
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Eric-W-Biederman/ucounts-Pair-inc_rlimit_ucounts-with-dec_rlimit_ucoutns-in-commit_creds/20211019-022345 git checkout 78e52b4abddecd7a6666f768874ee737c292830d
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=i386

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

>> security/keys/process_keys.c:923:21: error: more '%' conversions than data arguments [-Werror,-Wformat-insufficient-args]
                   WARN_ONCE(1, "In %s get_ucounts failed\n");
                                    ~^
   include/asm-generic/bug.h:150:38: note: expanded from macro 'WARN_ONCE'
           DO_ONCE_LITE_IF(condition, WARN, 1, format)
                                               ^~~~~~
   include/linux/once_lite.h:19:9: note: expanded from macro 'DO_ONCE_LITE_IF'
                           func(__VA_ARGS__);                              \
                                ^~~~~~~~~~~
   include/asm-generic/bug.h:132:29: note: expanded from macro 'WARN'
                   __WARN_printf(TAINT_WARN, format);                      \
                                             ^~~~~~
   include/asm-generic/bug.h:99:17: note: expanded from macro '__WARN_printf'
                   __warn_printk(arg);                                     \
                                 ^~~

1 error generated.

vim +923 security/keys/process_keys.c

906
907 /*
908 * Replace a process's session keyring on behalf of one of its children when
909 * the target process is about to resume userspace execution.
910 */
911 void key_change_session_keyring(struct callback_head *twork)
912 {
913 const struct cred *old = current_cred();
914 struct cred *new = container_of(twork, struct cred, rcu);
915
916 if (unlikely(current->flags & PF_EXITING)) {
917 put_cred(new);
918 return;
919 }
920
921 /* If get_ucounts fails more bits are needed in the refcount */
922 if (unlikely(!get_ucounts(old->ucounts))) {

 > 923			WARN_ONCE(1, "In %s get_ucounts failed\n");

924 put_cred(new);
925 return;
926 }
927
928 new-> uid = old-> uid;
929 new-> euid = old-> euid;
930 new-> suid = old-> suid;
931 new->fsuid = old->fsuid;
932 new-> gid = old-> gid;
933 new-> egid = old-> egid;
934 new-> sgid = old-> sgid;
935 new->fsgid = old->fsgid;
936 new->user = get_uid(old->user);
937 new->ucounts = old->ucounts;
938 new->user_ns = get_user_ns(old->user_ns);
939 new->group_info = get_group_info(old->group_info);
940
941 new->securebits = old->securebits;
942 new->cap_inheritable = old->cap_inheritable;
943 new->cap_permitted = old->cap_permitted;
944 new->cap_effective = old->cap_effective;
945 new->cap_ambient = old->cap_ambient;
946 new->cap_bset = old->cap_bset;
947
948 new->jit_keyring = old->jit_keyring;
949 new->thread_keyring = key_get(old->thread_keyring);
950 new->process_keyring = key_get(old->process_keyring);
951
952 security_transfer_creds(new, old);
953
954 commit_creds(new);
955 }
956

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#39 lore raw

Re: [PATCH 3/3] ucounts: Move get_ucounts from cred_alloc_blank to key_change_session_keyring

In reply to Eric W. Biederman
Thank you for the patch! Perhaps something to improve:

Hi "Eric,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linux/master]
[cannot apply to linus/master jmorris-security/next-testing v5.15 next-20211106] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Eric-W-Biederman/ucounts-Pair-inc_rlimit_ucounts-with-dec_rlimit_ucoutns-in-commit_creds/20211019-022345
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ec681c53f8d2d0ee362ff67f5b98dd8263c15002
config: i386-randconfig-a001-20211019 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d245f2e8597bfb52c34810a328d42b990e4af1a4)

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/78e52b4abddecd7a6666f768874ee737c292830d
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Eric-W-Biederman/ucounts-Pair-inc_rlimit_ucounts-with-dec_rlimit_ucoutns-in-commit_creds/20211019-022345 git checkout 78e52b4abddecd7a6666f768874ee737c292830d
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=i386

If you fix the issue, kindly add following tag as appropriate

All warnings (new ones prefixed by >>):

>> security/keys/process_keys.c:923:21: warning: more '%' conversions than data arguments [-Wformat-insufficient-args]
                   WARN_ONCE(1, "In %s get_ucounts failed\n");
                                    ~^
   include/asm-generic/bug.h:150:38: note: expanded from macro 'WARN_ONCE'
           DO_ONCE_LITE_IF(condition, WARN, 1, format)
                                               ^~~~~~
   include/linux/once_lite.h:19:9: note: expanded from macro 'DO_ONCE_LITE_IF'
                           func(__VA_ARGS__);                              \
                                ^~~~~~~~~~~
   include/asm-generic/bug.h:132:29: note: expanded from macro 'WARN'
                   __WARN_printf(TAINT_WARN, format);                      \
                                             ^~~~~~
   include/asm-generic/bug.h:99:17: note: expanded from macro '__WARN_printf'
                   __warn_printk(arg);                                     \
                                 ^~~

1 warning generated.

vim +923 security/keys/process_keys.c

906
907 /*
908 * Replace a process's session keyring on behalf of one of its children when
909 * the target process is about to resume userspace execution.
910 */
911 void key_change_session_keyring(struct callback_head *twork)
912 {
913 const struct cred *old = current_cred();
914 struct cred *new = container_of(twork, struct cred, rcu);
915
916 if (unlikely(current->flags & PF_EXITING)) {
917 put_cred(new);
918 return;
919 }
920
921 /* If get_ucounts fails more bits are needed in the refcount */
922 if (unlikely(!get_ucounts(old->ucounts))) {

 > 923			WARN_ONCE(1, "In %s get_ucounts failed\n");

924 put_cred(new);
925 return;
926 }
927
928 new-> uid = old-> uid;
929 new-> euid = old-> euid;
930 new-> suid = old-> suid;
931 new->fsuid = old->fsuid;
932 new-> gid = old-> gid;
933 new-> egid = old-> egid;
934 new-> sgid = old-> sgid;
935 new->fsgid = old->fsgid;
936 new->user = get_uid(old->user);
937 new->ucounts = old->ucounts;
938 new->user_ns = get_user_ns(old->user_ns);
939 new->group_info = get_group_info(old->group_info);
940
941 new->securebits = old->securebits;
942 new->cap_inheritable = old->cap_inheritable;
943 new->cap_permitted = old->cap_permitted;
944 new->cap_effective = old->cap_effective;
945 new->cap_ambient = old->cap_ambient;
946 new->cap_bset = old->cap_bset;
947
948 new->jit_keyring = old->jit_keyring;
949 new->thread_keyring = key_get(old->thread_keyring);
950 new->process_keyring = key_get(old->process_keyring);
951
952 security_transfer_creds(new, old);
953
954 commit_creds(new);
955 }
956

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#40 lore raw

cover ucounts: misc cleanups

In reply to Eric W. Biederman

The following changes are a set of miscellaneous fixes that makes the ucount code a little bit easier to read. There are all things that I ran into while helping hunt the crazy reference count bug.

I am aiming these at the next merge window and 5.16 rather than bug fixes to get into the current 5.15.

Eric W. Biederman (4):
ucounts: In set_cred_ucounts assume new->ucounts is non-NULL
ucounts: Remove unnecessary test for NULL ucount in get_ucounts
ucounts: Add get_ucounts_or_wrap for clarity
ucounts: Use atomic_long_sub_return for clarity

 kernel/cred.c   |  5 ++---
 kernel/ucount.c | 20 +++++++++++++-------
 2 files changed, 15 insertions(+), 10 deletions(-)

Eric

#41 lore raw

PATCH 1/4 ucounts: In set_cred_ucounts assume new->ucounts is non-NULL

Any cred that is destined for use by commit_creds must have a non-NULL cred->ucounts field. Only curing credential construction is a NULL cred->ucounts valid. Only abort_creds, put_cred, and put_cred_rcu needs to deal with a cred with a NULL ucount. As set_cred_ucounts is non of those case don't confuse people by handling something that can not happen.

---
 kernel/cred.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
kernel/cred.c +2 -3
index 1ae0b4948a5a..473d17c431f3 100644
@@ -676,15 +676,14 @@ int set_cred_ucounts(struct cred *new)
 	 * This optimization is needed because alloc_ucounts() uses locks
 	 * for table lookups.
 	 */
-	if (old_ucounts && old_ucounts->ns == new->user_ns && uid_eq(old_ucounts->uid, new->euid))
+	if (old_ucounts->ns == new->user_ns && uid_eq(old_ucounts->uid, new->euid))
 		return 0;
 
 	if (!(new_ucounts = alloc_ucounts(new->user_ns, new->euid)))
 		return -EAGAIN;
 
 	new->ucounts = new_ucounts;
-	if (old_ucounts)
-		put_ucounts(old_ucounts);
+	put_ucounts(old_ucounts);
 
 	return 0;
 }
Signature · 1 line
2.20.1
#42 lore raw

PATCH 2/4 ucounts: Remove unnecessary test for NULL ucount in get_ucounts

In reply to Eric W. Biederman

All of the callers of get_ucounts are passeds a non-NULL value so stop handling a NULL ucounts pointer in get_ucounts.

It is guaranteed that ever valid fully formed cred that is passed to commit_cred contains a non-NULL ucounts pointer. This in turn gurantees that current_ucounts() never returns NULL.

The call of get_ucounts in user_shm_lock is always passed current_ucounts().

The call of get_ucounts in mqueue_get_inode is always passed current_ucounts().

The call of get_ucounts in inc_rlmit_get_ucounts is always passed iter, after iter has been verified to be non-NULL.

The call of get_ucounts in key_change_session_keyring is always passed current_ucounts().

The call of get_ucounts in prepare_cred is always passed current_ucounts().

The call of get_ucounts in prepare_kernel_cred is always passed task->cred->ucounts or init_cred->ucounts which being on tasks are guaranteed to have a non-NULL ucounts field.

---
 kernel/ucount.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/ucount.c +1 -1
index eb03f3c68375..708d05164a7d 100644
@@ -152,7 +152,7 @@ static void hlist_add_ucounts(struct ucounts *ucounts)
 
 struct ucounts *get_ucounts(struct ucounts *ucounts)
 {
-	if (ucounts && atomic_add_negative(1, &ucounts->count)) {
+	if (atomic_add_negative(1, &ucounts->count)) {
 		put_ucounts(ucounts);
 		ucounts = NULL;
 	}
Signature · 1 line
2.20.1
#43 lore raw

PATCH 3/4 ucounts: Add get_ucounts_or_wrap for clarity

In reply to Eric W. Biederman

Add a helper function get_ucounts_or_wrap that is a trivial wrapper around atomic_add_negative, that makes it clear how atomic_add_negative is used in the context of ucounts.

---
 kernel/ucount.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
kernel/ucount.c +10 -4
index 708d05164a7d..133b6044fda4 100644
@@ -150,9 +150,15 @@ static void hlist_add_ucounts(struct ucounts *ucounts)
 	spin_unlock_irq(&ucounts_lock);
 }
 
+static inline bool get_ucounts_or_wrap(struct ucounts *ucounts)
+{
+	/* Returns true on a successful get, false if the count wraps. */
+	return !atomic_add_negative(1, &ucounts->count);
+}
+
 struct ucounts *get_ucounts(struct ucounts *ucounts)
 {
-	if (atomic_add_negative(1, &ucounts->count)) {
+	if (!get_ucounts_or_wrap(ucounts)) {
 		put_ucounts(ucounts);
 		ucounts = NULL;
 	}
@@ -163,7 +169,7 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid)
 {
 	struct hlist_head *hashent = ucounts_hashentry(ns, uid);
 	struct ucounts *ucounts, *new;
-	long overflow;
+	bool wrapped;
 
 	spin_lock_irq(&ucounts_lock);
 	ucounts = find_ucounts(ns, uid, hashent);
@@ -188,9 +194,9 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid)
 			return new;
 		}
 	}
-	overflow = atomic_add_negative(1, &ucounts->count);
+	wrapped = !get_ucounts_or_wrap(ucounts);
 	spin_unlock_irq(&ucounts_lock);
-	if (overflow) {
+	if (wrapped) {
 		put_ucounts(ucounts);
 		return NULL;
 	}
Signature · 1 line
2.20.1
#44 lore raw

PATCH 4/4 ucounts: Use atomic_long_sub_return for clarity

In reply to Eric W. Biederman

Decrement ucounts using atomic_long_sub_return to make it clear the point is for the ucount to decrease.

Not a big deal but it should make it easier to catch bugs.

---
 kernel/ucount.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/ucount.c +3 -3
index 133b6044fda4..4f5613dac227 100644
@@ -282,7 +282,7 @@ bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
 	struct ucounts *iter;
 	long new = -1; /* Silence compiler warning */
 	for (iter = ucounts; iter; iter = iter->ns->ucounts) {
-		long dec = atomic_long_add_return(-v, &iter->ucount[type]);
+		long dec = atomic_long_sub_return(v, &iter->ucount[type]);
 		WARN_ON_ONCE(dec < 0);
 		if (iter == ucounts)
 			new = dec;
@@ -295,7 +295,7 @@ static void do_dec_rlimit_put_ucounts(struct ucounts *ucounts,
 {
 	struct ucounts *iter, *next;
 	for (iter = ucounts; iter != last; iter = next) {
-		long dec = atomic_long_add_return(-1, &iter->ucount[type]);
+		long dec = atomic_long_sub_return(1, &iter->ucount[type]);
 		WARN_ON_ONCE(dec < 0);
 		next = iter->ns->ucounts;
 		if (dec == 0)
@@ -332,7 +332,7 @@ long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
 	}
 	return ret;
 dec_unwind:
-	dec = atomic_long_add_return(-1, &iter->ucount[type]);
+	dec = atomic_long_sub_return(1, &iter->ucount[type]);
 	WARN_ON_ONCE(dec < 0);
 unwind:
 	do_dec_rlimit_put_ucounts(ucounts, iter, type);
Signature · 1 line
2.20.1
Tested-by on the v1 series
#45 lore raw

Re: [PATCH 0/4] ucounts: misc cleanups

In reply to Eric W. Biederman
Quoted 16 lines · Eric W. Biederman

The following changes are a set of miscellaneous fixes that makes the ucount code a little bit easier to read. There are all things that I ran into while helping hunt the crazy reference count bug.

I am aiming these at the next merge window and 5.16 rather than bug fixes to get into the current 5.15.

Eric W. Biederman (4):
ucounts: In set_cred_ucounts assume new->ucounts is non-NULL
ucounts: Remove unnecessary test for NULL ucount in get_ucounts
ucounts: Add get_ucounts_or_wrap for clarity
ucounts: Use atomic_long_sub_return for clarity

Quoted 3 lines
 kernel/cred.c   |  5 ++---
 kernel/ucount.c | 20 +++++++++++++-------
 2 files changed, 15 insertions(+), 10 deletions(-)

Thanks for the cleanups. Tested the whole series on the latest 5.15-rc6.

Tested-by on the v1 series
#46 lore raw

Re: [PATCH 0/3] ucounts: misc fixes

In reply to Eric W. Biederman
Quoted 8 lines · Eric W. Biederman

While digging into the previous ucount kernel crashes I found some minor bugs in the ucount code. When hit these bugs all result in a ucount either being counted in the wrong location or leak of a struct ucounts.

Nothing particularly serious but certainly things that should be fixed.

Quoted 8 lines

Eric W. Biederman (3):
ucounts: Pair inc_rlimit_ucounts with dec_rlimit_ucoutns in commit_creds
ucounts: Proper error handling in set_cred_ucounts
ucounts: Move get_ucounts from cred_alloc_blank to key_change_session_keyring

 kernel/cred.c                | 9 ++++-----
 security/keys/process_keys.c | 8 ++++++++
 2 files changed, 12 insertions(+), 5 deletions(-)

Thanks for the fixes. Tested the whole series on the latest 5.15-rc6.

#47 lore raw

Re: [PATCH v2] ucounts: Fix signal ucount refcounting

In reply to Eric W. Biederman
Quoted 40 lines · Eric W. Biederman

In commit fda31c50292a ("signal: avoid double atomic counter increments for user accounting") Linus made a clever optimization to how rlimits and the struct user_struct. Unfortunately that optimization does not work in the obvious way when moved to nested rlimits. The problem is that the last decrement of the per user namespace per user sigpending counter might also be the last decrement of the sigpending counter in the parent user namespace as well. Which means that simply freeing the leaf ucount in __free_sigqueue is not enough.

Maintain the optimization and handle the tricky cases by introducing inc_rlimit_get_ucounts and dec_rlimit_put_ucounts.

By moving the entire optimization into functions that perform all of the work it becomes possible to ensure that every level is handled properly.

The new function inc_rlimit_get_ucounts returns 0 on failure to increment the ucount. This is different than inc_rlimit_ucounts which increments the ucounts and returns LONG_MAX if the ucount counter has exceeded it's maximum or it wrapped (to indicate the counter needs to decremented).

I wish we had a single user to account all pending signals to across all of the threads of a process so this complexity was not necessary

Fixes d64696905554 ("Reimplement RLIMIT_SIGPENDING on top of ucounts")

v1: https://lkml.kernel.org/r/87mtnavszx.fsf_-_@disp2133

---

This is my version of the fix with all of the feedback rolled in. I have tested it and believe this is ready to send out.

Quoted 6 lines

If folks code take a once over and see if I have spotted things.

For the people who are testing or have tested this I have added your tested-by's please let me know if you mind.

Eric

Retested on the latest 5.15-rc6. This patch fixes the following crash:

[ 3307.621443] ==================================================================
[ 3307.628890] BUG: KASAN: use-after-free in dec_ucount+0x50/0xd8
[ 3307.634903] Write of size 8 at addr ffffff80a5e4c520 by task kworker/7:3/201
[ 3307.642149]
[ 3307.643695] CPU: 7 PID: 201 Comm: kworker/7:3 Not tainted
5.15.0-rc6-lockdep+ #7
[ 3307.651291] Hardware name: Google Lazor (rev3+) with KB Backlight (DT)
[ 3307.658001] Workqueue: events free_user_ns
[ 3307.662231] Call trace:
[ 3307.664750]  dump_backtrace+0x0/0x42c
[ 3307.668522]  show_stack+0x24/0x30
[ 3307.671935]  dump_stack_lvl+0xd0/0x100
[ 3307.675797]  print_address_description+0x30/0x304
[ 3307.680646]  kasan_report+0x190/0x1d8
[ 3307.684419]  kasan_check_range+0x1ac/0x1bc
[ 3307.688630]  __kasan_check_write+0x44/0x54
[ 3307.692852]  dec_ucount+0x50/0xd8
[ 3307.696266]  free_user_ns+0x1b0/0x288
[ 3307.700036]  process_one_work+0x7b4/0x1130
[ 3307.704251]  worker_thread+0x800/0xcf4
[ 3307.708111]  kthread+0x2a8/0x358
[ 3307.711437]  ret_from_fork+0x10/0x20
[ 3307.715121]
[ 3307.716664] Allocated by task 6564:
[ 3307.720253]  kasan_save_stack+0x38/0x68
[ 3307.724206]  __kasan_kmalloc+0x9c/0xb8
[ 3307.728068]  kmem_cache_alloc_trace+0x260/0x32c
[ 3307.732729]  alloc_ucounts+0x150/0x374
[ 3307.736589]  set_cred_ucounts+0x178/0x240
[ 3307.740714]  __sys_setresuid+0x31c/0x4f8
[ 3307.744754]  __arm64_sys_setresuid+0x84/0x98
[ 3307.749153]  invoke_syscall+0xcc/0x2bc
[ 3307.753012]  el0_svc_common+0x118/0x1ec
[ 3307.756961]  do_el0_svc_compat+0x50/0x60
[ 3307.761005]  el0_svc_compat+0x5c/0xec
[ 3307.764774]  el0t_32_sync_handler+0xc0/0xf0
[ 3307.769083]  el0t_32_sync+0x1a4/0x1a8
[ 3307.772852]
[ 3307.774399] The buggy address belongs to the object at ffffff80a5e4c500
[ 3307.774399]  which belongs to the cache kmalloc-256 of size 256
[ 3307.787250] The buggy address is located 32 bytes inside of
[ 3307.787250]  256-byte region [ffffff80a5e4c500, ffffff80a5e4c600)
[ 3307.799216] The buggy address belongs to the page:
[ 3307.804141] page:fffffffe02979200 refcount:1 mapcount:0
mapping:0000000000000000 index:0xffffff80a5e4c100 pfn:0x125e48
[ 3307.815127] head:fffffffe02979200 order:3 compound_mapcount:0
compound_pincount:0
[ 3307.822808] flags: 0x8000000000010200(slab|head|zone=2)
[ 3307.828187] raw: 8000000000010200 fffffffe0250ba08 fffffffe00f04a08
ffffff808000c980
[ 3307.836148] raw: ffffff80a5e4c100 0000000000200001 00000001ffffffff
0000000000000000
[ 3307.844104] page dumped because: kasan: bad access detected
[ 3307.849837]
[ 3307.851381] Memory state around the buggy address:
[ 3307.856307]  ffffff80a5e4c400: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 3307.863729]  ffffff80a5e4c480: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 3307.871146] >ffffff80a5e4c500: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 3307.878562]                                ^
[ 3307.882956]  ffffff80a5e4c580: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 3307.890375]  ffffff80a5e4c600: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 3307.897800] ==================================================================
Quoted 132 lines
 include/linux/user_namespace.h |  2 ++
 kernel/signal.c                | 25 +++++------------
 kernel/ucount.c                | 49 ++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 19 deletions(-)
include/linux/user_namespace.h +2 -0
index eb70cabe6e7f..33a4240e6a6f 100644
@@ -127,6 +127,8 @@ static inline long get_ucounts_value(struct ucounts *ucounts, enum ucount_type t
 
 long inc_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
 bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v);
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type);
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type);
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max);
 
 static inline void set_rlimit_ucount_max(struct user_namespace *ns,
kernel/signal.c +6 -19
index a3229add4455..13d2505a14a0 100644
@@ -425,22 +425,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
         */
        rcu_read_lock();
        ucounts = task_ucounts(t);
-       sigpending = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-       switch (sigpending) {
-       case 1:
-               if (likely(get_ucounts(ucounts)))
-                       break;
-               fallthrough;
-       case LONG_MAX:
-               /*
-                * we need to decrease the ucount in the userns tree on any
-                * failure to avoid counts leaking.
-                */
-               dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1);
-               rcu_read_unlock();
-               return NULL;
-       }
+       sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
        rcu_read_unlock();
+       if (!sigpending)
+               return NULL;
 
        if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
                q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
@@ -449,8 +437,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
        }
 
        if (unlikely(q == NULL)) {
-               if (dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, 1))
-                       put_ucounts(ucounts);
+               dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);
        } else {
                INIT_LIST_HEAD(&q->list);
                q->flags = sigqueue_flags;
@@ -463,8 +450,8 @@ static void __sigqueue_free(struct sigqueue *q)
 {
        if (q->flags & SIGQUEUE_PREALLOC)
                return;
-       if (q->ucounts && dec_rlimit_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING, 1)) {
-               put_ucounts(q->ucounts);
+       if (q->ucounts) {
+               dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING);
                q->ucounts = NULL;
        }
        kmem_cache_free(sigqueue_cachep, q);
kernel/ucount.c +49 -1
index bb51849e6375..eb03f3c68375 100644
@@ -284,6 +284,55 @@ bool dec_rlimit_ucounts(struct ucounts *ucounts, enum ucount_type type, long v)
        return (new == 0);
 }
 
+static void do_dec_rlimit_put_ucounts(struct ucounts *ucounts,
+                               struct ucounts *last, enum ucount_type type)
+{
+       struct ucounts *iter, *next;
+       for (iter = ucounts; iter != last; iter = next) {
+               long dec = atomic_long_add_return(-1, &iter->ucount[type]);
+               WARN_ON_ONCE(dec < 0);
+               next = iter->ns->ucounts;
+               if (dec == 0)
+                       put_ucounts(iter);
+       }
+}
+
+void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+       do_dec_rlimit_put_ucounts(ucounts, NULL, type);
+}
+
+long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum ucount_type type)
+{
+       /* Caller must hold a reference to ucounts */
+       struct ucounts *iter;
+       long dec, ret = 0;
+
+       for (iter = ucounts; iter; iter = iter->ns->ucounts) {
+               long max = READ_ONCE(iter->ns->ucount_max[type]);
+               long new = atomic_long_add_return(1, &iter->ucount[type]);
+               if (new < 0 || new > max)
+                       goto unwind;
+               if (iter == ucounts)
+                       ret = new;
+               /*
+                * Grab an extra ucount reference for the caller when
+                * the rlimit count was previously 0.
+                */
+               if (new != 1)
+                       continue;
+               if (!get_ucounts(iter))
+                       goto dec_unwind;
+       }
+       return ret;
+dec_unwind:
+       dec = atomic_long_add_return(-1, &iter->ucount[type]);
+       WARN_ON_ONCE(dec < 0);
+unwind:
+       do_dec_rlimit_put_ucounts(ucounts, iter, type);
+       return 0;
+}
+
 bool is_ucounts_overlimit(struct ucounts *ucounts, enum ucount_type type, unsigned long max)
 {
        struct ucounts *iter;
--

2.20.1

#48 lore raw
In reply to Eric W. Biederman
Quoted 70 lines · Eric W. Biederman
Quoted 23 lines · [email protected] (Eric W. Biederman) writes:

Adding Rune Kleveland to the discussion as he also seems to have reproduced the issue.

Alex and I have been starring at the code and the reports and this bug is hiding well. Here is what we have figured out so far.

Both the warning from free_user_ns calling dec_ucount that Jordan Glover reported and the KASAN error that Yu Zhao has reported appear to have the same cause. Using a ucounts structure after it has been freed and reallocated as something else.

I have just skimmed through the recent report from Rune Kleveland and it appears also to be a use after free. Especially since the second failure in the log is slub complaining about trying to free the ucounts data structure.

We looked through the users of put_ucounts and we don't see any obvious buggy users that would be freeing the data structure early.

Alex has tried to reproduce this so far is not having any luck. Folks can you tell what compiler versions you are using and share your kernel config with us? That might help.

Quoted 6 lines

The little debug diff below is my guess of what is happening. If the folks who can reproduce this issue can try the patch below and let me know if the warnings fire that would be appreciated. It is still not enough to track down the bug but at least it will confirm my current hypothesis about how things look before there is a use of memory after it is freed.

Bah. Scratch that test patch. I just double checked myself and cred->ucounts and cred->user_ns->ucounts should never be equal, as the user namespace is counted in it's parent user namespace.

That observation now tells me I have a parent user namespace that went corrupt.

Back to the drawing board.

Quoted 28 lines

Thank you,
Eric

kernel/cred.c +6 -0
index f784e08c2fbd..e7ffaa3cf5a6 100644
@@ -120,6 +120,12 @@ static void put_cred_rcu(struct rcu_head *rcu)
 	if (cred->group_info)
 		put_group_info(cred->group_info);
 	free_uid(cred->user);
+#if 1
+	if ((cred->ucounts == cred->user_ns->ucounts) &&
+	    (atomic_read(&cred->ucounts->count) == 1)) {
+		WARN_ONCE(1, "put_cred_rcu: ucount count 1\n");
+	}
+#endif
 	if (cred->ucounts)
 		put_ucounts(cred->ucounts);
 	put_user_ns(cred->user_ns);
kernel/exit.c +0 -0
index 91a43e57a32e..60fd88b34c1a 100644
@@ -743,6 +743,13 @@ void __noreturn do_exit(long code)
 	if (unlikely(!tsk->pid))
 		panic("Attempted to kill the idle task!");
 
Quoted 11 lines

kernel/exit.c void __noreturn do_exit(long code) · line 755

Quoted 10 lines
kernel/exit.c +7 -0
+#if 1
+	if ((tsk->cred->ucounts == tsk->cred->user_ns->ucounts) &&
+	    (atomic_read(tsk->cred->ucounts->count) == 1)) {
+		WARN_ONCE(1, "do_exit: ucount count 1\n");
+	}
+#endif
+
 	/*
 	 * If do_exit is called because this processes oopsed, it's possible
 	 * that get_fs() was left as KERNEL_DS, so reset it to USER_DS before

It looks like I found a fairly reliable reproducer. I'm able to reproduce the problem on ARCH=um.

I added a bit of debugging and it looks like the namespace has a reference count problem:

[    6.970000] ------------[ cut here ]------------
[    6.970000] WARNING: CPU: 0 PID: 18 at kernel/ucount.c:257 dec_ucount+0x86/0xfc
[    6.970000] dec_ucounts: accessing freed ucounts: 0000000061202780
                                                     ^^^^^^^^^^^^^^^^

This is a pointer to the freed ucounts.

[    6.970000] Modules linked in:
[    6.970000] CPU: 0 PID: 18 Comm: kworker/u2:1 Tainted: G        W         5.15.0-rc3-00082-ga81d1c67022e-dirty #14
[    6.970000] Workqueue: netns cleanup_net
[    6.970000] Stack:
[    6.970000]  800bfca0 602693cb 603d3767 00000000
[    6.970000]  6048c52d 00000009 603d23b5 60046b28
[    6.970000]  800bfcc0 603d37a7 603d3767 800bfd20
[    6.970000] Call Trace:
[    6.970000]  [<603d23b5>] ? _printk+0x0/0xa1
[    6.970000]  [<600238df>] show_stack+0x14b/0x15a
[    6.970000]  [<602693cb>] ? dump_stack_print_info+0xeb/0xfa
[    6.970000]  [<603d3767>] ? dump_stack+0x0/0x45
[    6.970000]  [<603d23b5>] ? _printk+0x0/0xa1
[    6.970000]  [<60046b28>] ? __local_bh_enable_ip+0x0/0xf8
[    6.970000]  [<603d37a7>] dump_stack+0x40/0x45
[    6.970000]  [<603d3767>] ? dump_stack+0x0/0x45
[    6.970000]  [<60043633>] __warn+0x101/0x149
[    6.970000]  [<603d1559>] warn_slowpath_fmt+0xde/0xec
[    6.970000]  [<6003953b>] ? set_signals+0x0/0x48
[    6.970000]  [<60265087>] ? free_object+0x1d/0x73
[    6.970000]  [<603d147b>] ? warn_slowpath_fmt+0x0/0xec
[    6.970000]  [<60083a2d>] ? destroy_rcu_head+0x27/0x29
[    6.970000]  [<60083ba3>] ? __wait_rcu_gp+0x12d/0x14f
[    6.970000]  [<600846bb>] ? rcu_barrier+0x0/0x40
[    6.970000]  [<6006471d>] dec_ucount+0x86/0xfc
[    6.970000]  [<60064697>] ? dec_ucount+0x0/0xfc
[    6.970000]  [<6031221f>] cleanup_net+0x2cb/0x326
[    6.970000]  [<60039468>] ? unblock_signals+0x0/0xd3
[    6.970000]  [<60059daa>] process_one_work+0x1e1/0x2df
[    6.970000]  [<60039445>] ? block_signals+0x0/0x23
[    6.970000]  [<6003947c>] ? unblock_signals+0x14/0xd3
[    6.970000]  [<6005658e>] ? move_linked_works+0x0/0x8a
[    6.970000]  [<6005a49c>] worker_thread+0x293/0x3c0
[    6.970000]  [<600566bc>] ? set_pf_worker+0x0/0x6d
[    6.970000]  [<6005ecf2>] ? arch_local_irq_save+0x0/0x29
[    6.970000]  [<60045960>] ? do_exit+0x0/0x93e
[    6.970000]  [<6005a209>] ? worker_thread+0x0/0x3c0
[    6.970000]  [<60060554>] kthread+0x171/0x179
[    6.970000]  [<6002230e>] new_thread_handler+0x8e/0xbf
[    6.970000] ---[ end trace 02feadf6f35abde2 ]---
[    6.970000]
[    6.970000] Modules linked in:
[    6.970000] Pid: 18, comm: kworker/u2:1 Tainted: G        W         5.15.0-rc3-00082-ga81d1c67022e-dirty
[    6.970000] RIP: 0033:[<000000006006476f>]
[    6.970000] RSP: 00000000800bfe20  EFLAGS: 00010246
[    6.970000] RAX: 0000000000000000 RBX: 0000000000000048 RCX: 0000000000000000
[    6.970000] RDX: 00000000612027c8 RSI: 00000000ffffffff RDI: 0000000000000009
[    6.970000] RBP: 00000000800bfe40 R08: 0000000060551bc8 R09: 0000000000015920
[    6.970000] R10: 00000000600203e0 R11: 0000000000015920 R12: 0000000061202780
[    6.970000] R13: 000000006057bca6 R14: 0000000061202780 R15: 0000000060046b28
[    6.970000] Kernel panic - not syncing: Segfault with no mm
[    6.970000] CPU: 0 PID: 18 Comm: kworker/u2:1 Tainted: G        W         5.15.0-rc3-00082-ga81d1c67022e-dirty #14
[    6.970000] Workqueue: netns cleanup_net
[    6.970000] Stack:
[    6.970000]  800bfe48 612d69c0 800bfe70 60064697
[    6.970000]  800bfeb0 6031221f ffffffff800bfe90 605735c0
[    6.970000]  60039468 ffff8d00 800bfe70 800bfe70
[    6.970000] Call Trace:
[    6.970000]  [<60064697>] ? dec_ucount+0x0/0xfc
[    6.970000]  [<6031221f>] cleanup_net+0x2cb/0x326
[    6.970000]  [<60039468>] ? unblock_signals+0x0/0xd3
[    6.970000]  [<60059daa>] process_one_work+0x1e1/0x2df
[    6.970000]  [<60039445>] ? block_signals+0x0/0x23
[    6.970000]  [<6003947c>] ? unblock_signals+0x14/0xd3
[    6.970000]  [<6005658e>] ? move_linked_works+0x0/0x8a
[    6.970000]  [<6005a49c>] worker_thread+0x293/0x3c0
[    6.970000]  [<600566bc>] ? set_pf_worker+0x0/0x6d
[    6.970000]  [<6005ecf2>] ? arch_local_irq_save+0x0/0x29
[    6.970000]  [<60045960>] ? do_exit+0x0/0x93e
[    6.970000]  [<6005a209>] ? worker_thread+0x0/0x3c0
[    6.970000]  [<60060554>] kthread+0x171/0x179
[    6.970000]  [<6002230e>] new_thread_handler+0x8e/0xbf

This is where this ucounts was created:

[    5.530000] ------------[ cut here ]------------
[    5.530000] WARNING: CPU: 0 PID: 216 at kernel/ucount.c:187 alloc_ucounts+0x174/0x189
[    5.530000] allooc_ucounts: new ucounts ucounts=0000000061202780
[    5.530000] Modules linked in:
[    5.530000] CPU: 0 PID: 216 Comm: unshare Tainted: G        W         5.15.0-rc3-00082-ga81d1c67022e-dirty #14
[    5.530000] Stack:
[    5.530000]  8045bb00 602693cb 603d3767 00000000
[    5.530000]  6048c52d 00000009 603d23b5 6063d388
[    5.530000]  8045bb20 603d37a7 603d3767 8045bb80
[    5.530000] Call Trace:
[    5.530000]  [<603d23b5>] ? _printk+0x0/0xa1
[    5.530000]  [<600238df>] show_stack+0x14b/0x15a
[    5.530000]  [<602693cb>] ? dump_stack_print_info+0xeb/0xfa
[    5.530000]  [<603d3767>] ? dump_stack+0x0/0x45
[    5.530000]  [<603d23b5>] ? _printk+0x0/0xa1
[    5.530000]  [<603d37a7>] dump_stack+0x40/0x45
[    5.530000]  [<603d3767>] ? dump_stack+0x0/0x45
[    5.530000]  [<60043633>] __warn+0x101/0x149
[    5.530000]  [<60039468>] ? unblock_signals+0x0/0xd3
[    5.530000]  [<603d1559>] warn_slowpath_fmt+0xde/0xec
[    5.530000]  [<60274613>] ? memcmp+0x0/0x2f
[    5.530000]  [<60039445>] ? block_signals+0x0/0x23
[    5.530000]  [<603d147b>] ? warn_slowpath_fmt+0x0/0xec
[    5.530000]  [<600ff06d>] ? arch_local_irq_save+0x0/0x29
[    5.530000]  [<600ff8d7>] ? slab_post_alloc_hook+0x5b/0x1ae
[    5.530000]  [<60039445>] ? block_signals+0x0/0x23
[    5.530000]  [<600645e2>] alloc_ucounts+0x174/0x189
[    5.530000]  [<600645f7>] ? inc_ucount+0x0/0xa0
[    5.530000]  [<60064618>] inc_ucount+0x21/0xa0
[    5.530000]  [<6012f6e0>] alloc_mnt_ns+0x53/0x193
[    5.530000]  [<600ff06d>] ? arch_local_irq_save+0x0/0x29
[    5.530000]  [<601334c6>] ? copy_mnt_ns+0x0/0x29e
[    5.530000]  [<60133570>] copy_mnt_ns+0xaa/0x29e
[    5.530000]  [<600609a6>] create_new_namespaces+0x7c/0x2b4
[    5.530000]  [<60060ed7>] unshare_nsproxy_namespaces+0xb1/0xcb
[    5.530000]  [<600b1111>] ? unshare_userns+0x4c/0x78
[    5.530000]  [<60042dcb>] ksys_unshare+0x179/0x345
[    5.530000]  [<60042fb4>] sys_unshare+0x1d/0x21
[    5.530000]  [<60025b0a>] handle_syscall+0x8e/0xbe
[    5.530000]  [<6003c471>] userspace+0x3cf/0x536
[    5.530000]  [<600223e0>] fork_handler+0xa1/0xa3
[    5.530000] ---[ end trace 02feadf6f35abdd7 ]---
Signature · 1 line
Rgrds, legion
#49 lore raw
In reply to Yu Zhao
Quoted 89 lines · On Thu, 30 Sep 2021 16:27:34 -0600 Yu Zhao wrote:
Quoted 4 lines · Alexey Gladkov
Quoted 2 lines · Jordan Glover
Quoted 2 lines

I'm still investigating, but I would like to rule out one option.

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Could you check out the patch?

Thx, I added it to my kernel and will report in few days. Does this patch try to fix the issue or make it easier to track?

I suspect the error is caused by a race between allow_ucounts() and put_ucounts(). I think this patch could solve the problem.

Thanks for your help. Still can reproduce the problem with the change suggested.

[ 7761.885966] ==================================================================
[ 7761.893462] BUG: KASAN: use-after-free in dec_ucount+0x50/0xd8
[ 7761.899491] Write of size 8 at addr ffffff80c537b140 by task
kworker/u16:3/10303
[ 7761.907110]
[ 7761.908668] CPU: 0 PID: 10303 Comm: kworker/u16:3 Not tainted
5.14.0-lockdep+ #1
[ 7761.916289] Hardware name: Google Lazor (rev3+) with KB Backlight (DT)
[ 7761.923021] Workqueue: netns cleanup_net
[ 7761.927106] Call trace:
[ 7761.929648]  dump_backtrace+0x0/0x42c
[ 7761.933442]  show_stack+0x24/0x30
[ 7761.936878]  dump_stack_lvl+0xd0/0x100
[ 7761.940763]  print_address_description+0x30/0x304
[ 7761.945628]  kasan_report+0x190/0x1d8
[ 7761.949418]  kasan_check_range+0x1ac/0x1bc
[ 7761.953655]  __kasan_check_write+0x44/0x54
[ 7761.957891]  dec_ucount+0x50/0xd8
[ 7761.961334]  cleanup_net+0x630/0x718
[ 7761.965036]  process_one_work+0x7b4/0x10ec
[ 7761.969274]  worker_thread+0x800/0xcf4
[ 7761.973152]  kthread+0x2a8/0x358
[ 7761.976496]  ret_from_fork+0x10/0x18
[ 7761.980201]
[ 7761.981761] Allocated by task 4840:
[ 7761.985366]  kasan_save_stack+0x38/0x68
[ 7761.989342]  __kasan_kmalloc+0x9c/0xb8
[ 7761.993222]  kmem_cache_alloc_trace+0x2a4/0x370
[ 7761.997905]  alloc_ucounts+0x150/0x374
[ 7762.001787]  set_cred_ucounts+0x198/0x248
[ 7762.005935]  __sys_setresuid+0x31c/0x4f8
[ 7762.009993]  __arm64_sys_setresuid+0x84/0x98
[ 7762.014410]  invoke_syscall+0xd4/0x2c8
[ 7762.018292]  el0_svc_common+0x124/0x200
[ 7762.022265]  do_el0_svc_compat+0x54/0x64
[ 7762.026325]  el0_svc_compat+0x24/0x34
[ 7762.030124]  el0t_32_sync_handler+0xc0/0xf0
[ 7762.034451]  el0t_32_sync+0x19c/0x1a0
[ 7762.038241]
[ 7762.039799] Freed by task 0:
[ 7762.042778]  kasan_save_stack+0x38/0x68
[ 7762.046747]  kasan_set_track+0x28/0x3c
[ 7762.050625]  kasan_set_free_info+0x28/0x4c
[ 7762.054857]  ____kasan_slab_free+0x118/0x164
[ 7762.059277]  __kasan_slab_free+0x18/0x28
[ 7762.063339]  kfree+0x2f8/0x500
[ 7762.066505]  put_ucounts+0x11c/0x134
[ 7762.070209]  put_cred_rcu+0x1bc/0x35c
[ 7762.074006]  rcu_core+0xa68/0x1b20
[ 7762.077538]  rcu_core_si+0x1c/0x28
[ 7762.081061]  __do_softirq+0x4bc/0xedc
[ 7762.084851]
[ 7762.086401] The buggy address belongs to the object at ffffff80c537b100
[ 7762.086401]  which belongs to the cache kmalloc-256 of size 256
[ 7762.099267] The buggy address is located 64 bytes inside of
[ 7762.099267]  256-byte region [ffffff80c537b100, ffffff80c537b200)
[ 7762.111248] The buggy address belongs to the page:
[ 7762.116185] page:fffffffe0314de00 refcount:1 mapcount:0
mapping:0000000000000000 index:0xffffff80c537ad00 pfn:0x145378
[ 7762.127180] head:fffffffe0314de00 order:3 compound_mapcount:0
compound_pincount:0
[ 7762.134881] flags: 0x8000000000010200(slab|head|zone=2)
[ 7762.140286] raw: 8000000000010200 fffffffe02799408 fffffffe02020808
ffffff808000c980
[ 7762.148263] raw: ffffff80c537ad00 0000000000200004 00000001ffffffff
0000000000000000
[ 7762.156228] page dumped because: kasan: bad access detected
[ 7762.161974]
[ 7762.163532] Memory state around the buggy address:
[ 7762.168475]  ffffff80c537b000: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7762.175915]  ffffff80c537b080: fc fc fc fc fc fc fc fc fc fc fc fc

fc fc fc fc

Quoted 8 lines
[ 7762.183346] >ffffff80c537b100: fa fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7762.190774]                                            ^
[ 7762.196258]  ffffff80c537b180: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7762.203689]  ffffff80c537b200: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7762.211125] ==================================================================

Could you please check if it is due to count underflow? Given nothing wrong on the other side based on the efforts
"We looked through the users of put_ucounts and we don't see any obvious buggy users that would be freeing the data structure early."

Thanks
Hillf

kernel/ucount.c +4 -1
@@ -152,7 +152,10 @@ static void hlist_add_ucounts(struct uco
 
 struct ucounts *get_ucounts(struct ucounts *ucounts)
 {
-	if (ucounts && atomic_add_negative(1, &ucounts->count)) {
+	if (!ucounts)
+		return NULL;
+	WARN_ON(!atomic_read(&ucounts->count));
+	if (atomic_add_negative(1, &ucounts->count)) {
 		put_ucounts(ucounts);
 		ucounts = NULL;
 	}

--

#50 lore raw
Quoted 100 lines · Hillf Danton
Quoted 89 lines · On Thu, 30 Sep 2021 16:27:34 -0600 Yu Zhao wrote:
Quoted 4 lines · Alexey Gladkov
Quoted 2 lines · Jordan Glover
Quoted 2 lines

I'm still investigating, but I would like to rule out one option.

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Could you check out the patch?

Thx, I added it to my kernel and will report in few days. Does this patch try to fix the issue or make it easier to track?

I suspect the error is caused by a race between allow_ucounts() and put_ucounts(). I think this patch could solve the problem.

Thanks for your help. Still can reproduce the problem with the change suggested.

[ 7761.885966] ==================================================================
[ 7761.893462] BUG: KASAN: use-after-free in dec_ucount+0x50/0xd8
[ 7761.899491] Write of size 8 at addr ffffff80c537b140 by task
kworker/u16:3/10303
[ 7761.907110]
[ 7761.908668] CPU: 0 PID: 10303 Comm: kworker/u16:3 Not tainted
5.14.0-lockdep+ #1
[ 7761.916289] Hardware name: Google Lazor (rev3+) with KB Backlight (DT)
[ 7761.923021] Workqueue: netns cleanup_net
[ 7761.927106] Call trace:
[ 7761.929648]  dump_backtrace+0x0/0x42c
[ 7761.933442]  show_stack+0x24/0x30
[ 7761.936878]  dump_stack_lvl+0xd0/0x100
[ 7761.940763]  print_address_description+0x30/0x304
[ 7761.945628]  kasan_report+0x190/0x1d8
[ 7761.949418]  kasan_check_range+0x1ac/0x1bc
[ 7761.953655]  __kasan_check_write+0x44/0x54
[ 7761.957891]  dec_ucount+0x50/0xd8
[ 7761.961334]  cleanup_net+0x630/0x718
[ 7761.965036]  process_one_work+0x7b4/0x10ec
[ 7761.969274]  worker_thread+0x800/0xcf4
[ 7761.973152]  kthread+0x2a8/0x358
[ 7761.976496]  ret_from_fork+0x10/0x18
[ 7761.980201]
[ 7761.981761] Allocated by task 4840:
[ 7761.985366]  kasan_save_stack+0x38/0x68
[ 7761.989342]  __kasan_kmalloc+0x9c/0xb8
[ 7761.993222]  kmem_cache_alloc_trace+0x2a4/0x370
[ 7761.997905]  alloc_ucounts+0x150/0x374
[ 7762.001787]  set_cred_ucounts+0x198/0x248
[ 7762.005935]  __sys_setresuid+0x31c/0x4f8
[ 7762.009993]  __arm64_sys_setresuid+0x84/0x98
[ 7762.014410]  invoke_syscall+0xd4/0x2c8
[ 7762.018292]  el0_svc_common+0x124/0x200
[ 7762.022265]  do_el0_svc_compat+0x54/0x64
[ 7762.026325]  el0_svc_compat+0x24/0x34
[ 7762.030124]  el0t_32_sync_handler+0xc0/0xf0
[ 7762.034451]  el0t_32_sync+0x19c/0x1a0
[ 7762.038241]
[ 7762.039799] Freed by task 0:
[ 7762.042778]  kasan_save_stack+0x38/0x68
[ 7762.046747]  kasan_set_track+0x28/0x3c
[ 7762.050625]  kasan_set_free_info+0x28/0x4c
[ 7762.054857]  ____kasan_slab_free+0x118/0x164
[ 7762.059277]  __kasan_slab_free+0x18/0x28
[ 7762.063339]  kfree+0x2f8/0x500
[ 7762.066505]  put_ucounts+0x11c/0x134
[ 7762.070209]  put_cred_rcu+0x1bc/0x35c
[ 7762.074006]  rcu_core+0xa68/0x1b20
[ 7762.077538]  rcu_core_si+0x1c/0x28
[ 7762.081061]  __do_softirq+0x4bc/0xedc
[ 7762.084851]
[ 7762.086401] The buggy address belongs to the object at ffffff80c537b100
[ 7762.086401]  which belongs to the cache kmalloc-256 of size 256
[ 7762.099267] The buggy address is located 64 bytes inside of
[ 7762.099267]  256-byte region [ffffff80c537b100, ffffff80c537b200)
[ 7762.111248] The buggy address belongs to the page:
[ 7762.116185] page:fffffffe0314de00 refcount:1 mapcount:0
mapping:0000000000000000 index:0xffffff80c537ad00 pfn:0x145378
[ 7762.127180] head:fffffffe0314de00 order:3 compound_mapcount:0
compound_pincount:0
[ 7762.134881] flags: 0x8000000000010200(slab|head|zone=2)
[ 7762.140286] raw: 8000000000010200 fffffffe02799408 fffffffe02020808
ffffff808000c980
[ 7762.148263] raw: ffffff80c537ad00 0000000000200004 00000001ffffffff
0000000000000000
[ 7762.156228] page dumped because: kasan: bad access detected
[ 7762.161974]
[ 7762.163532] Memory state around the buggy address:
[ 7762.168475]  ffffff80c537b000: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7762.175915]  ffffff80c537b080: fc fc fc fc fc fc fc fc fc fc fc fc

fc fc fc fc

Quoted 8 lines
[ 7762.183346] >ffffff80c537b100: fa fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7762.190774]                                            ^
[ 7762.196258]  ffffff80c537b180: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7762.203689]  ffffff80c537b200: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7762.211125] ==================================================================
Quoted 4 lines

Could you please check if it is due to count underflow? Given nothing wrong on the other side based on the efforts
"We looked through the users of put_ucounts and we don't see any obvious buggy users that would be freeing the data structure early."

Thanks, Hillf.

Still can reproduce the problem without triggering the warning.

[ 7965.795189] ==================================================================
[ 7965.802642] BUG: KASAN: use-after-free in dec_ucount+0x50/0xd8
[ 7965.808653] Write of size 8 at addr ffffff8090294920 by task kworker/7:0/7002
[ 7965.815990]
[ 7965.817536] CPU: 7 PID: 7002 Comm: kworker/7:0 Not tainted 5.14.0-lockdep+ #2
[ 7965.824870] Hardware name: Google Lazor (rev3+) with KB Backlight (DT)
[ 7965.831576] Workqueue: events free_user_ns
[ 7965.835810] Call trace:
[ 7965.838338]  dump_backtrace+0x0/0x42c
[ 7965.842119]  show_stack+0x24/0x30
[ 7965.845540]  dump_stack_lvl+0xd0/0x100
[ 7965.849401]  print_address_description+0x30/0x304
[ 7965.854248]  kasan_report+0x190/0x1d8
[ 7965.858016]  kasan_check_range+0x1ac/0x1bc
[ 7965.862236]  __kasan_check_write+0x44/0x54
[ 7965.866463]  dec_ucount+0x50/0xd8
[ 7965.869876]  free_user_ns+0x1b0/0x288
[ 7965.873645]  process_one_work+0x7b4/0x10ec
[ 7965.877871]  worker_thread+0x800/0xcf4
[ 7965.881729]  kthread+0x2a8/0x358
[ 7965.885057]  ret_from_fork+0x10/0x18
[ 7965.888746]
[ 7965.890288] Allocated by task 19167:
[ 7965.893976]  kasan_save_stack+0x38/0x68
[ 7965.897923]  __kasan_kmalloc+0x9c/0xb8
[ 7965.901782]  __kmalloc+0x2c8/0x3c0
[ 7965.905287]  kvmalloc_node+0x64/0x104
[ 7965.909065]  v4l2_ctrl_new+0x478/0xc6c
[ 7965.912923]  v4l2_ctrl_new_std+0x280/0x374
[ 7965.917136]  venc_ctrl_init+0x4c4/0x7c8 [venus_enc]
[ 7965.922170]  venc_open+0x218/0x668 [venus_enc]
[ 7965.926748]  v4l2_open+0x158/0x234
[ 7965.930255]  chrdev_open+0x17c/0x37c
[ 7965.933942]  do_dentry_open+0x504/0xa44
[ 7965.937889]  vfs_open+0x84/0x98
[ 7965.941124]  path_openat+0x1980/0x1fac
[ 7965.944991]  do_filp_open+0x19c/0x2c0
[ 7965.948767]  do_sys_openat2+0xb8/0x298
[ 7965.952628]  do_sys_open+0x124/0x15c
[ 7965.956309]  __arm64_compat_sys_openat+0xa4/0xbc
[ 7965.961060]  invoke_syscall+0xd4/0x2c8
[ 7965.964920]  el0_svc_common+0x124/0x200
[ 7965.968873]  do_el0_svc_compat+0x54/0x64
[ 7965.972915]  el0_svc_compat+0x24/0x34
[ 7965.976688]  el0t_32_sync_handler+0xc0/0xf0
[ 7965.980999]  el0t_32_sync+0x19c/0x1a0
[ 7965.984781]
[ 7965.986330] Last potentially related work creation:
[ 7965.991342]  kasan_save_stack+0x38/0x68
[ 7965.995294]  kasan_record_aux_stack+0xdc/0x108
[ 7965.999866]  insert_work+0x60/0x22c
[ 7966.003458]  __queue_work+0xae8/0xe74
[ 7966.007223]  queue_work_on+0x100/0x148
[ 7966.011076]  drm_atomic_helper_commit+0x18c/0x1f4
[ 7966.015917]  drm_atomic_nonblocking_commit+0xc4/0xdc
[ 7966.021018]  drm_mode_atomic_ioctl+0x89c/0xaa0
[ 7966.025590]  drm_ioctl_kernel+0x15c/0x260
[ 7966.029720]  drm_ioctl+0x460/0x828
[ 7966.033229]  drm_compat_ioctl+0x1bc/0x230
[ 7966.037370]  __arm64_compat_sys_ioctl+0x1b0/0x1c4
[ 7966.042216]  invoke_syscall+0xd4/0x2c8
[ 7966.046071]  el0_svc_common+0x124/0x200
[ 7966.050015]  do_el0_svc_compat+0x54/0x64
[ 7966.054053]  el0_svc_compat+0x24/0x34
[ 7966.057819]  el0t_32_sync_handler+0xc0/0xf0
[ 7966.062119]  el0t_32_sync+0x19c/0x1a0
[ 7966.065884]
[ 7966.067424] Second to last potentially related work creation:
[ 7966.073329]  kasan_save_stack+0x38/0x68
[ 7966.077271]  kasan_record_aux_stack+0xdc/0x108
[ 7966.081837]  insert_work+0x60/0x22c
[ 7966.085434]  __queue_work+0xae8/0xe74
[ 7966.089202]  queue_work_on+0x100/0x148
[ 7966.093060]  drm_atomic_helper_commit+0x18c/0x1f4
[ 7966.097900]  drm_atomic_nonblocking_commit+0xc4/0xdc
[ 7966.103000]  drm_mode_atomic_ioctl+0x89c/0xaa0
[ 7966.107572]  drm_ioctl_kernel+0x15c/0x260
[ 7966.111697]  drm_ioctl+0x460/0x828
[ 7966.115200]  drm_compat_ioctl+0x1bc/0x230
[ 7966.119323]  __arm64_compat_sys_ioctl+0x1b0/0x1c4
[ 7966.124161]  invoke_syscall+0xd4/0x2c8
[ 7966.128016]  el0_svc_common+0x124/0x200
[ 7966.131962]  do_el0_svc_compat+0x54/0x64
[ 7966.135993]  el0_svc_compat+0x24/0x34
[ 7966.139762]  el0t_32_sync_handler+0xc0/0xf0
[ 7966.144067]  el0t_32_sync+0x19c/0x1a0
[ 7966.147837]
[ 7966.149374] The buggy address belongs to the object at ffffff8090294900
[ 7966.149374]  which belongs to the cache kmalloc-256 of size 256
[ 7966.162218] The buggy address is located 32 bytes inside of
[ 7966.162218]  256-byte region [ffffff8090294900, ffffff8090294a00)
[ 7966.174174] The buggy address belongs to the page:
[ 7966.179101] page:fffffffe0240a400 refcount:1 mapcount:0
mapping:0000000000000000 index:0xffffff8090294900 pfn:0x110290
[ 7966.190079] head:fffffffe0240a400 order:3 compound_mapcount:0
compound_pincount:0
[ 7966.197760] flags: 0x8000000000010200(slab|head|zone=2)
[ 7966.203137] raw: 8000000000010200 fffffffe002f3c08 fffffffe023f9008
ffffff808000c980
[ 7966.211086] raw: ffffff8090294900 0000000000200005 00000001ffffffff
0000000000000000
[ 7966.219034] page dumped because: kasan: bad access detected
[ 7966.224763]
[ 7966.226300] Memory state around the buggy address:
[ 7966.231228]  ffffff8090294800: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7966.238641]  ffffff8090294880: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7966.246055] >ffffff8090294900: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7966.253466]                                ^
[ 7966.257849]  ffffff8090294980: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 7966.265267]  ffffff8090294a00: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 7966.272678] ==================================================================
#51 lore raw
In reply to Hillf Danton
Quoted 31 lines · Hillf Danton

Could you please check if it is due to count underflow? Given nothing wrong

on the other side based on the efforts

"We looked through the users of put_ucounts and we don't see any obvious buggy

users that would be freeing the data structure early."

Thanks

Hillf

--- linux-5.14.4/kernel/ucount.c

+++ b/kernel/ucount.c

(quoted diff) +0 -4
@@ -152,7 +152,10 @@ static void hlist_add_ucounts(struct uco
 
 struct ucounts *get_ucounts(struct ucounts *ucounts)
 
 {
 
-   if (ucounts && atomic_add_negative(1, &ucounts->count)) {
 
-   if (!ucounts)
 
-         return NULL;
 
 
-   WARN_ON(!atomic_read(&ucounts->count));

Review static void hlist_add_ucounts(struct uco

Quoted 10 lines
(quoted diff) +0 -1
 
-   if (atomic_add_negative(1, &ucounts->count)) {
 
        put_ucounts(ucounts);
        ucounts = NULL;
 
 
    }
 
    --

For me above patch changed slightly the printed output. Now the warning comes from 'cleanup_net' instead of 'free_user_ns'. My system was also still responsive after the bug occurred which didn't happen previously. I can't say if this means anything or if this is result of above patch or instability of my reproducer.

------------[ cut here ]------------
WARNING: CPU: 2 PID: 27643 at kernel/ucount.c:256 dec_ucount+0x43/0x50
Modules linked in: <cut>
CPU: 2 PID: 27643 Comm: kworker/u8:3 Not tainted 5.14.9 #1 0274f3d0712a6dadc9a2cf8341ae333de732a31a
Workqueue: netns cleanup_net
RIP: 0010:dec_ucount+0x43/0x50
Code: 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 48 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 fd fc ff ff <0f> 0b eb e7 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 f8 48
RSP: 0018:ffffb34fc34cfe30 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa448eec5f3b0 RCX: ffffa447cfe1f540
RDX: ffffa447cfe1f580 RSI: ffffffffffffffff RDI: ffffa447c445c780
RBP: ffffa448eec5f380 R08: 0000000000000040 R09: ffffa44a196ac040
R10: 00000000001436be R11: 0000000000000259 R12: ffffb34fc34cfe10
R13: ffffb34fc34cfe40 R14: 00000000ffffffff R15: ffffa448eec5d414
FS:  0000000000000000(0000) GS:ffffa44a19700000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000072a95d359030 CR3: 000000000b20e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 cleanup_net+0x2e2/0x370
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
---[ end trace e5fdc3317f00d0e8 ]---
BUG: kernel NULL pointer dereference, address: 00000000000001e8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: 0000 [#1] SMP PTI
CPU: 2 PID: 27643 Comm: kworker/u8:3 Tainted: G        W         5.14.9 #1 0274f3d0712a6dadc9a2cf8341ae333de732a31a
Workqueue: netns cleanup_net
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 fd fc ff ff 0f 0b eb e7 66
RSP: 0018:ffffb34fc34cfe30 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa448eec5f3b0 RCX: ffffa447cfe1f540
RDX: ffffa447cfe1f580 RSI: ffffffffffffffff RDI: ffffa447c445c780
RBP: ffffa448eec5f380 R08: 0000000000000040 R09: ffffa44a196ac040
R10: 00000000001436be R11: 0000000000000259 R12: ffffb34fc34cfe10
R13: ffffb34fc34cfe40 R14: 00000000ffffffff R15: ffffa448eec5d414
FS:  0000000000000000(0000) GS:ffffa44a19700000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 000000000b20e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 cleanup_net+0x2e2/0x370
 process_one_work+0x1e1/0x380
 worker_thread+0x50/0x3a0
 ? rescuer_thread+0x360/0x360
 kthread+0x127/0x150
 ? set_kthread_struct+0x40/0x40
 ret_from_fork+0x22/0x30
Modules linked in: <cut>
CR2: 00000000000001e8
---[ end trace e5fdc3317f00d0e9 ]---
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 fd fc ff ff 0f 0b eb e7 66
RSP: 0018:ffffb34fc34cfe30 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa448eec5f3b0 RCX: ffffa447cfe1f540
RDX: ffffa447cfe1f580 RSI: ffffffffffffffff RDI: ffffa447c445c780
RBP: ffffa448eec5f380 R08: 0000000000000040 R09: ffffa44a196ac040
R10: 00000000001436be R11: 0000000000000259 R12: ffffb34fc34cfe10
R13: ffffb34fc34cfe40 R14: 00000000ffffffff R15: ffffa448eec5d414
FS:  0000000000000000(0000) GS:ffffa44a19700000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 000000000b20e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
#52 lore raw
Quoted 6 lines · On Thu, 07 Oct 2021 13:28:29 +0000 Jordan Glover wrote:

For me above patch changed slightly the printed output. Now the warning comes from 'cleanup_net' instead of 'free_user_ns'. My system was also still responsive after the bug occurred which didn't happen previously. I can't say if this means anything or if this is result of above patch or instability of my reproducer.

Thanks for your report.

It is the same issue as reported before and my patch did not help.

Hillf

Quoted 85 lines
------------[ cut here ]------------
WARNING: CPU: 2 PID: 27643 at kernel/ucount.c:256 dec_ucount+0x43/0x50
Modules linked in: <cut>
CPU: 2 PID: 27643 Comm: kworker/u8:3 Not tainted 5.14.9 #1 0274f3d0712a6dad=
c9a2cf8341ae333de732a31a
Workqueue: netns cleanup_net
RIP: 0010:dec_ucount+0x43/0x50
Code: 14 01 48 8b 02 48 89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b =
41 10 48 8b 88 e8 01 00 00 48 85 c9 75 d9 e9 fd fc ff ff <0f> 0b eb e7 66 0=
f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 f8 48
RSP: 0018:ffffb34fc34cfe30 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa448eec5f3b0 RCX: ffffa447cfe1f540
RDX: ffffa447cfe1f580 RSI: ffffffffffffffff RDI: ffffa447c445c780
RBP: ffffa448eec5f380 R08: 0000000000000040 R09: ffffa44a196ac040
R10: 00000000001436be R11: 0000000000000259 R12: ffffb34fc34cfe10
R13: ffffb34fc34cfe40 R14: 00000000ffffffff R15: ffffa448eec5d414
FS:  0000000000000000(0000) GS:ffffa44a19700000(0000) knlGS:000000000000000=
0
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000072a95d359030 CR3: 000000000b20e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
cleanup_net+0x2e2/0x370
process_one_work+0x1e1/0x380
worker_thread+0x50/0x3a0
? rescuer_thread+0x360/0x360
kthread+0x127/0x150
? set_kthread_struct+0x40/0x40
ret_from_fork+0x22/0x30
---[ end trace e5fdc3317f00d0e8 ]---
BUG: kernel NULL pointer dereference, address: 00000000000001e8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: 0000 [#1] SMP PTI
CPU: 2 PID: 27643 Comm: kworker/u8:3 Tainted: G        W         5.14.9 #1 =
0274f3d0712a6dadc9a2cf8341ae333de732a31a
Workqueue: netns cleanup_net
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 =
89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 0=
0 00 48 85 c9 75 d9 e9 fd fc ff ff 0f 0b eb e7 66
RSP: 0018:ffffb34fc34cfe30 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa448eec5f3b0 RCX: ffffa447cfe1f540
RDX: ffffa447cfe1f580 RSI: ffffffffffffffff RDI: ffffa447c445c780
RBP: ffffa448eec5f380 R08: 0000000000000040 R09: ffffa44a196ac040
R10: 00000000001436be R11: 0000000000000259 R12: ffffb34fc34cfe10
R13: ffffb34fc34cfe40 R14: 00000000ffffffff R15: ffffa448eec5d414
FS:  0000000000000000(0000) GS:ffffa44a19700000(0000) knlGS:000000000000000=
0
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 000000000b20e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
cleanup_net+0x2e2/0x370
process_one_work+0x1e1/0x380
worker_thread+0x50/0x3a0
? rescuer_thread+0x360/0x360
kthread+0x127/0x150
? set_kthread_struct+0x40/0x40
ret_from_fork+0x22/0x30
Modules linked in: <cut>
CR2: 00000000000001e8
---[ end trace e5fdc3317f00d0e9 ]---
RIP: 0010:dec_ucount+0x32/0x50
Code: 74 34 89 f6 48 89 f9 4c 8d 04 f5 20 00 00 00 4a 8d 14 01 48 8b 02 48 =
89 c6 48 83 ee 01 78 1c f0 48 0f b1 32 75 f0 48 8b 41 10 <48> 8b 88 e8 01 0=
0 00 48 85 c9 75 d9 e9 fd fc ff ff 0f 0b eb e7 66
RSP: 0018:ffffb34fc34cfe30 EFLAGS: 00010297
RAX: 0000000000000000 RBX: ffffa448eec5f3b0 RCX: ffffa447cfe1f540
RDX: ffffa447cfe1f580 RSI: ffffffffffffffff RDI: ffffa447c445c780
RBP: ffffa448eec5f380 R08: 0000000000000040 R09: ffffa44a196ac040
R10: 00000000001436be R11: 0000000000000259 R12: ffffb34fc34cfe10
R13: ffffb34fc34cfe40 R14: 00000000ffffffff R15: ffffa448eec5d414
FS:  0000000000000000(0000) GS:ffffa44a19700000(0000) knlGS:000000000000000=
0
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000000001e8 CR3: 000000000b20e005 CR4: 00000000003706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
#53 lore raw
In reply to Alexey Gladkov
Quoted 83 lines · Alexey Gladkov
Quoted 32 lines · Jordan Glover
Quoted 20 lines · On Thursday, September 16th, 2021 at 5:30 PM, [email protected] wrote:
Quoted 9 lines · Jordan Glover [email protected] writes:
Quoted 3 lines · On Wednesday, September 15th, 2021 at 10:42 PM, Jordan Glover…

I had about 2 containerized (flatpak/bubblewrap) apps (browser + music player) running . I quickly closed them with intent to shutdown the system but instead get the freeze and had to use magic sysrq to reboot. System logs end with what I posted and before there is nothing suspicious.

Maybe it's some random fluke. I'll reply if I hit it again.

Heh, it jut happened again. This time closing firefox alone had such

effect:

Ok. It looks like he have a couple of folks seeing issues here.

I thought we had all of the issues sorted out for the release of v5.14,

but it looks like there is still some little bug left.

If Alex doesn't beat me to it I will see if I can come up with a

Quoted 7 lines

debugging patch to make it easy to help track down where the reference

count is going wrong. It will be a little bit as my brain is mush at

the moment.

Eric

As the issue persist in 5.14.7 I would be very interested in such patch.

Quoted 7 lines

For now the thing is mostly reproducible when I close several tabs in ff then

close the browser in short period of time. When I close tabs then wait out

a bit then close the browser it doesn't happen so I guess some interrupted

cleanup triggers it.

I'm still investigating, but I would like to rule out one option.

Could you check out the patch?

kernel/ucount.c +0 -0

index bb51849e6375..f23f906f4f62 100644

--- a/kernel/ucount.c

+++ b/kernel/ucount.c

kernel/ucount.c +0 -5
@@ -201,11 +201,14 @@ void put_ucounts(struct ucounts *ucounts)
 
 {
 
 unsigned long flags;
 
-         if (atomic_dec_and_lock_irqsave(&ucounts->count, &ucounts_lock, flags)) {
 
 
 
-         spin_lock_irqsave(&ucounts_lock, flags);
 
 
-         if (atomic_dec_and_test(&ucounts->count)) {
 
                  hlist_del_init(&ucounts->node);
 
                  spin_unlock_irqrestore(&ucounts_lock, flags);
                  kfree(ucounts);
 
 
-                 return;
          }
 
 
-         spin_unlock_irqrestore(&ucounts_lock, flags);
Quoted 7 lines

}

static inline bool atomic_long_inc_below(atomic_long_t *v, int u)

---------------------------------------------------------------------

Rgrds, legion

I'm still able to reproduce the issue with above patch although situation changed/improved a bit as now I have to close tabs and browser really fast to hit it which means it's more unlikely to happen during real usage.

On the other hand the kernel logging cuts off much earlier, just after few lines:

------------[ cut here ]------------
WARNING: CPU: 0 PID: 20387 at kernel/ucount.c:256 dec_ucount+0x43/0x50
Modules linked in: ...

Jordan