[klibc] [PATCH] add mkstemp(3) using entropy from ELF aux vector AT_RANDOM

Thorsten Glaser tg at mirbsd.org
Sat Jan 28 13:15:06 PST 2012


- update AT_* definitions
- parse AT_RANDOM; provide some bytes as __klibc_rand48
- add mkstemp

Signed-off-by: Thorsten Glaser <tg at mirbsd.org>
---
 usr/include/stdlib.h        |    2 +
 usr/include/sys/elfcommon.h |   16 ++++++++-
 usr/klibc/Kbuild            |    1 +
 usr/klibc/libc_init.c       |    7 ++++
 usr/klibc/mkstemp.c         |   81 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 106 insertions(+), 1 deletions(-)
 create mode 100644 usr/klibc/mkstemp.c

diff --git a/usr/include/stdlib.h b/usr/include/stdlib.h
index 406f446..4706f71 100644
--- a/usr/include/stdlib.h
+++ b/usr/include/stdlib.h
@@ -79,6 +79,8 @@ static __inline__ void srandom(unsigned int __s)
 	srand48(__s);
 }
 
+__extern int mkstemp(char *);
+
 /* Basic PTY functions.  These only work if devpts is mounted! */
 
 __extern int unlockpt(int);
diff --git a/usr/include/sys/elfcommon.h b/usr/include/sys/elfcommon.h
index ad5e459..cf2b7ba 100644
--- a/usr/include/sys/elfcommon.h
+++ b/usr/include/sys/elfcommon.h
@@ -105,8 +105,22 @@
 #define AT_PLATFORM	15	/* string identifying CPU for optimizations */
 #define AT_HWCAP  	16	/* arch dependent hints at CPU capabilities */
 #define AT_CLKTCK 	17	/* frequency at which times() increments */
-/* 18..22 = ? */
+#define AT_FPUCW	18	/* used FPU control word */
+#define AT_DCACHEBSIZE	19	/* data cache block size */
+#define AT_ICACHEBSIZE	20	/* instruction cache block size */
+#define AT_UCACHEBSIZE	21	/* unified cache block size */
+#define AT_IGNOREPPC	22	/* (should be ignored; needed for powerpc) */
 #define AT_SECURE 	23	/* secure mode boolean */
+#define AT_BASE_PLATFORM 24	/* string identifying real platforms */
+#define AT_RANDOM	25	/* address of 16 random octets */
+/* 26..30 = ? */
+#define AT_EXECFN	31	/* filename of executable */
+#define AT_SYSINFO	32	/* global system page for syscalls etc. */
+#define AT_SYSINFO_EHDR	33	/* related to the above */
+#define AT_L1I_CACHESHAPE 34	/* "shape" of the L1 instruction cache */
+#define AT_L1D_CACHESHAPE 35	/* "shape" of the L1 data cache */
+#define AT_L2_CACHESHAPE  36	/* "shape" of the L2 cache */
+#define AT_L3_CACHESHAPE  37	/* "shape" of the L3 cache */
 
 /* Program header permission flags */
 #define PF_X            0x1
diff --git a/usr/klibc/Kbuild b/usr/klibc/Kbuild
index 753ab85..e736803 100644
--- a/usr/klibc/Kbuild
+++ b/usr/klibc/Kbuild
@@ -47,6 +47,7 @@ klib-y := vsnprintf.o snprintf.o vsprintf.o sprintf.o \
 	  time.o utime.o llseek.o nice.o getpriority.o \
 	  qsort.o bsearch.o \
 	  lrand48.o jrand48.o mrand48.o nrand48.o srand48.o seed48.o \
+	  mkstemp.o \
 	  inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \
 	  inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \
 	  send.o recv.o \
diff --git a/usr/klibc/libc_init.c b/usr/klibc/libc_init.c
index 8d18820..0bc9047 100644
--- a/usr/klibc/libc_init.c
+++ b/usr/klibc/libc_init.c
@@ -34,6 +34,9 @@
 char **environ;
 unsigned int __page_size, __page_shift;
 
+/* for use with jrand48() and friends */
+unsigned short __klibc_rand48[3];
+
 struct auxentry {
 	uintptr_t type;
 	uintptr_t v;
@@ -85,6 +88,10 @@ __noreturn __libc_init(uintptr_t * elfdata, void (*onexit) (void))
 		case AT_PAGESZ:
 			page_size = (unsigned int)(auxentry->v);
 			break;
+		case AT_RANDOM:
+			memcpy(__klibc_rand48, (void *)(auxentry->v),
+			    sizeof(__klibc_rand48));
+			break;
 		}
 		auxentry++;
 	}
diff --git a/usr/klibc/mkstemp.c b/usr/klibc/mkstemp.c
new file mode 100644
index 0000000..5dd7240
--- /dev/null
+++ b/usr/klibc/mkstemp.c
@@ -0,0 +1,81 @@
+/*-
+ * Compact mkstemp(3)-only implementation, for klibc
+ *
+ * Copyright (c) 2009, 2011, 2012
+ *	Thorsten Glaser <tg at mirbsd.org>
+ *
+ * This file is available under the same terms ("historic
+ * permission clause") as klibc itself or under the terms
+ * of The MirOS Licence (dual licenced).
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* from libc_main.c pre-filled from AT_RANDOM */
+extern unsigned short __klibc_rand48[3];
+
+int
+mkstemp(char *template)
+{
+	int i;
+	char *cp, *sp;
+	struct stat sbuf;
+
+	cp = template;
+	while (*cp)
+		++cp;
+
+	sp = cp;
+	/* generate random suffix */
+	while (sp > template && sp[-1] == 'X') {
+		i = (int)((unsigned int)jrand48(__klibc_rand48) % (26 + 26));
+		*--sp = i < 26 ? 'A' + i : 'a' + i - 26;
+	}
+	if (sp == cp) {
+		/* zero-length template or no X at its end */
+		errno = EINVAL;
+		return (-1);
+	}
+
+	/* check the target directory */
+	cp = sp;
+	while (cp > template && *cp != '/')
+		--cp;
+	if (cp > template) {
+		*cp = '\0';
+		i = stat(template, &sbuf);
+		*cp = '/';
+
+		if (i != 0) {
+			/* stat failed, pass errno */
+			return (-1);
+		}
+		if (!S_ISDIR(sbuf.st_mode)) {
+			errno = ENOTDIR;
+			return (-1);
+		}
+	}
+
+	while (1) {
+		if ((i = open(template, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0 ||
+		    errno != EEXIST)
+			break;
+
+		while (*cp == 'Z')
+			if (!*++cp)
+				return (-1);
+		if (*cp == 'z')
+			*cp = 'A';
+		else
+			++*cp;
+	}
+	return (i);
+}
-- 
1.7.8.3



More information about the klibc mailing list