From cbbcd319fcd2cd7f102ec0f7c551a3c482f8d7d8 Mon Sep 17 00:00:00 2001 From: millert Date: Fri, 16 Oct 2015 13:37:43 +0000 Subject: [PATCH] Implement real "flock" request and add it to userland programs that use pledge and file locking. OK deraadt@ --- bin/ksh/main.c | 4 ++-- libexec/login_skey/login_skey.c | 8 +++++++- sys/kern/kern_descrip.c | 11 ++++++++++- sys/kern/kern_pledge.c | 16 +++++++++++++--- sys/kern/vfs_syscalls.c | 8 +++++++- sys/sys/pledge.h | 4 +++- usr.bin/htpasswd/htpasswd.c | 4 ++-- usr.bin/mandoc/main.c | 6 +++--- usr.bin/mandoc/mandocdb.c | 6 +++--- usr.bin/openssl/openssl.c | 4 ++-- usr.bin/rcs/rcsprog.c | 4 ++-- usr.sbin/config/main.c | 4 ++-- usr.sbin/dev_mkdb/dev_mkdb.c | 4 ++-- usr.sbin/kvm_mkdb/kvm_mkdb.c | 4 ++-- usr.sbin/smtpd/queue.c | 4 ++-- usr.sbin/smtpd/smtpctl.c | 4 ++-- 16 files changed, 64 insertions(+), 31 deletions(-) diff --git a/bin/ksh/main.c b/bin/ksh/main.c index 8cf21dc96e5..8f62230b31e 100644 --- a/bin/ksh/main.c +++ b/bin/ksh/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.62 2015/10/10 20:35:00 deraadt Exp $ */ +/* $OpenBSD: main.c,v 1.63 2015/10/16 13:37:43 millert Exp $ */ /* * startup, main loop, environments and error handling @@ -103,7 +103,7 @@ main(int argc, char *argv[]) kshname = argv[0]; #ifndef MKNOD - if (pledge("stdio rpath wpath cpath fattr getpw proc exec tty", NULL) == -1) + if (pledge("stdio rpath wpath cpath fattr flock getpw proc exec tty", NULL) == -1) perror("pledge"); #endif diff --git a/libexec/login_skey/login_skey.c b/libexec/login_skey/login_skey.c index 63838238e17..1ca514a750f 100644 --- a/libexec/login_skey/login_skey.c +++ b/libexec/login_skey/login_skey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: login_skey.c,v 1.24 2015/01/16 06:39:50 deraadt Exp $ */ +/* $OpenBSD: login_skey.c,v 1.25 2015/10/16 13:37:43 millert Exp $ */ /* * Copyright (c) 2000, 2001, 2004 Todd C. Miller @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,11 @@ main(int argc, char *argv[]) (void)signal(SIGTSTP, suspend); (void)setpriority(PRIO_PROCESS, 0, 0); + if (pledge("stdio rpath wpath flock sendfd proc tty", NULL) == -1) { + syslog(LOG_AUTH|LOG_ERR, "pledge: %m"); + exit(1); + } + openlog(NULL, LOG_ODELAY, LOG_AUTH); while ((ch = getopt(argc, argv, "ds:v:")) != -1) { diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 76b8542b3ec..6de08b92085 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_descrip.c,v 1.120 2015/05/17 01:22:01 deraadt Exp $ */ +/* $OpenBSD: kern_descrip.c,v 1.121 2015/10/16 13:37:43 millert Exp $ */ /* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */ /* @@ -60,6 +60,7 @@ #include #include #include +#include #include @@ -461,6 +462,10 @@ restart: /* FALLTHROUGH */ case F_SETLK: + error = pledge_flock_check(p); + if (error != 0) + break; + if (fp->f_type != DTYPE_VNODE) { error = EBADF; break; @@ -524,6 +529,10 @@ restart: case F_GETLK: + error = pledge_flock_check(p); + if (error != 0) + break; + if (fp->f_type != DTYPE_VNODE) { error = EBADF; break; diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 7b26efd9468..888ef8b2444 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.32 2015/10/16 06:42:02 deraadt Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.33 2015/10/16 13:37:43 millert Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -224,7 +224,7 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_setsockopt] = PLEDGE_INET | PLEDGE_UNIX, [SYS_getsockopt] = PLEDGE_INET | PLEDGE_UNIX, - [SYS_flock] = PLEDGE_RW | PLEDGE_CPATH, + [SYS_flock] = PLEDGE_FLOCK | PLEDGE_YP_ACTIVE, }; static const struct { @@ -253,7 +253,7 @@ static const struct { { "abort", PLEDGE_ABORT }, { "fattr", PLEDGE_FATTR }, { "prot_exec", PLEDGE_PROTEXEC }, - { "flock", PLEDGE_RW | PLEDGE_CPATH }, + { "flock", PLEDGE_FLOCK }, }; int @@ -1209,6 +1209,16 @@ pledge_dns_check(struct proc *p, in_port_t port) return (EPERM); } +int +pledge_flock_check(struct proc *p) +{ + if ((p->p_p->ps_flags & PS_PLEDGE) == 0) + return (0); + if ((p->p_p->ps_pledge & PLEDGE_FLOCK)) + return (0); + return (pledge_fail(p, EPERM, PLEDGE_FLOCK)); +} + void pledge_dropwpaths(struct process *pr) { diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 584b541970a..35ad67a9f85 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_syscalls.c,v 1.230 2015/10/14 14:24:03 deraadt Exp $ */ +/* $OpenBSD: vfs_syscalls.c,v 1.231 2015/10/16 13:37:43 millert Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */ /* @@ -860,6 +860,12 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode, if (oflags & O_CREAT) p->p_pledgenote |= TMN_CPATH; + if (oflags & (O_EXLOCK | O_SHLOCK)) { + error = pledge_flock_check(p); + if (error != 0) + return (error); + } + fdplock(fdp); if ((error = falloc(p, &fp, &indx)) != 0) diff --git a/sys/sys/pledge.h b/sys/sys/pledge.h index 534629f0d0d..cfa80ee5024 100644 --- a/sys/sys/pledge.h +++ b/sys/sys/pledge.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pledge.h,v 1.2 2015/10/14 14:24:03 deraadt Exp $ */ +/* $OpenBSD: pledge.h,v 1.3 2015/10/16 13:37:44 millert Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -46,6 +46,7 @@ #define PLEDGE_EXEC 0x00080000 /* execve, child is free of pledge */ #define PLEDGE_ROUTE 0x00100000 /* routing lookups */ #define PLEDGE_MCAST 0x00200000 /* multicast joins */ +#define PLEDGE_FLOCK 0x00400000 /* file locking */ #define PLEDGE_ABORT 0x08000000 /* SIGABRT instead of SIGKILL */ @@ -74,6 +75,7 @@ int pledge_socket_check(struct proc *p, int domain); int pledge_setsockopt_check(struct proc *p, int level, int optname); int pledge_dns_check(struct proc *p, in_port_t port); int pledge_ioctl_check(struct proc *p, long com, void *); +int pledge_flock_check(struct proc *p); #define PLEDGE_MAXPATHS 8192 diff --git a/usr.bin/htpasswd/htpasswd.c b/usr.bin/htpasswd/htpasswd.c index fc285c24758..7cd139c7b59 100644 --- a/usr.bin/htpasswd/htpasswd.c +++ b/usr.bin/htpasswd/htpasswd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: htpasswd.c,v 1.13 2015/10/09 01:37:07 deraadt Exp $ */ +/* $OpenBSD: htpasswd.c,v 1.14 2015/10/16 13:37:44 millert Exp $ */ /* * Copyright (c) 2014 Florian Obser * @@ -57,7 +57,7 @@ main(int argc, char** argv) ssize_t linelen; mode_t old_umask; - if (pledge("stdio rpath wpath cpath tmppath tty", NULL) == -1) + if (pledge("stdio rpath wpath cpath flock tmppath tty", NULL) == -1) err(1, "pledge"); while ((c = getopt(argc, argv, "I")) != -1) { diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c index 6dab7fa11ac..07edb8c36b5 100644 --- a/usr.bin/mandoc/main.c +++ b/usr.bin/mandoc/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.155 2015/10/13 22:57:49 schwarze Exp $ */ +/* $OpenBSD: main.c,v 1.156 2015/10/16 13:37:44 millert Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2012, 2014, 2015 Ingo Schwarze @@ -134,7 +134,7 @@ main(int argc, char *argv[]) 0 == strncmp(__progname, "makewhatis", 10)) return mandocdb(argc, argv); - if (pledge("stdio rpath tmppath proc exec", NULL) == -1) + if (pledge("stdio rpath tmppath proc exec flock", NULL) == -1) err(1, "pledge"); /* Search options. */ @@ -276,7 +276,7 @@ main(int argc, char *argv[]) !isatty(STDOUT_FILENO)) use_pager = 0; - if (!use_pager && pledge("stdio rpath", NULL) == -1) + if (!use_pager && pledge("stdio rpath flock", NULL) == -1) err(1, "pledge"); /* Parse arguments. */ diff --git a/usr.bin/mandoc/mandocdb.c b/usr.bin/mandoc/mandocdb.c index a1a4af70b08..eae173b25fe 100644 --- a/usr.bin/mandoc/mandocdb.c +++ b/usr.bin/mandoc/mandocdb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mandocdb.c,v 1.157 2015/10/13 22:57:49 schwarze Exp $ */ +/* $OpenBSD: mandocdb.c,v 1.158 2015/10/16 13:37:44 millert Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011-2015 Ingo Schwarze @@ -333,7 +333,7 @@ mandocdb(int argc, char *argv[]) size_t j, sz; int ch, i; - if (pledge("stdio rpath wpath cpath fattr proc exec", NULL) == -1) { + if (pledge("stdio rpath wpath cpath fattr flock proc exec", NULL) == -1) { perror("pledge"); return (int)MANDOCLEVEL_SYSERR; } @@ -441,7 +441,7 @@ mandocdb(int argc, char *argv[]) * The existing database is usable. Process * all files specified on the command-line. */ - if (!nodb && pledge("stdio rpath wpath cpath fattr", + if (!nodb && pledge("stdio rpath wpath cpath fattr flock", NULL) == -1) { perror("pledge"); exitcode = (int)MANDOCLEVEL_SYSERR; diff --git a/usr.bin/openssl/openssl.c b/usr.bin/openssl/openssl.c index e842d6cc65d..43f0e9189c3 100644 --- a/usr.bin/openssl/openssl.c +++ b/usr.bin/openssl/openssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openssl.c,v 1.17 2015/10/10 22:28:51 doug Exp $ */ +/* $OpenBSD: openssl.c,v 1.18 2015/10/16 13:37:44 millert Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -438,7 +438,7 @@ main(int argc, char **argv) arg.data = NULL; arg.count = 0; - if (pledge("stdio inet rpath wpath cpath proc", NULL) == -1) { + if (pledge("stdio inet rpath wpath cpath proc flock", NULL) == -1) { fprintf(stderr, "openssl: pledge: %s\n", strerror(errno)); exit(1); } diff --git a/usr.bin/rcs/rcsprog.c b/usr.bin/rcs/rcsprog.c index 383cf2736cc..13bf3149ff1 100644 --- a/usr.bin/rcs/rcsprog.c +++ b/usr.bin/rcs/rcsprog.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcsprog.c,v 1.158 2015/10/10 20:35:01 deraadt Exp $ */ +/* $OpenBSD: rcsprog.c,v 1.159 2015/10/16 13:37:44 millert Exp $ */ /* * Copyright (c) 2005 Jean-Francois Brousseau * All rights reserved. @@ -128,7 +128,7 @@ main(int argc, char **argv) char **cmd_argv; int ret, cmd_argc; - if (pledge("stdio rpath wpath cpath fattr getpw", NULL) == -1) + if (pledge("stdio rpath wpath cpath fattr flock getpw", NULL) == -1) err(1, "pledge"); ret = -1; diff --git a/usr.sbin/config/main.c b/usr.sbin/config/main.c index 7f6b8a99968..33d82e17a81 100644 --- a/usr.sbin/config/main.c +++ b/usr.sbin/config/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.49 2015/10/12 15:56:58 deraadt Exp $ */ +/* $OpenBSD: main.c,v 1.50 2015/10/16 13:37:44 millert Exp $ */ /* $NetBSD: main.c,v 1.22 1997/02/02 21:12:33 thorpej Exp $ */ /* @@ -107,7 +107,7 @@ main(int argc, char *argv[]) int ch, eflag, uflag, fflag; char dirbuffer[PATH_MAX]; - if (pledge("stdio rpath wpath cpath", NULL) == -1) + if (pledge("stdio rpath wpath cpath flock", NULL) == -1) err(1, "pledge"); pflag = eflag = uflag = fflag = 0; diff --git a/usr.sbin/dev_mkdb/dev_mkdb.c b/usr.sbin/dev_mkdb/dev_mkdb.c index 83aaf7429ec..57506622e07 100644 --- a/usr.sbin/dev_mkdb/dev_mkdb.c +++ b/usr.sbin/dev_mkdb/dev_mkdb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev_mkdb.c,v 1.14 2015/10/12 16:01:53 deraadt Exp $ */ +/* $OpenBSD: dev_mkdb.c,v 1.15 2015/10/16 13:37:44 millert Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -61,7 +61,7 @@ main(int argc, char *argv[]) u_char buf[MAXNAMLEN + 1]; char dbtmp[PATH_MAX], dbname[PATH_MAX]; - if (pledge("stdio rpath wpath cpath", NULL) == -1) + if (pledge("stdio rpath wpath cpath flock", NULL) == -1) err(1, "pledge"); while ((ch = getopt(argc, argv, "")) != -1) diff --git a/usr.sbin/kvm_mkdb/kvm_mkdb.c b/usr.sbin/kvm_mkdb/kvm_mkdb.c index eff6a7b44ab..fa4c20393d5 100644 --- a/usr.sbin/kvm_mkdb/kvm_mkdb.c +++ b/usr.sbin/kvm_mkdb/kvm_mkdb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kvm_mkdb.c,v 1.23 2015/10/13 15:55:44 deraadt Exp $ */ +/* $OpenBSD: kvm_mkdb.c,v 1.24 2015/10/16 13:37:44 millert Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -170,7 +170,7 @@ kvm_mkdb(int fd, const char *dbdir, char *nlistpath, char *nlistname, } /* rename() later */ - if (pledge("stdio rpath wpath cpath", NULL) == -1) + if (pledge("stdio rpath wpath cpath flock", NULL) == -1) err(1, "pledge"); if (create_knlist(nlistpath, fd, db) != 0) { diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c index b2349771153..eff14eb18b3 100644 --- a/usr.sbin/smtpd/queue.c +++ b/usr.sbin/smtpd/queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.c,v 1.168 2015/10/14 22:01:43 gilles Exp $ */ +/* $OpenBSD: queue.c,v 1.169 2015/10/16 13:37:44 millert Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -643,7 +643,7 @@ queue(void) tv.tv_usec = 10; evtimer_add(&ev_qload, &tv); - if (pledge("stdio rpath wpath cpath recvfd sendfd", NULL) == -1) + if (pledge("stdio rpath wpath cpath flock recvfd sendfd", NULL) == -1) err(1, "pledge"); if (event_dispatch() < 0) diff --git a/usr.sbin/smtpd/smtpctl.c b/usr.sbin/smtpd/smtpctl.c index a198a952886..d34e5b2d343 100644 --- a/usr.sbin/smtpd/smtpctl.c +++ b/usr.sbin/smtpd/smtpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpctl.c,v 1.131 2015/10/15 08:18:23 sunil Exp $ */ +/* $OpenBSD: smtpctl.c,v 1.132 2015/10/16 13:37:44 millert Exp $ */ /* * Copyright (c) 2013 Eric Faurot @@ -932,7 +932,7 @@ main(int argc, char **argv) err(1, "setresgid"); /* we'll reduce further down the road */ - if (pledge("stdio rpath tmppath getpw recvfd", NULL) == -1) + if (pledge("stdio rpath tmppath flock getpw recvfd", NULL) == -1) err(1, "pledge"); sendmail = 1; -- 2.20.1