ELF programs with R_386_RELATIVE blocks are badly mapped into memory

Bug #1471029 reported by Douglas Bagnall on 2015-07-02
This bug affects 1 person
Affects Status Importance Assigned to Milestone
libxslt (Ubuntu)
linux (Ubuntu)

Bug Description

Running the Samba autobuild tests on a 15.04 openstack image results in a segfault in this command:

/usr/bin/xsltproc --nonet -o default/docs-xml/manpages/smb.conf.5 /home/ubuntu/autobuild/b22271/samba/docs-xml/xslt/man.xsl default/docs-xml/manpages/smb.conf.5.xml

I reported this upstream as a bug in xsltproc, but it was found to be impossible to reproduce using upstream source on the openstack instance:


Comment 8 (https://bugzilla.gnome.org/show_bug.cgi?id=751764#c8) is particularly informative.

The stack trace below shows the segfault actually occurs in libxml's xpath evaluation functions. I see no difference between xpath.c in upstream 2.9.2 and Ubuntu's version.

(gdb) bt 12
#0 0xb760f874 in xmlXPathCompOpEval (ctxt=0xba25d3e8, op=0xb86bc818) at ../../xpath.c:13606
#1 0xb760f82e in xmlXPathCompOpEval (ctxt=0xba25d3e8, op=0xb86bc890) at ../../xpath.c:13598
#2 0xb7610244 in xmlXPathCompOpEval (ctxt=0xba25d3e8, op=0xb86bc8b8) at ../../xpath.c:13529
#3 0xb760f9d6 in xmlXPathCompOpEval (ctxt=0xba25d3e8, op=0xb86bc8e0) at ../../xpath.c:13977
#4 0xb7612735 in xmlXPathCompOpEval (op=<optimized out>, ctxt=0xba25d3e8) at ../../xpath.c:14552
#5 xmlXPathRunEval (ctxt=0xba25d3e8, toBool=<optimized out>) at ../../xpath.c:14552
#6 0xb76171ed in xmlXPathCompiledEvalInternal (toBool=0, resObj=<synthetic pointer>, ctxt=<optimized out>, comp=<optimized out>) at ../../xpath.c:14915
#7 xmlXPathCompiledEval__internal_alias (comp=0xb866a948, ctx=0xb99bd308) at ../../xpath.c:14978
#8 0xb7787260 in xsltEvalVariable (ctxt=ctxt@entry=0xb9836560, variable=variable@entry=0xba25d3b0, castedComp=0xb86a4238) at ../../../libxslt/variables.c:903
#9 0xb778759a in xsltBuildVariable (ctxt=0xb9836560, castedComp=0xb86a4238, tree=0xb86a6978) at ../../../libxslt/variables.c:1759
#10 0xb7788bfa in xsltParseStylesheetCallerParam (ctxt=0xb86a6978, inst=0xb86a6978) at ../../../libxslt/variables.c:1975
#11 0xb779b9db in xsltCallTemplate (ctxt=0xb9836560, node=0xb85efed8, inst=0xb86a6880, castedComp=0xb86a4148) at ../../../libxslt/transform.c:4739
(More stack frames follow...)

(gdb) bt -5
#3311 0xb779a7de in xsltProcessOneNode (ctxt=0xb9836560, contextNode=0xb97586a0, withParams=0x0) at ../../../libxslt/transform.c:2097
#3312 0xb779d818 in xsltApplyStylesheetInternal (style=0xba25d3e8, style@entry=0xb85ee200, doc=0xb86bc7f0, doc@entry=0xb97586a0, params=0xb77ed340 <params>,
    output=0xb85e13e0 "default/docs-xml/manpages/smb.conf.5", profile=0x0, userCtxt=0xb9836560) at ../../../libxslt/transform.c:6159
#3313 0xb779df8d in xsltRunStylesheetUser (style=0xb85ee200, doc=0xb97586a0, params=0xb77ed340 <params>, output=0xb85e13e0 "default/docs-xml/manpages/smb.conf.5", SAX=0x0, IObuf=0x0,
    profile=0x0, userCtxt=0xb9836560) at ../../../libxslt/transform.c:6449
