99 normalize_path:: NormalizePath ,
1010 object:: {
1111 elf:: {
12- FileHeader32 , FileHeader64 , ET_DYN , ET_EXEC , STB_GLOBAL , STB_WEAK , STV_DEFAULT ,
12+ FileHeader32 , FileHeader64 , ET_DYN , ET_EXEC , SHN_UNDEF , STB_GLOBAL , STB_WEAK , STV_DEFAULT ,
1313 STV_HIDDEN ,
1414 } ,
1515 macho:: { MachHeader32 , MachHeader64 , MH_OBJECT , MH_TWOLEVEL } ,
@@ -265,6 +265,25 @@ static ELF_ALLOWED_LIBRARIES_BY_TRIPLE: Lazy<HashMap<&'static str, Vec<&'static
265265 . collect ( )
266266 } ) ;
267267
268+ static ELF_ALLOWED_LIBRARIES_BY_MODULE : Lazy < HashMap < & ' static str , Vec < & ' static str > > > =
269+ Lazy :: new ( || {
270+ [
271+ (
272+ // libcrypt is provided by the system, but only on older distros.
273+ "_crypt" ,
274+ vec ! [ "libcrypt.so.1" ] ,
275+ ) ,
276+ (
277+ // libtcl and libtk are shipped in our distribution.
278+ "_tkinter" ,
279+ vec ! [ "libtcl8.6.so" , "libtk8.6.so" ] ,
280+ ) ,
281+ ]
282+ . iter ( )
283+ . cloned ( )
284+ . collect ( )
285+ } ) ;
286+
268287static DARWIN_ALLOWED_DYLIBS : Lazy < Vec < MachOAllowedDylib > > = Lazy :: new ( || {
269288 [
270289 MachOAllowedDylib {
@@ -501,6 +520,29 @@ static IOS_ALLOWED_DYLIBS: Lazy<Vec<MachOAllowedDylib>> = Lazy::new(|| {
501520 . to_vec ( )
502521} ) ;
503522
523+ static ALLOWED_DYLIBS_BY_MODULE : Lazy < HashMap < & ' static str , Vec < MachOAllowedDylib > > > =
524+ Lazy :: new ( || {
525+ [ (
526+ // libtcl and libtk are shipped in our distribution.
527+ "_tkinter" ,
528+ vec ! [
529+ MachOAllowedDylib {
530+ name: "libtcl8.6.dylib" . to_string( ) ,
531+ max_compatibility_version: "1.0.0" . try_into( ) . unwrap( ) ,
532+ required: true ,
533+ } ,
534+ MachOAllowedDylib {
535+ name: "libtk8.6.dylib" . to_string( ) ,
536+ max_compatibility_version: "1.0.0" . try_into( ) . unwrap( ) ,
537+ required: true ,
538+ } ,
539+ ] ,
540+ ) ]
541+ . iter ( )
542+ . cloned ( )
543+ . collect ( )
544+ } ) ;
545+
504546static PLATFORM_TAG_BY_TRIPLE : Lazy < HashMap < & ' static str , & ' static str > > = Lazy :: new ( || {
505547 [
506548 ( "aarch64-apple-darwin" , "macosx-11.0-arm64" ) ,
@@ -591,6 +633,11 @@ const DEPENDENCY_PACKAGE_SYMBOLS: &[&str] = &[
591633 // liblzma
592634 "lzma_index_init" ,
593635 "lzma_stream_encoder" ,
636+ ] ;
637+
638+ // TODO(geofft): Conditionally prohibit these exported symbols
639+ // everywhere except libtcl and libtk. This should be a hashmap
640+ const _DEPENDENCY_PACKAGE_SYMBOLS_BUNDLED: & [ & str ] = & [
594641 // tcl
595642 "Tcl_Alloc" ,
596643 "Tcl_ChannelName" ,
@@ -967,11 +1014,13 @@ fn validate_elf<Elf: FileHeader<Endian = Endianness>>(
9671014 allowed_libraries. push ( "libc.so" . to_string ( ) ) ;
9681015 }
9691016
970- // Allow the _crypt extension module - and only it - to link against libcrypt,
971- // which is no longer universally present in Linux distros .
1017+ // Allow certain extension modules to link against shared libraries
1018+ // (either from the system or from our distribution) .
9721019 if let Some ( filename) = path. file_name ( ) {
973- if filename. to_string_lossy ( ) . starts_with ( "_crypt" ) {
974- allowed_libraries. push ( "libcrypt.so.1" . to_string ( ) ) ;
1020+ if let Some ( ( module, _) ) = filename. to_string_lossy ( ) . split_once ( ".cpython-" ) {
1021+ if let Some ( extra) = ELF_ALLOWED_LIBRARIES_BY_MODULE . get ( module) {
1022+ allowed_libraries. extend ( extra. iter ( ) . map ( |x| x. to_string ( ) ) ) ;
1023+ }
9751024 }
9761025 }
9771026
@@ -1109,6 +1158,7 @@ fn validate_elf<Elf: FileHeader<Endian = Endianness>>(
11091158 // to prevent them from being exported.
11101159 if DEPENDENCY_PACKAGE_SYMBOLS . contains ( & name. as_ref ( ) )
11111160 && matches ! ( symbol. st_bind( ) , STB_GLOBAL | STB_WEAK )
1161+ && symbol. st_shndx ( endian) != SHN_UNDEF
11121162 && symbol. st_visibility ( ) != STV_HIDDEN
11131163 {
11141164 context. errors . push ( format ! (
@@ -1124,6 +1174,7 @@ fn validate_elf<Elf: FileHeader<Endian = Endianness>>(
11241174 if filename. starts_with ( "libpython" )
11251175 && filename. ends_with ( ".so.1.0" )
11261176 && matches ! ( symbol. st_bind( ) , STB_GLOBAL | STB_WEAK )
1177+ && symbol. st_shndx ( endian) != SHN_UNDEF
11271178 && symbol. st_visibility ( ) == STV_DEFAULT
11281179 {
11291180 context. libpython_exported_symbols . insert ( name. to_string ( ) ) ;
@@ -1225,7 +1276,16 @@ fn validate_macho<Mach: MachHeader<Endian = Endianness>>(
12251276
12261277 dylib_names. push ( lib. clone ( ) ) ;
12271278
1228- let allowed = allowed_dylibs_for_triple ( target_triple) ;
1279+ let mut allowed = allowed_dylibs_for_triple ( target_triple) ;
1280+ // Allow certain extension modules to link against shared libraries
1281+ // (either from the system or from our distribution).
1282+ if let Some ( filename) = path. file_name ( ) {
1283+ if let Some ( ( module, _) ) = filename. to_string_lossy ( ) . split_once ( ".cpython-" ) {
1284+ if let Some ( extra) = ALLOWED_DYLIBS_BY_MODULE . get ( module) {
1285+ allowed. extend ( extra. clone ( ) ) ;
1286+ }
1287+ }
1288+ }
12291289
12301290 if let Some ( entry) = allowed. iter ( ) . find ( |l| l. name == lib) {
12311291 let load_version =
0 commit comments