Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 362167 - sys-apps/haveged-1.01 doesn't compile on hardened x86
Summary: sys-apps/haveged-1.01 doesn't compile on hardened x86
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Hardened (show other bugs)
Hardware: x86 Linux
: Normal major (vote)
Assignee: The Gentoo Linux Hardened Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-05 13:59 UTC by Faustus
Modified: 2011-12-13 15:46 UTC (History)
3 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Faustus 2011-04-05 13:59:29 UTC
make[2]: Entering directory `/var/tmp/portage/sys-apps/haveged-1.01/work/haveged-1.01/src'
i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I..  -DHAVE_ISA_X86  -Wall -Os -march=i686 -mtune=core2 -fomit-frame-pointer -pipe -MT haveged.o -MD -MP -MF .deps/haveged.Tpo -c -o haveged.o haveged.c
i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I..  -DHAVE_ISA_X86  -Wall -Os -march=i686 -mtune=core2 -fomit-frame-pointer -pipe -MT havege.o -MD -MP -MF .deps/havege.Tpo -c -o havege.o havege.c
mv -f .deps/haveged.Tpo .deps/haveged.Po
havege.c: In function ‘cpuid’:
havege.c:325: error: PIC register clobbered by ‘%ebx’ in ‘asm’

Selecting i686-pc-linux-gnu-4.4.5-hardenednopie with gcc-config, or passing -fno-pie option to the default (pie+ssp) i686-pc-linux-gnu-4.4.5 seems to fix the issue.
Comment 1 Faustus 2011-04-05 14:29:48 UTC
See also bug 341271.
Comment 2 taaroa 2011-04-05 17:00:16 UTC
 * Messages for package sys-apps/haveged-1.01:

 * Package:    sys-apps/haveged-1.01
 * Repository: gentoo
 * Maintainer: robbat2@gentoo.org
 * USE:        amd64 elibc_glibc kernel_linux userland_GNU
 * FEATURES:   fakeroot preserve-libs sandbox suidctl usersandbox
 * Package:    sys-apps/haveged-1.01
 * Repository: gentoo
 * Maintainer: robbat2@gentoo.org
 * USE:        amd64 elibc_glibc kernel_linux userland_GNU
 * FEATURES:   fakeroot preserve-libs sandbox suidctl usersandbox

p.s. 
% eix haveged
[I] sys-apps/haveged
     Available versions:  (~)1.01{tbz2}
     Installed versions:  1.01{tbz2}(00:49:54 06.04.2011)
     Homepage:            http://www.issihosts.com/haveged/
     Description:         A simple entropy daemon using the HAVEGE algorithm
p.p.s.
Portage 2.2.0_alpha29 (hardened/linux/amd64/no-multilib, gcc-4.5.2, glibc-2.13-r2, 2.6.38-hardened x86_64)


if you need support, post the output of 'emerge --info =sys-apps/haveged-1.01'
Comment 3 Faustus 2011-04-05 19:50:04 UTC
Portage 2.1.9.42 (hardened/linux/x86, gcc-4.4.5, glibc-2.11.3-r0, 2.6.32-gentoo-r7 i686)
=================================================================
                        System Settings
=================================================================
Timestamp of tree: Tue, 05 Apr 2011 00:45:01 +0000
app-shells/bash:     4.1_p9
dev-lang/python:     2.6.6-r2
dev-util/cmake:      2.8.1-r2
sys-apps/baselayout: 1.12.14-r1
sys-apps/sandbox:    2.4
sys-devel/autoconf:  2.65-r1
sys-devel/automake:  1.10.3, 1.11.1
sys-devel/binutils:  2.20.1-r1
sys-devel/gcc:       4.4.5
sys-devel/gcc-config: 1.4.1
sys-devel/libtool:   2.2.10
sys-devel/make:      3.81-r2
virtual/os-headers:  2.6.36.1 (sys-kernel/linux-headers)
ACCEPT_KEYWORDS="x86"
CBUILD="i686-pc-linux-gnu"
CFLAGS="-Os -march=i686 -mtune=core2 -fomit-frame-pointer"
CHOST="i686-pc-linux-gnu"
CXXFLAGS="-Os -march=i686 -mtune=core2 -fomit-frame-pointer"
DISTDIR="/usr/portage/distfiles"
FEATURES="assume-digests binpkg-logs collision-protect distlocks fixlafiles fixpackages news parallel-fetch protect-owned sandbox sfperms strict unknown-features-warn unmerge-logs unmerge-orphans userfetch userpriv usersandbox usersync"
FFLAGS=""
LDFLAGS="-Wl,--as-needed"
Comment 4 Anthony Basile gentoo-dev 2011-04-07 13:25:04 UTC
Okay here's the problem.  It comes from lines 50+ of src/havegedef.h which defines the CPUID macro.  Here's the original:

#define CPUID(op,regs) ASM("xchgl  %%ebx,%0\n\tcpuid  \n\txchgl  %%ebx,%0\n\t"\
  : "+r" (regs[1]), "=a" (regs[0]), "=c" (regs[3]), "=d" (regs[2])\
  : "1" (op), "2" (regs[3]) :  "%ebx")

The last field there, namely :"%ebx" tells gcc that ebx is a clobbered registered which breaks with PIC on x86.  It looks like they're trying to shield ebx in the asm by doing xchgl  %%ebx,%0  and  xchgl  %%ebx,%0   before and after calling cpuid so I think its safe to remove the clobbered field and rather than stort ebx in any available register, %0, store it on the stack.  So this macro would read:

#define CPUID(op,regs) ASM("pushl  %%ebx\n\tcpuid  \n\tpopl  %%ebx\n\t"\
  : "+r" (regs[1]), "=a" (regs[0]), "=c" (regs[3]), "=d" (regs[2])\
  : "1" (op), "2" (regs[3]))

It then compiles, runs and introduces entropy, but I'm not sure if this introduces any badness, like correlations in the random numbers.

I'll bounce this off of upstream.

@robbat2: I'll give you a patch when I'm convinced this is the right way to go.
Comment 5 Anthony Basile gentoo-dev 2011-04-07 13:26:08 UTC
Heh, helps if the maintainer of the package gets cc-ed.
Comment 6 Faustus 2011-04-07 13:58:10 UTC
Anthony, thanks for taking the time to look into the issue.

I certainly can't parse that #define (why the focus on EBX - only because of PIC? CPUID affects EDX and ECX as well; also what's the difference between %%EBX and %EBX, and what's %0? Oh well, I'm used to Intel syntax... Also, if I remember right, XCHG has an implicit LOCK prefix, but that probably is not the purpose here). Anyway, after replacing the #define, I have configured haveged (on hardened x86 above) as:

CFLAGS="-Os -march=i686 -mtune=core2 -fomit-frame-pointer" LDFLAGS="-Wl,--as-needed" ./configure --enable-nistest=yes

and ran "make check". The results are:

1 failed individual tests with THRESHOLD 0.001000 on 487 individual tests
PASS: nist/test.sh
==================
All 2 tests passed
==================

The "2 tests passed" are for the regular non-NIST tests, if I understand correctly. The results are the same I got without the patch, when compiling with -fno-pie, so randomness properties are probably unaffected.
Comment 7 Faustus 2011-04-07 14:12:30 UTC
PS. The compiler error in virt-what is also due to CPUID code:

void
cpu_sig (char *sig)
{
  unsigned int eax = 0x40000000;
  unsigned int *sig32 = (unsigned int *)sig;
  asm volatile (
        "xor %%ebx, %%ebx; cpuid"
        : "=a" (eax), "=b" (sig32[0]), "=c" (sig32[1]), "=d" (sig32[2])
        : "0" (eax));
  sig[12] = 0;
}

virt-what-cpuid-helper.c: In function ‘cpu_sig’:
virt-what-cpuid-helper.c:32: error: can't find a register in class ‘BREG’ while reloading ‘asm’
virt-what-cpuid-helper.c:32: error: ‘asm’ operand has impossible constraints
Comment 8 Anthony Basile gentoo-dev 2011-04-07 19:17:58 UTC
(In reply to comment #7)
> PS. The compiler error in virt-what is also due to CPUID code:
> 
> void
> cpu_sig (char *sig)
> {
>   unsigned int eax = 0x40000000;
>   unsigned int *sig32 = (unsigned int *)sig;
>   asm volatile (
>         "xor %%ebx, %%ebx; cpuid"
>         : "=a" (eax), "=b" (sig32[0]), "=c" (sig32[1]), "=d" (sig32[2])
>         : "0" (eax));
>   sig[12] = 0;
> }
> 
> virt-what-cpuid-helper.c: In function ‘cpu_sig’:
> virt-what-cpuid-helper.c:32: error: can't find a register in class ‘BREG’ while
> reloading ‘asm’
> virt-what-cpuid-helper.c:32: error: ‘asm’ operand has impossible constraints

Its not quite the same.  The haveged CPUID macro doesn't collect the value of ebx, but this function does and stores it in sig32[0].  If that is used later in the code, it will not have the expected value after cpuid, but whatever PIC was storing in ebx before running cpuid.

In either code we could always do -fno-PIC, but then we sacrifice all the PIC goodness.  I'm trying to avoid that as much as I can.
Comment 9 Faustus 2011-09-26 14:43:17 UTC
The bug persists in gcc-4.5.3-r1.
Comment 10 Faustus 2011-09-26 14:45:38 UTC
Also in haveged-1.1.
Comment 11 Anthony Basile gentoo-dev 2011-09-27 15:52:37 UTC
(In reply to comment #9)
> The bug persists in gcc-4.5.3-r1.

This is not an issue with the compiler version.  All hardened compiler versions will have this problem because its at the asm level.

I showed upstream the problem and fix, but got no response, comment #4.  I didn't want to just add that patch because I wanted some confirmation that this was the right way to go.

If you like, you can email upstream again.  Otherwise maybe we can just go ahead and add the fix.
Comment 12 Faustus 2011-09-27 17:15:11 UTC
Ok, I pinged upstream.
Comment 13 Faustus 2011-09-28 00:56:24 UTC
I have received a reply from Gary Wuetz, creator of haveged - the problem might be already fixed in haveged 1.2:

"For gcc >= 4.3, it uses compiler intrinsics to eliminate inline assembly. For older compilers, it uses its own copy of the gcc 4.3 intrinsic for cpuid which AFAIK fixes the pic problem."
Comment 14 Anthony Basile gentoo-dev 2011-09-28 01:10:32 UTC
@robbat2

Can you please bump haveged to 1.2 (or give me permission to do so).  Its as easy as just renaming the ebuild, I just tested.

I resume testing on this issue once 1.2 is in the tree.
Comment 15 Thomas Capricelli 2011-10-27 13:40:23 UTC
i have the same problem here on two x86 "hardened" servers. With misc versions of gcc. Can the version be bumped in portage as it seems to solve this issue?
Comment 16 Anthony Basile gentoo-dev 2011-10-27 14:20:22 UTC
(In reply to comment #15)
> i have the same problem here on two x86 "hardened" servers. With misc versions
> of gcc. Can the version be bumped in portage as it seems to solve this issue?

Its fixed in haveged-1.2 and haveged-1.3.  There is a significant rewrite of the CPUID code to avoid clobbering %ebx needed for pic/pie.  I emailed the author.  He never responded, but it looks like he got the message --- from the changelog:

+v1.2 (June 26, 2011))
+ * Address compiler issues by using compiler intrinsics.
+ * Fix cpuid pic issues once again.


@robbat2.  FYI haveged-1.3 just came out although a quick diff between 1.2 and 1.3 shows just improvements in entropy gathering algo and a new non daemon option to pipe entropy to stdout.  Could use a USE flag maybe?
Comment 17 Faustus 2011-12-13 14:59:17 UTC
Hi, haveged-1.2 is in the tree, and compiles fine on hardened x86. Should this bug be marked resolved?