#3314 0xb77ea12c in xsltProcess (doc=0xb97586a0, cur=0xb85ee200, filename=0xbfd59812 "default/docs-xml/manpages/smb.conf.5.xml") at ../../../xsltproc/xsltproc.c:483
#3315 0xb77e9298 in main (argc=6, argv=0xbfd58f94) at ../../../xsltproc/xsltproc.c:903
 total 0
 crw-rw---- 1 root audio 116, 1 Jul 9 00:13 seq
 crw-rw---- 1 root audio 116, 33 Jul 9 00:13 timer
AplayDevices: Error: [Errno 2] No such file or directory
ApportVersion: 2.17.2-0ubuntu1.1
Architecture: i386
ArecordDevices: Error: [Errno 2] No such file or directory
AudioDevicesInUse: Error: command ['fuser', '-v', '/dev/snd/timer', '/dev/snd/seq'] failed with exit code 1:
CRDA: Error: [Errno 2] No such file or directory
DistroRelease: Ubuntu 15.04
Ec2AMI: ami-0000012b
Ec2AMIManifest: FIXME
Ec2AvailabilityZone: nz-por-1a
Ec2InstanceType: c1.c4r4
Ec2Kernel: aki-00000005
Ec2Ramdisk: ari-00000005
IwConfig: Error: [Errno 2] No such file or directory
 Bus 001 Device 002: ID 0627:0001 Adomax Technology Co., Ltd
 Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
MachineType: OpenStack Foundation OpenStack Nova
Package: linux (not installed)

 PATH=(custom, no user)

ProcKernelCmdLine: BOOT_IMAGE=/boot/vmlinuz-3.19.0-20-generic root=LABEL=cloudimg-rootfs ro console=tty1 console=ttyS0
ProcVersionSignature: User Name 3.19.0-20.20-generic 3.19.8
 linux-restricted-modules-3.19.0-20-generic N/A
 linux-backports-modules-3.19.0-20-generic N/A
 linux-firmware N/A
RfKill: Error: [Errno 2] No such file or directory
Tags: vivid ec2-images
UdevLog: Error: [Errno 2] No such file or directory: '/var/log/udev'
Uname: Linux 3.19.0-20-generic i686
UpgradeStatus: No upgrade log present (probably fresh install)
UserGroups: adm audio cdrom dialout dip floppy netdev plugdev sudo video
_MarkForUpload: True
dmi.bios.date: 01/01/2011
dmi.bios.vendor: Bochs
dmi.bios.version: Bochs
dmi.chassis.type: 1
dmi.chassis.vendor: Bochs
dmi.modalias: dmi:bvnBochs:bvrBochs:bd01/01/2011:svnOpenStackFoundation:pnOpenStackNova:pvr99-2014.1.4:cvnBochs:ct1:cvr:
dmi.product.name: OpenStack Nova
dmi.product.version: 99-2014.1.4
dmi.sys.vendor: OpenStack Foundation

Rebuilding libxml2_2.9.2+dfsg1-3_i386.deb from ubuntu source with -O0 fixes the issue.

Actually I was wrong, -O0 doesn't fix it. Sorry.

I tried some more things:

1. Compiling with clang makes no difference.

2. Compiling with -fsanitize=address results a "stack overflow" message followed by a stack trace. It doesn't reveal as much as the post-mortum traceback in gdb. The address sanitizer seems to make the error deterministic.

3. Copying the debian/ packaging directory into the git tree and compiling from there makes no difference. Most of the
contents of debian/patches are already upstream anyway.

4. Switching the linker to gold makes no difference.

The process map (from apport-unpack) never lists memory as [stack], and always has a double [heap] listing with a window of 0x1000 in the middle. Like this:

dump9/ProcMaps:b7ccf000-bfabb000 rw-p 00000000 00:00 0 [heap]
dump9/ProcMaps:bfabc000-bfb14000 rw-p 00000000 00:00 0 [heap]

