Claudio Jeker wrote on 08.07.2026 19:47:
On Wed, Jul 08, 2026 at 07:43:44AM +0100, Thomas Kupper wrote:
Hi,
I was wondering what are the views on having the pledge(2) promise assembled
(in a 3rd party app). Scanning through base and ports, I could only find
pledge(2) promises as constant string argument. I did assume that it's the
safest way to make sure that the promise can't be fiddled with.
Since the app (Chrony) was not designed with pledge in mind, if became more
readable to assemble the promise string like:
(https://gitlab.com/chrony/chrony/-/commit/0ea7607358cc)
--- upstream commit 0ea76073 ---
if (snprintf(promises, sizeof (promises), "stdio%s%s%s%s",
needs_main_misc ? " rpath wpath cpath inet unix dns" : "",
needs_recvfd ? " recvfd" : "",
needs_sendfd ? " sendfd" : "",
needs_settime ? " settime" : "") >= sizeof (promises))
assert(0);
DEBUG_LOG("Pledging: %s", promises);
if (pledge(promises, NULL) < 0)
LOG_FATAL("pledge() failed");
---
Originally I stuck to the constant strings and Miroslav optimized it after
another change would have resulted in more complex if/else constructs.
We use static strings because they are easier to review.
Also the strings all use the same order to again help review of pledge
usage. Adding new capabilities to a pledge promise requires a review of
all current usage of that promise to understand the impact. Having all
pledge calls be the same style makes this a lot easier.
It is much harder to argue about your pledge above since it is unclear what
will end up in promises without code inspection. In this case it may not
matter since chrony is not part of base and ports pledge usage is normally
not checked in the above case.
Thanks a lot for taking the time to comment.
I see your point, one does have to have more knowledge of the app to see
which promises are in place in what conditions. It is doable and
Btw. assert(0) as a way to fail after snprintf() failure is special. If
compiled with -DNODEBUG the error is just ignore.
I myself don't have a lot of experience with programming and would
checked the return values. Checking the rest of the code, the return
value for snprintf() is almost never checked, only in some instances if
writing over the length of the buffer.
A quick look at FreeBSD src and OpenBSD src shows the same, the return
value is not checked.