PTRACE_POKEDATA on PROT_NONE page hangs kernel

Michael Elizabeth Chastain (mec@duracef.shout.net)
Sat, 19 Sep 1998 13:20:42 -0500


Hello kernel hackers,

Here is a small test program that locks the kernel with ptrace.
It calls PTRACE_POKEDATA on a target page in its child process.
The target page is not present and has protection type PROT_NONE.

My process is an IBM 486/SLC. I don't think this is a processor bug,
but I'm not sure. I've attached my .config file. I've been using
kernel version 2.1.109 but the bug also occurs in 2.1.110, 2.1.117,
and 2.1.122-pre-3.

The "put_long" function in arch/i386/kernel/ptrace.c goes into a loop
holding the kernel lock. I added some printk's and discovered that the
page table entry, pte_val(*pgtable), has the value 0x00ad3062 and stays
at that value while put_long keeps calling handle_mm_fault.

handle_mm_fault calls handle_pte_fault.

The first call to handle_pte_fault calls do_no_page. Subsequent calls
to handle_pte_fault call do_wp_page.

I binary-searched through the kernel versions and found that this
program works up to 2.1.108, and hangs the kernel in versions 2.1.109
and later. I think the changes in include/asm-i386/pgtable.h contribute
to the problem.

I suspect that somebody didn't consider the ptrace case in these code
paths. For example, handle_mm_fault has a comment: /* by the time we
get here, we already hold the mm semaphore */. But the ptrace code
does not acquire the mm semaphore in the target process. I'm also
thinking this could be a bug in some page-invalidation or cache-flush
code (or perhaps even my funky processor).

Attachments:

test program
my .config for 2.1.109
trace output from some printk's I added

Michael Elizabeth Chastain
<mailto:mec@shout.net>
"love without fear"

---

#include <sys/types.h> #include <sys/mman.h> #include <sys/resource.h> #include <sys/ptrace.h> #include <sys/wait.h>

#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>

int main( ) { int pid_child = fork( );

if ( pid_child == 0 ) { mmap( (char *) 0x40008000, 12288, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0 ); ptrace( PTRACE_TRACEME, getpid( ), 0, 0 ); kill( getpid( ), SIGTRAP ); for ( ; ; ) ; } else { int status; wait4( -1, &status, 0, 0 ); ptrace( PTRACE_POKEDATA, pid_child, 0x40008000, 0x1234 ); for ( ; ; ) ; } }

---

# # Automatically generated make config: don't edit #

# # Code maturity level options # # CONFIG_EXPERIMENTAL is not set

# # Processor type and features # # CONFIG_M386 is not set CONFIG_M486=y # CONFIG_M586 is not set # CONFIG_M686 is not set # CONFIG_MATH_EMULATION is not set

# # Loadable module support # CONFIG_MODULES=y # CONFIG_MODVERSIONS is not set # CONFIG_KMOD is not set

# # General setup # CONFIG_NET=y # CONFIG_PCI is not set # CONFIG_MCA is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y CONFIG_PARPORT=y CONFIG_PARPORT_PC=y # CONFIG_PARPORT_OTHER is not set

# # Plug and Play support # # CONFIG_PNP is not set

# # Block devices # CONFIG_BLK_DEV_FD=m CONFIG_BLK_DEV_IDE=y

# # Please see Documentation/ide.txt for help/info on IDE drives # # CONFIG_BLK_DEV_HD_IDE is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_BLK_DEV_IDECD is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set CONFIG_BLK_DEV_CMD640=y # CONFIG_BLK_DEV_CMD640_ENHANCED is not set # CONFIG_IDE_CHIPSETS is not set

# # Additional Block Devices # # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_XD is not set CONFIG_PARIDE_PARPORT=y # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_HD is not set

# # Networking options # CONFIG_PACKET=y # CONFIG_NETLINK is not set # CONFIG_FIREWALL is not set # CONFIG_NET_ALIAS is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set # CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set # CONFIG_SYN_COOKIES is not set

# # (it is safe to leave these untouched) # # CONFIG_INET_RARP is not set CONFIG_IP_NOSR=y CONFIG_SKB_LARGE=y

# # # # CONFIG_IPX is not set # CONFIG_ATALK is not set

# # SCSI support # # CONFIG_SCSI is not set

# # Network device support # CONFIG_NETDEVICES=y # CONFIG_ARCNET is not set CONFIG_DUMMY=m # CONFIG_EQUALIZER is not set # CONFIG_NET_ETHERNET is not set # CONFIG_FDDI is not set # CONFIG_DLCI is not set # CONFIG_PLIP is not set CONFIG_PPP=y

# # CCP compressors for PPP are only built as modules. # # CONFIG_SLIP is not set # CONFIG_NET_RADIO is not set # CONFIG_TR is not set # CONFIG_WAN_DRIVERS is not set # CONFIG_LAPBETHER is not set # CONFIG_X25_ASY is not set

# # Amateur Radio support # # CONFIG_HAMRADIO is not set

# # ISDN subsystem # # CONFIG_ISDN is not set

