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");
 

Reply via email to