-
Notifications
You must be signed in to change notification settings - Fork 34
Description
Spindle's audit libraries (libspindle_audit_pipe.so and libspindle_subaudit_pipe.so) return a hardcoded value of 1 from la_version(). Glibc 2.35 (released February 2022) bumped LAV_CURRENT to 2. On platforms where glibc enforces a minimum accepted version of 2, Spindle's audit libraries are silently rejected at
load time with the following error:
ERROR: audit interface 'libspindle_audit_pipe.so' requires version 1
(maximum supported version 2); ignored.
When the audit library is ignored, all symbol interception fails and any spawned process that depends on LD_AUDIT pointing to a Spindle library hangs indefinitely waiting for server communication that never
arrives, causing test timeouts.
Affected platforms
This is currently observed on Ubuntu 24.04 arm64 (aarch64). Ubuntu 24.04 x86_64 is not affected at this time, believed to be due to a difference in patch level between the amd64 and arm64 libc6 packages within
Ubuntu 24.04 Noble.
Root cause
spindle_la_version() is implemented in two places, both returning 1 unconditionally and discarding the version argument that glibc passes:
Spindle/src/client/auditclient/auditclient.c
Lines 30 to 35 in e731f24
| unsigned int spindle_la_version(unsigned int version) | |
| { | |
| (void)version; | |
| patchDTV_init(); | |
| return 1; | |
| } |
Spindle/src/client/subaudit/subaudit.c
Lines 28 to 43 in e731f24
| unsigned int spindle_la_version(unsigned int version) | |
| { | |
| (void)version; | |
| int result; | |
| int binding_offset = 0; | |
| result = get_ldso_metadata_bindingoffset(&binding_offset); | |
| if (result == -1) { | |
| err_printf("Unable to lookup binding offset\n"); | |
| return -1; | |
| } | |
| debug_printf3("Updating subaudit bindings with offset %d\n", binding_offset); | |
| init_plt_binding_func(binding_offset); | |
| return 1; | |
| } |
Additionally, the return -1 error path in subaudit.c is typed as unsigned int, so it silently returns 0xFFFFFFFF rather than -1, which would also be rejected by glibc (lav > LAV_CURRENT). Replacing with 0 would automatically disable the audit interface:
if (lav == 0)
...
unload_audit_module (dlmargs.map, original_tls_idx);
return;
}
Fix
In both spindle_la_version implementations, replace return 1 with return version, and remove the (void)version suppression. The error path in subaudit.c should return 0 (which glibc treats as an explicit
rejection) rather than -1.
auditclient.c:
unsigned int spindle_la_version(unsigned int version)
{
patchDTV_init();
return version;
}
subaudit.c:
unsigned int spindle_la_version(unsigned int version)
{
int result;
int binding_offset = 0;
result = get_ldso_metadata_bindingoffset(&binding_offset);
if (result == -1) {
err_printf("Unable to lookup binding offset\n");
return 0;
}
debug_printf3("Updating subaudit bindings with offset %d\n", binding_offset);
init_plt_binding_func(binding_offset);
return version;
}
Reference