Re: Capsicum and weak libc symbols

From: Vinícius_dos_Santos_Oliveira <vini.ipsmaker_at_gmail.com>
Date: Wed, 26 Feb 2025 13:45:32 UTC
Em ter., 25 de fev. de 2025 às 21:37, Konstantin Belousov
<kib@freebsd.org> escreveu:
> So what is the _actual_ problem for you with getaddrinfo()?
> Please show logs.

I can't show logs because I can't even write code for getaddrinfo w/o
the alias. I need to call the real getaddrinfo from my interposer. On
builds against /lib/libc.so.7, I use RTLD_NEXT to get the real
getaddrinfo, and that works. I need an alias for builds against
/usr/lib/libc.a (if I interpose getaddrinfo I can't access the
original getaddrinfo).

From my interposer, I translate the fake-resolved addresses back to
string versions and call the real getaddrinfo with
AI_NUMERICHOST|AI_NUMERICSERV:
<https://gitlab.com/emilua/emilua/-/blob/v0.11.0/src/proc_set_libc_service.cpp#L3757>.
This code is used for FreeBSD and Linux (hence why it's static
forward_getaddrinfo and not getaddrinfo). The interposition happens
here: <https://gitlab.com/emilua/emilua/-/blob/v0.11.0/src/freebsd/libc_service.cpp#L283>
(I'll remove the wrong usage of __attribute__((weak)) there once I
have the alias).

Calling the real getaddrinfo makes sure that freeaddrinfo will be
called later with data allocated by getaddrinfo.

Here's some Lua code making use of these features:
https://gitlab.com/emilua/emilua/-/blob/v0.11.0/test/libc_service_getaddrinfo.lua

Lua's spawn_vm() creates a new subprocess when 'subprocess' is given.
If 'libc_service' is also given, the interpositions will be used
(otherwise the new subprocess will just call the original functions as
usual). Line 5 is the code executed from the new subprocess, and it
calls getaddrinfo() to resolve "anonymous.invalid". The interposers
are called and forward the request to the process holding the other
end of 'libc_service' (it's just a pair of connected UNIX sockets
under the hood). The parent replies with IP=127.0.1.1 PORT=1. The
child translates the reply back to strings and calls the original
getaddrinfo().

The plan is to build several sandboxed apps using these features, and
I want them to run on FreeBSD as well. The first app will be a
Telegram client (already started by a colleague) using tdlib
(Telegram's official client library). Tdlib makes several calls to
ambient authority (e.g. starting IP connections, storing SQLite dbs to
disk, managing cache files, ...). Tdlib is deemed impossible to audit
(over 14k commits as of now, and it won't ever stabilize to a slow
pace so we can't ever catch up to current code as we try to audit), so
we'll just run it within a sandbox and save trouble.

The core of the sandbox is already pretty stable, and useful. For
instance, to open PNG/JPG/... files from the sandbox and show them on
the GUI, there's one function to parse the file into a
Format_ARGB32-encoded memfd-backed buffer. So the Lua programmer just
calls this function from a sandbox and sends the result to the GUI.
The GUI process just calls a different function to safely convert the
result back to what the Qt GUI can handle.

Here's the full story if you want the big picture, but the text is
kinda long, and not necessary for the purposes of asking for an alias
of getaddrinfo:
<https://blog.emilua.org/2025/01/12/software-sandboxing-basics/>.

Please let me know if there's any further info I can offer.

-- 
Vinícius dos Santos Oliveira