From nobody Thu Sep 8 16:36:26 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4MNlBR0qwNz4cS3t; Thu, 8 Sep 2022 16:36:31 +0000 (UTC) (envelope-from tijl@FreeBSD.org) Received: from smtp.freebsd.org (smtp.freebsd.org [IPv6:2610:1c1:1:606c::24b:4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MNlBR0DrYz3WXN; Thu, 8 Sep 2022 16:36:31 +0000 (UTC) (envelope-from tijl@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1662654991; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NHM4iM8NStv+l+isEt9AayqE2x56AVzeQ79tgC65AYs=; b=UDWj4HpdSfyyCfUzyOWYBJiZ8FDYL9DrlLIc5DPyftYqyM+a5vmvX+LXW3UVQhGK8k0Rrj iy9K1VEphkcyhfvvaOBiBifg1J/3eVC4C6t6JPx8TaHX4x1xUH7v0NYnNkQ7ZM7bC4GXir XNzuiK3IEvzEu6110tO2GNzJEno29clbylMHYCCrCHP0xFsAvQCVTDfSTEGORGGd4sL4e8 MhlFARoqi2gWsNT8zqJAVUz9eIU6SNgAQdb3aWWsAaVntgFz1xeCk52Q1WI4YE7XZwWs2z x5wrA9/P6NiOJmJ2LyXldWJK9C+l5qH1R6iKjC4tVZhvJnPHcyXtesyrzdeZCA== Received: from localhost (unknown [IPv6:2a02:a03f:894b:4700:fd1e:4ba8:eecd:e544]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: tijl) by smtp.freebsd.org (Postfix) with ESMTPSA id 4MNlBQ13n3z18v8; Thu, 8 Sep 2022 16:36:30 +0000 (UTC) (envelope-from tijl@FreeBSD.org) Date: Thu, 8 Sep 2022 18:36:26 +0200 From: =?UTF-8?B?VMSzbA==?= Coosemans To: Konstantin Belousov Cc: pho@freebsd.org, src-committers@freebsd.org, dev-commits-src-all@freebsd.org, dev-commits-src-main@freebsd.org Subject: Re: git: 95f773e59482 - main - i386 copyout_fast: improve detection of a fault on accessing userspace Message-ID: <20220908183626.0e560a16@FreeBSD.org> In-Reply-To: <20220908144909.7e6a0d6b@FreeBSD.org> References: <202208241925.27OJP9Fh069091@gitrepo.freebsd.org> <20220906171826.1629cfcf@FreeBSD.org> <20220906231745.1a0f3c15@FreeBSD.org> <20220907183804.29829b14@FreeBSD.org> <20220908144909.7e6a0d6b@FreeBSD.org> List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1662654991; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NHM4iM8NStv+l+isEt9AayqE2x56AVzeQ79tgC65AYs=; b=SaG2CRq5emi2N+Il5M7NZ+mjWiZ+LDnBrDd9tvllEW1fl5UsKUVwxoZlEbdYCUYa6QznFB T6lquqqiL5UElS6i9aFqUTnYOxnzAOKPMvTNJ1qmqQ99Jv+l3yWPB9SnojW1lfOFnasgcE EE7oIpprjwYogO2wrZlEboM6lkbSi/YCoTzgs3TYQ0btk2tx0Ty3eWgVlK4GG0xJqJEZir qpN9HH40ZtmoPyluuJcL5mr16SSvpVNMzxG0KuG63c+EIv2gn8FeklRkpJjgMFWY7XaLV5 UDQzWx3lWY8tiTPA0UMSOD8dBjQDgk5mV/ybAb5QIN5gtsKaDrElTp2knCQ9xw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1662654991; a=rsa-sha256; cv=none; b=rts3Fsp+KIe9Fqk8s4Rt7PA/xrL48tGmvZOOm00RPQwsq+vZwguH1+sOAxwywEA4utZCgk xgGLQwHLGnkDo6TILhXisv07x2grpPKq35u2fenVybE0zG21hXrbNYst7b3YBMo6UpaLjw A6AV4fB0y6ft2rzSM9qvT4ZQi6fJKOHc30osQb3vyIPHuqb/uC24wnqm0Ka6E44oEluAyT VAd0tEZR4y80mmxImE6q3WhV+rqryEB5Q373l4Eim2WlrdXAJzZMfmTW6BGTCiWFX+F54+ PhXF+Gb3N3eqITtIIkio+TiWTKVHDtH4SjyE9BIgtoXvmx+HdJ6WPT8/VuVSAg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N On Thu, 8 Sep 2022 14:49:09 +0200 T=C4=B3l Coosemans wro= te: > My patch adds a trylock after cli and an unlock before sti. If the > trylock fails panic("") is called. I put the lock at the base of the > trampoline stack so it's per cpu. The code between cli and sti is > supposed to be uninterruptible so the trylock should never fail, but it > does! Somehow there's a context switch to another thread that calls > copyout or copyin while the first thread was still busy copying when it > was switched out. This corrupts the trampoline stack and/or copyout_buf > of the first thread. I managed to find such a pair of threads. This is the first thread calling copyin, handling a page fault and handling an interrupt on top of the page fault: (kgdb) thread 202 [Switching to thread 202 (Thread 101397)] (kgdb) bt #0 0x009c55b6 in sched_switch (td=3D0x1a7fb000, flags=3D1538) at /home/tijl/freebsd/base/main/sys/kern/sched_4bsd.c:1099 #1 0x009abada in mi_switch (flags=3D1538) at /home/tijl/freebsd/base/main/sys/kern/kern_synch.c:545 #2 0x009a9d60 in critical_exit_preempt () at /home/tijl/freebsd/base/main/sys/kern/kern_switch.c:245 #3 0x0097507e in critical_exit () at /home/tijl/freebsd/base/main/sys/sys/systm.h:196 #4 0x00974fde in intr_event_handle (ie=3D0x4858e00, frame=3D0x1b076844) at /home/tijl/freebsd/base/main/sys/kern/kern_intr.c:1470 #5 0x00b7a86e in intr_execute_handlers (isrc=3D0xc8270c ,=20 frame=3D0x1b076844) at /home/tijl/freebsd/base/main/sys/x86/x86/intr_machdep.c:357 #6 0x00bad840 in atpic_handle_intr (vector=3D4, frame=3D0x1b076844) at /home/tijl/freebsd/base/main/sys/x86/isa/atpic.c:553 #7 0xffc03845 in ?? () #8 0x00000004 in ?? () #9 0x1b076844 in ?? () (kgdb) info sym 0xffc03845-setidt_disp=20 Xatpic_intr4_pti + 197 in section .text of /boot/kernel/kernel Further backtrace reconstructed with "frame view": #0 sse2_pagezero () at /home/tijl/freebsd/base/main/sys/i386/i386/support.s:56 56 movnti %ebx,(%ecx) #0 0x00b9aef5 in pagezero () at /home/tijl/freebsd/base/main/sys/i386/i386/pmap.c:4497 4497 sse2_pagezero(page); #0 pmap_nopae_zero_page () at /home/tijl/freebsd/base/main/sys/i386/i386/pmap.c:4524 4524 *cmap_pte2 =3D 0; #0 0x00b94bb1 in pmap_zero_page () at /home/tijl/freebsd/base/main/sys/i386/i386/pmap_base.c:668 668 pmap_methods_ptr->pm_zero_page(m); #0 0x00b31f02 in vm_fault_zerofill () at /home/tijl/freebsd/base/main/sys/vm/vm_fault.c:1114 1114 pmap_zero_page(fs->m); #0 0x00b31453 in vm_fault () at /home/tijl/freebsd/base/main/sys/vm/vm_fault.c:1602 1602 vm_fault_zerofill(&fs); #0 0x00b311c4 in vm_fault_trap () at /home/tijl/freebsd/base/main/sys/vm/vm_fault.c:683 683 result =3D vm_fault(map, trunc_page(vaddr), fault_type, fault_flags, #0 0x00ba7829 in trap_pfault () at /home/tijl/freebsd/base/main/sys/i386/i386/trap.c:849 849 rv =3D vm_fault_trap(map, eva, ftype, VM_FAULT_NORMAL, signo, ucode); #0 0x00ba6ec4 in trap () at /home/tijl/freebsd/base/main/sys/i386/i386/trap.c:474 474 (void)trap_pfault(frame, false, eva, NULL, NULL); (kgdb) x/3x 0x1b076a84 0x1b076a84: 0x1b076a90 0xffc031ff 0x1b076a90 (kgdb) info sym 0xffc031ff-setidt_disp=20 calltrap + 8 in section .text of /boot/kernel/kernel (kgdb) p/x *(struct trapframe *)0x1b076a90 $47 =3D {tf_fs =3D 0x8, tf_es =3D 0x28, tf_ds =3D 0x28, tf_edi =3D 0xe25c00= 0,=20 tf_esi =3D 0xffc04f80, tf_ebp =3D 0x1b076adc, tf_isp =3D 0x1b076abc,=20 tf_ebx =3D 0x141e000, tf_edx =3D 0xb8da80, tf_ecx =3D 0x1, tf_eax =3D 0x1= b076ad0,=20 tf_trapno =3D 0xc, tf_err =3D 0x2, tf_eip =3D 0xffc04362, tf_cs =3D 0x20,= =20 tf_eflags =3D 0x210017, tf_esp =3D 0xffbfc5a0, tf_ss =3D 0x1} (kgdb) info sym 0xffc04362-setidt_disp copyin_fast + 106 in section .text of /boot/kernel/kernel (kgdb) frame view 0x1b076adc 0xffc04362-setidt_disp #0 0x00b8da62 in copyin_fast () at /home/tijl/freebsd/base/main/sys/i386/i386/copyout_fast.s:133 133 rep; movsb (kgdb) disas 0xffc04362-setidt_disp Dump of assembler code for function copyin_fast: 0x00b8d9f8 <+0>: push %ebp 0x00b8d9f9 <+1>: mov %esp,%ebp 0x00b8d9fb <+3>: push %esi 0x00b8d9fc <+4>: push %edi 0x00b8d9fd <+5>: push %ebx 0x00b8d9fe <+6>: mov 0x14(%ebp),%ebx 0x00b8da01 <+9>: mov %fs:0x10,%eax 0x00b8da07 <+15>: mov 0x44(%eax),%edx 0x00b8da0a <+18>: mov 0x10(%ebp),%ecx 0x00b8da0d <+21>: mov 0x8(%ebp),%esi 0x00b8da10 <+24>: cli =20 0x00b8da11 <+25>: mov %fs:0x120,%edi 0x00b8da18 <+32>: mov $0xdeadc0de,%eax 0x00b8da1d <+37>: xchg %eax,-0xff0(%edi) 0x00b8da23 <+43>: cmp $0xdeadc0de,%eax 0x00b8da28 <+48>: jne 0xb8da36 0x00b8da2a <+50>: push $0xb8da7d 0x00b8da2f <+55>: mov $0x9a20b0,%eax 0x00b8da34 <+60>: call *%eax 0x00b8da36 <+62>: mov %fs:0x194,%edi 0x00b8da3d <+69>: mov %esp,%eax 0x00b8da3f <+71>: mov %fs:0x120,%esp 0x00b8da46 <+78>: mov %edx,%cr3 0x00b8da49 <+81>: mov $0xb8da80,%edx 0x00b8da4e <+86>: rep movsb %ds:(%esi),%es:(%edi) 0x00b8da50 <+88>: mov %ebx,%cr3 0x00b8da53 <+91>: mov %eax,%esp 0x00b8da55 <+93>: mov 0x10(%ebp),%ecx 0x00b8da58 <+96>: mov 0xc(%ebp),%edi 0x00b8da5b <+99>: mov %fs:0x194,%esi 0x00b8da62 <+106>: rep movsb %ds:(%esi),%es:(%edi) 0x00b8da64 <+108>: mov %fs:0x120,%edi 0x00b8da6b <+115>: movl $0x0,-0xff0(%edi) 0x00b8da75 <+125>: sti =20 0x00b8da76 <+126>: xor %eax,%eax 0x00b8da78 <+128>: pop %ebx 0x00b8da79 <+129>: pop %edi 0x00b8da7a <+130>: pop %esi 0x00b8da7b <+131>: leave =20 0x00b8da7c <+132>: ret =20 0x00b8da7d <+133>: add %ah,-0x70(%esi) End of assembler dump. #0 0x00b89208 in copyin () at /home/tijl/freebsd/base/main/sys/i386/i386/copyout.c:215 215 copyin_fast_tramp(udaddr, kaddr, len, pmap_get_kcr3()) =3D=3D 0)) #0 0x009ea24e in uiomove_faultflag () at /home/tijl/freebsd/base/main/sys/kern/subr_uio.c:255 255 error =3D copyin(iov->iov_base, cp, cnt); #0 0x009ea1a3 in uiomove () at /home/tijl/freebsd/base/main/sys/kern/subr_uio.c:198 198 return (uiomove_faultflag(cp, n, uio, 0)); #0 0x009f2ae0 in pipe_write () at /home/tijl/freebsd/base/main/sys/kern/sys_pipe.c:1252 1252 error =3D uiomove(&wpipe->pipe_buffer.buffer[wpipe->pipe_buffer.in], #0 0x009f1dc4 in fo_write () at /home/tijl/freebsd/base/main/sys/sys/file.h:349 349 return ((*fp->f_ops->fo_write)(fp, uio, active_cred, flags, td)); #0 0x009efac9 in dofilewrite () at /home/tijl/freebsd/base/main/sys/kern/sys_generic.c:565 565 if ((error =3D fo_write(fp, auio, td->td_ucred, flags, td))) { #0 0x009ef8cb in kern_writev () at /home/tijl/freebsd/base/main/sys/kern/sys_generic.c:492 492 error =3D dofilewrite(td, fd, fp, auio, (off_t)-1, 0); #0 0x009ef880 in sys_write () at /home/tijl/freebsd/base/main/sys/kern/sys_generic.c:407 407 error =3D kern_writev(td, uap->fd, &auio); #0 0x00ba7c00 in syscallenter () at /home/tijl/freebsd/base/main/sys/i386/i386/../../kern/subr_syscall.c= :189 189 error =3D (se->sy_call)(td, sa->args); #0 syscall () at /home/tijl/freebsd/base/main/sys/i386/i386/trap.c:1137 1137 if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) { This is the second thread calling copyout: (kgdb) thread 192 [Switching to thread 192 (Thread 101428)] (kgdb) bt #0 0x009a1dfd in dump_savectx () at /home/tijl/freebsd/base/main/sys/kern/kern_shutdown.c:404 #1 0x009a1e77 in doadump (textdump=3D0) at /home/tijl/freebsd/base/main/sys/kern/kern_shutdown.c:434 #2 0x008d1194 in db_dump (dummy=3D10315780, dummy2=3Dfalse, dummy3=3D-1,=20 dummy4=3D0x1b0bc850 "") at /home/tijl/freebsd/base/main/sys/ddb/db_command.c:593 #3 0x008d0f41 in db_command (last_cmdp=3D,=20 cmd_table=3D, dopager=3Dtrue) at /home/tijl/freebsd/base/main/sys/ddb/db_command.c:506 #4 0x008d0ddc in db_command_loop () at /home/tijl/freebsd/base/main/sys/ddb/db_command.c:553 #5 0x008d3b00 in db_trap (type=3D3, code=3D0) at /home/tijl/freebsd/base/main/sys/ddb/db_main.c:270 #6 0x009d6b89 in kdb_trap (type=3D3, code=3D0, tf=3D0x1b0bca14) at /home/tijl/freebsd/base/main/sys/kern/subr_kdb.c:745 #7 0x00ba6e9e in trap (frame=3D0x1b0bca14) at /home/tijl/freebsd/base/main/sys/i386/i386/trap.c:667 #8 0xffc031ff in ?? () #9 0x1b0bca14 in ?? () (kgdb) info sym 0xffc031ff-setidt_disp=20 calltrap + 8 in section .text of /boot/kernel/kernel Reconstructed backtrace: #0 breakpoint () at /home/tijl/freebsd/base/main/sys/i386/include/cpufunc.h:57 57 } #0 kdb_enter () at /home/tijl/freebsd/base/main/sys/kern/subr_kdb.c:509 509 kdb_why =3D KDB_WHY_UNSET; #0 0x009a21e6 in vpanic () at /home/tijl/freebsd/base/main/sys/kern/kern_shutdown.c:966 966 kdb_enter(KDB_WHY_PANIC, "panic"); #0 0x009a20c4 in panic () at /home/tijl/freebsd/base/main/sys/kern/kern_shutdown.c:903 903 vpanic(fmt, ap); #0 0x00b8d9af in copyout_fast () at /home/tijl/freebsd/base/main/sys/i386/i386/copyout_fast.s:65 65 movl PCPU(COPYOUT_BUF),%edi Dump of assembler code for function copyout_fast: 0x00b8d970 <+0>: push %ebp 0x00b8d971 <+1>: mov %esp,%ebp 0x00b8d973 <+3>: push %esi 0x00b8d974 <+4>: push %edi 0x00b8d975 <+5>: push %ebx 0x00b8d976 <+6>: mov 0x14(%ebp),%ebx 0x00b8d979 <+9>: mov %fs:0x10,%edx 0x00b8d980 <+16>: mov 0x44(%edx),%edx 0x00b8d983 <+19>: mov 0x10(%ebp),%ecx 0x00b8d986 <+22>: mov 0x8(%ebp),%esi 0x00b8d989 <+25>: cli =20 0x00b8d98a <+26>: mov %fs:0x120,%edi 0x00b8d991 <+33>: mov $0xdeadc0de,%eax 0x00b8d996 <+38>: xchg %eax,-0xff0(%edi) 0x00b8d99c <+44>: cmp $0xdeadc0de,%eax 0x00b8d9a1 <+49>: jne 0xb8d9af 0x00b8d9a3 <+51>: push $0xb8da7d 0x00b8d9a8 <+56>: mov $0x9a20b0,%eax 0x00b8d9ad <+61>: call *%eax 0x00b8d9af <+63>: mov %fs:0x194,%edi 0x00b8d9b6 <+70>: rep movsb %ds:(%esi),%es:(%edi) 0x00b8d9b8 <+72>: mov 0x10(%ebp),%ecx 0x00b8d9bb <+75>: mov %fs:0x194,%esi 0x00b8d9c2 <+82>: mov 0xc(%ebp),%edi 0x00b8d9c5 <+85>: mov %esp,%eax 0x00b8d9c7 <+87>: mov %fs:0x120,%esp 0x00b8d9ce <+94>: mov %edx,%cr3 0x00b8d9d1 <+97>: mov $0xb8da80,%edx 0x00b8d9d6 <+102>: rep movsb %ds:(%esi),%es:(%edi) 0x00b8d9d8 <+104>: mov %ebx,%cr3 0x00b8d9db <+107>: mov %eax,%esp 0x00b8d9dd <+109>: mov %fs:0x120,%edi 0x00b8d9e4 <+116>: movl $0x0,-0xff0(%edi) 0x00b8d9ee <+126>: sti =20 0x00b8d9ef <+127>: xor %eax,%eax 0x00b8d9f1 <+129>: pop %ebx 0x00b8d9f2 <+130>: pop %edi 0x00b8d9f3 <+131>: pop %esi 0x00b8d9f4 <+132>: leave =20 0x00b8d9f5 <+133>: ret =20 End of assembler dump. #0 0x00b892f8 in copyout () at /home/tijl/freebsd/base/main/sys/i386/i386/copyout.c:250 250 copyout_fast_tramp(kaddr, udaddr, len, pmap_get_kcr3()) =3D=3D 0)) #0 0x009f177c in pollout () at /home/tijl/freebsd/base/main/sys/kern/sys_generic.c:1687 1687 error =3D copyout(&fds->revents, &ufds->revents, #0 0x009f1233 in kern_poll () at /home/tijl/freebsd/base/main/sys/kern/sys_generic.c:1607 1607 error =3D pollout(td, kfds, ufds, nfds); #0 0x009f1194 in sys_poll () at /home/tijl/freebsd/base/main/sys/kern/sys_generic.c:1485 1485 return (kern_poll(td, uap->fds, uap->nfds, tsp, NULL)); #0 0x00ba7c00 in syscallenter () at /home/tijl/freebsd/base/main/sys/i386/i386/../../kern/subr_syscall.c= :189 189 error =3D (se->sy_call)(td, sa->args); #0 syscall () at /home/tijl/freebsd/base/main/sys/i386/i386/trap.c:1137 1137 if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {