Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve GNU ld scripts #22

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

winterheart
Copy link

Resolve GNU ld scripts with additional checks for UNIX-like systems (fixes #17).

libwhich.c Outdated
Comment on lines 386 to 407
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__ELF__)
/* Try to resolve ld script references. */
char *name;
const char *e;
if (err && *err == '/' && (e = strchr(err, ':'))) {
name = malloc(e - err);
strncpy(name, err, e - err);
char *test = resolve_ldscript(name);
if (test != NULL) {
// Let's try again...
lib = dlopen(test, RTLD_LAZY);
free(test);
}
if (name != NULL)
free(name);
}
}

if (!lib) {
#endif
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned in the bug report, I don't really want to be creating a fiction here about the result of dlopen on this input, which the Debian maintainers already marked invalid in bugzilla. But maybe useful for the error message to still parse the file name as you are doing here and then dumping that file to stderr/stdout to still save the user a step?

Suggested change
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__ELF__)
/* Try to resolve ld script references. */
char *name;
const char *e;
if (err && *err == '/' && (e = strchr(err, ':'))) {
name = malloc(e - err);
strncpy(name, err, e - err);
char *test = resolve_ldscript(name);
if (test != NULL) {
// Let's try again...
lib = dlopen(test, RTLD_LAZY);
free(test);
}
if (name != NULL)
free(name);
}
}
if (!lib) {
#endif
#ifndef _WIN32
/* Try to resolve ld script references. */
char *name;
const char *e;
if (err && *err == '/' && (e = strchr(err, ':'))) {
name = malloc(e - err + 1);
strncpy(name, err, e - err);
name[e - err] = '\0';
char *test = dump_utf8_file(name);
free(name);
}
#endif

Where the function dump_utf8_file dumps the text of a file if it seems to consist of only printable text:

void dump_utf8_file(const char *name)
{
    FILE *fp = fopen(name, "r");
    fseek(fp);
    size_t nb = ftell(fp);
    void *c = malloc(ftell(fp) + 1);
    rewind(fp);
    if (fread(c, nb + 1, 1, fp) != nb || !feof(fp))
        return;
    if (!u8_isprint(c, nb))
        return;
    fputs("File contents appear to be text:\n\n", stdout)
    fputs(c, stdout);
    fclose(fp);
}

void u8_isprint(const char *c, size_t nb) { /* check that nb bytes of c are valid utf8 encoded isprint characters */ }

Resolve GNU ld scripts with additional checks for UNIX-like systems (fixes vtjnash#17).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to find libm.so with GNU ld script
2 participants