lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed,  7 Oct 2015 15:43:53 +0200
From:	Daniel Borkmann <daniel@...earbox.net>
To:	davem@...emloft.net
Cc:	hannes@...essinduktion.org, ast@...mgrid.com,
	netdev@...r.kernel.org, Daniel Borkmann <daniel@...earbox.net>
Subject: [PATCH net-next 2/5] once: make helper generic for calling function once

From: Hannes Frederic Sowa <hannes@...essinduktion.org>

Make the get_random_once() helper generic enough, so that functions
in general would only be called once, where one user of this is then
net_get_random_once().

The only implementation specific call is to get_random_bytes(), all
the rest of this *_once() facility would be duplicated among different
subsystems otherwise. The new do_once() helper will be used by prandom()
later on, but might also be useful for other scenarios as well where a
one-time initialization in often-called, possibly fast-path code could
occur.

Signed-off-by: Hannes Frederic Sowa <hannes@...essinduktion.org>
Signed-off-by: Daniel Borkmann <daniel@...earbox.net>
---
 include/linux/once.h | 25 ++++++++++++++++++-------
 lib/once.c           | 34 +++++++++++++++++++++-------------
 2 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/include/linux/once.h b/include/linux/once.h
index 2a83b53..f7a51d5 100644
--- a/include/linux/once.h
+++ b/include/linux/once.h
@@ -3,22 +3,33 @@
 
 #include <linux/types.h>
 #include <linux/jump_label.h>
+#include <linux/uio.h>
 
-bool __get_random_once(void *buf, int nbytes, bool *done,
-		       struct static_key *once_key);
+bool __do_once(void (*func)(void *arg), void *arg, bool *done,
+	       struct static_key *once_key);
 
-#define get_random_once(buf, nbytes)					\
+#define do_once(func, arg)						\
 	({								\
 		bool ___ret = false;					\
 		static bool ___done = false;				\
 		static struct static_key ___once_key =			\
 			STATIC_KEY_INIT_TRUE;				\
 		if (static_key_true(&___once_key))			\
-			___ret = __get_random_once((buf),		\
-						   (nbytes),		\
-						   &___done,		\
-						   &___once_key);	\
+			___ret = __do_once((func), (arg),		\
+					   &___done,			\
+					   &___once_key);		\
 		___ret;							\
 	})
 
+void get_random_once_kvec(void *arg);
+
+#define get_random_once(buf, nbytes)					\
+	({								\
+		struct kvec __v = {					\
+			.iov_base = (buf),				\
+			.iov_len = (nbytes),				\
+		};							\
+		do_once(get_random_once_kvec, &__v);			\
+	})
+
 #endif /* _LINUX_ONCE_H */
diff --git a/lib/once.c b/lib/once.c
index 2d5a7de..1e62944 100644
--- a/lib/once.c
+++ b/lib/once.c
@@ -3,36 +3,36 @@
 #include <linux/once.h>
 #include <linux/random.h>
 
-struct __random_once_work {
+struct __once_work {
 	struct work_struct work;
 	struct static_key *key;
 };
 
-static void __random_once_deferred(struct work_struct *w)
+static void __once_deferred(struct work_struct *w)
 {
-	struct __random_once_work *work;
+	struct __once_work *work;
 
-	work = container_of(w, struct __random_once_work, work);
+	work = container_of(w, struct __once_work, work);
 	BUG_ON(!static_key_enabled(work->key));
 	static_key_slow_dec(work->key);
 	kfree(work);
 }
 
-static void __random_once_disable_jump(struct static_key *key)
+static void __once_disable_jump(struct static_key *key)
 {
-	struct __random_once_work *w;
+	struct __once_work *w;
 
 	w = kmalloc(sizeof(*w), GFP_ATOMIC);
 	if (!w)
 		return;
 
-	INIT_WORK(&w->work, __random_once_deferred);
+	INIT_WORK(&w->work, __once_deferred);
 	w->key = key;
 	schedule_work(&w->work);
 }
 
-bool __get_random_once(void *buf, int nbytes, bool *done,
-		       struct static_key *once_key)
+bool __do_once(void (*func)(void *arg), void *arg, bool *done,
+	       struct static_key *once_key)
 {
 	static DEFINE_SPINLOCK(lock);
 	unsigned long flags;
@@ -43,12 +43,20 @@ bool __get_random_once(void *buf, int nbytes, bool *done,
 		return false;
 	}
 
-	get_random_bytes(buf, nbytes);
+	func(arg);
 	*done = true;
 	spin_unlock_irqrestore(&lock, flags);
 
-	__random_once_disable_jump(once_key);
-
+	__once_disable_jump(once_key);
 	return true;
 }
-EXPORT_SYMBOL(__get_random_once);
+EXPORT_SYMBOL(__do_once);
+
+/* Helper function for once users. */
+void get_random_once_kvec(void *arg)
+{
+	struct kvec *v = arg;
+
+	get_random_bytes(v->iov_base, v->iov_len);
+}
+EXPORT_SYMBOL(get_random_once_kvec);
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists