We have encountered some puzzling segfaults when calling the `shutdown` utility, which are ultimately caused by the specific *name* of a function in `shutdown`, *not* by any of its code. Specifically, if:
1. A third-party shared library is loaded along with the `shutdown` utility (e.g. a NSS module [1]); and 2. The shared library uses the shutdown(2) syscall; then the shared library's invocation of shutdown(2) calls shutdown() in shutdown.c, instead of going to the kernel. If you're lucky, this merely results in the `wall` shutdown message being displayed twice. If you're unlucky then `shutdown` segfaults before actually performing the shutdown. The root problem is because the `shutdown` binary is exporting the "shutdown" symbol. Note that it's not *explicitly* exporting it; gcc goes out of its way to export it. Because you'd only call a function shutdown() if you were overriding shutdown(2), right? :F This can be easily demonstrated by a test program: ## ## test1.c: doesn't export anything ## $ cat > test1.c <<EOF int not_shutdown() { return 10; } int main(void) { return not_shutdown(); } EOF $ cc -o test1 test1.c $ nm -D test1 | grep -v ' [wWuU] ' $ ## ## test2.c: exports "shutdown", even though it only differs by a renamed ## function from test1.c ## $ cat > test2.c <<EOF int shutdown() { return 10; } int main(void) { return shutdown(); } EOF $ cc -o test2 test2.c $ nm -D test2 | grep -v ' [wWuU] ' 00000000004004e0 T shutdown $ The fix is obvious enough -- rename the shutdown() function to something else. I also do the same for warn(), which is also exported, presumably because it collides with warn(3). I looked through all the other binaries and these appear to be the only two functions being inadvertently exported. [1] http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html Richard Tollerton (2): shutdown.c: Avoid symbol collision with shutdown() shutdown.c: Avoid symbol collision with warn() src/shutdown.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) -- 1.8.4.2