Dear Debian developers,

I've filled a few individual bugs[1,2,3,4] but Emilio suggested, to bring up
the topic here for effectiveness and coordination.

Triggered by a blog post[5], I started to look into some of my Debian amd64
based systems and noticed, certain binaries and libraries have an overly huge
segment alignment (2MB instead of the usual 4kB).

This was no issue until "recently", as it was basically ignored by the Linux
kernel ELF loader and the (glibc based) runtime linker. However, kernel[6] and
glibc[7] patches changed this and the ELF segment alignment will be honored by
each respectively since then (kernel ELF loader, aligning PT_LOAD entries of
binaries accordingly; runtime linker, aligning PT_LOAD entries of loaded shared
libraries).

I wrote an article[8] about the topic, providing some history and relating it
to Debian releases. Basically, all binary packages that haven't been rebuild
since stretch are prone to the over-alignment.

The over-alignment is bad, as it reduces the number of available ASLR bits and,
thereby, weakens this probabilistic mitigation, accelerating brute force
attacks.

Fortunately, it's mostly only old packages that are affected. However, some of
these are used with recent software as well (the X related libraries, for
example).

To get rid of the over-alignment, a rebuild with a linker that doesn't enforce
the overly huge alignment any more is sufficient. In Debian terms that would be
anything starting with buster.

I, thereby, request to rebuild affected packages.

Detecting if a package is affected can be done with either the script[9] we
provided along with the blog post, or by making use of readelf. For the latter
it would be to look for oddities like below:

minipli@nuc:~$ readelf -WSl /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
There are 27 section headers, starting at offset 0x5208:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg 
Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      
0   0  0
  [ 1] .note.gnu.build-id NOTE            00000000000001c8 0001c8 000024 00   A 
 0   0  4
  [ 2] .gnu.hash         GNU_HASH        00000000000001f0 0001f0 000180 00   A  
3   0  8
  [ 3] .dynsym           DYNSYM          0000000000000370 000370 000600 18   A  
4   1  8
  [ 4] .dynstr           STRTAB          0000000000000970 000970 00041f 00   A  
0   0  1
  [ 5] .gnu.version      VERSYM          0000000000000d90 000d90 000080 02   A  
3   0  2
  [ 6] .gnu.version_r    VERNEED         0000000000000e10 000e10 000050 00   A  
4   2  8
  [ 7] .rela.dyn         RELA            0000000000000e60 000e60 0000c0 18   A  
3   0  8
  [ 8] .rela.plt         RELA            0000000000000f20 000f20 000258 18  AI  
3  22  8
  [ 9] .init             PROGBITS        0000000000001178 001178 000017 00  AX  
0   0  4
  [10] .plt              PROGBITS        0000000000001190 001190 0001a0 10  AX  
0   0 16
  [11] .plt.got          PROGBITS        0000000000001330 001330 000008 00  AX  
0   0  8
  [12] .text             PROGBITS        0000000000001340 001340 001908 00  AX  
0   0 16
  [13] .fini             PROGBITS        0000000000002c48 002c48 000009 00  AX  
0   0  4
  [14] .rodata           PROGBITS        0000000000002c60 002c60 001020 00   A  
0   0 32
  [15] .eh_frame_hdr     PROGBITS        0000000000003c80 003c80 00016c 00   A  
0   0  4
  [16] .eh_frame         PROGBITS        0000000000003df0 003df0 0008d4 00   A  
0   0  8
  [17] .init_array       INIT_ARRAY      0000000000204de0 004de0 000008 08  WA  
0   0  8
  [18] .fini_array       FINI_ARRAY      0000000000204de8 004de8 000008 08  WA  
0   0  8
  [19] .jcr              PROGBITS        0000000000204df0 004df0 000008 00  WA  
0   0  8
  [20] .dynamic          DYNAMIC         0000000000204df8 004df8 0001e0 10  WA  
4   0  8
  [21] .got              PROGBITS        0000000000204fd8 004fd8 000028 08  WA  
0   0  8
  [22] .got.plt          PROGBITS        0000000000205000 005000 0000e0 08  WA  
0   0  8
  [23] .data             PROGBITS        00000000002050e0 0050e0 000008 00  WA  
0   0  8
  [24] .bss              NOBITS          00000000002050e8 0050e8 000008 00  WA  
0   0  1
  [25] .gnu_debuglink    PROGBITS        0000000000000000 0050e8 000034 00      
0   0  1
  [26] .shstrtab         STRTAB          0000000000000000 00511c 0000ec 00      
0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), l (large), p (processor specific)

Elf file type is DYN (Shared object file)
Entry point 0x1340
There are 7 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz 
  Flg Align
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x0046c4 
0x0046c4 R E 0x200000
  LOAD           0x004de0 0x0000000000204de0 0x0000000000204de0 0x000308 
0x000310 RW  0x200000
  DYNAMIC        0x004df8 0x0000000000204df8 0x0000000000204df8 0x0001e0 
0x0001e0 RW  0x8
  NOTE           0x0001c8 0x00000000000001c8 0x00000000000001c8 0x000024 
0x000024 R   0x4
  GNU_EH_FRAME   0x003c80 0x0000000000003c80 0x0000000000003c80 0x00016c 
0x00016c R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 
0x000000 RW  0x10
  GNU_RELRO      0x004de0 0x0000000000204de0 0x0000000000204de0 0x000220 
0x000220 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version 
.gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata 
.eh_frame_hdr .eh_frame
   01     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
   02     .dynamic
   03     .note.gnu.build-id
   04     .eh_frame_hdr
   05
   06     .init_array .fini_array .jcr .dynamic .got

Note how the ELF program header LOAD entries request an alignment of 0x200000,
i.e. 2MB, but none of the sections actually requires such a huge alignment (max
is 32).


Thanks,
Mathias

[1] https://bugs.debian.org/1065484 (libatasmart4)
[2] https://bugs.debian.org/1065541 (libxshmfence1)
[3] https://bugs.debian.org/1065542 (libxxf86vm1)
[4] https://bugs.debian.org/1065540 (libxdmcp6)
[5] https://zolutal.github.io/aslrnt/
[6] https://git.kernel.org/linus/ce81bb256a22
[7] http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=718fdd87b1b9
[8] https://grsecurity.net/toolchain_necromancy_past_mistakes_haunting_aslr
[9] https://github.com/opensrcsec/paxtest/blob/master/contrib/check_align.sh

Reply via email to