drivers: fix symbol exports when map is omitted

Message ID 20221129140032.35940-1-david.marchand@redhat.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series drivers: fix symbol exports when map is omitted |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-aarch64-unit-testing success Testing PASS
ci/intel-Testing success Testing PASS
ci/github-robot: build success github build: passed
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/iol-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-abi-testing warning Testing issues

Commit Message

David Marchand Nov. 29, 2022, 2 p.m. UTC
  ld exports any global symbol by default if no version script is passed.
As a consequence, the incriminated change let any public symbol leak
out of the driver shared libraries.

Hide again those symbols by providing a default map file which
unexports any global symbol using a local: * catchall statement.

The check on symbols is skipped for this default map file as it is
intentionnally an empty map (see commit b67bdda86cd4 ("devtools: catch
empty symbol maps")) and there is nothing to check in it.

While at it, move Windows specific objects where needed for better
readability.

Fixes: 7dde9c844a37 ("drivers: omit symbol map when unneeded")
Cc: stable@dpdk.org

Reported-by: Luca Boccassi <luca.boccassi@microsoft.com> 
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
 drivers/meson.build | 70 ++++++++++++++++++++++++---------------------
 drivers/version.map |  3 ++
 2 files changed, 41 insertions(+), 32 deletions(-)
 create mode 100644 drivers/version.map
  

Comments

Ferruh Yigit Nov. 29, 2022, 6:23 p.m. UTC | #1
On 11/29/2022 2:00 PM, David Marchand wrote:
> ld exports any global symbol by default if no version script is passed.
> As a consequence, the incriminated change let any public symbol leak
> out of the driver shared libraries.
> 
> Hide again those symbols by providing a default map file which
> unexports any global symbol using a local: * catchall statement.
> 

I assume this will cause warnings for ABI check scripts, how can we
prevent the warnings?

> The check on symbols is skipped for this default map file as it is
> intentionnally an empty map (see commit b67bdda86cd4 ("devtools: catch
> empty symbol maps")) and there is nothing to check in it.
> 

How it is skipped, './devtools/check-symbol-maps.sh' still complains
about 'drivers/version.map' for me.

> While at it, move Windows specific objects where needed for better
> readability.
> 

+1

> Fixes: 7dde9c844a37 ("drivers: omit symbol map when unneeded")
> Cc: stable@dpdk.org
> 
> Reported-by: Luca Boccassi <luca.boccassi@microsoft.com> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>


Not tested on Windows, but for Linux:
Tested-by: Ferruh Yigit <ferruh.yigit@amd.com>
  
David Marchand Nov. 30, 2022, 7:13 a.m. UTC | #2
On Tue, Nov 29, 2022 at 7:23 PM Ferruh Yigit <ferruh.yigit@amd.com> wrote:
>
> On 11/29/2022 2:00 PM, David Marchand wrote:
> > ld exports any global symbol by default if no version script is passed.
> > As a consequence, the incriminated change let any public symbol leak
> > out of the driver shared libraries.
> >
> > Hide again those symbols by providing a default map file which
> > unexports any global symbol using a local: * catchall statement.
> >
>
> I assume this will cause warnings for ABI check scripts, how can we
> prevent the warnings?

Indeed.

Some options:
- add exhaustive suppression rules in devtools/libabigail.abignore,
- retag the v22.11 release with this fix, but we already announced it
and people started downloading the tarball,
- release a .1 version and compare ABI against it (either in the main
repo, or in the 22.11 stable branch, through for the ABI check in GHA,
it would be simpler to have the tag in the main repo..),

Do you have other ideas?


>
> > The check on symbols is skipped for this default map file as it is
> > intentionnally an empty map (see commit b67bdda86cd4 ("devtools: catch
> > empty symbol maps")) and there is nothing to check in it.
> >
>
> How it is skipped, './devtools/check-symbol-maps.sh' still complains
> about 'drivers/version.map' for me.

I had considered the call check-symbols.sh during build.
But it is true that if you call check-symbol-maps.sh alone, we will
get a warning.

I will exclude it in v2.


>
> > While at it, move Windows specific objects where needed for better
> > readability.
> >
>
> +1
>
> > Fixes: 7dde9c844a37 ("drivers: omit symbol map when unneeded")
> > Cc: stable@dpdk.org
> >
> > Reported-by: Luca Boccassi <luca.boccassi@microsoft.com>
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
>
>
> Not tested on Windows, but for Linux:
> Tested-by: Ferruh Yigit <ferruh.yigit@amd.com>

UNH Windows tests look fine.
  
David Marchand Nov. 30, 2022, 8:27 a.m. UTC | #3
On Wed, Nov 30, 2022 at 8:13 AM David Marchand
<david.marchand@redhat.com> wrote:
> > I assume this will cause warnings for ABI check scripts, how can we
> > prevent the warnings?
>
> Indeed.
>
> Some options:
> - add exhaustive suppression rules in devtools/libabigail.abignore,
> - retag the v22.11 release with this fix, but we already announced it
> and people started downloading the tarball,
> - release a .1 version and compare ABI against it (either in the main
> repo, or in the 22.11 stable branch, through for the ABI check in GHA,
> it would be simpler to have the tag in the main repo..),

(let's forget about my concern on GHA, we have the REF_GIT_REPO param,
so we can point at the dpdk-stable repo, and go with a "normal"
release in 22.11 stable branch)

>
> Do you have other ideas?
>
  
Ferruh Yigit Nov. 30, 2022, 9:19 a.m. UTC | #4
On 11/30/2022 8:27 AM, David Marchand wrote:
> On Wed, Nov 30, 2022 at 8:13 AM David Marchand
> <david.marchand@redhat.com> wrote:
>>> I assume this will cause warnings for ABI check scripts, how can we
>>> prevent the warnings?
>>
>> Indeed.
>>
>> Some options:
>> - add exhaustive suppression rules in devtools/libabigail.abignore,
>> - retag the v22.11 release with this fix, but we already announced it
>> and people started downloading the tarball,
>> - release a .1 version and compare ABI against it (either in the main
>> repo, or in the 22.11 stable branch, through for the ABI check in GHA,
>> it would be simpler to have the tag in the main repo..),
> 
> (let's forget about my concern on GHA, we have the REF_GIT_REPO param,
> so we can point at the dpdk-stable repo, and go with a "normal"
> release in 22.11 stable branch)
> 

OK to have v22.11.1 stable release with this fix.
  
Tyler Retzlaff Dec. 2, 2022, 12:11 a.m. UTC | #5
On Tue, Nov 29, 2022 at 06:23:21PM +0000, Ferruh Yigit wrote:
> On 11/29/2022 2:00 PM, David Marchand wrote:
> > ld exports any global symbol by default if no version script is passed.
> > As a consequence, the incriminated change let any public symbol leak
> > out of the driver shared libraries.
> > 
> 
> Not tested on Windows, but for Linux:

just for awareness the default is the opposite on windows symbols are
private by default and have to be explicitly made public.

also, for gcc we could go to the extreme and pass -fvisibility=hidden
and fix out any other symbols that are missed.

if you're really going wild you may consider introducing a macro that
can be expanded to __attribute__((visibility("default"))) combined with
-fvisibility=hidden (as opposed to version.map) the main benefit being
there's only a single source of truth about whether or not the symbol is
public, you don't have to look in 2 places.
(anyway, probably not a popular idea...)

ty
  

Patch

diff --git a/drivers/meson.build b/drivers/meson.build
index c4ff3ff1ba..77e92c3bce 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -206,44 +206,50 @@  foreach subpath:subdirs
 
         # now build the shared driver
         version_map = '@0@/@1@/version.map'.format(meson.current_source_dir(), drv_path)
-        implib = 'lib' + lib_name + '.dll.a'
 
         lk_deps = []
         lk_args = []
-        if fs.is_file(version_map)
-            def_file = custom_target(lib_name + '_def',
-                    command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
-                    input: version_map,
-                    output: '@0@_exports.def'.format(lib_name))
-
-            mingw_map = custom_target(lib_name + '_mingw',
-                    command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
-                    input: version_map,
-                    output: '@0@_mingw.map'.format(lib_name))
-
-            lk_deps = [version_map, def_file, mingw_map]
-            if is_windows
-                if is_ms_linker
-                    lk_args = ['-Wl,/def:' + def_file.full_path()]
-                    if meson.version().version_compare('<0.54.0')
-                        lk_args += ['-Wl,/implib:drivers\\' + implib]
-                    endif
-                else
-                    lk_args = ['-Wl,--version-script=' + mingw_map.full_path()]
+        if not fs.is_file(version_map)
+            version_map = '@0@/version.map'.format(meson.current_source_dir())
+            lk_deps += [version_map]
+        else
+            lk_deps += [version_map]
+            if not is_windows and developer_mode
+                # on unix systems check the output of the
+                # check-symbols.sh script, using it as a
+                # dependency of the .so build
+                lk_deps += custom_target(lib_name + '.sym_chk',
+                        command: [check_symbols, version_map, '@INPUT@'],
+                        capture: true,
+                        input: static_lib,
+                        output: lib_name + '.sym_chk')
+            endif
+        endif
+
+        if is_windows
+            if is_ms_linker
+                def_file = custom_target(lib_name + '_def',
+                        command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
+                        input: version_map,
+                        output: '@0@_exports.def'.format(lib_name))
+                lk_deps += def_file
+
+                lk_args = ['-Wl,/def:' + def_file.full_path()]
+                if meson.version().version_compare('<0.54.0')
+                    implib = 'lib' + lib_name + '.dll.a'
+                    lk_args += ['-Wl,/implib:drivers\\' + implib]
                 endif
             else
-                lk_args = ['-Wl,--version-script=' + version_map]
-                if developer_mode
-                    # on unix systems check the output of the
-                    # check-symbols.sh script, using it as a
-                    # dependency of the .so build
-                    lk_deps += custom_target(lib_name + '.sym_chk',
-                            command: [check_symbols, version_map, '@INPUT@'],
-                            capture: true,
-                            input: static_lib,
-                            output: lib_name + '.sym_chk')
-                endif
+                mingw_map = custom_target(lib_name + '_mingw',
+                        command: [map_to_win_cmd, '@INPUT@', '@OUTPUT@'],
+                        input: version_map,
+                        output: '@0@_mingw.map'.format(lib_name))
+                lk_deps += [mingw_map]
+
+                lk_args = ['-Wl,--version-script=' + mingw_map.full_path()]
             endif
+        else
+            lk_args = ['-Wl,--version-script=' + version_map]
         endif
 
         shared_lib = shared_library(lib_name, sources,
diff --git a/drivers/version.map b/drivers/version.map
new file mode 100644
index 0000000000..78c3585d7c
--- /dev/null
+++ b/drivers/version.map
@@ -0,0 +1,3 @@ 
+DPDK_23 {
+	local: *;
+};