Bug in the dynamic linker for FreeBSD 14?

I am asking this here as I am unsure of/not knowledgable enough to know whether or not this is infact a bug or intended behaviour. Please let me know if there is a more apt place for these kinds of questions.

This program I'm working on, when compiled for FreeBSD, calls fdlopen(3) to load a dynamic library from memory. This is how I'm doing that more specifically:
C:
// void* lib_bin, size_t lib_len

int fd = shm_open(SHM_ANON, O_RDWR, 0);
ftruncate(fd, lib_len);

void* lib_mem = mmap(NULL, lib_len, PROT_WRITE, MAP_SHARED, fd, 0);
memcpy(lib_mem, lib_bin, lib_len);

munmap(lib_mem, lib_len);

void* lib = fdlopen(fd, RTLD_LAZY);
close(fd);

Running this on FreeBSD 13 works fine, FreeBSD 14 spits out this error:

Cannot fstatfs "<unknown>"

Digging around, I find, in libexec/rtld-elf/rtld.c:

C:
/*
 * but first, make sure that environment variables haven't been
 * used to circumvent the noexec flag on a filesystem.
 */
if (dangerous_ld_env) {
    if (fstatfs(fd, &fs) != 0) {
        _rtld_error("Cannot fstatfs \"%s\"", printable_path(path));
        return NULL;
    }
    if (fs.f_flags & MNT_NOEXEC) {
        _rtld_error("Cannot execute objects on %s", fs.f_mntonname);
        return NULL;
    }
}

And this is the first thing that seems weird to me. Why is it calling fstatfs(3) before checking if the file descriptor doesn't necessarily refer to a file which resides on a physical filesystem? It doesn't say so on the manpage, but, again, digging around, that's what the error returned by fstatfs(3), EINVAL, supposedly means.

Secondly, why then is dangerous_ld_env even set in the first place? Well, as of this commit:

C:
ld_dynamic_weak = ld_get_env_var(LD_DYNAMIC_WEAK) == NULL;

...
    
dangerous_ld_env = libmap_disable || libmap_override != NULL ||
    ld_library_path != NULL || ld_preload != NULL ||
    ld_elf_hints_path != NULL || ld_loadfltr || ld_dynamic_weak;

Should this not be

C:
ld_dynamic_weak = ld_get_env_var(LD_DYNAMIC_WEAK) != NULL;

instead? Or is this actually intended and am I just not understanding the point of this?
 
You should really only install -CURRENT if you're prepared to participate in fact-finding and troubleshooting sessions with the FreeBSD developers on the freebsd-current mailing list. The forums lack the knowledge and resources to answer in-depth questions about new developments and their ramifications.
 
Look at the flags on shm_open O_RDWR. Look at the comment around the fstatfs call, it looks to be checking for exec status on fd. Just a guess, but the shm segment isn't executable so the check fails.
 

Alrightly, thank you.

Look at the flags on shm_open O_RDWR. Look at the comment around the fstatfs call, it looks to be checking for exec status on fd. Just a guess, but the shm segment isn't executable so the check fails.

I don't think the code is directly executed, so I don't think it needs to be executable. Besides, that's not what the fstatfs(3) error tells me.

Ask on freebsd-current@, kib@ may be able to help you on this problem.

Will do. Thanks for your guys' help!
 
Back
Top