summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Ipsum <richardipsum@fastmail.co.uk>2017-06-05 18:32:27 +0100
committerRichard Ipsum <richardipsum@fastmail.co.uk>2017-06-11 21:21:35 +0100
commit9271157304dbd707f87343df0106c3465b50d6a1 (patch)
tree6ed5df7009ab8edeb067cf86d4fbbf74cf9a3d44
parent5fcf093b8a8880bda56e0b9afe0dee8e9927c4c5 (diff)
downloadlua-scrypt-git-9271157304dbd707f87343df0106c3465b50d6a1.tar.gz
Harden reading from /dev/urandom
Guard against short reads.
-rw-r--r--luascrypt.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/luascrypt.c b/luascrypt.c
index 9fad808..11ae799 100644
--- a/luascrypt.c
+++ b/luascrypt.c
@@ -26,7 +26,9 @@ static void
luascrypt_salt_gen(char *salt, int saltlen)
{
int fd;
- /* We'd go with libscrypt's implementation, but since libscrypt's salt
+ /* Following comment applies to libscrypt prior to 1.21:
+ *
+ * We'd go with libscrypt's implementation, but since libscrypt's salt
* generation is time based, we cannot fully trust it to generate
* unique salts so to improve our chances we assume we have urandom
* and fall back to libscrypt's implementation if we don't. Since the
@@ -37,8 +39,28 @@ luascrypt_salt_gen(char *salt, int saltlen)
fd = open("/dev/urandom", O_RDONLY);
if (fd >= 0) {
- read(fd, salt, saltlen); /* Ignore errors in these two calls */
- close(fd); /* Since we have our fallback. */
+ size_t total = 0;
+ ssize_t n;
+
+ while (total < saltlen) {
+ n = read(fd, salt + total, saltlen - total);
+ if (n == 0) {
+ break;
+ }
+
+ if (n == -1) {
+ if (errno == EINTR) {
+ continue; /* just try again */
+ }
+
+ /* Ignore all other errors, since we have our fallback. */
+ break;
+ }
+
+ total += n;
+ }
+
+ close(fd);
}
}