Page 1 of 1

ERROR: RPATH is not allowed

Posted: 2011-02-22T03:31:13-07:00
by yecril71pl
Trying to build using your ImageMagick.spec:
+ /usr/lib/rpm/brp-rpath
ERROR: RPATH "/usr/src/packages/BUILD/ImageMagick-6.6.7-7/magick/.libs" on /usr/src/packages/BUILDROOT/ImageMagick-6.6.7-7.x86_64
/usr/lib/perl5/vendor_perl/5.12.3/x86_64-linux-thread-multi/auto/Image/Magick/Magick.so is not allowed
RPATH is a private header of the ELF object format that allows to declare a search path where a shared library that an object depends on can be found. It is considered unsafe because it allows arbitrary code injection by malware installed in such additional search locations. It is usually introduced by passing additional library directories to the compiler (gcc -Lpath).

Note that the declared path /usr/src/packages/BUILD/ImageMagick-6.6.7-7/magick/.libs, apart from introducing a security threat, is obviously not useful at run time.

In this particular case, this abomination is created with the following command:

Code: Select all

LD_RUN_PATH="/usr/src/packages/BUILD/ImageMagick-6.6.7-7/PerlMagick/../magick/.libs"  \
cc  -shared -L/usr/src/packages/BUILD/ImageMagick-6.6.7-7/magick/.libs  \
Magick.o  -o blib/arch/auto/Image/Magick/Magick.so 	\
   -L/usr/src/packages/BUILD/ImageMagick-6.6.7-7/PerlMagick/../magick/.libs -lMagickCore -lm  	\
(Source: Makefile)

The command line is generated by MakeMaker, probably from the following input:

Code: Select all

# defaults for LIBS & INC & CCFLAGS params that we later pass to Writemakefile
my $INC_magick = '-I../ -I@top_srcdir@ @CPPFLAGS@ -I"' . $Config{'usrinc'} . '/ImageMagick"';
my $LIBS_magick = '-L../magick/.libs -lMagickCore -lperl @MATH_LIBS@';
my $CCFLAGS_magick = "$Config{'ccflags'} @CFLAGS@";
my $LDFLAGS_magick   = "-L../magick/.libs -lMagickCore $Config{'ldflags'} @LDFLAGS@";
my $LDDLFLAGS_magick = "-L../magick/.libs -lMagickCore $Config{'lddlflags'} @LDFLAGS@";
(Source: Makefile.PL.in)

And here is the actual script that does the failing test. It is undocumented but quite readable as a specification of requirements:

Code: Select all

for FILE in $(find $RPM_BUILD_ROOT -type f \( -perm -0100 -o -perm -0010 -o -perm -0001 \) 2>/dev/null); do
    for RPATH_VAL in $(objdump -p "$FILE" 2>/dev/null | egrep -w '(RPATH|RUNPATH)' | awk '{ print $2 ":"}'); do
	if [ "${RPATH_VAL:0:7}" = "\$ORIGIN" ]; then continue;fi

	while [ -n "$RPATH_VAL" ]; do
	    RPATH_VAL_NXT=${RPATH_VAL%%:*}
	    RPATH_VAL=${RPATH_VAL##$RPATH_VAL_NXT:}
	    test -d "$RPATH_VAL_NXT" && RPATH_VAL_NXT=$(cd ${RPATH_VAL_NXT//#\/\//\/}; pwd -P)

	    case ":$RPATH_VAL_NXT" in
	       :/usr/lib*)
	            ;;
	       :/lib*)
	            ;;
	       :/opt/*/lib*)
	            ;;
	       :/usr/X11R6/lib*)
	            ;;
	       *)
	 	    echo "ERROR: RPATH \"$RPATH_VAL_NXT\" on $FILE is not allowed"
		    HAD_ERRORS=1
	    esac
	done
    done
done

(from brp-rpath, © SuSE, 2005)

It seems that RPATH is introduced under the influence of $LD_RUN_PATH, unless -fuse-linker-plugin is used. I used explicit @LDFLAGS@ but it turns out that $LDFLAGS is not used for $(INST_DYNAMIC), so it did not help at all.

So here is another weirdness:
# MakeMaker Parameters:

# LDDLFLAGS => q[-L../magick/.libs -lMagickCore -shared -L/usr/local/lib64 -fstack-protector -fuse-linker-plugin]
# LDFLAGS => q[-L../magick/.libs -lMagickCore -L/usr/local/lib64 -fstack-protector -fuse-linker-plugin]

LDDLFLAGS = -shared -L/usr/src/packages/BUILD/ImageMagick-6.6.7-7/magick/.libs
LDFLAGS = -L../magick/.libs -lMagickCore -L/usr/local/lib64 -fstack-protector -fuse-linker-plugin
(Makefile) :shock:

This phenomenon is caused by the following code in ImageMagick.spec:

Code: Select all

--with-perl-options="INSTALLDIRS=vendor %{?perl_prefix} CC='%__cc -L$PWD/magick/.libs' LDDLFLAGS='-shared -L$PWD/magick/.libs'"
Setting of CC has no effect whatsoever because it is overridden; LDDLFLAGS should not be set here.