Hi, Here is version 2 of my unveil patch. Many thanks to Rodrigo for his kind assistance! Improvements: - Unveil is disabled by default. It can be enabled using: configure --enable-unveil - There is now a dUnveil() wrapper which simplifies the code and error handling - Locale check and custom cursor icons unveil fix To-Do: - Add prefs parsing to plugins to get 'save_dir' (may need help here) - Add a dillorc pref to enable/disable unveil (same issue as above) - Localize wget and $AUTHORITY - A few other items from my previous to-do list Regards, Alex diff -upr a/configure.ac b/configure.ac --- a/configure.ac Sat Jul 27 12:54:47 2024 +++ b/configure.ac Thu Aug 1 16:40:16 2024 @@ -36,6 +36,11 @@ AC_ARG_ENABLE([insure], [enable_insure=$enableval], [enable_insure=no]) +AC_ARG_ENABLE([unveil], + [AS_HELP_STRING([--enable-unveil], [Build with support for unveil])], + [enable_unveil=$enableval], + [enable_unveil=no]) + AC_ARG_ENABLE([ipv6], [AS_HELP_STRING([--enable-ipv6], [Build with support for IPv6])], [enable_ipv6=$enableval], @@ -619,6 +624,9 @@ if test "x$enable_insure" = "xyes" ; then CC="insure -Zoi \"compiler $CC\"" LIBS="$LIBS -lstdc++-2-libc6.1-1-2.9.0" fi +if test "x$enable_unveil" = "xyes" ; then + AC_DEFINE([ENABLE_UNVEIL], [1], [Enable unveil]) +fi if test "x$enable_threaded_dns" = "xyes" ; then CFLAGS="$CFLAGS -DD_DNS_THREADED" fi @@ -725,4 +733,5 @@ _AS_ECHO([ GIF enabled : ${enable_gif}]) _AS_ECHO([ SVG enabled : ${enable_svg}]) _AS_ECHO([]) _AS_ECHO([ HTML tests : ${html_tests_ok}]) +_AS_ECHO([ unveil enabled : ${enable_unveil}]) _AS_ECHO([]) diff -upr a/dpi/bookmarks.c b/dpi/bookmarks.c --- a/dpi/bookmarks.c Sat Jul 27 12:54:47 2024 +++ b/dpi/bookmarks.c Thu Aug 1 16:40:50 2024 @@ -1606,6 +1606,20 @@ static void termination_handler(int signum) exit(signum); } +/** + * Use unveil on OpenBSD + */ +static void dUnveil(const char *path, const char *perm) +{ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + if (unveil(path, perm) == -1) { + MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno)); + exit(1); + } + #endif + #endif +} /* * -- MAIN ------------------------------------------------------------------- @@ -1617,6 +1631,16 @@ int main(void) { char *tok; Dsh *sh; + /* Use unveil on OpenBSD */ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + char *dil_bm = dStrconcat(dGethomedir(), "/.dillo/bm.txt", NULL); + dUnveil(dil_bm, "rwc"); + dFree(dil_bm); + unveil(NULL, NULL); + #endif + #endif + /* Arrange the cleanup function for terminations via exit() */ atexit(cleanup); diff -upr a/dpi/cookies.c b/dpi/cookies.c --- a/dpi/cookies.c Sat Jul 27 12:54:47 2024 +++ b/dpi/cookies.c Thu Aug 1 16:40:50 2024 @@ -1632,6 +1632,20 @@ static void termination_handler(int signum) exit(signum); } +/** + * Use unveil on OpenBSD + */ +static void dUnveil(const char *path, const char *perm) +{ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + if (unveil(path, perm) == -1) { + MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno)); + exit(1); + } + #endif + #endif +} /* * -- MAIN ------------------------------------------------------------------- @@ -1643,6 +1657,16 @@ int main(void) { int sock_fd, code; char *buf; Dsh *sh; + + /* Use unveil on OpenBSD */ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + char *dil_loc = dStrconcat(dGethomedir(), "/.dillo", NULL); + dUnveil(dil_loc, "rwc"); + dFree(dil_loc); + unveil(NULL, NULL); + #endif + #endif /* Arrange the cleanup function for terminations via exit() */ atexit(cleanup); diff -upr a/dpi/datauri.c b/dpi/datauri.c --- a/dpi/datauri.c Sat Jul 27 12:54:47 2024 +++ b/dpi/datauri.c Thu Aug 1 16:40:50 2024 @@ -280,6 +280,21 @@ static unsigned char *datauri_get_data(char *url, size return data; } +/** + * Use unveil on OpenBSD + */ +static void dUnveil(const char *path, const char *perm) +{ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + if (unveil(path, perm) == -1) { + MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno)); + exit(1); + } + #endif + #endif +} + /* * */ @@ -289,6 +304,17 @@ int main(void) unsigned char *data; int rc; size_t data_size = 0; + + /* Use unveil on OpenBSD */ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + dUnveil("/tmp", "rwc"); + char *dil_loc = dStrconcat(dGethomedir(), "/.dillo", NULL); + dUnveil(dil_loc, "rwc"); + dFree(dil_loc); + unveil(NULL, NULL); + #endif + #endif /* Initialize the SockHandler */ sh = a_Dpip_dsh_new(STDIN_FILENO, STDOUT_FILENO, 8*1024); diff -upr a/dpi/downloads.cc b/dpi/downloads.cc --- a/dpi/downloads.cc Sat Jul 27 12:54:47 2024 +++ b/dpi/downloads.cc Thu Aug 1 16:40:50 2024 @@ -1098,12 +1098,45 @@ static void custLabelMeasure(const Fl_Label* o, int& W fl_measure(o->value, W, H, interpret_symbols); } +/** + * Use unveil on OpenBSD + */ +static void dUnveil(const char *path, const char *perm) +{ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + if (unveil(path, perm) == -1) { + MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno)); + exit(1); + } + #endif + #endif +} - //int main(int argc, char **argv) int main() { int ww = 420, wh = 85; + + /* Use unveil on OpenBSD */ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + dUnveil("/tmp", "rwc"); + dUnveil("/etc/fonts", "r"); + dUnveil("/usr/local/bin/wget", "x"); + char *xauth_loc = dStrconcat(dGethomedir(), "/.Xauthority", NULL); + dUnveil(xauth_loc, "r"); + dFree(xauth_loc); + dUnveil("/usr/local/share/fonts", "r"); + char *dil_loc = dStrconcat(dGethomedir(), "/.dillo", NULL); + dUnveil(dil_loc, "rwc"); + dFree(dil_loc); + char *dl_loc = dStrconcat(dGethomedir(), "/Downloads", NULL); + dUnveil(dl_loc, "rwc"); + dFree(dl_loc); + unveil(NULL, NULL); + #endif + #endif Fl::lock(); diff -upr a/dpi/file.c b/dpi/file.c --- a/dpi/file.c Sat Jul 27 12:54:47 2024 +++ b/dpi/file.c Thu Aug 1 16:40:50 2024 @@ -1063,6 +1063,20 @@ static int File_check_fds(uint_t seconds) return st; } +/** + * Use unveil on OpenBSD + */ +static void dUnveil(const char *path, const char *perm) +{ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + if (unveil(path, perm) == -1) { + MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno)); + exit(1); + } + #endif + #endif +} int main(void) { @@ -1070,6 +1084,19 @@ int main(void) socklen_t sin_sz; int sock_fd, c_st, st = 1; + /* Use unveil on OpenBSD */ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + dUnveil("/tmp", "rw"); + char *dl_loc = dStrconcat(dGethomedir(), "/Downloads", NULL); + dUnveil(dl_loc, "rw"); + dFree(dl_loc); + char *dil_loc = dStrconcat(dGethomedir(), "/.dillo", NULL); + dUnveil(dil_loc, "rwc"); + unveil(NULL, NULL); + #endif + #endif + /* Arrange the cleanup function for abnormal terminations */ if (signal (SIGINT, termination_handler) == SIG_IGN) signal (SIGINT, SIG_IGN); diff -upr a/dpi/ftp.c b/dpi/ftp.c --- a/dpi/ftp.c Sat Jul 27 12:54:47 2024 +++ b/dpi/ftp.c Thu Aug 1 16:40:50 2024 @@ -272,6 +272,21 @@ static int try_ftp_transfer(char *url) return (no_such_file ? -1 : (aborted ? -2 : nb)); } +/** + * Use unveil on OpenBSD + */ +static void dUnveil(const char *path, const char *perm) +{ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + if (unveil(path, perm) == -1) { + MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno)); + exit(1); + } + #endif + #endif +} + /* * */ @@ -281,6 +296,21 @@ int main(int argc, char **argv) char *dpip_tag = NULL, *cmd = NULL, *url = NULL, *url2 = NULL; int st, rc; char *p, *d_cmd; + + /* Use unveil on OpenBSD */ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + dUnveil("/tmp", "rwc"); + dUnveil("/usr/local/bin/wget", "x"); + char *dil_loc = dStrconcat(dGethomedir(), "/.dillo", NULL); + dUnveil(dil_loc, "rwc"); + dFree(dil_loc); + char *dl_loc = dStrconcat(dGethomedir(), "/download", NULL); + dUnveil(dl_loc, "rwc"); + dFree(dl_loc); + unveil(NULL, NULL); + #endif + #endif /* wget may need to write a temporary file... */ rc = chdir("/tmp"); diff -upr a/dpi/vsource.c b/dpi/vsource.c --- a/dpi/vsource.c Sat Jul 27 12:54:47 2024 +++ b/dpi/vsource.c Thu Aug 1 16:40:50 2024 @@ -178,6 +178,21 @@ void send_html_text(Dsh *sh, const char *url, int data a_Dpip_dsh_write_str(sh, 1, "</table></body></html>"); } +/** + * Use unveil on OpenBSD + */ +static void dUnveil(const char *path, const char *perm) +{ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + if (unveil(path, perm) == -1) { + MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno)); + exit(1); + } + #endif + #endif +} + /* * */ @@ -187,6 +202,16 @@ int main(void) int data_size; char *dpip_tag, *cmd = NULL, *cmd2 = NULL, *url = NULL, *size_str = NULL; char *d_cmd; + + /* Use unveil on OpenBSD */ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + char *dil_loc = dStrconcat(dGethomedir(), "/.dillo", NULL); + dUnveil(dil_loc, "r"); + dFree(dil_loc); + unveil(NULL, NULL); + #endif + #endif _MSG("starting...\n"); //sleep(20); diff -upr a/dpid/main.c b/dpid/main.c --- a/dpid/main.c Sat Jul 27 12:54:47 2024 +++ b/dpid/main.c Thu Aug 1 16:41:04 2024 @@ -220,6 +220,21 @@ static int get_open_max(void) #endif } +/** + * Use unveil on OpenBSD + */ +static void dUnveil(const char *path, const char *perm) +{ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + if (unveil(path, perm) == -1) { + MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno)); + exit(1); + } + #endif + #endif +} + /*! \todo * \li Add a dpid_idle_timeout variable to dpidrc * \bug Infinite loop if plugin crashes before it accepts a connection @@ -236,6 +251,17 @@ int main(void) services_list = NULL; //daemon(0,0); /* Use 0,1 for feedback */ /* TODO: call setsid() ?? */ + + /* Use unveil on OpenBSD */ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + dUnveil("/usr/local/lib/dillo", "rx"); + dUnveil("/usr/local/etc/dillo", "r"); + char *dil_loc = dStrconcat(dGethomedir(), "/.dillo", NULL); + dUnveil(dil_loc, "rwc"); + unveil(NULL, NULL); + #endif + #endif /* Allow read and write access, but only for the user. * TODO: can this cause trouble with umount? */ diff -upr a/src/dillo.cc b/src/dillo.cc --- a/src/dillo.cc Sat Jul 27 12:54:47 2024 +++ b/src/dillo.cc Thu Aug 1 16:40:06 2024 @@ -379,6 +379,21 @@ static DilloUrl *makeStartUrl(char *str, bool local) return start_url; } +/** + * Use unveil on OpenBSD + */ +static void dUnveil(const char *path, const char *perm) +{ + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + if (unveil(path, perm) == -1) { + MSG("unveil(%s, %s) failed: %s\n", path, perm, strerror(errno)); + exit(1); + } + #endif + #endif +} + /* * MAIN */ @@ -462,7 +477,34 @@ int main(int argc, char **argv) fclose(fp); } dLib_show_messages(prefs.show_msg); - + + // Use unveil on OpenBSD + #ifdef ENABLE_UNVEIL + #ifdef __OpenBSD__ + dUnveil("/usr/local/share/fonts", "r"); + dUnveil("/usr/local/share/icons", "r"); + dUnveil("/usr/X11R6/share/X11/locale", "r"); + dUnveil("/usr/X11R6/lib/X11/fonts", "r"); + dUnveil("/usr/local/etc/dillo", "r"); + dUnveil("/tmp", "rwc"); + dUnveil("/usr/local/bin/dpid", "x"); + dUnveil("/etc/fonts", "r"); + dUnveil("/etc/resolv.conf", "r"); + dUnveil("/etc/ssl/cert.pem", "r"); + dUnveil(prefs.save_dir, "rwc"); + char *dil_loc = dStrconcat(dGethomedir(), "/.dillo", NULL); + dUnveil(dil_loc, "rwc"); + dFree(dil_loc); + char *icons_loc = dStrconcat(dGethomedir(), "/.icons", NULL); + dUnveil(icons_loc, "r"); + dFree(icons_loc); + char *xauth_loc = dStrconcat(dGethomedir(), "/.Xauthority", NULL); + dUnveil(xauth_loc, "r"); + dFree(xauth_loc); + unveil(NULL, NULL); + #endif + #endif + // initialize internal modules a_Dpi_init(); a_Dns_init();