Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .github/scripts/check-versioned-symbols.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/bin/bash
# Check for unversioned symbols in libraries

set -e

# Function to check if a library has versioned symbols
has_versioned_symbols() {
local lib=$1
# Check if the library has version definitions
if readelf -V "$lib" 2>/dev/null | grep -q "Version definition section"; then
return 0
else
return 1
fi
}

# Function to get unversioned symbols from a library
get_unversioned_symbols() {
local lib=$1
objdump -T "$lib" | \
grep -F .text | \
awk '{if($6=="Base") {print $7;}}' | \
c++filt | \
awk '/[() ]/ {print " \"" $0 "\";";}
!/[() ]/ {print " " $0 ";";}' | \
sort
}

# Libraries to check
LIBRARIES=(
"lib/.libs/libaudit.so"
"auparse/.libs/libauparse.so"
"auplugin/.libs/libauplugin.so"
)

echo "Checking for versioned symbols in built libraries..."

# Track if any library uses versioned symbols
has_versioned=0
# Track if we found any unversioned symbols
found_unversioned=0

for lib in "${LIBRARIES[@]}"; do
if [ ! -f "$lib" ]; then
echo "Warning: Library $lib not found, skipping..."
continue
fi

if has_versioned_symbols "$lib"; then
echo "- Library $lib has versioned symbols"
has_versioned=1

# Check for unversioned symbols
unversioned=$(get_unversioned_symbols "$lib")
if [ -n "$unversioned" ]; then
echo "ERROR: Found unversioned symbols in $lib:"
echo "$unversioned"
found_unversioned=1
else
echo " No unversioned symbols found"
fi
else
echo "- Library $lib does not have versioned symbols (version script not applied)"
fi
echo
done

if [ $has_versioned -eq 0 ]; then
echo "No libraries with versioned symbols were found."
echo "This is expected if the linker does not support version scripts."
exit 0
fi

if [ $found_unversioned -eq 1 ]; then
echo "FAIL: Unversioned symbols were found in libraries with version scripts!"
exit 1
fi

echo "SUCCESS: All libraries with versioned symbols have all symbols properly versioned."
exit 0
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,6 @@ jobs:

- name: Run tests
run: make check

- name: Check for unversioned symbols
run: ./.github/scripts/check-versioned-symbols.sh
3 changes: 3 additions & 0 deletions auparse/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ nodist_libauparse_la_SOURCES = $(BUILT_SOURCES)
libauparse_la_LIBADD = ${top_builddir}/lib/libaudit.la ${top_builddir}/common/libaucommon.la
libauparse_la_DEPENDENCIES = $(libauparse_la_SOURCES) ${top_builddir}/config.h ${top_builddir}/common/libaucommon.la
libauparse_la_LDFLAGS = -Wl,-z,relro
if HAVE_LD_VERSION_SCRIPT
libauparse_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libauparse.map
endif

