[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