[SERVER-62494] Research effect of gnu-unique flags on mongo_csfle.so Created: 10/Jan/22  Updated: 20/Jan/22  Resolved: 20/Jan/22

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Sergey Galtsev (Inactive) Assignee: Sergey Galtsev (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File src_20220119-1440.tgz    
Issue Links:
Depends
is depended on by SERVER-62156 CSFLE: linux library to use extra swi... Closed
Sprint: Security 2022-01-24
Participants:

 Description   
  • build csfle without any gnu-unique flags, with the v3 GCC and the v4 gcc. Does the resulting binary contain any STB_GNU_UNIQUE symbols? If so, are they from the mongodb/third_party code, or are they from the toolchain C++ runtime?
  • If it does contain them from mongo/third_party, does building our sources with fno-gnu-unique eliminate them? Does linking with -Wl,-no-gnu-unique eliminate them?
  • If it does contain them from the toolchain C++ runtime, can Wl,-no-gnu-unique eliminate them by downgrading them from STB_GNU_UNIQUE to something else?
  • If we cannot eliminate them easily (e.g. the toolchain ones persist despite Wl,-no-gnu-unique, are there issues when dlopen’ing the csfle.so library in the context of another library that has STB_GNU_UNIQUE symbols that should be resolved to, say, the system C++ runtime?

The above questions should be answered by using tools like nm and readelf for the first few, and LD_DEBUG for the latter.



 Comments   
Comment by Sergey Galtsev (Inactive) [ 20/Jan/22 ]

Tests were performed using following command line:

 

scripts/scons.py --variables-files=etc/scons/mongodbtoolchain_v3_gcc.vars \
    build/install/lib/libbase.so --link-model=dynamic
# optionally:
# SHLINKFLAGS_EXTRA=-Wl,--no-gnu-unique
# CCFLAGS=-fno-gnu-unique
 
nm build/install/lib/libbase.so  | grep  " u " | c++filt

Result:

  • No flags - yes "u" symbols
  • SHLINKFLAGS_EXTRA only: no "u" symbols
  • CCFLAGS only: most "u" symbols gone, but std::mersenne_twister_engine-related remain
  • Both SHLINKFLAGS and CCFLAGS : no "u" symbols

Conclusion:

Must use both SHLINKFLAGS_EXTRA=Wl,-no-gnu-unique and CCFLAGS=-fno-gnu-unique

 

Comment by Sergey Galtsev (Inactive) [ 20/Jan/22 ]

Some more permutations tested:

sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh 
0000000000154008 u var1
000000000007e599 W _Z10var1_func3v
000000000007e50a T _Z9var1_funcv
000000000007e516 T _ZN1X10var1_func2Ev
sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-fno-gnu-unique"
0000000000154008 V var1
000000000007e599 W _Z10var1_func3v
000000000007e50a T _Z9var1_funcv
000000000007e516 T _ZN1X10var1_func2Ev
sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-fno-gnu-unique" "-Wl,--no-gnu-unique"
0000000000154008 V var1
000000000007e599 W _Z10var1_func3v
000000000007e50a T _Z9var1_funcv
000000000007e516 T _ZN1X10var1_func2Ev
sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-Wl,--no-gnu-unique"
0000000000154008 D var1
000000000007e599 W _Z10var1_func3v
000000000007e50a T _Z9var1_funcv
000000000007e516 T _ZN1X10var1_func2Ev
sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-Wl,--version-script,main.version_script" "-fno-gnu-unique" "-Wl,--no-gnu-unique"
00000000000e7008 d var1
0000000000015439 t _Z10var1_func3v
00000000000153aa t _Z9var1_funcv
00000000000153b6 t _ZN1X10var1_func2Ev
sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-Wl,--version-script,main.version_script"
00000000000e7008 d var1
0000000000015439 t _Z10var1_func3v
00000000000153aa t _Z9var1_funcv
00000000000153b6 t _ZN1X10var1_func2Ev
sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-Wl,--version-script,main.version_script" "-fno-gnu-unique" 
00000000000e7008 d var1
0000000000015439 t _Z10var1_func3v
00000000000153aa t _Z9var1_funcv
00000000000153b6 t _ZN1X10var1_func2Ev
sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-Wl,--version-script,main.version_script" "-Wl,--no-gnu-unique"
00000000000e7008 d var1
0000000000015439 t _Z10var1_func3v
00000000000153aa t _Z9var1_funcv
00000000000153b6 t _ZN1X10var1_func2Ev

Comment by Sergey Galtsev (Inactive) [ 20/Jan/22 ]

Setting:

compiling simple code with several symbols "varXXX"

 

 

build.sh:
#!/bin/bash
g++ -Wl,--fatal-warnings -Wl,--no-as-needed -pthread -Wl,-z,now -fuse-ld=gold -fstack-protector-strong -Wl,--gdb-index \
 -Wl,--no-threads -Wl,--build-id -Wl,--hash-style=gnu -Wl,-z,noexecstack -Wl,--warn-execstack -Wl,-z,relro \
 -Wl,--compress-debug-sections=zlib-gabi -Wl,-z,origin -Wl,--enable-new-dtags -shared -Wl,-rpath=\$ORIGIN/../lib \
 -Wl,-z,defs -fPIC "$@" main.cpp -std=c++17 -o main.so
nm main.so | grep var1

 

Switches Tested:

 

./build.sh
 ./build.sh "-fno-gnu-unique"
 ./build.sh "-Wl,--version-script,main.version_script"
 ./build.sh "-Wl,--version-script,main.version_script" "-fno-gnu-unique"

 

Results:

Same experiment repeated with /opt/mongodbtoolchain/v3/bin/g++ and /opt/mongodbtoolchain/v4/bin/g++ with exactly same result

 

(venv) sgmongo@melandru:~/Projects/2022/research/src$ g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0(venv) sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh
0000000000003008 u var1
0000000000000ba4 W _Z10var1_func3v
0000000000000b0a T _Z9var1_funcv
0000000000000b1a T _ZN1X10var1_func2Ev
(venv) sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-fno-gnu-unique"
0000000000003008 V var1
0000000000000ba4 W _Z10var1_func3v
0000000000000b0a T _Z9var1_funcv
0000000000000b1a T _ZN1X10var1_func2Ev
(venv) sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-Wl,--version-script,main.version_script"
0000000000002008 d var1
00000000000009e4 t _Z10var1_func3v
000000000000094a t _Z9var1_funcv
000000000000095a t _ZN1X10var1_func2Ev
(venv) sgmongo@melandru:~/Projects/2022/research/src$ ./build.sh "-Wl,--version-script,main.version_script" "-fno-gnu-unique"
0000000000002008 d var1
00000000000009e4 t _Z10var1_func3v
000000000000094a t _Z9var1_funcv

Sympol types

https://sourceware.org/binutils/docs/binutils/nm.html

 

T
 t
 
The symbol is in the text (code) section.
 
u
 
The symbol is a unique global symbol. This is a GNU extension to the standard set of ELF symbol bindings. For such a symbol the dynamic linker will make sure that in the entire process there is just one symbol with this name and type in use.
 
V
 v
 
The symbol is a weak object. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the weak symbol becomes zero with no error. On some systems, uppercase indicates that a default value has been specified.
 
W
 w
 
The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified.

 
 

Interpretaton:

-fno-gnu-unique has an effect of converting symbol marked as gnu-unique to a weak object. I could not figure out how to generate functions as gnu-unique
Wl,-version-script has an effect of converting gnu-unique symbols to data. for functions, T becomes t, but unclear what actually changes since they refer to the same thing

We might need to still use -fno-gnu-unique in case a version-script somehow gets disabled, but the best way of ensuring "u" symbols do not appear in the resulting so is writing a test to run during the build.

Generated at Thu Feb 08 05:55:17 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.