util/nvmutil: Use unveil, and harden pledges

After /dev/urandom (for MAC address randomisation) and
the GbE file have been handled, unveil them. Unveil is
a system call provided by OpenBSD that, when called,
restricts access only to the files and/or directories
specified, each given specific permissions.

You can learn more about unveil here:

https://man.openbsd.org/unveil.2

An ifdef rule makes nvmutil only use unveil on OpenBSD,
because it's not available anywhere else. This is the same
as with the pledge() system call.

Where invalid arguments are given, and no action performed,
pledge promises are also reduced to just stdio, preventing
any writes to files, or reads from files.

Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
Leah Rowe
2023-05-31 08:53:08 +01:00
parent c2cd191676
commit 78fc89352b
+21 -6
View File
@@ -57,6 +57,7 @@ void setWord(int pos16, int partnum, uint16_t val16);
void byteswap(int n, int partnum); void byteswap(int n, int partnum);
void writeGbeFile(int *fd, const char *filename, size_t nw); void writeGbeFile(int *fd, const char *filename, size_t nw);
void xpledge(const char *promises, const char *execpromises); void xpledge(const char *promises, const char *execpromises);
void xunveil(const char *path, const char *permissions);
#define FILENAME argv[1] #define FILENAME argv[1]
#define COMMAND argv[2] #define COMMAND argv[2]
@@ -79,7 +80,7 @@ uint8_t big_endian;
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
xpledge("stdio rpath wpath", NULL); xpledge("stdio rpath wpath unveil", NULL);
size_t nr = 128; size_t nr = 128;
int fd, flags = O_RDWR; int fd, flags = O_RDWR;
void (*cmd)(void) = NULL; void (*cmd)(void) = NULL;
@@ -92,7 +93,7 @@ main(int argc, char *argv[])
if (argc == 3) { if (argc == 3) {
if (strcmp(COMMAND, "dump") == 0) { if (strcmp(COMMAND, "dump") == 0) {
xpledge("stdio rpath", NULL); xpledge("stdio rpath unveil", NULL);
flags = O_RDONLY; flags = O_RDONLY;
cmd = &cmd_dump; cmd = &cmd_dump;
} else if (strcmp(COMMAND, "setmac") == 0) { } else if (strcmp(COMMAND, "setmac") == 0) {
@@ -125,16 +126,20 @@ main(int argc, char *argv[])
(cmd == &cmd_setchecksum) | (cmd == &cmd_brick); (cmd == &cmd_setchecksum) | (cmd == &cmd_brick);
readGbeFile(&fd, FILENAME, flags, nr); readGbeFile(&fd, FILENAME, flags, nr);
(void)rhex(); (void)rhex();
if (flags == O_RDONLY) xunveil("/dev/urandom", "r");
if (flags == O_RDONLY) {
xpledge("stdio", NULL); xpledge("stdio", NULL);
else } else {
xpledge("stdio wpath", NULL); xpledge("stdio wpath unveil", NULL);
xunveil(FILENAME, "w");
}
if (strMac != NULL) if (strMac != NULL)
cmd_setmac(strMac); /* nvm gbe.bin setmac */ cmd_setmac(strMac); /* nvm gbe.bin setmac */
else if (cmd != NULL) else if (cmd != NULL)
(*cmd)(); /* all other commands except setmac */ (*cmd)(); /* all other commands except setmac */
writeGbeFile(&fd, FILENAME, nr); writeGbeFile(&fd, FILENAME, nr);
} } else
xpledge("stdio", NULL);
if ((errno != 0) && (cmd != &cmd_dump)) if ((errno != 0) && (cmd != &cmd_dump))
err(errno, NULL); err(errno, NULL);
@@ -381,3 +386,13 @@ xpledge(const char *promises, const char *execpromises)
err(errno, NULL); err(errno, NULL);
#endif #endif
} }
void
xunveil(const char *path, const char *permissions)
{
(void)path; (void)permissions;
#ifdef __OpenBSD__
if (unveil(path, permissions) == -1)
err(errno, NULL);
#endif
}