https://bugs.kde.org/show_bug.cgi?id=396415

            Bug ID: 396415
           Summary: Valgrind is not looking up $ORIGIN rpath of shebang
                    programs
           Product: valgrind
           Version: 3.10.0
          Platform: Other
                OS: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: jsew...@acm.org
          Reporter: jack.zhao.f...@gmail.com
  Target Milestone: ---

> uname -a
Linux zanarkand 3.10.0-693.2.2.el7.x86_64 #1 SMP Sat Sep 9 03:55:24 EDT 2017
x86_64 x86_64 x86_64 GNU/Linux

> valgrind --version
valgrind-3.10.0

-----

Steps to reproduce:


1. Write a bare-minimum library with something that can be included. Mine
looked like this:

> cat foo.h
extern void doSomething(void);

> cat foo.cpp 
#include <iostream>

void doSomething(void) {
    std::cout << "did something" << std::endl;
}


2. Write a bare-minimum program that accepts a file as an argument and does
something to the file. Make sure to include the library we just made and invoke
its function. In my case I made it just print the file contents to stdout after
invoking the doSomething function. See:

> cat main.cpp 
#include <iostream>
#include <fstream>
#include <string>
#include "foo.h"

int main(int argc, char* argv[]) {
    doSomething();
    if (argc != 2) {
        std::cerr << "one parameter, should be file path" << std::endl;
    }
    std::string line;
    std::ifstream myfile(argv[1]);
    if (myfile.is_open()) {
        while(getline(myfile, line)) {
            std::cout << line << std::endl;
        }
        myfile.close();
    }
}


3. Build the library as a shared object (i.e. libfoo.so)

4. Build the main program with the following rpath: $ORIGIN/../lib, see:

> readelf -d main

Dynamic section at offset 0x1de8 contains 28 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libfoo.so]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/../lib]
 0x000000000000000c (INIT)               0x400c90
 0x000000000000000d (FINI)               0x401104
 0x0000000000000019 (INIT_ARRAY)         0x601dc8
 0x000000000000001b (INIT_ARRAYSZ)       16 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x601dd8
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x400298
 0x0000000000000005 (STRTAB)             0x4005e8
 0x0000000000000006 (SYMTAB)             0x4002e8
 0x000000000000000a (STRSZ)              976 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x602000
 0x0000000000000002 (PLTRELSZ)           480 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x400ab0
 0x0000000000000007 (RELA)               0x400a68
 0x0000000000000008 (RELASZ)             72 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x4009f8
 0x000000006fffffff (VERNEEDNUM)         3
 0x000000006ffffff0 (VERSYM)             0x4009b8
 0x0000000000000000 (NULL)               0x0

5. Put the library and main program in the following directories:

test_repro/lib/libfoo.so
test_repro/bin/main

6. Create the following file at the following location with a shebang line that
points to main:

test_repro/script/subdir/myscript (the `subdir` is important here)

> cat myscript
#!/path/to/my/test_repro/bin/main
lorem ipsum

7. Make the 'myscript' file executable, and run it. It should work - main gets
invoked as the program to feed the file into, and main is able to load in
libfoo.so.

8. Run myscript through valgrind (i.e. `valgrind ./myscript`) and observe that
it fails to load libfoo.so

-----

Note that:

 - issue does not happen when running `valgrind /path/to/my/test_repro/bin/main
myscript` (i.e. when execution does not depend on shebang)

 - issue does not happen when rpath contains an absolute path to
/path/to/my/test_repro/lib, only when rpath relies on $ORIGIN

 - issue does not happen if I put `myscript` into `test_repro/script` instead
of `test_repro/script/subdir`. This suggests that $ORIGIN path is processed but
treated as path relative to `myscript` instead of path relative to the shebang
program `main`.


Anyway, thanks!

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to