message.c:
cp ${top_srcdir}/lib/message.c .
Expand Down
90 changes: 90 additions & 0 deletions auparse/libauparse.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* Avoid modifying a symbol set after it has been released
When adding features in a new release, add a new set
Removing features is a breaking change */
LIBAUDIT_4.1 {
global:
auparse_add_callback;
auparse_destroy;
auparse_destroy_ext;
auparse_do_interpretation;
auparse_feed;
auparse_feed_age_events;
auparse_feed_has_data;
auparse_feed_has_ready_event;
auparse_find_field;
auparse_find_field_next;
auparse_first_field;
auparse_first_record;
_auparse_flush_caches;
auparse_flush_feed;
_auparse_free_interpretations;
auparse_get_field_int;
auparse_get_field_name;
auparse_get_field_num;
auparse_get_field_str;
auparse_get_field_type;
auparse_get_filename;
auparse_get_line_number;
auparse_get_milli;
auparse_get_node;
auparse_get_num_fields;
auparse_get_num_records;
auparse_get_record_interpretations;
auparse_get_record_num;
auparse_get_record_text;
auparse_get_serial;
auparse_get_time;
auparse_get_timestamp;
auparse_get_type;
auparse_get_type_name;
auparse_goto_field_num;
auparse_goto_record_num;
auparse_init;
auparse_interp_adjust_type;
auparse_interpret_field;
auparse_interpret_realpath;
auparse_interpret_sock_address;
auparse_interpret_sock_family;
auparse_interpret_sock_port;
_auparse_load_interpretations;
_auparse_lookup_interpretation;
auparse_metrics;
auparse_new_buffer;
auparse_next_event;
auparse_next_field;
auparse_next_record;
auparse_node_compare;
auparse_normalize;
auparse_normalize_get_action;
auparse_normalize_get_event_kind;
auparse_normalize_get_results;
auparse_normalize_how;
auparse_normalize_key;
auparse_normalize_object_first_attribute;
auparse_normalize_object_kind;
auparse_normalize_object_kind_int;
auparse_normalize_object_next_attribute;
auparse_normalize_object_primary;
auparse_normalize_object_primary2;
auparse_normalize_object_secondary;
auparse_normalize_session;
auparse_normalize_subject_first_attribute;
auparse_normalize_subject_kind;
auparse_normalize_subject_next_attribute;
auparse_normalize_subject_primary;
auparse_normalize_subject_secondary;
auparse_reset;
auparse_set_eoe_timeout;
auparse_set_escape_mode;
auparse_timestamp_compare;
ausearch_add_expression;
ausearch_add_interpreted_item;
ausearch_add_item;
ausearch_add_regex;
ausearch_add_timestamp_item;
ausearch_add_timestamp_item_ex;
ausearch_clear;
ausearch_cur_event;
ausearch_next_event;
ausearch_set_stop;
};
5 changes: 4 additions & 1 deletion auplugin/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/lib -I${top_srcdir}/common \
lib_LTLIBRARIES = libauplugin.la
include_HEADERS = auplugin.h

libauplugin_la_SOURCES = auplugin-fgets.c auplugin.c
libauplugin_la_SOURCES = auplugin-fgets.c auplugin.c
libauplugin_la_LDFLAGS = -Wl,-z,relro -version-info $(VERSION_INFO)
if HAVE_LD_VERSION_SCRIPT
libauplugin_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libauplugin.map
endif
libauplugin_la_LIBADD = ${top_builddir}/audisp/libqueue.la \
${top_builddir}/auparse/libauparse.la -lpthread

27 changes: 27 additions & 0 deletions auplugin/libauplugin.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* Avoid modifying a symbol set after it has been released
When adding features in a new release, add a new set
Removing features is a breaking change */
LIBAUDIT_4.1 {
global:
auplugin_event_feed;
auplugin_event_loop;
auplugin_fgets;
auplugin_fgets_clear;
auplugin_fgets_clear_r;
auplugin_fgets_destroy;
auplugin_fgets_eof;
auplugin_fgets_eof_r;
auplugin_fgets_init;
auplugin_fgets_more;
auplugin_fgets_more_r;
auplugin_fgets_r;
auplugin_init;
auplugin_queue_depth;
auplugin_queue_max_depth;
auplugin_queue_overflow;
auplugin_register_stats_callback;
auplugin_report_stats;
auplugin_setvbuf;
auplugin_setvbuf_r;
auplugin_stop;
};
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([subdir-objects foreign])
LT_INIT
gl_LD_VERSION_SCRIPT
AC_SUBST(LIBTOOL_DEPS)
OLDLIBS="$LIBS"
m4_include([src/libev/libev.m4])
Expand Down
3 changes: 3 additions & 0 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ libaudit_la_SOURCES = libaudit.c netlink.c \
libaudit_la_LIBADD = $(CAPNG_LDADD) ${top_builddir}/common/libaucommon.la
libaudit_la_DEPENDENCIES = $(libaudit_la_SOURCES) ../config.h ${top_builddir}/common/libaucommon.la
libaudit_la_LDFLAGS = -Wl,-z,relro -version-info $(VERSION_INFO)
if HAVE_LD_VERSION_SCRIPT
libaudit_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libaudit.map
endif
nodist_libaudit_la_SOURCES = $(BUILT_SOURCES)

