Hi, Since the databases that require rpath only need to access one file we can add one attribute to the struct getentdb to identify which of those DBs we need unveiled. For group/hosts/passwd the files are already whitelisted through pledge(2) so I set them as NULL.
With that information we can now check if the unveil attribute is not NULL and then unveil(2) the database file as needed. I tested all databases by enumerating all entries (for the ones that support it) and by selecting specific entries without any apparent issues. Comments? OK? The initial pledge(2) is so short lived that I was tempted to remove it, but I'm open to suggestions :) Index: getent.c =================================================================== RCS file: /cvs/src/usr.bin/getent/getent.c,v retrieving revision 1.14 diff -u -p -u -r1.14 getent.c --- getent.c 1 Feb 2016 19:57:28 -0000 1.14 +++ getent.c 24 Sep 2018 09:36:43 -0000 @@ -77,15 +77,16 @@ static struct getentdb { const char *name; int (*fn)(int, char *[]); const char *pledge; + const char *unveil; } databases[] = { - { "ethers", ethers, "stdio rpath" }, - { "group", group, "stdio getpw" }, - { "hosts", hosts, "stdio dns" }, - { "passwd", passwd, "stdio getpw" }, - { "protocols", protocols, "stdio rpath" }, - { "rpc", rpc, "stdio rpath" }, - { "services", services, "stdio rpath" }, - { "shells", shells, "stdio rpath" }, + { "ethers", ethers, "stdio rpath", "/etc/ethers" }, + { "group", group, "stdio getpw", NULL }, + { "hosts", hosts, "stdio dns", NULL }, + { "passwd", passwd, "stdio getpw", NULL }, + { "protocols", protocols, "stdio rpath", "/etc/protocols" }, + { "rpc", rpc, "stdio rpath", "/etc/rpc" }, + { "services", services, "stdio rpath", "/etc/services" }, + { "shells", shells, "stdio rpath", "/etc/shells" }, { NULL, NULL, }, }; @@ -95,13 +96,17 @@ main(int argc, char *argv[]) { struct getentdb *curdb; - if (pledge("stdio dns rpath getpw", NULL) == -1) + if (pledge("stdio rpath dns getpw unveil", NULL) == -1) err(1, "pledge"); if (argc < 2) usage(); for (curdb = databases; curdb->name != NULL; curdb++) { if (strcmp(curdb->name, argv[1]) == 0) { + if (curdb->unveil != NULL) { + if (unveil(curdb->unveil, "r") == -1) + err(1, "unveil"); + } if (pledge(curdb->pledge, NULL) == -1) err(1, "pledge");