Re: Capsicum and weak libc symbols

From: Vinícius_dos_Santos_Oliveira <vini.ipsmaker_at_gmail.com>
Date: Wed, 19 Feb 2025 09:57:57 UTC
Em sex., 7 de fev. de 2025 às 00:08, Konstantin Belousov
<kostikbel@gmail.com> escreveu:
> On Thu, Feb 06, 2025 at 10:40:52PM -0300, Vinícius dos Santos Oliveira wrote:
> > [...]
>
> The purpose of the weak attribute is to allow the weak symbol to be undefined.
> It is not about the order of resolution (by default our rtld indeed prefers
> non-weak over weak, but it is a bug, and there is knob to turn this behavior
> off).
>
> If you need to interpose symbol, just link the interposing object before the
> object that supplies the symbol to be preempted by your definition.

There are two use cases for interposing symbols:

* with rtld
* without rtld (fully static binaries)

I don't want to change what rtld sees. I don't want to change
/lib/libc.so.7. It works fines as is right now.

I want to change what /usr/bin/ld.lld sees. I only want the symbols to
be weak in /usr/lib/libc.a.

For instance, the following code fails to compile when you try to
build a static binary (it works fine on the default mode though):


#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

DIR *opendir(const char *name)
{
    if (name[0] == '\0') {
        errno = ENOENT;
        return NULL;
    }

    int fd = open(name, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC);
    if (fd == -1) {
        return NULL;
    }

    DIR *ret = fdopendir(fd);
    if (!ret) {
        int saved_errno = errno;
        close(fd);
        errno = saved_errno;
    }
    return ret;
}

int main(int argc, char *argv[])
{
  (void)argc;
  (void)argv;
}


The build output for for clang -static will be:


ld: error: duplicate symbol: opendir
>>> defined at t2.c
>>>            /tmp/t2-3cf81c.o:(opendir)
>>> defined at opendir.c:55 (/usr/src/lib/libc/gen/opendir.c:55)
>>>            opendir.o:(.text+0x0) in archive /usr/lib/libc.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)


Meanwhile symbols such as unlink are weak (in /usr/lib/libc.a) and I
can interpose them easily in static builds as well.

However with further investigation I've realised that weak symbols in
/usr/lib/libc.a are also weak in /lib/libc.so.7. Does FreeBSD use the
same weak attributes whether it's building libc.so.7 or libc.a?


-- 
Vinícius dos Santos Oliveira
https://vinipsmaker.github.io/