The stack pointer is using the second of these (i.e., in this case bfabc000-bfb14000, and the segfault is when it hits the window. Typically this allows the stack a few hundred kB (352k in the example above).

It looks like something is putting the process's memory together wrongly.

OK, so sampling the last two lines of the process map every 0.2 seconds:

b772c000-b772e000 rw-p 00005000 fd:01 67267 /usr/bin/xsltproc
bfe83000-bfea4000 rw-p 00000000 00:00 0 [stack]
b7894000-b849e000 rw-p 00000000 00:00 0 [heap]
bfe83000-bfea4000 rw-p 00000000 00:00 0 [stack]
b7894000-b90d5000 rw-p 00000000 00:00 0 [heap]
bfe83000-bfea4000 rw-p 00000000 00:00 0 [stack]

The heap starts to squeeze the stack for room. When they are separated by 64k, the heap takes over the stacks naming rights, and the sizes are fixed:

b7894000-bfe32000 rw-p 00000000 00:00 0 [heap]
bfe4c000-bfea4000 rw-p 00000000 00:00 0 [stack]
b7894000-bfe32000 rw-p 00000000 00:00 0 [heap]
bfe3d000-bfea4000 rw-p 00000000 00:00 0 [stack]
b7894000-bfe32000 rw-p 00000000 00:00 0 [heap]
bfe33000-bfea4000 rw-p 00000000 00:00 0 [heap]
b7894000-bfe32000 rw-p 00000000 00:00 0 [heap]
bfe33000-bfea4000 rw-p 00000000 00:00 0 [heap]

The stack is fixed in size from here on in, so it is only a matter of luck and time.

b7894000-bfe32000 rw-p 00000000 00:00 0 [heap]
bfe33000-bfea4000 rw-p 00000000 00:00 0 [heap]
b7894000-bfe32000 rw-p 00000000 00:00 0 [heap]
bfe33000-bfea4000 rw-p 00000000 00:00 0 [heap]


b7894000-bfe32000 rw-p 00000000 00:00 0 [heap]
bfe33000-bfea4000 rw-p 00000000 00:00 0 [heap]

Why? I don't know.

This is a dynamic linking/loading problem, not related to libxml2 (or xsltproc) as first thought. The problem seems to be that executables with R_386_RELATIVE components are being mapped entirely (including the heap) into memory between roughly B7000000 and BFFFFFFF, which gives them roughly 140M to work with. Most programs can cope with that, but some (e.g. xsltproc performing described task) cannot.

I don't know whether to blame ld-linux.so or the kernel. This is on a 15.04 cloud image with 4GB running on openstack.

affects: libxml2 (Ubuntu) → glibc (Ubuntu)
Download full text (11.4 KiB)

For example, look at /bin/systemd, which has R_386_RELATIVE blocks:

$ objdump -R /bin/systemd |head -7

/bin/systemd: file format elf32-i386

00148440 R_386_RELATIVE *ABS*
00148444 R_386_RELATIVE *ABS*

and it's memory looks like this:

$ sudo cat /proc/1/maps
b7268000-b726a000 rw-p 00000000 00:00 0
b726a000-b726e000 r-xp 00000000 fd:01 2167 /lib/i386-linux-gnu/libuuid.so.1.3.0
b726e000-b726f000 r--p 00003000 fd:01 2167 /lib/i386-linux-gnu/libuuid.so.1.3.0
b726f000-b7270000 rw-p 00004000 fd:01 2167 /lib/i386-linux-gnu/libuuid.so.1.3.0
b7270000-b72b3000 r-xp 00000000 fd:01 2120 /lib/i386-linux-gnu/libblkid.so.1.1.0
b72b3000-b72b6000 r--p 00043000 fd:01 2120 /lib/i386-linux-gnu/libblkid.so.1.1.0
b72b6000-b72b7000 rw-p 00046000 fd:01 2120 /lib/i386-linux-gnu/libblkid.so.1.1.0
b72b7000-b72b9000 rw-p 00000000 00:00 0
b72b9000-b72bc000 r-xp 00000000 fd:01 2130 /lib/i386-linux-gnu/libdl-2.21.so
b72bc000-b72bd000 r--p 00002000 fd:01 2130 /lib/i386-linux-gnu/libdl-2.21.so
b72bd000-b72be000 rw-p 00003000 fd:01 2130 /lib/i386-linux-gnu/libdl-2.21.so
b72be000-b732e000 r-xp 00000000 fd:01 2103 /lib/i386-linux-gnu/libpcre.so.3.13.1
b732e000-b732f000 r--p 0006f000 fd:01 2103 /lib/i386-linux-gnu/libpcre.so.3.13.1
b732f000-b7330000 rw-p 00070000 fd:01 2103 /lib/i386-linux-gnu/libpcre.so.3.13.1
b7330000-b7337000 r-xp 00000000 fd:01 2090 /lib/i386-linux-gnu/librt-2.21.so
b7337000-b7338000 r--p 00006000 fd:01 2090 /lib/i386-linux-gnu/librt-2.21.so
b7338000-b7339000 rw-p 00007000 fd:01 2090 /lib/i386-linux-gnu/librt-2.21.so
b7339000-b7385000 r-xp 00000000 fd:01 2154 /lib/i386-linux-gnu/libmount.so.1.1.0
b7385000-b7386000 r--p 0004b000 fd:01 2154 /lib/i386-linux-gnu/libmount.so.1.1.0
b7386000-b7387000 rw-p 0004c000 fd:01 2154 /lib/i386-linux-gnu/libmount.so.1.1.0
b7387000-b7388000 rw-p 00000000 00:00 0
b7388000-b7394000 r-xp 00000000 fd:01 2076 /lib/i386-linux-gnu/libapparmor.so.1.2.1
b7394000-b7395000 r--p 0000b000 fd:01 2076 /lib/i386-linux-gnu/libapparmor.so.1.2.1
b7395000-b7396000 rw-p 0000c000 fd:01 2076 /lib/i386-linux-gnu/libapparmor.so.1.2.1
b7396000-b7397000 rw-p 00000000 00:00 0
b7397000-b73b1000 r-xp 00000000 fd:01 2142 /lib/i386-linux-gnu/libkmod.so.2.2.8
b73b1000-b73b2000 r--p 00019000 fd:01 2142 /lib/i386-linux-gnu/libkmod.so.2.2.8
b73b2000-b73b3000 rw-p 0001a000 fd:01 2142 /lib/i386-linux-gnu/libkmod.so.2.2.8
b73b3000-b73cd000 r-xp 00000000 fd:01 2118 /lib/i386-linux-gnu/libaudit.so.1.0.0
b73cd000-b73ce000 r--p 00019000 fd:01 2118 /lib/i386-linux-gnu/libaudit.so.1.0.0
b73ce000-b73cf000 rw-p 0001a000 fd:01 2118 /lib/i386-linux-gnu/libaudit.so.1.0.0
b73cf000-b73d9000 rw-p 00000000 00:00 0
b73d9000-b73e7000 r-xp 00000000 fd:01 2097 /lib/i386-linux-gnu/libpam.so.0.83.1
b73e7000-b73e8000 r--p 0000d000 fd:01 2097 /lib/i386-linux-gnu/libpam.so.0.83.1
b73e8000-b73e9000 rw-p 0000e000 fd:01 2097 /lib/i386-linux-gnu/libpam.so.0.83.1
b73e9000-b73ed000 r-xp 00000000 fd:01 2067 /lib/i386-linux-gnu/libcap....

summary: - Segfault in xsltproc on i386
+ ELF programs with R_386_RELATIVE blocks are badly mapped into memory

I wrote:
> For example, look at /bin/systemd, which has R_386_RELATIVE blocks
> [demonstrates brokenness]

Another way to look at it seems to be that the properly mapped programs have R_386_COPY blocks.

Aron Xu (happyaron) wrote :

Let's keep a task for xlstproc to track it.

Changed in libxslt (Ubuntu):
status: New → Triaged

It seems like a kernel thing. brk is returning bad addresses. Below, tail is an unaffected process, and xsltproc is affected. brk should be returning a 7 digit hex address, like it does for tail.

$ head -2 *.strace
==> tail.strace <==
execve("/usr/bin/tail", ["tail", "xsltproc.strace"], [/* 33 vars */]) = 0
brk(0) = 0x98a2000

==> xsltproc.strace <==
execve("/usr/bin/xsltproc", ["/usr/bin/xsltproc", "--nonet", "-o", "default/docs-xml/manpages/smb.co"..., "/home/ubuntu/autobuild/b22271/sa"..., "default/docs-xml/manpages/smb.co"...], [/* 33 vars */]) = 0
brk(0) = 0xb84f1000

Bug is fixed in upstream kernel 4.2.0 rc3, with the heap getting roughly 800Mb to use and the stack 135.

80085000-8008a000 r-xp 00000000 fd:01 58216 /usr/bin/xsltproc
8008a000-8008b000 r--p 00004000 fd:01 58216 /usr/bin/xsltproc
8008b000-8008c000 rw-p 00005000 fd:01 58216 /usr/bin/xsltproc
81432000-9176b000 rw-p 00000000 00:00 0 [heap]
b56e7000-b5747000 rw-p 00000000 00:00 0
b57a8000-b58df000 rw-p 00000000 00:00 0
b58df000-b58fb000 r-xp 00000000 fd:01 2095 /lib/i386-linux-gnu/libgcc_s.so.1
b771c000-b771d000 rw-p 00043000 fd:01 67414 /usr/lib/i386-linux-gnu/libxslt.so.1.1.28
b7726000-b7728000 rw-p 00000000 00:00 0
b7728000-b772a000 r--p 00000000 00:00 0 [vvar]
b772a000-b772b000 r-xp 00000000 00:00 0 [vdso]
b772b000-b774d000 r-xp 00000000 fd:01 2083 /lib/i386-linux-gnu/ld-2.21.so
b774d000-b774e000 r--p 00021000 fd:01 2083 /lib/i386-linux-gnu/ld-2.21.so
b774e000-b774f000 rw-p 00022000 fd:01 2083 /lib/i386-linux-gnu/ld-2.21.so
bfe18000-bff04000 rw-p 00000000 00:00 0 [stack]

I am suspicious of fs/binfmt_elf.c, and in particular [upstream a87938b2e/ ubuntu b51621abb] "fs/binfmt_elf.c: fix bug in loading of PIE binaries" , but I have no proof yet.

So, it isn't the ld-linux.so, it is the kernel on 32 bit i386, where exec is loading PIE elf binaries in such a way that the heap and the stack are next to each other and have very little room. About 20% of /usr/bin/* (and others, like /bin/systemd) on the vivid cloud image is affected, though in many cases their memory use is too low to cause problems.

The problem was discovered in the samba test suite, which uses xsltproc to generate manpages. One of the bigger man pages caused a segfault.

affects: glibc (Ubuntu) → linux (Ubuntu)

This bug is missing log files that will aid in diagnosing the problem. From a terminal window please run:

apport-collect 1471029

and then change the status of the bug to 'Confirmed'.

If, due to the nature of the issue you have encountered, you are unable to run this command, please add a comment stating that fact and change the bug status to 'Confirmed'.

This change has been made by an automated script, maintained by the Ubuntu Kernel Team.

Changed in linux (Ubuntu):
status: New → Incomplete

apport information

tags: added: apport-collected ec2-images vivid
description: updated

apport information

apport information

apport information

apport information

apport information

apport information

apport information

Changed in linux (Ubuntu):
importance: Undecided → Medium
status: Incomplete → Triaged
tags: added: kernel-bug-fixed-upstream kernel-da-key
Joseph Salisbury (jsalisbury) wrote :

I build a Utopic test kernel with a revert of commit a87938b2e. Can you test this kernel and see if it resolves this bug. I can also built test kernels for the other Ubuntu releases if this first test kernel does in fact resolve the bug.

The test kernel can be downloaded from:

hi Joseph

Those packages don't want to install on the i386:

    dpkg: error processing archive linux-tools-3.16.0-44-generic_3.16.0-44.59~lp1471029_amd64.deb (--install):
    package architecture (amd64) does not match system (i386)

(In compiling the 4.2 upstream kernel for i386, I ended up using a whole series of magic flags -- something like this:

   DEB_HOST_ARCH=i386 linux32 fakeroot make-kpkg –arch i386 –cross-compile – ...

BTW, the machine in question now has sufficient disk to compile a kernel, so I could do it there if that is easier.

Joseph Salisbury (jsalisbury) wrote :

I uploaded i386 version of the .deb files. They can be downloaded from:


Thanks Joseph!
It's no better with 3.16.0-44-generic #59~lp1471029. Perhaps even slightly worse -- in my sample of 2 I've seen the heap at b8d- and b94-, while I think stock Vivid 3.19 was most often in the b7's.

$ uname -a
Linux samba-build-i386-4-32bit 3.16.0-44-generic #59~lp1471029 SMP Wed Jul 22 22:24:19 UTC 2015 i686 i686 i686 GNU/Linux

$ /usr/bin/xsltproc --nonet -o default/docs-xml/manpages/smb.conf.5 /home/ubuntu/autobuild/b22271/samba/docs-xml/xslt/man.xsl default/docs-xml/manpages/smb.conf.5.xml & (set -e; for x in {1..200}; do cat /proc/$!/maps > proc-maps/$!-$x; sleep 0.2;done)
[1] 919
[1]+ Segmentation fault

$ head proc-maps/919-2
b5976000-b5979000 rw-p 00000000 00:00 0
b5979000-b5995000 r-xp 00000000 fd:01 2095 /lib/i386-linux-gnu/libgcc_s.so.1
b5995000-b5996000 rw-p 0001b000 fd:01 2095 /lib/i386-linux-gnu/libgcc_s.so.1
b5996000-b5997000 rw-p 00000000 00:00 0
b5997000-b5a80000 r-xp 00000000 fd:01 56064 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.20
b5a80000-b5a84000 r--p 000e9000 fd:01 56064 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.20
b5a84000-b5a85000 rw-p 000ed000 fd:01 56064 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.20
b5a85000-b5a8c000 rw-p 00000000 00:00 0
b5a8c000-b70f7000 r-xp 00000000 fd:01 55921 /usr/lib/i386-linux-gnu/libicudata.so.52.1
b70f7000-b70f8000 r--p 0166a000 fd:01 55921 /usr/lib/i386-linux-gnu/libicudata.so.52.1

$ tail proc-maps/919-2
b77c3000-b77c4000 r-xp 00000000 00:00 0 [vdso]
b77c4000-b77c6000 r--p 00000000 00:00 0 [vvar]
b77c6000-b77e8000 r-xp 00000000 fd:01 2083 /lib/i386-linux-gnu/ld-2.21.so
b77e8000-b77e9000 r--p 00021000 fd:01 2083 /lib/i386-linux-gnu/ld-2.21.so
b77e9000-b77ea000 rw-p 00022000 fd:01 2083 /lib/i386-linux-gnu/ld-2.21.so
b77ea000-b77ef000 r-xp 00000000 fd:01 58216 /usr/bin/xsltproc
b77ef000-b77f0000 r--p 00004000 fd:01 58216 /usr/bin/xsltproc
b77f0000-b77f1000 rw-p 00005000 fd:01 58216 /usr/bin/xsltproc
b8db2000-b8f11000 rw-p 00000000 00:00 0 [heap]
bfbd8000-bfbf9000 rw-p 00000000 00:00 0 [stack]

Colin Ian King (colin-king) wrote :

Commit a87938b2e was included in 3.19.0-20.20 (see commit b51621abbcb4694b8d2842ce3a66006a60bba6e5), so perhaps trying this would be the first step to see if that commit fixes things. As it stands, I've checked the heap and stack on a VM image using this kernel and there is now plenty of space for the stack and heap.

hi Colin,

I first met on a 3.19.0-20 build:

Linux samba-build-i386-32bit 3.19.0-20-generic #20-Ubuntu SMP Fri May 29 10:06:53 UTC 2015 i686 i686 i686 GNU/Linux

and as far as I can tell (taking into account Joseph's 3.16 and upstream 4.2rc3), that a87938b/b51621a commit is neither the cure or culprit.

It is interesting that it works for you on a VM -- it looks like the specific VM peculiarities matter. I'll try to find out what my VM actually is, beyond "openstack".

> I'll try to find out what my VM actually is, beyond "openstack".

KVM 2.0.0+dfsg-2ubuntu1.11

The processor (per attached files above) is "Intel Xeon E312xx (Sandy Bridge)".

Changed in libxslt (Ubuntu):
importance: Undecided → Medium
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers