summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2013-05-31 18:41:25 +0000
committertedu <tedu@openbsd.org>2013-05-31 18:41:25 +0000
commit44d38a949297ef9d4dde1ad9394cb1e0ea90e14a (patch)
treec3e5399f0291ab408b648ec411716e679ec4c44f /lib/libc
parentunfortunately the sparc pagesize handling also requires uvm_extern.h (diff)
downloadwireguard-openbsd-44d38a949297ef9d4dde1ad9394cb1e0ea90e14a.tar.xz
wireguard-openbsd-44d38a949297ef9d4dde1ad9394cb1e0ea90e14a.zip
add shm_open and friends which i have been told ports programs would
like to use. ok deraadt guenther
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gen/Makefile.inc8
-rw-r--r--lib/libc/gen/shm_open.389
-rw-r--r--lib/libc/gen/shm_open.c115
3 files changed, 209 insertions, 3 deletions
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index e39258c979b..fb2f7eb8f9a 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.59 2013/04/15 16:38:21 matthew Exp $
+# $OpenBSD: Makefile.inc,v 1.60 2013/05/31 18:41:25 tedu Exp $
# gen sources
.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/gen ${LIBCSRCDIR}/gen
@@ -18,7 +18,7 @@ SRCS+= alarm.c assert.c auth_subr.c authenticate.c \
pw_dup.c pwcache.c raise.c readdir.c readdir_r.c readpassphrase.c \
rewinddir.c scandir.c \
seekdir.c setdomainname.c sethostname.c setjmperr.c setmode.c \
- setproctitle.c siginterrupt.c siglist.c signal.c signame.c \
+ setproctitle.c shm_open.c siginterrupt.c siglist.c signal.c signame.c \
sigsetops.c sleep.c statvfs.c strtofflags.c sysconf.c sysctl.c \
syslog.c syslog_r.c telldir.c time.c times.c timezone.c \
tolower_.c ttyname.c \
@@ -51,7 +51,8 @@ MAN+= alarm.3 auth_subr.3 authenticate.3 basename.3 clock.3 confstr.3 \
posix_spawn_file_actions_init.3 posix_spawnattr_getflags.3 \
posix_spawnattr_getpgroup.3 posix_spawnattr_init.3 \
psignal.3 pw_dup.3 pwcache.3 raise.3 readpassphrase.3 \
- scandir.3 setjmp.3 setmode.3 setproctitle.3 siginterrupt.3 signal.3 \
+ scandir.3 setjmp.3 setmode.3 setproctitle.3 shm_open.3 \
+ siginterrupt.3 signal.3 \
sigsetops.3 sleep.3 statvfs.3 sysconf.3 sysctl.3 strtofflags.3 \
syslog.3 time.3 times.3 timezone.3 toascii.3 tolower.3 toupper.3 \
ttyname.3 ualarm.3 uname.3 unvis.3 usleep.3 utime.3 valloc.3 vis.3
@@ -140,6 +141,7 @@ MLINKS+=scandir.3 alphasort.3
MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \
setjmp.3 longjmperror.3 setjmp.3 sigsetjmp.3 setjmp.3 siglongjmp.3
MLINKS+=setmode.3 getmode.3
+MLINKS+=shm_open.3 shm_unlink.3 shm_open.3 shm_mkstemp.3
MLINKS+=sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.3 \
sigsetops.3 sigaddset.3 sigsetops.3 sigdelset.3 \
sigsetops.3 sigismember.3
diff --git a/lib/libc/gen/shm_open.3 b/lib/libc/gen/shm_open.3
new file mode 100644
index 00000000000..04510c79cd0
--- /dev/null
+++ b/lib/libc/gen/shm_open.3
@@ -0,0 +1,89 @@
+.\" $OpenBSD: shm_open.3,v 1.1 2013/05/31 18:41:25 tedu Exp $
+.\"
+.\" Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: May 31 2013 $
+.Dt SHM_OPEN 3
+.Os
+.Sh NAME
+.Nm shm_open ,
+.Nm shm_unlink ,
+.Nm shm_mkstemp
+.Nd "create and destroy shared memory objects"
+.Sh SYNOPSIS
+.In sys/mman.h
+.Ft int
+.Fn shm_open "const char *path" "int flags" "mode_t mode"
+.Ft int
+.Fn shm_unlink "const char *path"
+.Ft int
+.Fn shm_mkstemp "char *template"
+.Sh DESCRIPTION
+The
+.Fn shm_open
+function opens a shared memory object and returns a file descriptor suitable
+for use with
+.Xr mmap 2 .
+The
+.Fa flags
+argument has the same meaning as provided to
+.Xr open 2
+and must include at least
+.Dv O_RDONLY
+or
+.Dv O_RDWR
+and may also include a combination of
+.Dv O_CREAT , O_EXCL ,
+or
+.Dv O_TRUNC .
+This implementation forces the
+.Fa mode
+to be 0600 or 0400, and prohibits sharing between different UIDs.
+.Pp
+.Fn shm_unlink
+is used to remove a shared memory object.
+The object is not freed until all references to it have been released via
+.Xr close 2 .
+.Pp
+If a temporary shared memory object is desired, the
+.Fn shm_mkstemp
+function should be preferred as it avoids several possible security
+holes that tend to appear in programs trying to create their own unique
+temporary names.
+The
+.Fa template
+argument is a string with at least six trailing Xs as described in
+.Xr mkstemp 3 .
+.Sh RETURN VALUES
+.Fn shm_open
+and
+.Fn shm_mkstemp
+return a file descriptor on successful completion.
+They may fail for any of the reasons listed in
+.Xr open 2 .
+.Sh SEE ALSO
+.Xr mmap 2
+.Sh STANDARDS
+.Fn shm_open
+and
+.Fn shm_unlink
+appear in
+.St -p1003.1-2001 .
+This implementation deviates from the standard by permitting less sharing.
+.Pp
+.Fn shm_mkstemp
+is an extension.
+.Sh AUTHORS
+.An Ted Unangst Aq tedu@openbsd.org .
diff --git a/lib/libc/gen/shm_open.c b/lib/libc/gen/shm_open.c
new file mode 100644
index 00000000000..069baf73966
--- /dev/null
+++ b/lib/libc/gen/shm_open.c
@@ -0,0 +1,115 @@
+/* $OpenBSD */
+/*
+ * Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sha2.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* SHA256_DIGEST_STRING_LENGTH includes nul */
+/* "/tmp/" + sha256 + ".shm" */
+#define SHM_PATH_SIZE (5 + SHA256_DIGEST_STRING_LENGTH + 4)
+
+static void
+makeshmpath(const char *origpath, char *shmpath, size_t len)
+{
+ char buf[SHA256_DIGEST_STRING_LENGTH];
+
+ SHA256Data(origpath, strlen(origpath), buf);
+ snprintf(shmpath, len, "/tmp/%s.shm", buf);
+}
+
+int
+shm_open(const char *path, int flags, mode_t mode)
+{
+ char shmpath[SHM_PATH_SIZE];
+ struct stat sb;
+ int fd;
+
+ if (flags & ~(O_RDONLY | O_RDWR |
+ O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC | O_NOFOLLOW)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ flags |= O_CLOEXEC | O_NOFOLLOW;
+ mode = mode & 0600;
+
+ makeshmpath(path, shmpath, sizeof(shmpath));
+
+ fd = open(shmpath, flags, mode);
+ if (fd == -1)
+ return -1;
+ if (fstat(fd, &sb) == -1 || !S_ISREG(sb.st_mode)) {
+ errno = EINVAL;
+ close(fd);
+ return -1;
+ }
+ if (sb.st_uid != getuid()) {
+ errno = EPERM;
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+int
+shm_unlink(const char *path)
+{
+ char shmpath[SHM_PATH_SIZE];
+
+ makeshmpath(path, shmpath, sizeof(shmpath));
+ return unlink(shmpath);
+}
+
+char *_mktemp(char *);
+
+int
+shm_mkstemp(char *template)
+{
+ size_t templatelen;
+ char *t;
+ int i, fd;
+
+ templatelen = strlen(template);
+ t = malloc(templatelen + 1);
+ if (!t)
+ return -1;
+ t[templatelen] = '\0';
+
+ fd = -1;
+ for (i = 0; i < INT_MAX; i++) {
+ memcpy(t, template, templatelen);
+ if (!_mktemp(t))
+ break;
+ fd = shm_open(t, O_RDWR | O_EXCL | O_CREAT, 0600);
+ if (fd != -1) {
+ memcpy(template, t, templatelen);
+ break;
+ }
+ }
+
+ free(t);
+ return fd;
+}
+