BUILT_SOURCES = actiontabs.h errtabs.h fieldtabs.h flagtabs.h \
Expand Down
86 changes: 86 additions & 0 deletions lib/libaudit.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* Avoid modifying a symbol set after it has been released
When adding features in a new release, add a new set
Removing features is a breaking change */
LIBAUDIT_4.1 {
global:
audit_action_to_name;
audit_add_rule_data;
audit_add_watch;
audit_add_watch_dir;
audit_can_control;
audit_can_read;
audit_can_write;
audit_close;
audit_delete_rule_data;
audit_detect_machine;
audit_determine_machine;
audit_elf_to_machine;
audit_encode_nv_string;
audit_encode_value;
audit_errno_to_name;
audit_field_to_name;
audit_flag_to_name;
audit_format_signal_info;
audit_fstype_to_name;
audit_ftype_to_name;
audit_get_features;
audit_getloginuid;
audit_get_reply;
audit_get_session;
audit_is_enabled;
audit_log_acct_message;
audit_log_semanage_message;
audit_log_user_avc_message;
audit_log_user_command;
audit_log_user_comm_message;
audit_log_user_message;
audit_machine_to_elf;
audit_machine_to_name;
audit_make_equivalent;
audit_msg_type_to_name;
audit_name_to_action;
audit_name_to_errno;
audit_name_to_field;
audit_name_to_flag;
audit_name_to_fstype;
audit_name_to_ftype;
audit_name_to_machine;
audit_name_to_msg_type;
audit_name_to_syscall;
audit_name_to_uringop;
audit_number_to_errmsg;
audit_open;
audit_operator_to_symbol;
_audit_parse_syscall;
audit_request_features;
audit_request_rules_list_data;
audit_request_signal_info;
audit_request_status;
audit_reset_backlog_wait_time_actual;
audit_reset_lost;
audit_rule_create_data;
audit_rule_fieldpair_data;
audit_rule_free_data;
audit_rule_init_data;
audit_rule_interfield_comp_data;
audit_rule_io_uringbyname_data;
audit_rule_syscallbyname_data;
__audit_send;
audit_send;
audit_set_backlog_limit;
audit_set_backlog_wait_time;
audit_set_enabled;
audit_set_failure;
audit_set_feature;
audit_setloginuid;
audit_set_loginuid_immutable;
audit_set_pid;
audit_set_rate_limit;
audit_syscall_to_name;
audit_trim_subtrees;
audit_update_watch_perms;
audit_uringop_to_name;
audit_value_needs_encoding;
get_auditfail_action;
set_aumessage_mode;
};
50 changes: 50 additions & 0 deletions m4/ld-version-script.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# ld-version-script.m4
# serial 7
dnl Copyright (C) 2008-2026 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This file is offered as-is, without any warranty.

dnl From Simon Josefsson

# FIXME: The test below returns a false positive for mingw
# cross-compiles, 'local:' statements does not reduce number of
# exported symbols in a DLL. Use --disable-ld-version-script to work
# around the problem.

# gl_LD_VERSION_SCRIPT
# --------------------
# Check if LD supports linker scripts, and define automake conditional
# HAVE_LD_VERSION_SCRIPT if so.
AC_DEFUN([gl_LD_VERSION_SCRIPT],
[
AC_ARG_ENABLE([ld-version-script],
[AS_HELP_STRING([[--enable-ld-version-script]],
[enable linker version script (default is enabled when possible)])],
[have_ld_version_script=$enableval],
[AC_CACHE_CHECK([if LD -Wl,--version-script works],
[gl_cv_sys_ld_version_script],
[gl_cv_sys_ld_version_script=no
saved_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
echo foo >conftest.map
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[],
[cat > conftest.map <<EOF
VERS_1 {
global: sym;
};

VERS_2 {
global: sym;
} VERS_1;
EOF
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[gl_cv_sys_ld_version_script=yes])])
rm -f conftest.map
LDFLAGS=$saved_LDFLAGS])
have_ld_version_script=$gl_cv_sys_ld_version_script])
AM_CONDITIONAL([HAVE_LD_VERSION_SCRIPT],
[test "$have_ld_version_script" = yes])
])