View on GitHub

IRAF Community Distribution

IRAF maintained by the community

Home | Installation | Packages | X11IRAF | PyRAF | Forum ↗

iraf-v216 · Code · Issues (50) · Pull requests (81)

iraf.net Issue #103

IRAF may crash on new (PIE default) Linux systems

closed closed olebole opened this issue on 2017-10-11


olebole commented on 2017-10-11

Newer Linux systems (Fedora, Arch Linux, Debian) compile binaries with gcc by default as Position Independent Executables.

During the start of a PIE executable, all symbols are relocated and get a new value. This affects the mem_ symbol defined in zsvjmp.s, which is no longer 0 after startup on these systems:

$ cat memtest.c  
#include <stdio.h>  
  
extern int mem_;  
  
int main(void) {  
  printf("%p\n", &mem_);  
  return 0;  
}  
$ gcc zsvjmp.s memtest.c -o memtest  
$ ./memtest  
0x55bc774d1000  

This becomes a problem, when malloc() returns a pointer below the address of mem_, since this results in a negative value for bufptr in mgdptr.x, which finally leads to a memory corruption reported by mgtfwa.x.

To reproduce, compile IRAF with PIE enabled, set the stacksize to unlimited (ulimit -s unlimited), start cl and run

cl> help help  
Memory fwa has been corrupted  

See also this stackoverflow discussion about the problem.

There are basically two ways to deal with this: First, one can just disable PIE during the compilation. Then, the mem_ symbol is kept as zero, and the problem disappears (and the help works as expected):

$ gcc zsvjmp.s memtest.c -o memtest -no-pie  
$ ./memtest  
(nil)  

The disadvantage is however, that the -no-pie linker option is quite recent and does not exist on older machines, so unconditionally setting this will break backward compatibility. On newer systems, this flag however would need to be set in any case, also when compiling tasks written by the user.

The other way would be to fix the misbehaviour with negative indices. Differently to zmalloc(), which provides absolute indices not related to mem_, negative values should be not a problem for kmalloc/krealloc, which handle indices relative to mem_. One place where negative values are handled improperly is the use of mod() in mgdptr.x which returns a negative result for negative input. The other place is coerce.x, which uses integer division (which rounds into the wrong direction for negative values: towards zero instead of towards the smaller value).


Fixed in #105


Last updated on 2017-10-14