There are three pledges:
- at the start
- after daemon(3) to drop "proc exec" unless scripts are used
- after sio_open(3) to drop "cpath dpath" unless metadata is used

Our port has libdaemon and metadata disabled, so it always ends up with
"stdio rpath wpath inet unix dns [proc exec] audio", but the diff does
account for them, such that enabling them does the right thing.

One might be able to drop more and/or use unveil(2), but that needs
careful hoisting and consideration of other features our port currently
does not enable.

Feedback? Objection? OK?

Index: Makefile
===================================================================
RCS file: /cvs/ports/audio/shairport-sync/Makefile,v
diff -u -p -r1.7 Makefile
--- Makefile    31 Jan 2024 08:47:23 -0000      1.7
+++ Makefile    5 Feb 2024 11:45:53 -0000
@@ -1,7 +1,7 @@
 COMMENT =      AirPlay audio player
 
 DIST_TUPLE =   github  mikebrady       shairport-sync  4.3.2   .
-REVISION =     0
+REVISION =     1
 
 CATEGORIES =   audio net
 
Index: patches/patch-shairport_c
===================================================================
RCS file: patches/patch-shairport_c
diff -N patches/patch-shairport_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-shairport_c   5 Feb 2024 12:04:21 -0000
@@ -0,0 +1,75 @@
+Index: shairport.c
+--- shairport.c.orig
++++ shairport.c
+@@ -1929,6 +1929,12 @@ void _display_config(const char *filename, const int l
+ #define display_config(argc, argv) _display_config(__FILE__, __LINE__, argc, 
argv)
+ 
+ int main(int argc, char **argv) {
++#if defined(__OpenBSD__)
++  /* Start with the superset of all potentially required promises. */
++  if (pledge("stdio rpath wpath cpath dpath inet unix dns proc exec audio", 
NULL) == -1)
++    die("pledge: %s", strerror(errno));
++#endif
++
+   memset(&config, 0, sizeof(config)); // also clears all strings, BTW
+   /* Check if we are called with -V or --version parameter */
+   if (argc >= 2 && ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], 
"--version") == 0))) {
+@@ -2102,6 +2108,16 @@ int main(int argc, char **argv) {
+   // parse arguments into config -- needed to locate pid_dir
+   int audio_arg = parse_options(argc, argv);
+ 
++#if defined(__OpenBSD__)
++  /* Any command to be executed at runtime? */
++  int run_cmds =
++    config.cmd_active_start != NULL ||
++    config.cmd_active_stop != NULL ||
++    config.cmd_set_volume != NULL ||
++    config.cmd_start != NULL ||
++    config.cmd_stop != NULL;
++#endif
++
+   // mDNS supports maximum of 63-character names (we append 13).
+   if (strlen(config.service_name) > 50) {
+     warn("The service name \"%s\" is too long (max 50 characters) and has 
been truncated.",
+@@ -2237,6 +2253,16 @@ int main(int argc, char **argv) {
+ 
+ #endif
+ 
++#if defined(__OpenBSD__)
++  /* Past daemon(3)'s double fork(2). */
++
++  /* Only user-defined commands are executed. */
++  if (!run_cmds)
++    /* Drop "proc exec". */
++    if (pledge("stdio rpath wpath cpath dpath inet unix dns audio", NULL) == 
-1)
++      die("pledge: %s", strerror(errno));
++#endif
++
+ #ifdef CONFIG_AIRPLAY_2
+ 
+   if (has_fltp_capable_aac_decoder() == 0) {
+@@ -2351,6 +2377,24 @@ int main(int argc, char **argv) {
+         config.output_name == NULL ? "<unspecified>" : config.output_name);
+   }
+   config.output->init(argc - audio_arg, argv + audio_arg);
++
++#if defined(__OpenBSD__)
++  /* Past first and last sio_open(3), sndio(7) only needs "audio". */
++
++# ifdef CONFIG_METADATA
++  /* Only coverart cache is created.
++   * Only metadata pipe is special. */
++  if (!config.metadata_enabled)
++# endif
++    /* Drop "cpath dpath". */
++    if (run_cmds) {
++      if (pledge("stdio rpath wpath inet unix dns proc exec audio", NULL) == 
-1)
++        die("pledge: %s", strerror(errno));
++    } else {
++      if (pledge("stdio rpath wpath inet unix dns audio", NULL) == -1)
++        die("pledge: %s", strerror(errno));
++    }
++#endif
+ 
+   // pthread_cleanup_push(main_cleanup_handler, NULL);
+ 

Reply via email to