Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.0: libsemanage uses libsepol non-public symbols. #204

Closed
kloczek opened this issue Feb 22, 2020 · 18 comments
Closed

3.0: libsemanage uses libsepol non-public symbols. #204

kloczek opened this issue Feb 22, 2020 · 18 comments

Comments

@kloczek
Copy link

kloczek commented Feb 22, 2020

Looks like libsemanage cannot be linked against shared libsepol because it uses libsepol symbols not listed in libsepol.map.in :/

gcc -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection  -Os -I../include -D_GNU_SOURCE -Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld  -shared -o libsemanage.so.1 boolean_record.lo booleans_active.lo booleans_activedb.lo booleans_file.lo booleans_local.lo booleans_policy.lo booleans_policydb.lo context_record.lo database.lo database_activedb.lo database_file.lo database_join.lo database_llist.lo database_policydb.lo debug.lo direct_api.lo fcontext_record.lo fcontexts_file.lo fcontexts_local.lo fcontexts_policy.lo genhomedircon.lo handle.lo ibendport_record.lo ibendports_file.lo ibendports_local.lo ibendports_policy.lo ibendports_policydb.lo ibpkey_record.lo ibpkeys_file.lo ibpkeys_local.lo ibpkeys_policy.lo ibpkeys_policydb.lo iface_record.lo interfaces_file.lo interfaces_local.lo interfaces_policy.lo interfaces_policydb.lo modules.lo node_record.lo nodes_file.lo nodes_local.lo nodes_policy.lo nodes_policydb.lo parse_utils.lo policy_components.lo port_record.lo ports_file.lo ports_local.lo ports_policy.lo ports_policydb.lo semanage_store.lo seuser_record.lo seusers_file.lo seusers_local.lo seusers_policy.lo user_base_record.lo user_extra_record.lo user_record.lo users_base_file.lo users_base_policydb.lo users_extra_file.lo users_join.lo users_local.lo users_policy.lo utilities.lo conf-scan.lo conf-parse.lo -lsepol -laudit -lselinux -lbz2 -Wl,-soname,libsemanage.so.1,--version-script=libsemanage.map,-z,defs
/usr/bin/ld: boolean_record.lo: in function `semanage_bool_create_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/boolean_record.c:168: undefined reference to `sepol_bool_create'
/usr/bin/ld: boolean_record.lo: in function `semanage_bool_key_create':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/boolean_record.c:32: undefined reference to `sepol_bool_key_create'
/usr/bin/ld: boolean_record.lo: in function `semanage_bool_get_name_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/boolean_record.c:81: undefined reference to `sepol_bool_get_name'
/usr/bin/ld: boolean_record.lo: in function `semanage_bool_get_value_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/boolean_record.c:150: undefined reference to `sepol_bool_get_value'
/usr/bin/ld: boolean_record.lo: in function `semanage_bool_set_value_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/boolean_record.c:158: undefined reference to `sepol_bool_set_value'
/usr/bin/ld: context_record.lo: in function `semanage_context_get_user':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/context_record.c:15: undefined reference to `sepol_context_get_user'
/usr/bin/ld: context_record.lo: in function `semanage_context_get_role':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/context_record.c:29: undefined reference to `sepol_context_get_role'
/usr/bin/ld: context_record.lo: in function `semanage_context_get_type':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/context_record.c:43: undefined reference to `sepol_context_get_type'
/usr/bin/ld: context_record.lo: in function `semanage_context_get_mls':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/context_record.c:57: undefined reference to `sepol_context_get_mls'
/usr/bin/ld: context_record.lo: in function `semanage_context_create':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/context_record.c:72: undefined reference to `sepol_context_create'
/usr/bin/ld: context_record.lo: in function `semanage_context_from_string_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/context_record.c:98: undefined reference to `sepol_context_from_string'
/usr/bin/ld: database_policydb.lo: in function `dbase_policydb_drop_cache':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/database_policydb.c:48: undefined reference to `sepol_policydb_free'
/usr/bin/ld: database_policydb.lo: in function `dbase_policydb_cache':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/database_policydb.c:107: undefined reference to `sepol_policydb_create'
/usr/bin/ld: /home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/database_policydb.c:152: undefined reference to `sepol_policydb_free'
/usr/bin/ld: debug.lo: in function `semanage_msg_relay_handler':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/debug.c:109: undefined reference to `sepol_msg_get_fname'
/usr/bin/ld: /home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/debug.c:110: undefined reference to `sepol_msg_get_channel'
/usr/bin/ld: /home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/debug.c:111: undefined reference to `sepol_msg_get_level'
/usr/bin/ld: direct_api.lo: in function `semanage_direct_commit':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:1419: undefined reference to `cil_compile'
/usr/bin/ld: /home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:1423: undefined reference to `cil_build_policydb'
/usr/bin/ld: /home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:1428: undefined reference to `cil_filecons_to_string'
/usr/bin/ld: direct_api.lo: in function `semanage_direct_update_seuser':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:723: undefined reference to `cil_selinuxusers_to_string'
/usr/bin/ld: direct_api.lo: in function `semanage_direct_update_user_extra':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:668: undefined reference to `cil_userprefixes_to_string'
/usr/bin/ld: direct_api.lo: in function `semanage_direct_commit':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:1478: undefined reference to `sepol_policydb_create'
/usr/bin/ld: /home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:1649: undefined reference to `sepol_policydb_free'
/usr/bin/ld: /home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:1675: undefined reference to `sepol_policydb_free'
/usr/bin/ld: direct_api.lo: in function `semanage_direct_mls_enabled':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:2203: undefined reference to `sepol_policydb_create'
/usr/bin/ld: /home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/direct_api.c:2213: undefined reference to `sepol_policydb_free'
/usr/bin/ld: genhomedircon.lo: in function `check_line':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/genhomedircon.c:568: undefined reference to `sepol_context_from_string'
/usr/bin/ld: genhomedircon.lo: in function `write_contexts':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/genhomedircon.c:633: undefined reference to `sepol_context_from_string'
/usr/bin/ld: ibendport_record.lo: in function `semanage_ibendport_create_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibendport_record.c:123: undefined reference to `sepol_ibendport_create'
/usr/bin/ld: ibendport_record.lo: in function `semanage_ibendport_key_create':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibendport_record.c:53: undefined reference to `sepol_ibendport_key_create'
/usr/bin/ld: ibendport_record.lo: in function `semanage_ibendport_get_ibdev_name_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibendport_record.c:76: undefined reference to `sepol_ibendport_get_ibdev_name'
/usr/bin/ld: ibendport_record.lo: in function `semanage_ibendport_set_ibdev_name_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibendport_record.c:85: undefined reference to `sepol_ibendport_set_ibdev_name'
/usr/bin/ld: ibendport_record.lo: in function `semanage_ibendport_get_port_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibendport_record.c:92: undefined reference to `sepol_ibendport_get_port'
/usr/bin/ld: ibendport_record.lo: in function `semanage_ibendport_set_port_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibendport_record.c:99: undefined reference to `sepol_ibendport_set_port'
/usr/bin/ld: ibendport_record.lo: in function `semanage_ibendport_get_con_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibendport_record.c:106: undefined reference to `sepol_ibendport_get_con'
/usr/bin/ld: ibendport_record.lo: in function `semanage_ibendport_set_con_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibendport_record.c:115: undefined reference to `sepol_ibendport_set_con'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_create_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:151: undefined reference to `sepol_ibpkey_create'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_key_create':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:53: undefined reference to `sepol_ibpkey_key_create'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_get_subnet_prefix_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:76: undefined reference to `sepol_ibpkey_get_subnet_prefix'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_get_subnet_prefix_bytes_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:83: undefined reference to `sepol_ibpkey_get_subnet_prefix_bytes'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_set_subnet_prefix_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:92: undefined reference to `sepol_ibpkey_set_subnet_prefix'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_set_subnet_prefix_bytes_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:100: undefined reference to `sepol_ibpkey_set_subnet_prefix_bytes'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_get_low_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:107: undefined reference to `sepol_ibpkey_get_low'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_get_high_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:114: undefined reference to `sepol_ibpkey_get_high'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_set_range_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:128: undefined reference to `sepol_ibpkey_set_range'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_get_con_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:135: undefined reference to `sepol_ibpkey_get_con'
/usr/bin/ld: ibpkey_record.lo: in function `semanage_ibpkey_set_con_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/ibpkey_record.c:143: undefined reference to `sepol_ibpkey_set_con'
/usr/bin/ld: iface_record.lo: in function `semanage_iface_create_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/iface_record.c:136: undefined reference to `sepol_iface_create'
/usr/bin/ld: iface_record.lo: in function `semanage_iface_key_create':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/iface_record.c:56: undefined reference to `sepol_iface_key_create'
/usr/bin/ld: iface_record.lo: in function `semanage_iface_get_name_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/iface_record.c:81: undefined reference to `sepol_iface_get_name'
/usr/bin/ld: iface_record.lo: in function `semanage_iface_get_ifcon_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/iface_record.c:99: undefined reference to `sepol_iface_get_ifcon'
/usr/bin/ld: iface_record.lo: in function `semanage_iface_set_ifcon_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/iface_record.c:108: undefined reference to `sepol_iface_set_ifcon'
/usr/bin/ld: iface_record.lo: in function `semanage_iface_get_msgcon_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/iface_record.c:116: undefined reference to `sepol_iface_get_msgcon'
/usr/bin/ld: iface_record.lo: in function `semanage_iface_set_msgcon_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/iface_record.c:126: undefined reference to `sepol_iface_set_msgcon'
/usr/bin/ld: node_record.lo: in function `semanage_node_key_free_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:76: undefined reference to `sepol_node_key_free'
/usr/bin/ld: node_record.lo: in function `semanage_node_create_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:207: undefined reference to `sepol_node_create'
/usr/bin/ld: node_record.lo: in function `semanage_node_key_create':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:59: undefined reference to `sepol_node_key_create'
/usr/bin/ld: node_record.lo: in function `semanage_node_get_addr_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:86: undefined reference to `sepol_node_get_addr'
/usr/bin/ld: node_record.lo: in function `semanage_node_get_addr_bytes_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:96: undefined reference to `sepol_node_get_addr_bytes'
/usr/bin/ld: node_record.lo: in function `semanage_node_set_addr_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:105: undefined reference to `sepol_node_set_addr'
/usr/bin/ld: node_record.lo: in function `semanage_node_get_mask_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:125: undefined reference to `sepol_node_get_mask'
/usr/bin/ld: node_record.lo: in function `semanage_node_get_mask_bytes_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:135: undefined reference to `sepol_node_get_mask_bytes'
/usr/bin/ld: node_record.lo: in function `semanage_node_set_mask_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:144: undefined reference to `sepol_node_set_mask'
/usr/bin/ld: node_record.lo: in function `semanage_node_get_proto_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:163: undefined reference to `sepol_node_get_proto'
/usr/bin/ld: node_record.lo: in function `semanage_node_set_proto_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:171: undefined reference to `sepol_node_set_proto'
/usr/bin/ld: node_record.lo: in function `semanage_node_get_proto_str_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:179: undefined reference to `sepol_node_get_proto_str'
/usr/bin/ld: node_record.lo: in function `semanage_node_get_con_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:188: undefined reference to `sepol_node_get_con'
/usr/bin/ld: node_record.lo: in function `semanage_node_set_con_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/node_record.c:197: undefined reference to `sepol_node_set_con'
/usr/bin/ld: port_record.lo: in function `semanage_port_create_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/port_record.c:159: undefined reference to `sepol_port_create'
/usr/bin/ld: port_record.lo: in function `semanage_port_key_create':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/port_record.c:57: undefined reference to `sepol_port_key_create'
/usr/bin/ld: port_record.lo: in function `semanage_port_get_proto_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/port_record.c:82: undefined reference to `sepol_port_get_proto'
/usr/bin/ld: port_record.lo: in function `semanage_port_set_proto_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/port_record.c:90: undefined reference to `sepol_port_set_proto'
/usr/bin/ld: port_record.lo: in function `semanage_port_get_low_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/port_record.c:107: undefined reference to `sepol_port_get_low'
/usr/bin/ld: port_record.lo: in function `semanage_port_get_high_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/port_record.c:115: undefined reference to `sepol_port_get_high'
/usr/bin/ld: port_record.lo: in function `semanage_port_set_range_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/port_record.c:131: undefined reference to `sepol_port_set_range'
/usr/bin/ld: port_record.lo: in function `semanage_port_get_con_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/port_record.c:140: undefined reference to `sepol_port_get_con'
/usr/bin/ld: port_record.lo: in function `semanage_port_set_con_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/port_record.c:149: undefined reference to `sepol_port_set_con'
/usr/bin/ld: user_base_record.lo: in function `semanage_user_base_create':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/user_base_record.c:157: undefined reference to `sepol_user_create'
/usr/bin/ld: user_base_record.lo: in function `semanage_user_base_get_mlslevel':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/user_base_record.c:79: undefined reference to `sepol_user_get_mlslevel'
/usr/bin/ld: user_base_record.lo: in function `semanage_user_base_get_mlsrange':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/user_base_record.c:94: undefined reference to `sepol_user_get_mlsrange'
/usr/bin/ld: user_base_record.lo: in function `semanage_user_base_has_role':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/user_base_record.c:131: undefined reference to `sepol_user_has_role'
/usr/bin/ld: user_base_record.lo: in function `semanage_user_base_get_roles':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/user_base_record.c:140: undefined reference to `sepol_user_get_roles'
/usr/bin/ld: user_record.lo: in function `semanage_user_compare_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/user_record.c:72: undefined reference to `sepol_user_key_unpack'
/usr/bin/ld: user_record.lo: in function `semanage_user_key_create_internal':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/user_record.c:37: undefined reference to `sepol_user_key_create'
/usr/bin/ld: user_record.lo: in function `semanage_user_key_unpack':
/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/user_record.c:64: undefined reference to `sepol_user_key_unpack'
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:91: libsemanage.so.1] Error 1
make[1]: Leaving directory '/home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src'
make: *** [Makefile:2: all] Error 2
error: Bad exit status from /var/tmp/rpm-tmp.2FDrUb (%build)
@stephensmalley
Copy link
Member

