Contributed by rueda on from the want TLS with that ramen? dept.
Fresh from the recently concluded
j2k25 hackathon comes this report from Klemens Nanni (kn@
), who writes:
New country, lots of ramen, friends and new folks - heck, yes!
Having missed the last four (our five?, hard to tell…) hackathons, j2k25 aligned just right to finish our holidays with beautiful sights and culinary delights between streaks of hacking, leaving all else aside for a solid week - it was refreshing retreat and sparked plans to make another, even longer trip through Japan!
This time, I brought a few unfished and/or unanswered diffs, but also specifically wanted to look into unfamiliar code, now that folks were around to ask for advice and discuss with.
First, the installer and
rc(8)
were due for cleanup: common code for randomness seed files used by bootloaders andrc
seemed unnecessarily different, so I synced their logic, style and comments wrt. subtle, yet important details around thesticky(8)
bit:
Basically, as now clarified in
chmod(2)
,+t
on files is no effect in the kernel, so bootblocks have long since repurposed this ancient semantic to signal entropy bits, i.e. whether they had read the same/etc/random.seed
off disk and marked it with+t
a second time, without the installer orrc(8)
updating it during upgradeor boot/shutdown.NOTE: random seed is being reused.If you ever saw this, it meant that the tiny shim of FFS write support expected a fresh file, but saw the (same) old
sticky
one again.Afterwards came a tweak to the '
Location of sets?
' question to opt "http
" and "nfs
" choices behind functional network forinstall77.*
to correctly default to[disk]
or[cd0]
instead of[http]
in offline environments without interfaces; this seems small, but I appreciate each step towards more boring<Enter>
(or lessautoinstall(8)
lines) doing the right thing.
Unless there's a dedicated ports hackathon, I try to stay away from that tree with its time consuming chores, but with new
devel/abseil-cpp
(important dependency) andnet/tdesktop
in the queue, moving fast with lots of other changes actually saves time as diffs don't need retesting over time.So I dedicated a day to a) the new abseil LTS as well as building and syncing almost every consumer and b) non-trivial surgery in
net/tdlib
to update and split the port intonet/tdlib/td{lib,e2e}
wheretde2e
exposes private API - effectively a completely different library used by Telegram Desktop. This was the result of prior discussions with other systems' package maintainers plus great feedback from tb@ and sthen@ as usual.Next, just when I thought this ports effort concluded, users reported Telegram group calls being broken (not new) on OpenBSD… I hadn't even used that feature before, but decided to poke further with my head still
/p/pobj/
trying to make sense of all this alien code.A tour through
net/tg_owt
,security/libsrtp
and tdesktop plus hints from folks on FreeBSD and Linux led to the theory that something in LibreSSL DTLS goes wrong - debug logs only prompted more questions:(openssl_adapter.cc:820): read_alert fatal internal error SSL negotiation finished successfullyI looked a little further, but decided to not waste more hackathon time on what is likely no easy fix.
Having rsadowski@ around, we discussed issues I have been seeing in the KDE Plasma desktop: a crash whilst typing in the program search and a log file filling itself endlessly by tracking file changes to itself (can't make this up). I just showed it to him, we tried a few things until he nailed it down and fixed both by disabling unhelpful bits and providing a convenient kde-plasma update to crank resources.
Having returned the favour with reviews for KDE Plasma packages^W^W^W even slower bulk builds, I could finally return to base!
Back in 2023 my notebook ran out of battery once too often while working focused; knowing battery life isn't great, I've been using
apmd(8)
's-z/-Z
to automatically suspend/hibernate below a certain battery threshold and it saved me every time, but what I actually wanted was some kind of warning *before* that feature kicked in, so I could plug into AC and continue work without being forcefully interrupted, losing network, etc.Thus I hacked together
[-w percent]
plus a/etc/apm/warnlow
hook that would a) issue warning logs whilst on battery *and* below the given threshold, but more importantly also run the script every time it triggered. It worked great for me, so I mailed it out, but never got a response and quickly forgot about it after becoming used to it.It wasn't until a chat with tobhe@ about various quirks around (ARM) notebooks, that this came up and I dusted off the diff in my tree to mail a new version around, now with better docs and someone interested in it.
This time jmc@ caught wind as well, provided valuable feedback and a fresh look onto the manual. Finally, OKs from Tobias and Jason for code and docs got the
warnlow
feature in together with brief examples (precisely what I use) andchangelist(5)
for script change detection.
Sitting next to job@, we kept disussing the old and new
watch(1)
[Not linked to build at time of writing - Ed.] tool he was working on: what it should (not) do, which aspects should be similiar to existing base tools liketop(1)
orsystat(1)
, what to rip our and/or keep in sync with other watch tools; small steps, quick diffs and OKs and demos to show, all without delay across timezones or throug mail is exactly what hackathons are for!
Last comes a chapter about
chroot(2)
, its relation withdaemon(3)
in some base programs, code being copied around and old, yet novel ideas that seem to be a better solution… or not.An unrelated question made me look at
tftpd(8)
weeks ago. Back then I noticed its localrdaemon()
function, studied it further, read CVS history, but it felt like I was missing the crucial point. Indeed, jca@, who authored this code in 2016, had to explain the obvious to me after I mailed wrong diff around, asking for clues.The gist is:
chroot(2)
beforedaemon(3)
causes the latter to fail closing standard streams (/dev/null
is no longer around). The "fun" bit is thatdaemon(3)
won't report this in any way and still return "success", which makes you believe everything works as expected unless you peek throughktrace(1)
or inspect a program withfstat(1)
.Thus
rdaemon()
came to be a local copy taking a preopened file descriptor todup2(2)
so programs can 1) open/dev/null
, 2)chroot(/somewhere)
and 3)rdaemon(nullfd)
to avoid the pitfall of silently leaving 0, 1, 2 open after forking into the background.millert@ had already pointed out FreeBSD's
daemonfd(3)
being exactly what daemons liketftpd(8)
need, wherechroot(2)
guarantees filesystem containment inside the server's directory root without the need for ugly, brittle string checks around "../" and what not to mitigate path traversal attacks.So I ported
daemonfd(3)
, madetftpd(8)
use that instead ofrdaemon()
, mailed the combined diff as PoC and enthusiastically set out to clean up other base daemons which copied overrdaemon()
, thinking it'd be a few similiar tweaks, but I noticed how none out of the six other programs actually relied onchroot()
for the same path-rewrite semantics liketftpd
does. One didn't even usechroot()
, but still hadrdaemon()
. Some even lack filesystem access underpledge(2)
without "[rwc]path
", questioning, imho, the need to move/
for the process. Another one unable topledge()
now employs theunveil("/", "")
idiom.Details and discussions about this with a handful of people, mostly deraadt@ though, spread across many mails, diffs and conversations often going over related ideas. I learned a lot about how
unveil(2)
works internally, how it is massively more complex than the simple and battle-testedchroot()
concept and that they're not interchangable as means to security programs.pledge()
a lot simpler and easier to reason about, but even there seem to be arguments for having bothchroot()
andpledge()
instead of relying on the latter without*path
promises alone.
Out of all this also came the wish for a new mechanism to contain file path operations on a finer per-directory level, without the need for privileged operations, that would simple enough to implement and trust and could be used where
chroot(2)
could not.I had recently read about the
openat(2)
O_BENEATH
flag in FreeBSD and Linux, which initially sounded like a viable solution, but talking with Theo made it pretty clear, that having to opt into a mechanism for every single open of a file is a kind of backwards semantic, considering that an attribute of the containing directory itself seems more natural and less error-prone rather than setting a flag for each path that's to be resolved inside of that and never elsewhere.More on that is better read in Theo's mail on tech@ titled "openat(2) is mostly useless, sadly" than repeated here. I'll just add that this was^Wstill is a fun ride for me through
namei(9)
plus friends and promising use cases for such a potential newO_BELOW
flag.
Many thanks to the OpenBSD foundation and Yasuoka for enabling this wonderful trip and awesome hackathon!