# # CD-ROM drivers (not for SCSI or IDE/ATAPI drives) # # CONFIG_CD_NO_IDESCSI is not set

# # Filesystems # # CONFIG_QUOTA is not set # CONFIG_MINIX_FS is not set CONFIG_EXT2_FS=y # CONFIG_ISO9660_FS is not set CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set CONFIG_PROC_FS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SUNRPC is not set # CONFIG_LOCKD is not set # CONFIG_CODA_FS is not set # CONFIG_SMB_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_NTFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_ROMFS_FS is not set # CONFIG_AUTOFS_FS is not set # CONFIG_UFS_FS is not set # CONFIG_MAC_PARTITION is not set CONFIG_NLS=y

# # Native Language Support # CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set # CONFIG_NLS_CODEPAGE_860 is not set # CONFIG_NLS_CODEPAGE_861 is not set # CONFIG_NLS_CODEPAGE_862 is not set # CONFIG_NLS_CODEPAGE_863 is not set # CONFIG_NLS_CODEPAGE_864 is not set # CONFIG_NLS_CODEPAGE_865 is not set # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set # CONFIG_NLS_CODEPAGE_874 is not set CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set # CONFIG_NLS_ISO8859_5 is not set # CONFIG_NLS_ISO8859_6 is not set # CONFIG_NLS_ISO8859_7 is not set # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_ISO8859_9 is not set # CONFIG_NLS_KOI8_R is not set

# # Character devices # CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_SERIAL=y # CONFIG_SERIAL_CONSOLE is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_PRINTER=m CONFIG_PRINTER_READBACK=y # CONFIG_MOUSE is not set # CONFIG_UMISC is not set # CONFIG_QIC02_TAPE is not set # CONFIG_APM is not set # CONFIG_WATCHDOG is not set # CONFIG_RTC is not set # CONFIG_VIDEO_DEV is not set # CONFIG_NVRAM is not set # CONFIG_JOYSTICK is not set # CONFIG_MISC_RADIO is not set

# # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set

# # Console drivers # CONFIG_VGA_CONSOLE=y

# # Sound # # CONFIG_SOUND is not set

# # Kernel hacking # # CONFIG_PROFILE is not set CONFIG_MAGIC_SYSRQ=y

---

Linux version 2.1.109 (mec@smoke.fire.com) (gcc version 2.7.2) #5 Sat Sep 19 07:35:24 CDT 1998 Console: colour VGA+ 80x25 Calibrating delay loop... 14.23 BogoMIPS Memory: 14520k/16000k available (688k kernel code, 392k reserved, 376k data, 24k init) Checking if this processor honours the WP bit even in supervisor mode... Ok. CPU: Cyrix Cx486DLC Checking 386/387 coupling... OK, FPU using old IRQ 13 error reporting Checking 'hlt' instruction... OK. POSIX conformance testing by UNIFIX Swansea University Computer Society NET3.039 for Linux 2.1 NET3: Unix domain sockets 0.16 for Linux NET3.038. Swansea University Computer Society TCP/IP for NET3.037 IP Protocols: ICMP, UDP, TCP Starting kswapd v 1.5 parport0: PC-style at 0x378 [SPP] Serial driver version 4.26 with no serial options enabled ttyS00 at 0x03f8 (irq = 4) is a 16450 ttyS01 at 0x02f8 (irq = 3) is a 16550A hda: Conner Peripherals 170MB - CP30174E, ATA DISK drive hdb: Conner Peripherals 540MB - CFS540A, ATA DISK drive ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 hda: Conner Peripherals 170MB - CP30174E, 162MB w/32kB Cache, CHS=903/8/46 hdb: Conner Peripherals 540MB - CFS540A, 516MB w/64kB Cache, CHS=1050/16/63 PPP: version 2.3.3 (demand dialling) TCP compression code copyright 1989 Regents of the University of California PPP line discipline registered. Partition check: hda: hda1 hda2 hdb: hdb1 hdb2 hdb3 hdb4 VFS: Mounted root (ext2 filesystem) readonly. Freeing unused kernel memory: 24k freed Adding Swap: 16628k swap-space (priority -1)

handle_pte_fault: !pte_present put_long: addr: 40008000 *pgtable: 00d85062 handle_pte_fault: do_wp_page put_long: addr: 40008000 *pgtable: 00d85062 handle_pte_fault: do_wp_page put_long: addr: 40008000 *pgtable: 00d85062 handle_pte_fault: do_wp_page put_long: addr: 40008000 *pgtable: 00d85062 handle_pte_fault: do_wp_page put_long: addr: 40008000 *pgtable: 00d85062 handle_pte_fault: do_wp_page put_long: addr: 40008000 *pgtable: 00d85062 handle_pte_fault: do_wp_page put_long: addr: 40008000 *pgtable: 00d85062 handle_pte_fault: do_wp_page put_long: addr: 40008000 *pgtable: 00d85062 handle_pte_fault: do_wp_page put_long: addr: 40008000 *pgtable: 00d85062 handle_pte_fault: do_wp_page put_long: too many repetitions

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/