1. 25 Sep, 2023 7 commits
  2. 22 Sep, 2023 4 commits
    • Andrii Nakryiko's avatar
      Merge branch 'libbpf: Support symbol versioning for uprobe' · 831916fb
      Andrii Nakryiko authored
      Hengqi Chen says:
      
      ====================
      Dynamic symbols in shared library may have the same name, for example:
      
          $ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
          000000000009b1a0 T __pthread_rwlock_wrlock@GLIBC_2.2.5
          000000000009b1a0 T pthread_rwlock_wrlock@@GLIBC_2.34
          000000000009b1a0 T pthread_rwlock_wrlock@GLIBC_2.2.5
      
          $ readelf -W --dyn-syms /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
            706: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 __pthread_rwlock_wrlock@GLIBC_2.2.5
            2568: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@@GLIBC_2.34
            2571: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@GLIBC_2.2.5
      
      There are two pthread_rwlock_wrlock symbols in libc.so .dynsym section.
      The one with @@ is the default version, the other is hidden.
      Note that the version info is stored in .gnu.version and .gnu.version_d
      sections of libc and the two symbols are at the _same_ offset.
      
      Currently, specify `pthread_rwlock_wrlock`, `pthread_rwlock_wrlock@@GLIBC_2.34`
      or `pthread_rwlock_wrlock@GLIBC_2.2.5` in bpf_uprobe_opts::func_name won't work.
      Because there are two `pthread_rwlock_wrlock` in .dynsym sections without the
      version suffix and both are global bind.
      
      We could solve this by introducing symbol versioning ([0]). So that users can
      specify func, func@LIB_VERSION or func@@LIB_VERSION to attach a uprobe.
      
      This patchset resolves symbol conflicts and add symbol versioning for uprobe.
        - Patch 1 resolves symbol conflicts at the same offset
        - Patch 2 adds symbol versioning for dynsym
        - Patch 3 adds selftests for the above changes
      
      Changes from v3:
        - Address comments from Andrii
      
      Changes from v2:
        - Add uretprobe selfttest (Alan)
        - Check symbol exact match (Alan)
        - Fix typo (Jiri)
      
      Changes from v1:
        - Address comments from Alan and Jiri
        - Add selftests (Someone reminds me that there is an attempt at [1]
          and part of the selftest code from Andrii is taken from there)
      
        [0]: https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html
        [1]: https://lore.kernel.org/lkml/CAEf4BzZTrjjyyOm3ak9JsssPSh6T_ZmGd677a2rt5e5rBLUrpQ@mail.gmail.com/
      ====================
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      831916fb
    • Hengqi Chen's avatar
      selftests/bpf: Add tests for symbol versioning for uprobe · 7089f85a
      Hengqi Chen authored
      This exercises the newly added dynsym symbol versioning logics.
      Now we accept symbols in form of func, func@LIB_VERSION or
      func@@LIB_VERSION.
      
      The test rely on liburandom_read.so. For liburandom_read.so, we have:
      
          $ nm -D liburandom_read.so
                           w __cxa_finalize@GLIBC_2.17
                           w __gmon_start__
                           w _ITM_deregisterTMCloneTable
                           w _ITM_registerTMCloneTable
          0000000000000000 A LIBURANDOM_READ_1.0.0
          0000000000000000 A LIBURANDOM_READ_2.0.0
          000000000000081c T urandlib_api@@LIBURANDOM_READ_2.0.0
          0000000000000814 T urandlib_api@LIBURANDOM_READ_1.0.0
          0000000000000824 T urandlib_api_sameoffset@LIBURANDOM_READ_1.0.0
          0000000000000824 T urandlib_api_sameoffset@@LIBURANDOM_READ_2.0.0
          000000000000082c T urandlib_read_without_sema@@LIBURANDOM_READ_1.0.0
          00000000000007c4 T urandlib_read_with_sema@@LIBURANDOM_READ_1.0.0
          0000000000011018 D urandlib_read_with_sema_semaphore@@LIBURANDOM_READ_1.0.0
      
      For `urandlib_api`, specifying `urandlib_api` will cause a conflict because
      there are two symbols named urandlib_api and both are global bind.
      For `urandlib_api_sameoffset`, there are also two symbols in the .so, but
      both are at the same offset and essentially they refer to the same function
      so no conflict.
      Signed-off-by: default avatarHengqi Chen <hengqi.chen@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Reviewed-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
      Link: https://lore.kernel.org/bpf/20230918024813.237475-4-hengqi.chen@gmail.com
      7089f85a
    • Hengqi Chen's avatar
      libbpf: Support symbol versioning for uprobe · bb7fa093
      Hengqi Chen authored
      In current implementation, we assume that symbol found in .dynsym section
      would have a version suffix and use it to compare with symbol user supplied.
      According to the spec ([0]), this assumption is incorrect, the version info
      of dynamic symbols are stored in .gnu.version and .gnu.version_d sections
      of ELF objects. For example:
      
          $ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
          000000000009b1a0 T __pthread_rwlock_wrlock@GLIBC_2.2.5
          000000000009b1a0 T pthread_rwlock_wrlock@@GLIBC_2.34
          000000000009b1a0 T pthread_rwlock_wrlock@GLIBC_2.2.5
      
          $ readelf -W --dyn-syms /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
            706: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 __pthread_rwlock_wrlock@GLIBC_2.2.5
            2568: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@@GLIBC_2.34
            2571: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@GLIBC_2.2.5
      
      In this case, specify pthread_rwlock_wrlock@@GLIBC_2.34 or
      pthread_rwlock_wrlock@GLIBC_2.2.5 in bpf_uprobe_opts::func_name won't work.
      Because the qualified name does NOT match `pthread_rwlock_wrlock` (without
      version suffix) in .dynsym sections.
      
      This commit implements the symbol versioning for dynsym and allows user to
      specify symbol in the following forms:
        - func
        - func@LIB_VERSION
        - func@@LIB_VERSION
      
      In case of symbol conflicts, error out and users should resolve it by
      specifying a qualified name.
      
        [0]: https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.htmlSigned-off-by: default avatarHengqi Chen <hengqi.chen@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Reviewed-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
      Link: https://lore.kernel.org/bpf/20230918024813.237475-3-hengqi.chen@gmail.com
      bb7fa093
    • Hengqi Chen's avatar
      libbpf: Resolve symbol conflicts at the same offset for uprobe · 7257cee6
      Hengqi Chen authored
      Dynamic symbols in shared library may have the same name, for example:
      
          $ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
          000000000009b1a0 T __pthread_rwlock_wrlock@GLIBC_2.2.5
          000000000009b1a0 T pthread_rwlock_wrlock@@GLIBC_2.34
          000000000009b1a0 T pthread_rwlock_wrlock@GLIBC_2.2.5
      
          $ readelf -W --dyn-syms /lib/x86_64-linux-gnu/libc.so.6 | grep rwlock_wrlock
           706: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 __pthread_rwlock_wrlock@GLIBC_2.2.5
          2568: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@@GLIBC_2.34
          2571: 000000000009b1a0   878 FUNC    GLOBAL DEFAULT   15 pthread_rwlock_wrlock@GLIBC_2.2.5
      
      Currently, users can't attach a uprobe to pthread_rwlock_wrlock because
      there are two symbols named pthread_rwlock_wrlock and both are global
      bind. And libbpf considers it as a conflict.
      
      Since both of them are at the same offset we could accept one of them
      harmlessly. Note that we already does this in elf_resolve_syms_offsets.
      Signed-off-by: default avatarHengqi Chen <hengqi.chen@gmail.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Reviewed-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
      Link: https://lore.kernel.org/bpf/20230918024813.237475-2-hengqi.chen@gmail.com
      7257cee6
  3. 21 Sep, 2023 29 commits