From 8647a3478674979cca582774168a6f220de171ef Mon Sep 17 00:00:00 2001
From: Jose Bollo <jose.bollo@iot.bzh>
Date: Thu, 6 Sep 2018 16:01:20 +0200
Subject: afb-session: Use ad-hoc pseudo-random uuid

The use of the generator given by the lib uuid
implies the use of the system call 'getrandom'
without the flag GRND_NONBLOCK. It has a weird
effect on boot because many binders require
the generation of uuid at the same time but
getrandom is subject to starving.

This introduced a tiny pseudo-random generation
of UUID that does not implies the use of 'getrandom'.

Bug-AGL: SPEC-1655

Change-Id: I5131072881d7a53f0edda9e36762985c96a04550
Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
---
 src/afb-session.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/src/afb-session.c b/src/afb-session.c
index adfed2ad..fdc88fdf 100644
--- a/src/afb-session.c
+++ b/src/afb-session.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <uuid/uuid.h>
 #include <errno.h>
+#include <unistd.h>
 
 #include "afb-session.h"
 #include "afb-hook.h"
@@ -106,7 +107,56 @@ static inline time_t time_now()
 static void new_uuid(char uuid[SIZEUUID])
 {
 	uuid_t newuuid;
+
+#if defined(USE_UUID_GENERATE)
 	uuid_generate(newuuid);
+#else
+	struct timespec ts;
+	static uint16_t pid;
+	static uint16_t counter;
+	static char state[32];
+	static struct random_data rdata;
+
+	int32_t x;
+	clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+	if (pid == 0) {
+		pid = (uint16_t)getpid();
+		counter = (uint16_t)(ts.tv_nsec >> 8);
+		rdata.state = NULL;
+		initstate_r((((unsigned)pid) << 16) + ((unsigned)counter),
+					state, sizeof state, &rdata);
+	}
+	ts.tv_nsec ^= (long)ts.tv_sec;
+	if (++counter == 0)
+		counter = 1;
+
+	newuuid[0] = (char)(ts.tv_nsec >> 24);
+	newuuid[1] = (char)(ts.tv_nsec >> 16);
+	newuuid[2] = (char)(ts.tv_nsec >> 8);
+	newuuid[3] = (char)(ts.tv_nsec);
+
+	newuuid[4] = (char)(pid >> 8);
+	newuuid[5] = (char)(pid);
+
+	random_r(&rdata, &x);
+	newuuid[6] = (char)(((x >> 16) & 0x0f) | 0x40); /* pseudo-random version */
+	newuuid[7] = (char)(x >> 8);
+
+	random_r(&rdata, &x);
+	newuuid[8] = (char)(((x >> 16) & 0x3f) | 0x80); /* variant RFC4122 */
+	newuuid[9] = (char)(x >> 8);
+
+	random_r(&rdata, &x);
+	newuuid[10] = (char)(x >> 16);
+	newuuid[11] = (char)(x >> 8);
+
+	random_r(&rdata, &x);
+	newuuid[12] = (char)(x >> 16);
+	newuuid[13] = (char)(x >> 8);
+
+	newuuid[14] = (char)(counter >> 8);
+	newuuid[15] = (char)(counter);
+#endif
 	uuid_unparse_lower(newuuid, uuid);
 }
 
-- 
cgit