Although nbdkit_read_password is primarily intended for use during
.config, which is before any other thread might be trying to fork,
this function is exported for generic use by plugins, and we have no
guarantee that a user will not try to use it at other times when there
are multiple threads and where an fd leak would be detrimental.
However, although POSIX will eventually be adding fopen("re") to make
this easy [1], Haiku does not support that yet [2]. So we have to do
it by hand with the lower-level open(O_CLOEXEC)/fdopen. Our
recently-added unit test should ensure that things still work.
[1]
http://austingroupbugs.net/view.php?id=411
[2]
https://dev.haiku-os.org/ticket/15219
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
server/public.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/server/public.c b/server/public.c
index 4b8b1d2b..523a31f9 100644
--- a/server/public.c
+++ b/server/public.c
@@ -1,5 +1,5 @@
/* nbdkit
- * Copyright (C) 2013-2018 Red Hat Inc.
+ * Copyright (C) 2013-2019 Red Hat Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -36,6 +36,7 @@
#include <config.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -241,11 +242,19 @@ nbdkit_read_password (const char *value, char **password)
/* Read password from a file. */
else if (value[0] == '+') {
- fp = fopen (&value[1], "r");
- if (fp == NULL) {
+ int fd;
+
+ fd = open (&value[1], O_CLOEXEC | O_RDONLY);
+ if (fd == -1) {
nbdkit_error ("open %s: %m", &value[1]);
return -1;
}
+ fp = fdopen (fd, "r");
+ if (fp == NULL) {
+ nbdkit_error ("fdopen %s: %m", &value[1]);
+ close (fd);
+ return -1;
+ }
r = getline (password, &n, fp);
err = errno;
fclose (fp);
--
2.20.1