Page MenuHomeFreeBSD

Fix RTLD_NEXT handling to not return the symbol from the current library.
ClosedPublic

Authored by bdrewery on Jul 14 2016, 8:51 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Dec 8, 7:21 AM
Unknown Object (File)
Nov 28 2024, 4:51 AM
Unknown Object (File)
Nov 28 2024, 4:51 AM
Unknown Object (File)
Nov 26 2024, 4:35 AM
Unknown Object (File)
Nov 2 2024, 6:39 AM
Unknown Object (File)
Nov 2 2024, 6:39 AM
Unknown Object (File)
Nov 2 2024, 6:39 AM
Unknown Object (File)
Nov 2 2024, 6:39 AM
Subscribers

Details

Summary

The root of the problem here is that TAILQ_FOREACH_FROM will default to
the head of the list if passed NULL.

Before r294373, this code was:

if (handle == RTLD_NEXT)
    obj = obj->next;
for (; obj != NULL; obj = obj->next) {

After r294373 it was:

if (handle == RTLD_NEXT)
      obj = globallist_next(obj);
TAILQ_FOREACH_FROM(obj, &obj_list, next) {

TAILQ_FOREACH_FROM expands to:

for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));
    (var);
    (var) = TAILQ_NEXT((var), field))

Thus if passed NULL it defaults to the head of the list. The code here would
end up iterating over all shared libraries and eventually find the current
shared library and return the symbol from itself.

Sponsored by: EMC / Isilon Storage Division
MFC after: 1 week

Test Plan

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 4520
Build 4572: arc lint + arc unit

Event Timeline

bdrewery retitled this revision from to Fix RTLD_NEXT handling to not return the symbol from the current library..
bdrewery updated this object.
bdrewery edited the test plan for this revision. (Show Details)
bdrewery added a reviewer: kib.
bdrewery added subscribers: markj, cem, kan.

By the way, the whitespace is a disaster in this file :(

What may be unclear is that in my test case, obj is becomes NULL from globallist_next(obj) since there are no further libraries loaded.

cem added a reviewer: cem.
This revision is now accepted and ready to land.Jul 14 2016, 9:02 PM
markj added a reviewer: markj.
ngie added a reviewer: ngie.

I agree with the analysis and the direction of the fix, but think that the actual code changes add unneccessary layers there. Why not replace TAILQ_FOREACH_FROM() line with

for (; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
...

? We never need to start iteration from the obj_list head.

In D7216#150086, @kib wrote:

I agree with the analysis and the direction of the fix, but think that the actual code changes add unneccessary layers there. Why not replace TAILQ_FOREACH_FROM() line with

for (; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
...

? We never need to start iteration from the obj_list head.

Sure

bdrewery edited edge metadata.

Simplify the change

This revision now requires review to proceed.Jul 15 2016, 3:55 PM
cem edited edge metadata.
This revision is now accepted and ready to land.Jul 15 2016, 4:01 PM
ngie edited edge metadata.
kib edited edge metadata.
This revision was automatically updated to reflect the committed changes.