Bug reporting system is down. Just mail to bugs@
The fix is likely to msync(2) before unmap(2).
-Otto
On Fri, Jul 13, 2012 at 01:43:04PM +0200, Michael Shuldman wrote:
> I sent the below via sendbug yesterday, but have not received any
> automatic ack as I did in the past I believe, so wonder if perhaps
> it was lost somewhere?
> I checked the maillog, and see it was accepted by some mailserver,
> so the problem does not seem to be on this end:
>
> Jul 12 13:54:49 jensen qmail: 1342094089.476514 delivery 74877:
> success: 192.43.244.163_accepted_message./Remote_host_said:
> _250_2.0.0_q6CBsljV002798_Message_accepted_for_delivery/
>
>
> I've also tried using http://www.openbsd.org/query-pr.html to look
> for the pr, but only get a "The requested URL /cgi-bin/query-pr-wrapper
> was not found on this server." error when I try to query something.
>
> With kind regards,
>
>
> SENDBUG: -*- sendbug -*-
> SENDBUG: Lines starting with `SENDBUG' will be removed automatically.
> SENDBUG:
> SENDBUG: Choose from the following categories:
> SENDBUG:
> SENDBUG: system user library documentation kernel alpha amd64 arm hppa i386
> m68k m88k mips64 powerpc sh sparc sparc64 vax
> SENDBUG:
> SENDBUG:
> Organization: Inferno Nettverk A/S, Oslo, Norway; http://www.inet.no
> To: [email protected]
> Subject:
> From: [email protected]
> Cc: [email protected]
> Reply-To: [email protected]
>
> >Synopsis: mmap(2)'ed memory is not the same it was before unmap(2)
> >Category: kernel
> >Environment:
> System : OpenBSD 5.1
> Details : OpenBSD 5.1 (GENERIC.MP) #188: Sun Feb 12 09:55:11 MST
> 2012
>
> [email protected]:/usr/src/sys/arch/i386/compile/GENERIC.MP
>
> Architecture: OpenBSD.i386
> Machine : i386
> >Description:
> /*
> * The test mmap(2)s a file, moves some of the mmap(2)-ed memory
> * around, unmap(2)s, and then truncate(2)s the file to a smaller size.
> *
> * Afterwards it again mmap(2)'s the same file using the smaller
> * (truncated) size and checks that the contents, up to the smaller
> * truncated size, is correct and the same as it was before the
> unmap(2).
> *
> * On OpenBSD this for some reason fails and we end up with
> * old data from the previous iteration in the remapped array. :-/
> */
>
> Regards,
>
> >How-To-Repeat:
>
> Save the below info mmap_open-close.c and run:
> $ gcc -ggdb -W -Wall mmap_open-close.c && ./a.out
>
> #include <sys/types.h>
> #include <sys/uio.h>
> #include <sys/mman.h>
>
> #include <assert.h>
> #include <unistd.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <errno.h>
> #include <fcntl.h>
>
> #ifndef MAP_FAILED
> #define MAP_FAILED (-1)
> #endif
>
> #define ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
> #define FILENAME ".tmpfile"
> #define TESTITERATIONS (128)
>
> int
> main(void)
> {
> FILE *fp;
> size_t testi, i;
> int array[2];
>
> assert(ELEMENTS(array) % 2 == 0);
>
> if ((fp = fopen(FILENAME, "w+")) == NULL) {
> fprintf(stderr, "fopen(%s) failed: %s", FILENAME, strerror(errno));
> exit(1);
> }
>
> if (ftruncate(fileno(fp), (off_t)sizeof(array)) == -1) {
> perror("ftruncate()");
> exit(1);
> }
>
> printf("created file %s of size %lu, mmap()'ing it ...\n",
> FILENAME, (unsigned long)sizeof(array));
>
> fclose(fp);
>
> for (testi = 0; testi < TESTITERATIONS; ++testi) {
> /*
> * This test mmap(2)'s a file, moves some of the mmap(2)-ed memory
> * around, unmap(2)s, and then truncate(2)s the file to a smaller size.
> *
> * Afterwards it again mmap(2)'s the same file using the smaller
> * (truncated) size and checks that the contents, up to the smaller
> * truncated size, is correct and the same as it was before the
> unmap(2).
> *
> * On OpenBSD this for some reason fails and we end up with
> * old data from the previous iteration in the remapped array. :-/
> */
> off_t truncatedsize;
> int *map, beforeunmap[ELEMENTS(array)], afterremap[ELEMENTS(array)];
>
> /* just to make sure user does not change one but not the other. */
> assert(sizeof(*map) == sizeof(*array));
>
> for (i = 0; i < ELEMENTS(array); ++i)
> array[i] = (int)random();
>
> if ((fp = fopen(FILENAME, "r+")) == NULL) {
> fprintf(stderr, "fopen(%s) failed: %s", FILENAME, strerror(errno));
> exit(1);
> }
>
> if ((map = mmap(NULL,
> sizeof(array),
> PROT_READ | PROT_WRITE,
> MAP_SHARED,
> fileno(fp),
> (off_t)0)) == MAP_FAILED) {
> perror("mmap()");
> exit(1);
> }
>
> fclose(fp);
>
> memcpy(map, array, sizeof(array));
> memcpy(beforeunmap, map, sizeof(array));
>
> assert(memcmp(map, array, sizeof(array)) == 0);
> assert(memcmp(beforeunmap, array, sizeof(array)) == 0);
>
> /* using a constant here makes things works on OpenBSD too however. */
> array[0] = array[1]; /* 0xdeadbeef */
> map[0] = array[1]; /* 0xdeadbeef */
>
> memcpy(beforeunmap, map, sizeof(array));
>
> assert(memcmp(map, array, sizeof(array)) == 0);
> assert(memcmp(beforeunmap, array, sizeof(array)) == 0);
>
> #if 1 /*
> * this breaks things on OpenBSD, at least release 5.0 and 5.1.
> */
>
> truncatedsize = (off_t)(sizeof(array) / 2);
> assert(memcmp(map, array, (size_t)truncatedsize) == 0);
> assert(memcmp(beforeunmap, array, (size_t)truncatedsize) == 0);
>
> if (munmap(map, sizeof(array)) == -1) {
> perror("munmap()");
> exit(1);
> }
>
> if (truncate(FILENAME, truncatedsize) == -1) {
> perror("truncate()");
> exit(1);
> }
>
> #else /* no truncation; works on OpenBSD too. */
>
> truncatedsize = (off_t)sizeof(array);
> #endif
>
> if ((fp = fopen(FILENAME, "r+")) == NULL) {
> fprintf(stderr, "fopen(%s) failed: %s", FILENAME, strerror(errno));
> exit(1);
> }
>
> if ((map = mmap(NULL,
> truncatedsize,
> PROT_READ | PROT_WRITE,
> MAP_SHARED,
> fileno(fp),
> (off_t)0)) == MAP_FAILED) {
> perror("mmap()");
> exit(1);
> }
>
> fclose(fp);
>
> bzero(afterremap, sizeof(afterremap));
> memcpy(afterremap, map, (size_t)truncatedsize);
>
> /* OpenBSD fails here. */
> if (beforeunmap[0] != afterremap[0]) {
> printf("on iteration %lu re-mapped() array index 0 of size %lu "
> "does not match what we unmapped() previously\n",
> (unsigned long)testi + 1,
> (unsigned long)sizeof(beforeunmap[0]));
>
> assert(beforeunmap[0] == afterremap[0]);
> }
>
> if (memcmp(beforeunmap, afterremap, (size_t)truncatedsize) != 0) {
> printf("on iteration %lu re-mapped() data of size %lu (%s) "
> "does not match what we unmapped() previously\n",
> (unsigned long)testi + 1,
> (unsigned long)truncatedsize,
> truncatedsize == sizeof(array) ? "not truncated" :
> "truncated");
>
> assert(memcmp(beforeunmap, afterremap, (size_t)truncatedsize) == 0);
> }
>
> if (truncate(FILENAME, (size_t)sizeof(array)) == -1) {
> perror("truncate()");
> exit(1);
> }
> }
>
> printf("tested through %lu iterations, all ok\n", (unsigned long)testi);
>
> if (unlink(FILENAME) != 0) {
> perror("unlink()");
> exit(1);
> }
>
> return 0;
> }
> >Fix:
> <how to correct or work around the problem, if known (multiple lines)>
>
> SENDBUG: Run sendbug as root if this is an ACPI report!
> SENDBUG: dmesg and usbdevs are attached.
> SENDBUG: Feel free to delete or use the -D flag if they contain sensitive
> information.
>
> dmesg:
> OpenBSD 5.1 (GENERIC.MP) #188: Sun Feb 12 09:55:11 MST 2012
> [email protected]:/usr/src/sys/arch/i386/compile/GENERIC.MP
> cpu0: Intel(R) Xeon(R) CPU X3430 @ 2.40GHz ("GenuineIntel" 686-class) 2.40 GHz
> cpu0:
> FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,SBF,NXE,LONG,SSE3,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,LAHF
> real mem = 2138230784 (2039MB)
> avail mem = 2093129728 (1996MB)
> mainbus0 at root
> bios0 at mainbus0: AT/286+ BIOS, date 12/31/99, BIOS32 rev. 0 @ 0xfdb80,
> SMBIOS rev. 2.6 @ 0xdf010 (55 entries)
> bios0: vendor HP version "O26" date 01/26/2010
> bios0: HP ProLiant DL120 G6
> acpi0 at bios0: rev 2
> acpi0: sleep states S0 S4 S5
> acpi0: tables DSDT FACP TCPA SSDT SPMI EINJ HEST BERT SSDT ERST APIC MCFG
> HPET BOOT SPCR
> acpi0: wakeup devices PEG_(S4) P0P3(S4) P0P5(S4) PEX1(S4) PEX2(S4) PEX3(S4)
> PEX4(S4) PEX5(S4) PEX6(S4) PEX7(S4) PEX8(S4)
> acpitimer0 at acpi0: 3579545 Hz, 24 bits
> acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
> cpu0 at mainbus0: apid 0 (boot processor)
> cpu0: apic clock running at 132MHz
> cpu1 at mainbus0: apid 2 (application processor)
> cpu1: Intel(R) Xeon(R) CPU X3430 @ 2.40GHz ("GenuineIntel" 686-class) 2.40 GHz
> cpu1:
> FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,SBF,NXE,LONG,SSE3,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,LAHF
> cpu2 at mainbus0: apid 4 (application processor)
> cpu2: Intel(R) Xeon(R) CPU X3430 @ 2.40GHz ("GenuineIntel" 686-class) 2.40 GHz
> cpu2:
> FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,SBF,NXE,LONG,SSE3,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,LAHF
> cpu3 at mainbus0: apid 6 (application processor)
> cpu3: Intel(R) Xeon(R) CPU X3430 @ 2.40GHz ("GenuineIntel" 686-class) 2.40 GHz
> cpu3:
> FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,SBF,NXE,LONG,SSE3,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,LAHF
> ioapic0 at mainbus0: apid 1 pa 0xfec00000, version 20, 24 pins
> acpimcfg0 at acpi0 addr 0xe0000000, bus 0-47
> acpihpet0 at acpi0: 14318179 Hz
> acpiprt0 at acpi0: bus -1 (PEG_)
> acpiprt1 at acpi0: bus -1 (PEG2)
> acpiprt2 at acpi0: bus 1 (P0P3)
> acpiprt3 at acpi0: bus -1 (P0P5)
> acpiprt4 at acpi0: bus 0 (PCI0)
> acpiprt5 at acpi0: bus 16 (PEX1)
> acpiprt6 at acpi0: bus -1 (PEX2)
> acpiprt7 at acpi0: bus -1 (PEX3)
> acpiprt8 at acpi0: bus -1 (PEX4)
> acpiprt9 at acpi0: bus 32 (PEX5)
> acpiprt10 at acpi0: bus 34 (PEX6)
> acpiprt11 at acpi0: bus 36 (PEX7)
> acpiprt12 at acpi0: bus 38 (PEX8)
> acpicpu0 at acpi0: PSS
> acpicpu1 at acpi0: PSS
> acpicpu2 at acpi0: PSS
> acpicpu3 at acpi0: PSS
> acpibtn0 at acpi0: PWRB
> bios0: ROM list: 0xc0000/0x8000 0xc8000/0x1e00 0xca000/0x1000 0xdf000/0x1000!
> ipmi at mainbus0 not configured
> cpu0: Enhanced SpeedStep 2394 MHz: speeds: 2394, 2261, 2128, 1995, 1862,
> 1729, 1596, 1463, 1330, 1197 MHz
> pci0 at mainbus0 bus 0: configuration mode 1 (bios)
> pchb0 at pci0 dev 0 function 0 "Intel Core DMI" rev 0x11
> ppb0 at pci0 dev 3 function 0 "Intel Core PCIE" rev 0x11
> pci1 at ppb0 bus 1
> "Intel Core Management" rev 0x11 at pci0 dev 8 function 0 not configured
> "Intel Core Scratch" rev 0x11 at pci0 dev 8 function 1 not configured
> "Intel Core Control" rev 0x11 at pci0 dev 8 function 2 not configured
> "Intel Core Misc" rev 0x11 at pci0 dev 8 function 3 not configured
> "Intel Core QPI Link" rev 0x11 at pci0 dev 16 function 0 not configured
> "Intel Core QPI Routing" rev 0x11 at pci0 dev 16 function 1 not configured
> ehci0 at pci0 dev 26 function 0 "Intel 3400 USB" rev 0x05: apic 1 int 16
> usb0 at ehci0: USB revision 2.0
> uhub0 at usb0 "Intel EHCI root hub" rev 2.00/1.00 addr 1
> ppb1 at pci0 dev 28 function 0 "Intel 3400 PCIE" rev 0x05: apic 1 int 17
> pci2 at ppb1 bus 16
> ppb2 at pci0 dev 28 function 4 "Intel 3400 PCIE" rev 0x05: apic 1 int 17
> pci3 at ppb2 bus 32
> bge0 at pci3 dev 0 function 0 "Broadcom BCM5723" rev 0x10, BCM5784 A1
> (0x5784100): apic 1 int 16, address d4:85:64:38:ad:64
> brgphy0 at bge0 phy 1: BCM5784 10/100/1000baseT PHY, rev. 4
> ppb3 at pci0 dev 28 function 5 "Intel 3400 PCIE" rev 0x05: apic 1 int 16
> pci4 at ppb3 bus 34
> bge1 at pci4 dev 0 function 0 "Broadcom BCM5723" rev 0x10, BCM5784 A1
> (0x5784100): apic 1 int 17, address d4:85:64:38:ad:65
> brgphy1 at bge1 phy 1: BCM5784 10/100/1000baseT PHY, rev. 4
> ppb4 at pci0 dev 28 function 6 "Intel 3400 PCIE" rev 0x05: apic 1 int 18
> pci5 at ppb4 bus 36
> vga1 at pci5 dev 0 function 0 "Matrox MGA G200e (ServerEngines)" rev 0x02
> wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
> wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
> ppb5 at pci0 dev 28 function 7 "Intel 3400 PCIE" rev 0x05: apic 1 int 19
> pci6 at ppb5 bus 38
> ehci1 at pci0 dev 29 function 0 "Intel 3400 USB" rev 0x05: apic 1 int 23
> usb1 at ehci1: USB revision 2.0
> uhub1 at usb1 "Intel EHCI root hub" rev 2.00/1.00 addr 1
> ppb6 at pci0 dev 30 function 0 "Intel 82801BA Hub-to-PCI" rev 0xa5
> pci7 at ppb6 bus 48
> pcib0 at pci0 dev 31 function 0 "Intel 3420 LPC" rev 0x05
> pciide0 at pci0 dev 31 function 2 "Intel 3400 SATA" rev 0x05: DMA, channel 0
> configured to native-PCI, channel 1 configured to native-PCI
> pciide0: using apic 1 int 18 for native-PCI interrupt
> wd0 at pciide0 channel 0 drive 0: <ST3500418AS>
> wd0: 16-sector PIO, LBA48, 476940MB, 976773168 sectors
> wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 6
> ichiic0 at pci0 dev 31 function 3 "Intel 3400 SMBus" rev 0x05: apic 1 int 18
> iic0 at ichiic0
> pciide1 at pci0 dev 31 function 5 "Intel 3400 SATA" rev 0x05: DMA, channel 0
> wired to native-PCI, channel 1 wired to native-PCI
> pciide1: using apic 1 int 17 for native-PCI interrupt
> isa0 at pcib0
> isadma0 at isa0
> com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
> pckbc0 at isa0 port 0x60/5
> kbc: cmd word write error
> pcppi0 at isa0 port 0x61
> spkr0 at pcppi0
> npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
> mtrr: Pentium Pro MTRR support
> uhub2 at uhub0 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2
> uhub3 at uhub1 port 1 "Intel Rate Matching Hub" rev 2.00/0.00 addr 2
> uhidev0 at uhub3 port 1 configuration 1 interface 0 "ServerEngines SE USB
> Device" rev 1.10/0.01 addr 3
> uhidev0: iclass 3/1
> ukbd0 at uhidev0: 8 modifier keys, 6 key codes
> wskbd0 at ukbd0 mux 1
> wskbd0: connecting to wsdisplay0
> uhidev1 at uhub3 port 1 configuration 1 interface 1 "ServerEngines SE USB
> Device" rev 1.10/0.01 addr 3
> uhidev1: iclass 3/1
> ums0 at uhidev1: 8 buttons, Z dir
> wsmouse0 at ums0 mux 0
> vscsi0 at root
> scsibus0 at vscsi0: 256 targets
> softraid0 at root
> scsibus1 at softraid0: 256 targets
> root on wd0a swap on wd0b dump on wd0b
>
> usbdevs:
> Controller /dev/usb0:
> addr 1: high speed, self powered, config 1, EHCI root hub(0x0000),
> Intel(0x8086), rev 1.00
> port 1 addr 2: high speed, self powered, config 1, Rate Matching
> Hub(0x0020), Intel(0x8087), rev 0.00
> port 1 powered
> port 2 powered
> port 3 powered
> port 4 powered
> port 5 powered
> port 6 addr 3: high speed, self powered, config 1, Rikiki USB 3(0x1057),
> LaCie(0x059f), rev 0.00, iSerialNumber 00000000f33f604d00f0
> port 2 powered
> Controller /dev/usb1:
> addr 1: high speed, self powered, config 1, EHCI root hub(0x0000),
> Intel(0x8086), rev 1.00
> port 1 addr 2: high speed, self powered, config 1, Rate Matching
> Hub(0x0020), Intel(0x8087), rev 0.00
> port 1 addr 3: full speed, self powered, config 1, SE USB Device(0x0000),
> ServerEngines(0x0000), rev 0.01, iSerialNumber 60196D5744A104
> port 2 powered
> port 3 powered
> port 4 powered
> port 5 powered
> port 6 powered
> port 7 powered
> port 8 powered
> port 2 powered
>
> --
> _ //
> \X/ -- Michael Shuldman