Bug 267671 - [libc] Remove unnecessary printf to stderr in stdlib/cxa_thread_atexit_impl.c
Summary: [libc] Remove unnecessary printf to stderr in stdlib/cxa_thread_atexit_impl.c
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 13.1-RELEASE
Hardware: amd64 Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-11-09 22:18 UTC by Erik Jensen
Modified: 2023-12-25 16:32 UTC (History)
4 users (show)

See Also:


Attachments
diff of Eric's patch (563 bytes, patch)
2023-07-10 19:18 UTC, Rainer Hurling
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Erik Jensen 2022-11-09 22:18:11 UTC
This is a request to remove the printf statement in stdlib/cxa_thread_atexit_impl.c in the function walk_cb_call.



The function signature is currently
"
static void
walk_cb_call(struct cxa_thread_dtor *dtor)
{
	struct dl_phdr_info phdr_info;

	if (_rtld_addr_phdr(dtor->dso, &phdr_info) &&
	    __elf_phdr_match_addr(&phdr_info, dtor->func))
		dtor->func(dtor->obj);
	else
		fprintf(stderr, "__cxa_thread_call_dtors: dtr %p from "
		    "unloaded dso, skipping\n", (void *)(dtor->func));
}
"

and I suggest to modify it to read

"
static void
walk_cb_call(struct cxa_thread_dtor *dtor)
{
	struct dl_phdr_info phdr_info;

	if (_rtld_addr_phdr(dtor->dso, &phdr_info) &&
	    __elf_phdr_match_addr(&phdr_info, dtor->func))
		dtor->func(dtor->obj);
}
"

Currently, walk_cb_call does all the necessary checks (as far as I can tell) in its if-statement, calling the destructor of a given dso only if the dso has not already been unloaded.
If the dso appears multiple times as the list of dsos is iterated over in the function cxa_thread_walk (in the same source file), the error message will be printed multiple times to the user.

A specific dso might very well appear multiple times in the list of dsos, if it is linked into several other dsos on which a given program relies.

The error message could perhaps be considered informative while debugging, but it does not add any functionality and it potentially gives any end-user a wrong impression of the integrity of a program that has this behaviour.
As such, I suggest to remove the print statement from the source code.
Comment 1 Rainer Hurling freebsd_committer freebsd_triage 2023-07-10 19:18:34 UTC
Created attachment 243333 [details]
diff of Eric's patch

I cannot judge whether Eric Jensen's analysis is correct and the fprintf() is unnecessary. My C/C++ knowledge is not sufficient for that. 

Nevertheless I tried the patch on my 14.0-CURRENT box to avoid such dso error messages. With my port graphics/qgis I have exactly the described problem, that a whole bunch of '__cxa_thread_call_dtors' errors are printed on the console. The patch suppresses these outputs as desired.

If there is a general feeling that Eric's suggestion is good and sufficient, I too would appreciate a corresponding commit. For simplicity I have attached the patch ;)
Comment 2 David Chisnall freebsd_committer freebsd_triage 2023-10-01 18:32:41 UTC
If this printf is reached, then you have a bug in your code that is very likely to lead to security issues (dangling code pointers, which can lead to trivial arbitrary code execution). I would *strongly* recommend fixing it.
Comment 3 Rainer Hurling freebsd_committer freebsd_triage 2023-10-02 07:31:31 UTC
(In reply to David Chisnall from comment #2)

Thanks for the reply. 

In my case, the error messages occur when using my graphics/qgis port. This application is very complex and uses extensively Qt5 functionalities. 

Unfortunately, since I am not a coder myself, I have no approach on how to track down the root cause and thus the potential security issue. So far I can't find any systematics for the occurrence of the error message. The messages occur every now and then while working in QGIS, but always exactly 27 times when exiting QGIS. It is always exactly the same message, even after a new call of QGIS:

__cxa_thread_call_dtors: dtr 0x82dd12f90 from unloaded dso, skipping

I could use a little help to generate more information about this error.
Comment 4 Willem Jan Withagen 2023-10-29 01:03:42 UTC
(In reply to David Chisnall from comment #2)

Well, yes and no....

I agree the patch is wrong, but there is probably not all that much with the used code as well

I had the same trouble in my Ceph-porting ....
Libraries get multiple time loaded, but in FreeBSD they get unloaded on the first call to unload the library....

So there should be some sort of ref counting how much times it was loaded and then only really unload on the transition from 1 to 0, as last unload.

Getting most ports that also work on Linux, or even are developed on it, the are likely to have this problem.

I never got around to do something like implementing such a mechanism