stephensmalley commented Feb 24, 2020

Not sure what you mean here or how you are building this, but libsemanage builds fine for me and only uses symbols from libsepol exported by libsepol.map.

@kloczek
Copy link
Author

kloczek commented Feb 24, 2020

Yes uit builds but on linking it uses static libsepol.

I've been trying to build libsemanage using only shared libsepol and I found that libsemanage uses libsepol symbols which are not listed in public symbols of that library.
Here is the patch to try link libsemanage using shared libsepol :

--- libsemanage-2.9/src/Makefile~       2019-03-15 10:32:30.000000000 +0000
+++ libsemanage-2.9/src/Makefile        2019-07-13 19:43:11.810422982 +0100
@@ -65,7 +65,7 @@

 SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./

-all: $(LIBA) $(LIBSO) $(LIBPC)
+all: $(LIBSO) $(LIBPC)

 pywrap: all $(SWIGSO)

@@ -134,7 +134,6 @@

 install: all
        test -d $(DESTDIR)$(LIBDIR) || install -m 755 -d $(DESTDIR)$(LIBDIR)
-       install -m 644 $(LIBA) $(DESTDIR)$(LIBDIR)
        install -m 755 $(LIBSO) $(DESTDIR)$(LIBDIR)
        test -d $(DESTDIR)$(LIBDIR)/pkgconfig || install -m 755 -d $(DESTDIR)$(LIBDIR)/pkgconfig
        install -m 644 $(LIBPC) $(DESTDIR)$(LIBDIR)/pkgconfig
@@ -155,7 +154,7 @@
        /sbin/restorecon $(DESTDIR)$(LIBDIR)/$(LIBSO)

 clean:
-       -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(SWIGRUBYSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c *.o *.lo *~
+       -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(SWIGRUBYSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c *.o *.lo *~

 distclean: clean
        rm -f $(GENERATED) $(SWIGFILES)
--- a/tests/Makefile~   2019-11-28 12:46:48.000000000 +0000
+++ b/tests/Makefile    2020-02-22 21:50:19.645095244 +0000
@@ -14,7 +14,7 @@

 all: $(EXECUTABLE) $(POLICIES)

-$(EXECUTABLE): $(OBJECTS) ../src/libsemanage.a
+$(EXECUTABLE): $(OBJECTS) ../src/libsemanage.so
        $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)

 %.policy: %.cil
@@ -24,5 +24,5 @@
        rm -rf $(OBJECTS) $(POLICIES) $(EXECUTABLE)

 test: all
-       ./$(EXECUTABLE)
+       LD_LIBRARY_PATH=../srs ./$(EXECUTABLE)

@stephensmalley
Copy link
Member

stephensmalley commented Feb 24, 2020

The first error you showed was:

/usr/bin/ld: boolean_record.lo: in function semanage_bool_create_internal': /home/tkloczko/rpmbuild/BUILD/libsemanage-3.0/src/boolean_record.c:168: undefined reference to sepol_bool_create'

but sepol_bool_* is exported by libsepol.map.in and is visible in the symbol table of libsepol.so.1.
libsemanage.so.1 does not statically link with libsepol.a AFAIK; that would be a bug if true.
libsemanage/tests contains a set of unit tests; those do statically link with libsemanage.a and AFAICT that's by design - they are unit tests including internal functions not merely public APIs/ABIs.
Your LD_LIBRARY_PATH above also looks wrong regardless (../srs versus ../src). Anyway if you change the Makefile in a way that breaks the build, that's not our bug.

@kloczek
Copy link
Author

kloczek commented Feb 24, 2020

I have installed libsepol generated with LTO and just rebuild libsepol without LTO:

[tkloczko@barrel src]$ nm  -D /usr/lib64/libsepol.so | grep sepol_bool ; nm  -D /usr/lib64/libsepol.so | grep -c sepol_bool
000000000002c318 T sepol_bool_clone
000000000002c2fa T sepol_bool_compare
000000000002c309 T sepol_bool_compare2
000000000002c61b T sepol_bool_count
000000000002c62a T sepol_bool_exists
00000000000057cf T sepol_bool_free
000000000002c7d2 T sepol_bool_iterate
000000000002c1ad T sepol_bool_key_extract
000000000002c2db T sepol_bool_key_free
000000000002c6cc T sepol_bool_query
000000000002c3e4 T sepol_bool_set
00000000000057ea T sepol_bool_set_name
12
[tkloczko@barrel src]$ nm  -D libsepol.so | grep sepol_bool ; nm  -D libsepol.so | grep sepol_bool -c
000000000000a001 T sepol_bool_clone
0000000000009eb1 T sepol_bool_compare
0000000000009ec0 T sepol_bool_compare2
000000000000a455 T sepol_bool_count
0000000000009f63 T sepol_bool_create
000000000000a464 T sepol_bool_exists
0000000000009fe2 T sepol_bool_free
0000000000009ecf T sepol_bool_get_name
0000000000009f53 T sepol_bool_get_value
000000000000a681 T sepol_bool_iterate
0000000000009d34 T sepol_bool_key_create
0000000000009e21 T sepol_bool_key_extract
0000000000009e92 T sepol_bool_key_free
0000000000009e16 T sepol_bool_key_unpack
000000000000a53f T sepol_bool_query
000000000000a1bc T sepol_bool_set
0000000000009ed7 T sepol_bool_set_name
0000000000009f5b T sepol_bool_set_value
18

As you see in case binary optimised with LTO there are missing 5 sepol_bool_* symbols. And I found just why,

Yopu are listing some symbols which are listed in installed API header giles as hidden.

[tkloczko@barrel src]$ grep sepol_bool_create *
boolean_internal.h:    hidden_proto(sepol_bool_create)     <== HERE
boolean_record.c:int sepol_bool_create(sepol_handle_t * handle, sepol_bool_t ** bool_ptr)
boolean_record.c:hidden_def(sepol_bool_create)
boolean_record.c:       if (sepol_bool_create(handle, &new_bool) < 0)
Binary file boolean_record.lo matches
booleans.c:     if (sepol_bool_create(handle, &tmp_record) < 0)
Binary file booleans.lo matches
Binary file libsepol.so matches
Binary file libsepol.so.1 matches

If symbol is hidden it is automatically removed by LTO.

You shoud decide which one symbols should be public and which one private/hiddenm.

@stephensmalley
Copy link
Member

hidden_proto() doesn't hide the exported symbol definition; it creates a hidden internal variant of the symbol with an _internal suffix for internal callers to use to avoid the unnecessary cost and risk of those internal callers being resolved to an external implementation provided by some other shared object. hidden_proto/hidden_def stuff came from Red Hat glibc folks originally IIRC.

@stephensmalley
Copy link
Member

Looking back at history, it came from Ulrich Drepper originally to reduce relocations and PLT entries and avoid need for any PLT entries for local symbols

@kloczek
Copy link
Author

kloczek commented Feb 24, 2020

Looks like this macro is affecting LTO generated DSOs.

I understand you intention however looks like Urlich prepared this approach when no one have been even thinking about LTO.
I think that this level of optimisation in case of SELinux libraries whichj are used only sporadically by live code is not needed bedcause SELinux libraries code is not frequently used and definitelly is not critical from point of view of performance. At the same time using LTO may give much more optimisation.

Here is exact list of symbols libsepol symbols which will be affected by this issue:

[tkloczko@barrel src]$ grep hidden_proto * | awk -F: '{print $2}' | sed 's/ //g' | grep ^hidden_proto | sort
hidden_proto(sepol_bool_create)
hidden_proto(sepol_bool_free)
hidden_proto(sepol_bool_get_name)
hidden_proto(sepol_bool_get_value)
hidden_proto(sepol_bool_key_create)
hidden_proto(sepol_bool_key_unpack)
hidden_proto(sepol_bool_set_name)
hidden_proto(sepol_bool_set_value)
hidden_proto(sepol_context_clone)
hidden_proto(sepol_context_create)
hidden_proto(sepol_context_free)
hidden_proto(sepol_context_from_string)
hidden_proto(sepol_context_get_mls)
hidden_proto(sepol_context_get_role)
hidden_proto(sepol_context_get_type)
hidden_proto(sepol_context_get_user)
hidden_proto(sepol_context_set_mls)
hidden_proto(sepol_context_set_role)
hidden_proto(sepol_context_set_type)
hidden_proto(sepol_context_set_user)
hidden_proto(sepol_ibendport_create)
hidden_proto(sepol_ibendport_free)
hidden_proto(sepol_ibendport_get_con)
hidden_proto(sepol_ibendport_get_ibdev_name)
hidden_proto(sepol_ibendport_get_port)
hidden_proto(sepol_ibendport_key_create)
hidden_proto(sepol_ibendport_key_unpack)
hidden_proto(sepol_ibendport_set_con)
hidden_proto(sepol_ibendport_set_ibdev_name)
hidden_proto(sepol_ibendport_set_port)
hidden_proto(sepol_ibpkey_create)
hidden_proto(sepol_ibpkey_free)
hidden_proto(sepol_ibpkey_get_con)
hidden_proto(sepol_ibpkey_get_high)
hidden_proto(sepol_ibpkey_get_low)
hidden_proto(sepol_ibpkey_get_subnet_prefix)
hidden_proto(sepol_ibpkey_get_subnet_prefix_bytes)
hidden_proto(sepol_ibpkey_key_create)
hidden_proto(sepol_ibpkey_key_unpack)
hidden_proto(sepol_ibpkey_set_con)
hidden_proto(sepol_ibpkey_set_range)
hidden_proto(sepol_ibpkey_set_subnet_prefix)
hidden_proto(sepol_ibpkey_set_subnet_prefix_bytes)
hidden_proto(sepol_iface_create)
hidden_proto(sepol_iface_free)
hidden_proto(sepol_iface_get_ifcon)
hidden_proto(sepol_iface_get_msgcon)
hidden_proto(sepol_iface_get_name)
hidden_proto(sepol_iface_key_create)
hidden_proto(sepol_iface_key_unpack)
hidden_proto(sepol_iface_set_ifcon)
hidden_proto(sepol_iface_set_msgcon)
hidden_proto(sepol_iface_set_name)
hidden_proto(sepol_module_package_create)
hidden_proto(sepol_module_package_free)
hidden_proto(sepol_msg_get_channel)
hidden_proto(sepol_msg_get_fname)
hidden_proto(sepol_msg_get_level)
hidden_proto(sepol_node_create)
hidden_proto(sepol_node_free)
hidden_proto(sepol_node_get_addr)
hidden_proto(sepol_node_get_addr_bytes)
hidden_proto(sepol_node_get_con)
hidden_proto(sepol_node_get_mask)
hidden_proto(sepol_node_get_mask_bytes)
hidden_proto(sepol_node_get_proto)
hidden_proto(sepol_node_get_proto_str)
hidden_proto(sepol_node_key_create)
hidden_proto(sepol_node_key_free)
hidden_proto(sepol_node_key_unpack)
hidden_proto(sepol_node_set_addr)
hidden_proto(sepol_node_set_addr_bytes)
hidden_proto(sepol_node_set_con)
hidden_proto(sepol_node_set_mask)
hidden_proto(sepol_node_set_mask_bytes)
hidden_proto(sepol_node_set_proto)
hidden_proto(sepol_policydb_create)
hidden_proto(sepol_policydb_free)
hidden_proto(sepol_port_create)
hidden_proto(sepol_port_free)
hidden_proto(sepol_port_get_con)
hidden_proto(sepol_port_get_high)
hidden_proto(sepol_port_get_low)
hidden_proto(sepol_port_get_proto)
hidden_proto(sepol_port_get_proto_str)
hidden_proto(sepol_port_key_create)
hidden_proto(sepol_port_key_unpack)
hidden_proto(sepol_port_set_con)
hidden_proto(sepol_port_set_proto)
hidden_proto(sepol_port_set_range)
hidden_proto(sepol_user_add_role)
hidden_proto(sepol_user_create)
hidden_proto(sepol_user_free)
hidden_proto(sepol_user_get_mlslevel)
hidden_proto(sepol_user_get_mlsrange)
hidden_proto(sepol_user_get_roles)
hidden_proto(sepol_user_has_role)
hidden_proto(sepol_user_key_create)
hidden_proto(sepol_user_key_unpack)
hidden_proto(sepol_user_set_mlslevel)
hidden_proto(sepol_user_set_mlsrange)
hidden_proto(sepol_user_set_name)

@stephensmalley
Copy link
Member

Per the earlier discussion in #165, there are other challenges with LTO and the use of symbol versioning unless those have been overcome.
I don't personally care whether hidden_proto/hidden_def stays or goes but at least at one time someone at Red Hat thought it was important for performance and we should make sure switching it doesn't create a significant regression. Admittedly the first patch was for libselinux, which is more critical, but then the same approach got applied to libsepol and then libsemanage.

@kloczek
Copy link
Author

kloczek commented Feb 24, 2020

Versioning symbols is now fine.
It is a lot libraries which are possible to optimise using LTO and they are with versioned symbols.

@stephensmalley
Copy link
Member

Ok, if you want to submit patches to the list to drop the hidden_proto/hidden_def stuff from libsepol and libsemanage I won't object. Doing it to libselinux would require at least demonstrating that it is a net win performance wise since that one is widely used.

@kloczek
Copy link
Author

kloczek commented Feb 25, 2020

Will back in few days because first Ill try to test whole SELinux stack with LTO than if all will be OK will try to prepare separated PRs against each component.

@fishilico
Copy link
Member

By the way, if you want to drop hidden_proto/hidden_def, you might be interested in replacing some of the functionality that these macro provide by linking with -Bsymbolic. I do not know about the performance impact, but this flag seems to achieve the aim of making internal references to global (public/exported) symbols bound directly. If you are interested, I prototyped a commit: fishilico@80a0fdb

@kloczek
Copy link
Author

kloczek commented Feb 25, 2020

That kind of things does ac/am/lt based tooling.

I think that I've already asked you did you you will accept ac/am/lt based build/release automation and you said IIRC now.
Maintaining hand crafted set of Makefile files is nightmare ..

@fishilico
Copy link
Member

Please do not change the subject of the current issue. If you want to discuss about upgrading the build/release files/scripts to something more maintainable (like autotools, cmake, meson...), please open a different issue or start a thread on the mailing list (selinux@vger.kernel.org).

@stephensmalley
Copy link
Member

That kind of things does ac/am/lt based tooling.

I think that I've already asked you did you you will accept ac/am/lt based build/release automation and you said IIRC now.
Maintaining hand crafted set of Makefile files is nightmare ..

Previously discussed here:
#190

williamcroberts pushed a commit to williamcroberts/selinux that referenced this issue Mar 12, 2020
With the old hidden_def and hidden_proto DSO infrastructure removed,
correctness of the map file becomes paramount, as it is what filters out
public API. Because of this, the wild cards should not be used, as it
lets some functions through that should not be made public API. Thus
remove the wild cards, and sort the list.

Additionally, verify that nothing changed in external symbols as well:

This was checked by generating an old export map (from master):
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > old.map

Then creating a new one for this library after this patch is applied:
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > new.map

And diffing them:
diff old.map new.map

Fixes: SELinuxProject#165
Fixes: SELinuxProject#204

Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: William Roberts <william.c.roberts@intel.com>
williamcroberts pushed a commit to williamcroberts/selinux that referenced this issue Mar 12, 2020
With the old hidden_def and hidden_proto DSO infrastructure removed,
correctness of the map file becomes paramount, as it is what filters out
public API. Because of this, the wild cards should not be used, as it
lets some functions through that should not be made public API. Thus
remove the wild cards, and sort the list.

Additionally, verify that nothing changed in external symbols as well:

This was checked by generating an old export map (from master):
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > old.map

Then creating a new one for this library after this patch is applied:
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > new.map

And diffing them:
diff old.map new.map

Fixes: SELinuxProject#165
Fixes: SELinuxProject#204

Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: William Roberts <william.c.roberts@intel.com>
williamcroberts pushed a commit to williamcroberts/selinux that referenced this issue Mar 13, 2020
With the old hidden_def and hidden_proto DSO infrastructure removed,
correctness of the map file becomes paramount, as it is what filters out
public API. Because of this, the wild cards should not be used, as it
lets some functions through that should not be made public API. Thus
remove the wild cards, and sort the list.

Additionally, verify that nothing changed in external symbols as well:

This was checked by generating an old export map (from master):
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > old.map

Then creating a new one for this library after this patch is applied:
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > new.map

And diffing them:
diff old.map new.map

Fixes: SELinuxProject#165
Fixes: SELinuxProject#204

Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: William Roberts <william.c.roberts@intel.com>
williamcroberts pushed a commit to williamcroberts/selinux that referenced this issue Mar 13, 2020
With the old hidden_def and hidden_proto DSO infrastructure removed,
correctness of the map file becomes paramount, as it is what filters out
public API. Because of this, the wild cards should not be used, as it
lets some functions through that should not be made public API. Thus
remove the wild cards, and sort the list.

Additionally, verify that nothing changed in external symbols as well:

This was checked by generating an old export map (from master):
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > old.map

Then creating a new one for this library after this patch is applied:
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > new.map

And diffing them:
diff old.map new.map

Fixes: SELinuxProject#165
Fixes: SELinuxProject#204

Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: William Roberts <william.c.roberts@intel.com>
@david3chan
Copy link

Yes uit builds but on linking it uses static libsepol.

I've been trying to build libsemanage using only shared libsepol and I found that libsemanage uses libsepol symbols which are not listed in public symbols of that library.
Here is the patch to try link libsemanage using shared libsepol :

--- libsemanage-2.9/src/Makefile~       2019-03-15 10:32:30.000000000 +0000
+++ libsemanage-2.9/src/Makefile        2019-07-13 19:43:11.810422982 +0100
@@ -65,7 +65,7 @@

 SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./

-all: $(LIBA) $(LIBSO) $(LIBPC)
+all: $(LIBSO) $(LIBPC)

 pywrap: all $(SWIGSO)

@@ -134,7 +134,6 @@

 install: all
        test -d $(DESTDIR)$(LIBDIR) || install -m 755 -d $(DESTDIR)$(LIBDIR)
-       install -m 644 $(LIBA) $(DESTDIR)$(LIBDIR)
        install -m 755 $(LIBSO) $(DESTDIR)$(LIBDIR)
        test -d $(DESTDIR)$(LIBDIR)/pkgconfig || install -m 755 -d $(DESTDIR)$(LIBDIR)/pkgconfig
        install -m 644 $(LIBPC) $(DESTDIR)$(LIBDIR)/pkgconfig
@@ -155,7 +154,7 @@
        /sbin/restorecon $(DESTDIR)$(LIBDIR)/$(LIBSO)

 clean:
-       -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(SWIGRUBYSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c *.o *.lo *~
+       -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(SWIGRUBYSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c *.o *.lo *~

 distclean: clean
        rm -f $(GENERATED) $(SWIGFILES)
--- a/tests/Makefile~   2019-11-28 12:46:48.000000000 +0000
+++ b/tests/Makefile    2020-02-22 21:50:19.645095244 +0000
@@ -14,7 +14,7 @@

 all: $(EXECUTABLE) $(POLICIES)

-$(EXECUTABLE): $(OBJECTS) ../src/libsemanage.a
+$(EXECUTABLE): $(OBJECTS) ../src/libsemanage.so
        $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)

 %.policy: %.cil
@@ -24,5 +24,5 @@
        rm -rf $(OBJECTS) $(POLICIES) $(EXECUTABLE)

 test: all
-       ./$(EXECUTABLE)
+       LD_LIBRARY_PATH=../srs ./$(EXECUTABLE)

I followed the same patch, but the same "undefined reference to ..." happended.
Does anyone know how to solve the issue?

thank you in advance!

@fishilico
Copy link
Member

@david3chan As explained in #204 (comment) :

libsemanage/tests contains a set of unit tests; those do statically link with libsemanage.a and AFAICT that's by design - they are unit tests including internal functions not merely public APIs/ABIs.

For example libsemanage/tests/test_utilities.c tests semanage_rtrim, which is an internal function. It is normal that it is not exported by libsemanage.so.

Do you encounter "undefined reference to ..." outside of tests?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants