commit: dce7387ae2c7293204031c7698d2fca5995e3f84
parent e5b9ffd458933b9f68a6609b96d308192b2dbd86
Author: Michael Forney <mforney@mforney.org>
Date: Fri, 30 Apr 2021 18:02:18 -0700
openbsd: Update to 6.9
Diffstat:
34 files changed, 747 insertions(+), 815 deletions(-)
diff --git a/pkg/openbsd/patch/0009-patch-Avoid-d_namlen.patch b/pkg/openbsd/patch/0009-patch-Avoid-d_namlen.patch
@@ -1,4 +1,4 @@
-From 91483dfca3aa6373451120db45c60198faa0766e Mon Sep 17 00:00:00 2001
+From 602381b693ff286ed17a9a04bfceaeb255992843 Mon Sep 17 00:00:00 2001
From: Michael Forney <mforney@mforney.org>
Date: Sat, 4 Jun 2016 18:40:37 -0700
Subject: [PATCH] patch: Avoid d_namlen
@@ -8,10 +8,10 @@ Subject: [PATCH] patch: Avoid d_namlen
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/usr.bin/patch/backupfile.c b/usr.bin/patch/backupfile.c
-index d9e40bcba..1d7858ae3 100644
+index ed0767762e0..fc05e48e68d 100644
--- a/usr.bin/patch/backupfile.c
+++ b/usr.bin/patch/backupfile.c
-@@ -95,7 +95,7 @@ max_backup_version(const char *file, const char *dir)
+@@ -106,7 +106,7 @@ max_backup_version(const char *file, const char *dir)
file_name_length = strlen(file);
while ((dp = readdir(dirp)) != NULL) {
@@ -21,5 +21,5 @@ index d9e40bcba..1d7858ae3 100644
this_version = version_number(file, dp->d_name, file_name_length);
--
-2.12.2
+2.31.1
diff --git a/pkg/openbsd/patch/0010-patch-Fix-with-musl-s-basename-dirname.patch b/pkg/openbsd/patch/0010-patch-Fix-with-musl-s-basename-dirname.patch
@@ -1,46 +0,0 @@
-From e16acc0e80f475b2139eabe1b07b7eb0521a7918 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Sat, 4 Jun 2016 20:13:35 -0700
-Subject: [PATCH] patch: Fix with musl's basename/dirname
-
----
- usr.bin/patch/backupfile.c | 15 ++++++++-------
- 1 file changed, 8 insertions(+), 7 deletions(-)
-
-diff --git a/usr.bin/patch/backupfile.c b/usr.bin/patch/backupfile.c
-index 1d7858ae3..243d00e32 100644
---- a/usr.bin/patch/backupfile.c
-+++ b/usr.bin/patch/backupfile.c
-@@ -53,21 +53,22 @@ static void invalid_arg(const char *, const char *, int);
- char *
- find_backup_file_name(const char *file)
- {
-- char *dir, *base_versions;
-+ char *path, *base_versions;
- int highest_backup;
-
- if (backup_type == simple)
- return concat(file, simple_backup_suffix);
-- base_versions = concat(basename(file), ".~");
-- if (base_versions == NULL)
-+ path = strdup(file);
-+ if (path == NULL)
- return NULL;
-- dir = dirname(file);
-- if (dir == NULL) {
-- free(base_versions);
-+ base_versions = concat(basename(path), ".~");
-+ if (base_versions == NULL) {
-+ free(path);
- return NULL;
- }
-- highest_backup = max_backup_version(base_versions, dir);
-+ highest_backup = max_backup_version(base_versions, dirname(path));
- free(base_versions);
-+ free(path);
- if (backup_type == numbered_existing && highest_backup == 0)
- return concat(file, simple_backup_suffix);
- return make_version_name(file, highest_backup + 1);
---
-2.12.2
-
diff --git a/pkg/openbsd/patch/0011-pax-Fix-GNU-long-name-handling-with-short-read.patch b/pkg/openbsd/patch/0010-pax-Fix-GNU-long-name-handling-with-short-read.patch
diff --git a/pkg/openbsd/patch/0012-pax-Support-xz-compression-with-J-flag.patch b/pkg/openbsd/patch/0011-pax-Support-xz-compression-with-J-flag.patch
diff --git a/pkg/openbsd/patch/0013-setprogname-Explicitly-discard-const-qualifier.patch b/pkg/openbsd/patch/0012-setprogname-Explicitly-discard-const-qualifier.patch
diff --git a/pkg/openbsd/patch/0014-readpassphrase-Support-systems-without-VSTATUS-and-T.patch b/pkg/openbsd/patch/0013-readpassphrase-Support-systems-without-VSTATUS-and-T.patch
diff --git a/pkg/openbsd/patch/0015-Remove-getpass-definition.patch b/pkg/openbsd/patch/0014-Remove-getpass-definition.patch
diff --git a/pkg/openbsd/patch/0015-doas-Port-to-linux-musl.patch b/pkg/openbsd/patch/0015-doas-Port-to-linux-musl.patch
@@ -0,0 +1,564 @@
+From 3eac1566f49c5edb13c41009b571b1b391f5f841 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Sun, 26 Feb 2017 16:50:55 -0800
+Subject: [PATCH] doas: Port to linux/musl
+
+Remove -a login style option and BSD authentication. Instead, compare
+against shadow file.
+
+Use timestamp files in /run/doas instead of TIOC*VERAUTH to implement
+persist.
+
+Use initgroups/setgid/setuid instead of setusercontext.
+
+Provide UID_MAX and GID_MAX defaults.
+
+Use LOGIN_NAME_MAX instead of _PW_NAME_LEN.
+
+Remove call to closefrom.
+
+Replace calls to errc with err after setting errno.
+
+Call openlog at start to set syslog identity.
+
+Remove unveil/pledge since they aren't supported on Linux.
+
+Simplify handling of PATH in the environment since we don't have
+login.conf with per-user default PATH.
+---
+ usr.bin/doas/doas.1 | 9 ---
+ usr.bin/doas/doas.c | 159 ++++++++++++++---------------------------
+ usr.bin/doas/doas.h | 6 +-
+ usr.bin/doas/env.c | 17 ++---
+ usr.bin/doas/parse.y | 1 +
+ usr.bin/doas/persist.c | 133 ++++++++++++++++++++++++++++++++++
+ 6 files changed, 196 insertions(+), 129 deletions(-)
+ create mode 100644 usr.bin/doas/persist.c
+
+diff --git a/usr.bin/doas/doas.1 b/usr.bin/doas/doas.1
+index 4d2e09777c8..a91705e8e3f 100644
+--- a/usr.bin/doas/doas.1
++++ b/usr.bin/doas/doas.1
+@@ -22,7 +22,6 @@
+ .Sh SYNOPSIS
+ .Nm doas
+ .Op Fl Lns
+-.Op Fl a Ar style
+ .Op Fl C Ar config
+ .Op Fl u Ar user
+ .Ar command
+@@ -67,14 +66,6 @@ The working directory is not changed.
+ .Pp
+ The options are as follows:
+ .Bl -tag -width tenletters
+-.It Fl a Ar style
+-Use the specified authentication style when validating the user,
+-as allowed by
+-.Pa /etc/login.conf .
+-A list of doas-specific authentication methods may be configured by adding an
+-.Sq auth-doas
+-entry in
+-.Xr login.conf 5 .
+ .It Fl C Ar config
+ Parse and check the configuration file
+ .Ar config ,
+diff --git a/usr.bin/doas/doas.c b/usr.bin/doas/doas.c
+index be05be3a968..46b0ceb136b 100644
+--- a/usr.bin/doas/doas.c
++++ b/usr.bin/doas/doas.c
+@@ -20,8 +20,6 @@
+ #include <sys/ioctl.h>
+
+ #include <limits.h>
+-#include <login_cap.h>
+-#include <bsd_auth.h>
+ #include <readpassphrase.h>
+ #include <string.h>
+ #include <stdio.h>
+@@ -33,13 +31,22 @@
+ #include <syslog.h>
+ #include <errno.h>
+ #include <fcntl.h>
++#include <shadow.h>
+
+ #include "doas.h"
+
++#ifndef UID_MAX
++#define UID_MAX 65535
++#endif
++
++#ifndef GID_MAX
++#define GID_MAX 65535
++#endif
++
+ static void __dead
+ usage(void)
+ {
+- fprintf(stderr, "usage: doas [-Lns] [-a style] [-C config] [-u user]"
++ fprintf(stderr, "usage: doas [-Lns] [-C config] [-u user]"
+ " command [args]\n");
+ exit(1);
+ }
+@@ -199,23 +206,36 @@ checkconfig(const char *confpath, int argc, char **argv,
+ }
+ }
+
++static int
++verifypasswd(const char *user, const char *pass)
++{
++ struct spwd *sp;
++ char *p1, *p2;
++
++ sp = getspnam(user);
++ if (!sp)
++ return 0;
++ p1 = sp->sp_pwdp;
++ if (p1[0] == '!' || p1[0] == '*')
++ return 0;
++ p2 = crypt(pass, p1);
++ if (!p2)
++ return 0;
++ return strcmp(p1, p2) == 0;
++}
++
+ static void
+-authuser(char *myname, char *login_style, int persist)
++authuser(char *myname, int persist)
+ {
+ char *challenge = NULL, *response, rbuf[1024], cbuf[128];
+- auth_session_t *as;
+- int fd = -1;
++ int fd = -1, valid = 0;
+
+- if (persist)
+- fd = open("/dev/tty", O_RDWR);
+- if (fd != -1) {
+- if (ioctl(fd, TIOCCHKVERAUTH) == 0)
++ if (persist) {
++ fd = openpersist(&valid);
++ if (valid)
+ goto good;
+ }
+
+- if (!(as = auth_userchallenge(myname, login_style, "auth-doas",
+- &challenge)))
+- errx(1, "Authentication failed");
+ if (!challenge) {
+ char host[HOST_NAME_MAX + 1];
+ if (gethostname(host, sizeof(host)))
+@@ -227,75 +247,31 @@ authuser(char *myname, char *login_style, int persist)
+ response = readpassphrase(challenge, rbuf, sizeof(rbuf),
+ RPP_REQUIRE_TTY);
+ if (response == NULL && errno == ENOTTY) {
+- syslog(LOG_AUTHPRIV | LOG_NOTICE,
+- "tty required for %s", myname);
++ syslog(LOG_NOTICE, "tty required for %s", myname);
+ errx(1, "a tty is required");
+ }
+- if (!auth_userresponse(as, response, 0)) {
++ if (!verifypasswd(myname, response)) {
+ explicit_bzero(rbuf, sizeof(rbuf));
+- syslog(LOG_AUTHPRIV | LOG_NOTICE,
+- "failed auth for %s", myname);
++ syslog(LOG_NOTICE, "failed auth for %s", myname);
+ errx(1, "Authentication failed");
+ }
+ explicit_bzero(rbuf, sizeof(rbuf));
+ good:
+ if (fd != -1) {
+- int secs = 5 * 60;
+- ioctl(fd, TIOCSETVERAUTH, &secs);
++ setpersist(fd);
+ close(fd);
+ }
+ }
+
+-int
+-unveilcommands(const char *ipath, const char *cmd)
+-{
+- char *path = NULL, *p;
+- int unveils = 0;
+-
+- if (strchr(cmd, '/') != NULL) {
+- if (unveil(cmd, "x") != -1)
+- unveils++;
+- goto done;
+- }
+-
+- if (!ipath) {
+- errno = ENOENT;
+- goto done;
+- }
+- path = strdup(ipath);
+- if (!path) {
+- errno = ENOENT;
+- goto done;
+- }
+- for (p = path; p && *p; ) {
+- char buf[PATH_MAX];
+- char *cp = strsep(&p, ":");
+-
+- if (cp) {
+- int r = snprintf(buf, sizeof buf, "%s/%s", cp, cmd);
+- if (r >= 0 && r < sizeof buf) {
+- if (unveil(buf, "x") != -1)
+- unveils++;
+- }
+- }
+- }
+-done:
+- free(path);
+- return (unveils);
+-}
+-
+ int
+ main(int argc, char **argv)
+ {
+- const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:"
+- "/usr/local/bin:/usr/local/sbin";
+ const char *confpath = NULL;
+ char *shargv[] = { NULL, NULL };
+ char *sh;
+- const char *p;
+ const char *cmd;
+ char cmdline[LINE_MAX];
+- char mypwbuf[_PW_BUF_LEN], targpwbuf[_PW_BUF_LEN];
++ char mypwbuf[1024], targpwbuf[1024];
+ struct passwd mypwstore, targpwstore;
+ struct passwd *mypw, *targpw;
+ const struct rule *rule;
+@@ -308,28 +284,20 @@ main(int argc, char **argv)
+ int nflag = 0;
+ char cwdpath[PATH_MAX];
+ const char *cwd;
+- char *login_style = NULL;
+ char **envp;
+
+ setprogname("doas");
+-
+- closefrom(STDERR_FILENO + 1);
++ openlog("doas", 0, LOG_AUTHPRIV);
+
+ uid = getuid();
+
+- while ((ch = getopt(argc, argv, "a:C:Lnsu:")) != -1) {
++ while ((ch = getopt(argc, argv, "C:Lnsu:")) != -1) {
+ switch (ch) {
+- case 'a':
+- login_style = optarg;
+- break;
+ case 'C':
+ confpath = optarg;
+ break;
+ case 'L':
+- i = open("/dev/tty", O_RDWR);
+- if (i != -1)
+- ioctl(i, TIOCCLRVERAUTH);
+- exit(i == -1);
++ exit(clearpersist() != 0);
+ case 'u':
+ if (parseuid(optarg, &target) != 0)
+ errx(1, "unknown user");
+@@ -399,47 +367,30 @@ main(int argc, char **argv)
+ cmd = argv[0];
+ if (!permit(uid, groups, ngroups, &rule, target, cmd,
+ (const char **)argv + 1)) {
+- syslog(LOG_AUTHPRIV | LOG_NOTICE,
+- "command not permitted for %s: %s", mypw->pw_name, cmdline);
+- errc(1, EPERM, NULL);
++ syslog(LOG_NOTICE, "command not permitted for %s: %s", mypw->pw_name, cmdline);
++ errno = EPERM;
++ err(1, NULL);
+ }
+
+ if (!(rule->options & NOPASS)) {
+ if (nflag)
+ errx(1, "Authentication required");
+
+- authuser(mypw->pw_name, login_style, rule->options & PERSIST);
++ authuser(mypw->pw_name, rule->options & PERSIST);
+ }
+
+- if ((p = getenv("PATH")) != NULL)
+- formerpath = strdup(p);
+- if (formerpath == NULL)
+- formerpath = "";
+-
+- if (unveil(_PATH_LOGIN_CONF, "r") == -1 ||
+- unveil(_PATH_LOGIN_CONF ".db", "r") == -1)
+- err(1, "unveil");
+- if (rule->cmd) {
+- if (setenv("PATH", safepath, 1) == -1)
+- err(1, "failed to set PATH '%s'", safepath);
+- }
+- if (unveilcommands(getenv("PATH"), cmd) == 0)
+- goto fail;
+-
+- if (pledge("stdio rpath getpw exec id", NULL) == -1)
+- err(1, "pledge");
+-
+ rv = getpwuid_r(target, &targpwstore, targpwbuf, sizeof(targpwbuf), &targpw);
+ if (rv != 0)
+ err(1, "getpwuid_r failed");
+ if (targpw == NULL)
+ errx(1, "no passwd entry for target");
+
+- if (setusercontext(NULL, targpw, target, LOGIN_SETGROUP |
+- LOGIN_SETPATH |
+- LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK |
+- LOGIN_SETUSER) != 0)
+- errx(1, "failed to set user context for target");
++ if (initgroups(targpw->pw_name, targpw->pw_gid) == -1)
++ err(1, "initgroups");
++ if (setgid(targpw->pw_gid) == -1)
++ err(1, "setgid");
++ if (setuid(targpw->pw_uid) == -1)
++ err(1, "setuid");
+
+ if (pledge("stdio rpath exec", NULL) == -1)
+ err(1, "pledge");
+@@ -453,23 +404,17 @@ main(int argc, char **argv)
+ err(1, "pledge");
+
+ if (!(rule->options & NOLOG)) {
+- syslog(LOG_AUTHPRIV | LOG_INFO,
+- "%s ran command %s as %s from %s",
++ syslog(LOG_INFO, "%s ran command %s as %s from %s",
+ mypw->pw_name, cmdline, targpw->pw_name, cwd);
+ }
+
+ envp = prepenv(rule, mypw, targpw);
+
+- /* setusercontext set path for the next process, so reset it for us */
+ if (rule->cmd) {
+ if (setenv("PATH", safepath, 1) == -1)
+ err(1, "failed to set PATH '%s'", safepath);
+- } else {
+- if (setenv("PATH", formerpath, 1) == -1)
+- err(1, "failed to set PATH '%s'", formerpath);
+ }
+ execvpe(cmd, argv, envp);
+-fail:
+ if (errno == ENOENT)
+ errx(1, "%s: command not found", cmd);
+ err(1, "%s", cmd);
+diff --git a/usr.bin/doas/doas.h b/usr.bin/doas/doas.h
+index 0b3585822eb..63254dabfca 100644
+--- a/usr.bin/doas/doas.h
++++ b/usr.bin/doas/doas.h
+@@ -29,13 +29,17 @@ extern struct rule **rules;
+ extern size_t nrules;
+ extern int parse_errors;
+
+-extern const char *formerpath;
++extern const char *safepath;
+
+ struct passwd;
+
+ char **prepenv(const struct rule *, const struct passwd *,
+ const struct passwd *);
+
++int openpersist(int *valid);
++int setpersist(int fd);
++int clearpersist(void);
++
+ #define PERMIT 1
+ #define DENY 2
+
+diff --git a/usr.bin/doas/env.c b/usr.bin/doas/env.c
+index 2d93a4089b6..dc9be691955 100644
+--- a/usr.bin/doas/env.c
++++ b/usr.bin/doas/env.c
+@@ -28,7 +28,7 @@
+
+ #include "doas.h"
+
+-const char *formerpath;
++const char *safepath = "/bin";
+
+ struct envnode {
+ RB_ENTRY(envnode) node;
+@@ -103,7 +103,7 @@ createenv(const struct rule *rule, const struct passwd *mypw,
+ addnode(env, "DOAS_USER", mypw->pw_name);
+ addnode(env, "HOME", targpw->pw_dir);
+ addnode(env, "LOGNAME", targpw->pw_name);
+- addnode(env, "PATH", getenv("PATH"));
++ addnode(env, "PATH", safepath);
+ addnode(env, "SHELL", targpw->pw_shell);
+ addnode(env, "USER", targpw->pw_name);
+
+@@ -200,17 +200,10 @@ fillenv(struct env *env, const char **envlist)
+ /* assign value or inherit from environ */
+ if (eq) {
+ val = eq + 1;
+- if (*val == '$') {
+- if (strcmp(val + 1, "PATH") == 0)
+- val = formerpath;
+- else
+- val = getenv(val + 1);
+- }
++ if (*val == '$')
++ val = getenv(val + 1);
+ } else {
+- if (strcmp(name, "PATH") == 0)
+- val = formerpath;
+- else
+- val = getenv(name);
++ val = getenv(name);
+ }
+ /* at last, we have something to insert */
+ if (val) {
+diff --git a/usr.bin/doas/parse.y b/usr.bin/doas/parse.y
+index eaaf8c4b2e6..587fd2c93a8 100644
+--- a/usr.bin/doas/parse.y
++++ b/usr.bin/doas/parse.y
+@@ -19,6 +19,7 @@
+ #include <sys/types.h>
+ #include <ctype.h>
+ #include <unistd.h>
++#include <stdlib.h>
+ #include <stdint.h>
+ #include <stdarg.h>
+ #include <stdio.h>
+diff --git a/usr.bin/doas/persist.c b/usr.bin/doas/persist.c
+new file mode 100644
+index 00000000000..4ad1bf1efbf
+--- /dev/null
++++ b/usr.bin/doas/persist.c
+@@ -0,0 +1,133 @@
++#include <errno.h>
++#include <fcntl.h>
++#include <limits.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <time.h>
++#include <unistd.h>
++
++#include "doas.h"
++
++#define PERSIST_DIR "/run/doas"
++#define PERSIST_TIMEOUT 5 * 60
++
++static int
++ttyid(dev_t *tty)
++{
++ int fd, i;
++ char buf[BUFSIZ], *p;
++ ssize_t n;
++
++ fd = open("/proc/self/stat", O_RDONLY);
++ if (fd == -1)
++ return -1;
++ n = read(fd, buf, sizeof(buf) - 1);
++ if (n >= 0)
++ buf[n] = '\0';
++ /* check that we read the whole file */
++ n = read(fd, buf, 1);
++ close(fd);
++ if (n != 0)
++ return -1;
++ p = strrchr(buf, ')');
++ if (!p)
++ return -1;
++ ++p;
++ /* ttr_nr is the 5th field after executable name, so skip the next 4 */
++ for (i = 0; i < 4; ++i) {
++ p = strchr(++p, ' ');
++ if (!p)
++ return -1;
++ }
++ *tty = strtol(p, &p, 10);
++ if (*p != ' ')
++ return -1;
++ return 0;
++}
++
++static int
++persistpath(char *buf, size_t len)
++{
++ dev_t tty;
++ int n;
++
++ if (ttyid(&tty) < 0)
++ return -1;
++ n = snprintf(buf, len, PERSIST_DIR "/%ju-%ju", (uintmax_t)getuid(), (uintmax_t)tty);
++ if (n < 0 || n >= (int)len)
++ return -1;
++ return 0;
++}
++
++int
++openpersist(int *valid)
++{
++ char path[256];
++ struct stat st;
++ struct timespec ts;
++ int fd;
++
++ if (stat(PERSIST_DIR, &st) < 0) {
++ if (errno != ENOENT)
++ return -1;
++ if (mkdir(PERSIST_DIR, 0700) < 0)
++ return -1;
++ } else if (st.st_uid != 0 || st.st_mode != (S_IFDIR | 0700)) {
++ return -1;
++ }
++ if (persistpath(path, sizeof(path)) < 0)
++ return -1;
++ fd = open(path, O_RDONLY);
++ if (fd == -1) {
++ char tmp[256];
++ struct timespec ts[2] = { { .tv_nsec = UTIME_OMIT }, { 0 } };
++ int n;
++
++ n = snprintf(tmp, sizeof(tmp), PERSIST_DIR "/.tmp-%d", getpid());
++ if (n < 0 || n >= (int)sizeof(tmp))
++ return -1;
++ fd = open(tmp, O_RDONLY | O_CREAT | O_EXCL, 0);
++ if (fd == -1)
++ return -1;
++ if (futimens(fd, ts) < 0 || rename(tmp, path) < 0) {
++ close(fd);
++ unlink(tmp);
++ return -1;
++ }
++ *valid = 0;
++ } else {
++ *valid = clock_gettime(CLOCK_BOOTTIME, &ts) == 0 &&
++ fstat(fd, &st) == 0 &&
++ (ts.tv_sec < st.st_mtim.tv_sec ||
++ (ts.tv_sec == st.st_mtim.tv_sec && ts.tv_nsec < st.st_mtim.tv_nsec)) &&
++ st.st_mtime - ts.tv_sec <= PERSIST_TIMEOUT;
++ }
++ return fd;
++}
++
++int
++setpersist(int fd)
++{
++ struct timespec times[2];
++
++ if (clock_gettime(CLOCK_BOOTTIME, ×[1]) < 0)
++ return -1;
++ times[0].tv_nsec = UTIME_OMIT;
++ times[1].tv_sec += PERSIST_TIMEOUT;
++ return futimens(fd, times);
++}
++
++int
++clearpersist(void)
++{
++ char path[256];
++
++ if (persistpath(path, sizeof(path)) < 0)
++ return -1;
++ if (unlink(path) < 0 && errno != ENOENT)
++ return -1;
++ return 0;
++}
+--
+2.31.1
+
diff --git a/pkg/openbsd/patch/0016-doas-Port-to-linux-musl.patch b/pkg/openbsd/patch/0016-doas-Port-to-linux-musl.patch
@@ -1,562 +0,0 @@
-From 9e07250958968c674c1b1041d8b2887c9e1edfc3 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Sun, 26 Feb 2017 16:50:55 -0800
-Subject: [PATCH] doas: Port to linux/musl
-
-Remove -a login style option and BSD authentication. Instead, compare
-against shadow file.
-
-Use timestamp files in /run/doas instead of TIOC*VERAUTH to implement
-persist.
-
-Use initgroups/setgid/setuid instead of setusercontext.
-
-Provide UID_MAX and GID_MAX defaults.
-
-Use LOGIN_NAME_MAX instead of _PW_NAME_LEN.
-
-Remove call to closefrom.
-
-Replace calls to errc with err after setting errno.
-
-Call openlog at start to set syslog identity.
-
-Remove unveil/pledge since they aren't supported on Linux.
-
-Simplify handling of PATH in the environment since we don't have
-login.conf with per-user default PATH.
----
- usr.bin/doas/doas.1 | 9 ---
- usr.bin/doas/doas.c | 158 ++++++++++++++---------------------------
- usr.bin/doas/doas.h | 6 +-
- usr.bin/doas/env.c | 17 ++---
- usr.bin/doas/parse.y | 1 +
- usr.bin/doas/persist.c | 133 ++++++++++++++++++++++++++++++++++
- 6 files changed, 196 insertions(+), 128 deletions(-)
- create mode 100644 usr.bin/doas/persist.c
-
-diff --git a/usr.bin/doas/doas.1 b/usr.bin/doas/doas.1
-index fc769bdb336..c7196e347a9 100644
---- a/usr.bin/doas/doas.1
-+++ b/usr.bin/doas/doas.1
-@@ -22,7 +22,6 @@
- .Sh SYNOPSIS
- .Nm doas
- .Op Fl Lns
--.Op Fl a Ar style
- .Op Fl C Ar config
- .Op Fl u Ar user
- .Ar command
-@@ -67,14 +66,6 @@ The working directory is not changed.
- .Pp
- The options are as follows:
- .Bl -tag -width tenletters
--.It Fl a Ar style
--Use the specified authentication style when validating the user,
--as allowed by
--.Pa /etc/login.conf .
--A list of doas-specific authentication methods may be configured by adding an
--.Sq auth-doas
--entry in
--.Xr login.conf 5 .
- .It Fl C Ar config
- Parse and check the configuration file
- .Ar config ,
-diff --git a/usr.bin/doas/doas.c b/usr.bin/doas/doas.c
-index a723c67a3eb..8b0c2931f92 100644
---- a/usr.bin/doas/doas.c
-+++ b/usr.bin/doas/doas.c
-@@ -20,8 +20,6 @@
- #include <sys/ioctl.h>
-
- #include <limits.h>
--#include <login_cap.h>
--#include <bsd_auth.h>
- #include <readpassphrase.h>
- #include <string.h>
- #include <stdio.h>
-@@ -33,13 +31,22 @@
- #include <syslog.h>
- #include <errno.h>
- #include <fcntl.h>
-+#include <shadow.h>
-
- #include "doas.h"
-
-+#ifndef UID_MAX
-+#define UID_MAX 65535
-+#endif
-+
-+#ifndef GID_MAX
-+#define GID_MAX 65535
-+#endif
-+
- static void __dead
- usage(void)
- {
-- fprintf(stderr, "usage: doas [-Lns] [-a style] [-C config] [-u user]"
-+ fprintf(stderr, "usage: doas [-Lns] [-C config] [-u user]"
- " command [args]\n");
- exit(1);
- }
-@@ -197,23 +204,36 @@ checkconfig(const char *confpath, int argc, char **argv,
- }
- }
-
-+static int
-+verifypasswd(const char *user, const char *pass)
-+{
-+ struct spwd *sp;
-+ char *p1, *p2;
-+
-+ sp = getspnam(user);
-+ if (!sp)
-+ return 0;
-+ p1 = sp->sp_pwdp;
-+ if (p1[0] == '!' || p1[0] == '*')
-+ return 0;
-+ p2 = crypt(pass, p1);
-+ if (!p2)
-+ return 0;
-+ return strcmp(p1, p2) == 0;
-+}
-+
- static void
--authuser(char *myname, char *login_style, int persist)
-+authuser(char *myname, int persist)
- {
- char *challenge = NULL, *response, rbuf[1024], cbuf[128];
-- auth_session_t *as;
-- int fd = -1;
-+ int fd = -1, valid = 0;
-
-- if (persist)
-- fd = open("/dev/tty", O_RDWR);
-- if (fd != -1) {
-- if (ioctl(fd, TIOCCHKVERAUTH) == 0)
-+ if (persist) {
-+ fd = openpersist(&valid);
-+ if (valid)
- goto good;
- }
-
-- if (!(as = auth_userchallenge(myname, login_style, "auth-doas",
-- &challenge)))
-- errx(1, "Authorization failed");
- if (!challenge) {
- char host[HOST_NAME_MAX + 1];
- if (gethostname(host, sizeof(host)))
-@@ -225,75 +245,31 @@ authuser(char *myname, char *login_style, int persist)
- response = readpassphrase(challenge, rbuf, sizeof(rbuf),
- RPP_REQUIRE_TTY);
- if (response == NULL && errno == ENOTTY) {
-- syslog(LOG_AUTHPRIV | LOG_NOTICE,
-- "tty required for %s", myname);
-+ syslog(LOG_NOTICE, "tty required for %s", myname);
- errx(1, "a tty is required");
- }
-- if (!auth_userresponse(as, response, 0)) {
-+ if (!verifypasswd(myname, response)) {
- explicit_bzero(rbuf, sizeof(rbuf));
-- syslog(LOG_AUTHPRIV | LOG_NOTICE,
-- "failed auth for %s", myname);
-+ syslog(LOG_NOTICE, "failed auth for %s", myname);
- errx(1, "Authorization failed");
- }
- explicit_bzero(rbuf, sizeof(rbuf));
- good:
- if (fd != -1) {
-- int secs = 5 * 60;
-- ioctl(fd, TIOCSETVERAUTH, &secs);
-+ setpersist(fd);
- close(fd);
- }
- }
-
--int
--unveilcommands(const char *ipath, const char *cmd)
--{
-- char *path = NULL, *p;
-- int unveils = 0;
--
-- if (strchr(cmd, '/') != NULL) {
-- if (unveil(cmd, "x") != -1)
-- unveils++;
-- goto done;
-- }
--
-- if (!ipath) {
-- errno = ENOENT;
-- goto done;
-- }
-- path = strdup(ipath);
-- if (!path) {
-- errno = ENOENT;
-- goto done;
-- }
-- for (p = path; p && *p; ) {
-- char buf[PATH_MAX];
-- char *cp = strsep(&p, ":");
--
-- if (cp) {
-- int r = snprintf(buf, sizeof buf, "%s/%s", cp, cmd);
-- if (r >= 0 && r < sizeof buf) {
-- if (unveil(buf, "x") != -1)
-- unveils++;
-- }
-- }
-- }
--done:
-- free(path);
-- return (unveils);
--}
--
- int
- main(int argc, char **argv)
- {
-- const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:"
-- "/usr/local/bin:/usr/local/sbin";
- const char *confpath = NULL;
- char *shargv[] = { NULL, NULL };
- char *sh;
-- const char *p;
- const char *cmd;
- char cmdline[LINE_MAX];
-- char mypwbuf[_PW_BUF_LEN], targpwbuf[_PW_BUF_LEN];
-+ char mypwbuf[1024], targpwbuf[1024];
- struct passwd mypwstore, targpwstore;
- struct passwd *mypw, *targpw;
- const struct rule *rule;
-@@ -306,28 +282,20 @@ main(int argc, char **argv)
- int nflag = 0;
- char cwdpath[PATH_MAX];
- const char *cwd;
-- char *login_style = NULL;
- char **envp;
-
- setprogname("doas");
--
-- closefrom(STDERR_FILENO + 1);
-+ openlog("doas", 0, LOG_AUTHPRIV);
-
- uid = getuid();
-
-- while ((ch = getopt(argc, argv, "a:C:Lnsu:")) != -1) {
-+ while ((ch = getopt(argc, argv, "C:Lnsu:")) != -1) {
- switch (ch) {
-- case 'a':
-- login_style = optarg;
-- break;
- case 'C':
- confpath = optarg;
- break;
- case 'L':
-- i = open("/dev/tty", O_RDWR);
-- if (i != -1)
-- ioctl(i, TIOCCLRVERAUTH);
-- exit(i == -1);
-+ exit(clearpersist() != 0);
- case 'u':
- if (parseuid(optarg, &target) != 0)
- errx(1, "unknown user");
-@@ -395,47 +363,30 @@ main(int argc, char **argv)
- cmd = argv[0];
- if (!permit(uid, groups, ngroups, &rule, target, cmd,
- (const char **)argv + 1)) {
-- syslog(LOG_AUTHPRIV | LOG_NOTICE,
-- "failed command for %s: %s", mypw->pw_name, cmdline);
-- errc(1, EPERM, NULL);
-+ syslog(LOG_NOTICE, "failed command for %s: %s", mypw->pw_name, cmdline);
-+ errno = EPERM;
-+ err(1, NULL);
- }
-
- if (!(rule->options & NOPASS)) {
- if (nflag)
- errx(1, "Authorization required");
-
-- authuser(mypw->pw_name, login_style, rule->options & PERSIST);
-+ authuser(mypw->pw_name, rule->options & PERSIST);
- }
-
-- if ((p = getenv("PATH")) != NULL)
-- formerpath = strdup(p);
-- if (formerpath == NULL)
-- formerpath = "";
--
-- if (unveil(_PATH_LOGIN_CONF, "r") == -1 ||
-- unveil(_PATH_LOGIN_CONF ".db", "r") == -1)
-- err(1, "unveil");
-- if (rule->cmd) {
-- if (setenv("PATH", safepath, 1) == -1)
-- err(1, "failed to set PATH '%s'", safepath);
-- }
-- if (unveilcommands(getenv("PATH"), cmd) == 0)
-- goto fail;
--
-- if (pledge("stdio rpath getpw exec id", NULL) == -1)
-- err(1, "pledge");
--
- rv = getpwuid_r(target, &targpwstore, targpwbuf, sizeof(targpwbuf), &targpw);
- if (rv != 0)
- err(1, "getpwuid_r failed");
- if (targpw == NULL)
- errx(1, "no passwd entry for target");
-
-- if (setusercontext(NULL, targpw, target, LOGIN_SETGROUP |
-- LOGIN_SETPATH |
-- LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK |
-- LOGIN_SETUSER) != 0)
-- errx(1, "failed to set user context for target");
-+ if (initgroups(targpw->pw_name, targpw->pw_gid) == -1)
-+ err(1, "initgroups");
-+ if (setgid(targpw->pw_gid) == -1)
-+ err(1, "setgid");
-+ if (setuid(targpw->pw_uid) == -1)
-+ err(1, "setuid");
-
- if (pledge("stdio rpath exec", NULL) == -1)
- err(1, "pledge");
-@@ -448,21 +399,16 @@ main(int argc, char **argv)
- if (pledge("stdio exec", NULL) == -1)
- err(1, "pledge");
-
-- syslog(LOG_AUTHPRIV | LOG_INFO, "%s ran command %s as %s from %s",
-+ syslog(LOG_INFO, "%s ran command %s as %s from %s",
- mypw->pw_name, cmdline, targpw->pw_name, cwd);
-
- envp = prepenv(rule, mypw, targpw);
-
-- /* setusercontext set path for the next process, so reset it for us */
- if (rule->cmd) {
- if (setenv("PATH", safepath, 1) == -1)
- err(1, "failed to set PATH '%s'", safepath);
-- } else {
-- if (setenv("PATH", formerpath, 1) == -1)
-- err(1, "failed to set PATH '%s'", formerpath);
- }
- execvpe(cmd, argv, envp);
--fail:
- if (errno == ENOENT)
- errx(1, "%s: command not found", cmd);
- err(1, "%s", cmd);
-diff --git a/usr.bin/doas/doas.h b/usr.bin/doas/doas.h
-index 6f50fc22869..4e4e74476c1 100644
---- a/usr.bin/doas/doas.h
-+++ b/usr.bin/doas/doas.h
-@@ -29,13 +29,17 @@ extern struct rule **rules;
- extern int nrules;
- extern int parse_errors;
-
--extern const char *formerpath;
-+extern const char *safepath;
-
- struct passwd;
-
- char **prepenv(const struct rule *, const struct passwd *,
- const struct passwd *);
-
-+int openpersist(int *valid);
-+int setpersist(int fd);
-+int clearpersist(void);
-+
- #define PERMIT 1
- #define DENY 2
-
-diff --git a/usr.bin/doas/env.c b/usr.bin/doas/env.c
-index 2d93a4089b6..dc9be691955 100644
---- a/usr.bin/doas/env.c
-+++ b/usr.bin/doas/env.c
-@@ -28,7 +28,7 @@
-
- #include "doas.h"
-
--const char *formerpath;
-+const char *safepath = "/bin";
-
- struct envnode {
- RB_ENTRY(envnode) node;
-@@ -103,7 +103,7 @@ createenv(const struct rule *rule, const struct passwd *mypw,
- addnode(env, "DOAS_USER", mypw->pw_name);
- addnode(env, "HOME", targpw->pw_dir);
- addnode(env, "LOGNAME", targpw->pw_name);
-- addnode(env, "PATH", getenv("PATH"));
-+ addnode(env, "PATH", safepath);
- addnode(env, "SHELL", targpw->pw_shell);
- addnode(env, "USER", targpw->pw_name);
-
-@@ -200,17 +200,10 @@ fillenv(struct env *env, const char **envlist)
- /* assign value or inherit from environ */
- if (eq) {
- val = eq + 1;
-- if (*val == '$') {
-- if (strcmp(val + 1, "PATH") == 0)
-- val = formerpath;
-- else
-- val = getenv(val + 1);
-- }
-+ if (*val == '$')
-+ val = getenv(val + 1);
- } else {
-- if (strcmp(name, "PATH") == 0)
-- val = formerpath;
-- else
-- val = getenv(name);
-+ val = getenv(name);
- }
- /* at last, we have something to insert */
- if (val) {
-diff --git a/usr.bin/doas/parse.y b/usr.bin/doas/parse.y
-index dd9466e5f13..d1f698c7679 100644
---- a/usr.bin/doas/parse.y
-+++ b/usr.bin/doas/parse.y
-@@ -19,6 +19,7 @@
- #include <sys/types.h>
- #include <ctype.h>
- #include <unistd.h>
-+#include <stdlib.h>
- #include <stdint.h>
- #include <stdarg.h>
- #include <stdio.h>
-diff --git a/usr.bin/doas/persist.c b/usr.bin/doas/persist.c
-new file mode 100644
-index 00000000000..4ad1bf1efbf
---- /dev/null
-+++ b/usr.bin/doas/persist.c
-@@ -0,0 +1,133 @@
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <limits.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#include <time.h>
-+#include <unistd.h>
-+
-+#include "doas.h"
-+
-+#define PERSIST_DIR "/run/doas"
-+#define PERSIST_TIMEOUT 5 * 60
-+
-+static int
-+ttyid(dev_t *tty)
-+{
-+ int fd, i;
-+ char buf[BUFSIZ], *p;
-+ ssize_t n;
-+
-+ fd = open("/proc/self/stat", O_RDONLY);
-+ if (fd == -1)
-+ return -1;
-+ n = read(fd, buf, sizeof(buf) - 1);
-+ if (n >= 0)
-+ buf[n] = '\0';
-+ /* check that we read the whole file */
-+ n = read(fd, buf, 1);
-+ close(fd);
-+ if (n != 0)
-+ return -1;
-+ p = strrchr(buf, ')');
-+ if (!p)
-+ return -1;
-+ ++p;
-+ /* ttr_nr is the 5th field after executable name, so skip the next 4 */
-+ for (i = 0; i < 4; ++i) {
-+ p = strchr(++p, ' ');
-+ if (!p)
-+ return -1;
-+ }
-+ *tty = strtol(p, &p, 10);
-+ if (*p != ' ')
-+ return -1;
-+ return 0;
-+}
-+
-+static int
-+persistpath(char *buf, size_t len)
-+{
-+ dev_t tty;
-+ int n;
-+
-+ if (ttyid(&tty) < 0)
-+ return -1;
-+ n = snprintf(buf, len, PERSIST_DIR "/%ju-%ju", (uintmax_t)getuid(), (uintmax_t)tty);
-+ if (n < 0 || n >= (int)len)
-+ return -1;
-+ return 0;
-+}
-+
-+int
-+openpersist(int *valid)
-+{
-+ char path[256];
-+ struct stat st;
-+ struct timespec ts;
-+ int fd;
-+
-+ if (stat(PERSIST_DIR, &st) < 0) {
-+ if (errno != ENOENT)
-+ return -1;
-+ if (mkdir(PERSIST_DIR, 0700) < 0)
-+ return -1;
-+ } else if (st.st_uid != 0 || st.st_mode != (S_IFDIR | 0700)) {
-+ return -1;
-+ }
-+ if (persistpath(path, sizeof(path)) < 0)
-+ return -1;
-+ fd = open(path, O_RDONLY);
-+ if (fd == -1) {
-+ char tmp[256];
-+ struct timespec ts[2] = { { .tv_nsec = UTIME_OMIT }, { 0 } };
-+ int n;
-+
-+ n = snprintf(tmp, sizeof(tmp), PERSIST_DIR "/.tmp-%d", getpid());
-+ if (n < 0 || n >= (int)sizeof(tmp))
-+ return -1;
-+ fd = open(tmp, O_RDONLY | O_CREAT | O_EXCL, 0);
-+ if (fd == -1)
-+ return -1;
-+ if (futimens(fd, ts) < 0 || rename(tmp, path) < 0) {
-+ close(fd);
-+ unlink(tmp);
-+ return -1;
-+ }
-+ *valid = 0;
-+ } else {
-+ *valid = clock_gettime(CLOCK_BOOTTIME, &ts) == 0 &&
-+ fstat(fd, &st) == 0 &&
-+ (ts.tv_sec < st.st_mtim.tv_sec ||
-+ (ts.tv_sec == st.st_mtim.tv_sec && ts.tv_nsec < st.st_mtim.tv_nsec)) &&
-+ st.st_mtime - ts.tv_sec <= PERSIST_TIMEOUT;
-+ }
-+ return fd;
-+}
-+
-+int
-+setpersist(int fd)
-+{
-+ struct timespec times[2];
-+
-+ if (clock_gettime(CLOCK_BOOTTIME, ×[1]) < 0)
-+ return -1;
-+ times[0].tv_nsec = UTIME_OMIT;
-+ times[1].tv_sec += PERSIST_TIMEOUT;
-+ return futimens(fd, times);
-+}
-+
-+int
-+clearpersist(void)
-+{
-+ char path[256];
-+
-+ if (persistpath(path, sizeof(path)) < 0)
-+ return -1;
-+ if (unlink(path) < 0 && errno != ENOENT)
-+ return -1;
-+ return 0;
-+}
---
-2.30.1
-
diff --git a/pkg/openbsd/patch/0017-pwcache-Don-t-use-fixed-buffer-sizes.patch b/pkg/openbsd/patch/0016-pwcache-Don-t-use-fixed-buffer-sizes.patch
diff --git a/pkg/openbsd/patch/0018-Add-standalone-freezero.patch b/pkg/openbsd/patch/0017-Add-standalone-freezero.patch
diff --git a/pkg/openbsd/patch/0019-m4-Use-hand-written-lexer-to-avoid-cycle-in-bootstra.patch b/pkg/openbsd/patch/0018-m4-Use-hand-written-lexer-to-avoid-cycle-in-bootstra.patch
diff --git a/pkg/openbsd/patch/0020-m4-Use-_Noreturn-instead-of-__dead.patch b/pkg/openbsd/patch/0019-m4-Use-_Noreturn-instead-of-__dead.patch
diff --git a/pkg/openbsd/patch/0021-m4-Add-missing-includes.patch b/pkg/openbsd/patch/0020-m4-Add-missing-includes.patch
diff --git a/pkg/openbsd/patch/0022-libutil-Add-missing-includes.patch b/pkg/openbsd/patch/0021-libutil-Add-missing-includes.patch
diff --git a/pkg/openbsd/patch/0023-acme-client-Add-missing-includes.patch b/pkg/openbsd/patch/0022-acme-client-Add-missing-includes.patch
diff --git a/pkg/openbsd/patch/0024-rsync-Add-missing-includes.patch b/pkg/openbsd/patch/0023-rsync-Add-missing-includes.patch
diff --git a/pkg/openbsd/patch/0025-rsync-Use-standard-S_ISVTX-instead-of-S_ISTXT.patch b/pkg/openbsd/patch/0024-rsync-Use-standard-S_ISVTX-instead-of-S_ISTXT.patch
diff --git a/pkg/openbsd/patch/0025-rsync-Avoid-pointer-arithmetic-on-void.patch b/pkg/openbsd/patch/0025-rsync-Avoid-pointer-arithmetic-on-void.patch
@@ -0,0 +1,149 @@
+From 56fcd604ca9bf0ae936307c3e56d232a3daef919 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Sat, 15 Jun 2019 20:06:13 -0700
+Subject: [PATCH] rsync: Avoid pointer arithmetic on `void *`
+
+---
+ usr.bin/rsync/blocks.c | 8 ++++----
+ usr.bin/rsync/downloader.c | 2 +-
+ usr.bin/rsync/io.c | 12 ++++++------
+ usr.bin/rsync/sender.c | 5 +++--
+ 4 files changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/usr.bin/rsync/blocks.c b/usr.bin/rsync/blocks.c
+index 4f21a41833d..242590e5bae 100644
+--- a/usr.bin/rsync/blocks.c
++++ b/usr.bin/rsync/blocks.c
+@@ -157,7 +157,7 @@ blk_find(struct sess *sess, struct blkstat *st,
+ if (!recomp) {
+ fhash = (st->s1 & 0xFFFF) | (st->s2 << 16);
+ } else {
+- fhash = hash_fast(st->map + st->offs, (size_t)osz);
++ fhash = hash_fast((char *)st->map + st->offs, (size_t)osz);
+ st->s1 = fhash & 0xFFFF;
+ st->s2 = fhash >> 16;
+ }
+@@ -170,7 +170,7 @@ blk_find(struct sess *sess, struct blkstat *st,
+ if (st->hint < blks->blksz &&
+ fhash == blks->blks[st->hint].chksum_short &&
+ (size_t)osz == blks->blks[st->hint].len) {
+- hash_slow(st->map + st->offs, (size_t)osz, md, sess);
++ hash_slow((char *)st->map + st->offs, (size_t)osz, md, sess);
+ have_md = 1;
+ if (memcmp(md, blks->blks[st->hint].chksum_long, blks->csum) == 0) {
+ LOG4("%s: found matching hinted match: "
+@@ -203,7 +203,7 @@ blk_find(struct sess *sess, struct blkstat *st,
+ (intmax_t)ent->blk->offs, ent->blk->len);
+
+ if (have_md == 0) {
+- hash_slow(st->map + st->offs, (size_t)osz, md, sess);
++ hash_slow((char *)st->map + st->offs, (size_t)osz, md, sess);
+ have_md = 1;
+ }
+
+@@ -221,7 +221,7 @@ blk_find(struct sess *sess, struct blkstat *st,
+ * block in the sequence.
+ */
+
+- map = st->map + st->offs;
++ map = (char *)st->map + st->offs;
+ st->s1 -= map[0];
+ st->s2 -= osz * map[0];
+
+diff --git a/usr.bin/rsync/downloader.c b/usr.bin/rsync/downloader.c
+index 9ddb8600a73..36b086f74c8 100644
+--- a/usr.bin/rsync/downloader.c
++++ b/usr.bin/rsync/downloader.c
+@@ -495,7 +495,7 @@ again:
+ sz = tok == p->blk.blksz - 1 ? p->blk.rem : p->blk.len;
+ assert(sz);
+ assert(p->map != MAP_FAILED);
+- buf = p->map + (tok * p->blk.len);
++ buf = (char *)p->map + (tok * p->blk.len);
+
+ /*
+ * Now we read from our block.
+diff --git a/usr.bin/rsync/io.c b/usr.bin/rsync/io.c
+index 27beba693d4..847af4c4c1b 100644
+--- a/usr.bin/rsync/io.c
++++ b/usr.bin/rsync/io.c
+@@ -117,7 +117,7 @@ io_write_blocking(int fd, const void *buf, size_t sz)
+ ERRX("io_write_nonblocking: short write");
+ return 0;
+ }
+- buf += wsz;
++ buf = (char *)buf + wsz;
+ sz -= wsz;
+ }
+
+@@ -156,7 +156,7 @@ io_write_buf(struct sess *sess, int fd, const void *buf, size_t sz)
+ }
+ sess->total_write += wsz;
+ sz -= wsz;
+- buf += wsz;
++ buf = (char *)buf + wsz;
+ }
+
+ return 1;
+@@ -250,7 +250,7 @@ io_read_blocking(int fd, void *buf, size_t sz)
+ ERRX("io_read_nonblocking: short read");
+ return 0;
+ }
+- buf += rsz;
++ buf = (char *)buf + rsz;
+ sz -= rsz;
+ }
+
+@@ -367,7 +367,7 @@ io_read_buf(struct sess *sess, int fd, void *buf, size_t sz)
+ }
+ sz -= rsz;
+ sess->mplex_read_remain -= rsz;
+- buf += rsz;
++ buf = (char *)buf + rsz;
+ sess->total_read += rsz;
+ continue;
+ }
+@@ -463,7 +463,7 @@ io_buffer_buf(void *buf, size_t *bufpos, size_t buflen, const void *val,
+ {
+
+ assert(*bufpos + valsz <= buflen);
+- memcpy(buf + *bufpos, val, valsz);
++ memcpy((char *)buf + *bufpos, val, valsz);
+ *bufpos += valsz;
+ }
+
+@@ -661,7 +661,7 @@ io_unbuffer_buf(const void *buf, size_t *bufpos, size_t bufsz, void *val,
+ {
+
+ assert(*bufpos + valsz <= bufsz);
+- memcpy(val, buf + *bufpos, valsz);
++ memcpy(val, (char *)buf + *bufpos, valsz);
+ *bufpos += valsz;
+ }
+
+diff --git a/usr.bin/rsync/sender.c b/usr.bin/rsync/sender.c
+index 00add6b4e6c..0ac8226816f 100644
+--- a/usr.bin/rsync/sender.c
++++ b/usr.bin/rsync/sender.c
+@@ -128,7 +128,7 @@ send_up_fsm(struct sess *sess, size_t *phase,
+ return 0;
+ }
+ io_lowbuffer_buf(sess, *wb, &pos, *wbsz,
+- up->stat.map + up->stat.curpos, sz);
++ (char *)up->stat.map + up->stat.curpos, sz);
+
+ up->stat.curpos += sz;
+ if (up->stat.curpos == up->stat.curlen)
+@@ -568,7 +568,8 @@ rsync_sender(struct sess *sess, int fdin,
+ if ((pfd[1].revents & POLLOUT) && wbufsz > 0) {
+ assert(pfd[2].fd == -1);
+ assert(wbufsz - wbufpos);
+- ssz = write(fdout, wbuf + wbufpos, wbufsz - wbufpos);
++ ssz = write(fdout,
++ (char *)wbuf + wbufpos, wbufsz - wbufpos);
+ if (ssz == -1) {
+ ERR("write");
+ goto out;
+--
+2.31.1
+
diff --git a/pkg/openbsd/patch/0028-Include-sys-sysmacros.h-if-necessary.patch b/pkg/openbsd/patch/0026-Include-sys-sysmacros.h-if-necessary.patch
diff --git a/pkg/openbsd/patch/0026-rsync-Use-1-instead-of-INFTIM-for-poll-timeout.patch b/pkg/openbsd/patch/0026-rsync-Use-1-instead-of-INFTIM-for-poll-timeout.patch
@@ -1,25 +0,0 @@
-From 588522657724047a2e4c838e62dfff5db41bd506 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Fri, 14 Jun 2019 12:44:02 -0700
-Subject: [PATCH] rsync: Use -1 instead of INFTIM for poll timeout
-
----
- usr.bin/rsync/extern.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/usr.bin/rsync/extern.h b/usr.bin/rsync/extern.h
-index 040588003a4..64a02349adc 100644
---- a/usr.bin/rsync/extern.h
-+++ b/usr.bin/rsync/extern.h
-@@ -47,7 +47,7 @@
- * Use this for debugging deadlocks.
- * All poll events will use it and catch time-outs.
- */
--#define POLL_TIMEOUT (INFTIM)
-+#define POLL_TIMEOUT (-1)
-
- /*
- * Operating mode for a client or a server.
---
-2.22.0
-
diff --git a/pkg/openbsd/patch/0029-nc-Portability-fixes-from-libressl-portable.patch b/pkg/openbsd/patch/0027-nc-Portability-fixes-from-libressl-portable.patch
diff --git a/pkg/openbsd/patch/0027-rsync-Avoid-pointer-arithmetic-on-void.patch b/pkg/openbsd/patch/0027-rsync-Avoid-pointer-arithmetic-on-void.patch
@@ -1,148 +0,0 @@
-From bae6ab2cb50b4c5784dcd17207f145707c77f317 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Sat, 15 Jun 2019 20:06:13 -0700
-Subject: [PATCH] rsync: Avoid pointer arithmetic on `void *`
-
----
- usr.bin/rsync/blocks.c | 8 ++++----
- usr.bin/rsync/downloader.c | 2 +-
- usr.bin/rsync/io.c | 12 ++++++------
- usr.bin/rsync/sender.c | 4 ++--
- 4 files changed, 13 insertions(+), 13 deletions(-)
-
-diff --git a/usr.bin/rsync/blocks.c b/usr.bin/rsync/blocks.c
-index 4f21a41833d..242590e5bae 100644
---- a/usr.bin/rsync/blocks.c
-+++ b/usr.bin/rsync/blocks.c
-@@ -157,7 +157,7 @@ blk_find(struct sess *sess, struct blkstat *st,
- if (!recomp) {
- fhash = (st->s1 & 0xFFFF) | (st->s2 << 16);
- } else {
-- fhash = hash_fast(st->map + st->offs, (size_t)osz);
-+ fhash = hash_fast((char *)st->map + st->offs, (size_t)osz);
- st->s1 = fhash & 0xFFFF;
- st->s2 = fhash >> 16;
- }
-@@ -170,7 +170,7 @@ blk_find(struct sess *sess, struct blkstat *st,
- if (st->hint < blks->blksz &&
- fhash == blks->blks[st->hint].chksum_short &&
- (size_t)osz == blks->blks[st->hint].len) {
-- hash_slow(st->map + st->offs, (size_t)osz, md, sess);
-+ hash_slow((char *)st->map + st->offs, (size_t)osz, md, sess);
- have_md = 1;
- if (memcmp(md, blks->blks[st->hint].chksum_long, blks->csum) == 0) {
- LOG4("%s: found matching hinted match: "
-@@ -203,7 +203,7 @@ blk_find(struct sess *sess, struct blkstat *st,
- (intmax_t)ent->blk->offs, ent->blk->len);
-
- if (have_md == 0) {
-- hash_slow(st->map + st->offs, (size_t)osz, md, sess);
-+ hash_slow((char *)st->map + st->offs, (size_t)osz, md, sess);
- have_md = 1;
- }
-
-@@ -221,7 +221,7 @@ blk_find(struct sess *sess, struct blkstat *st,
- * block in the sequence.
- */
-
-- map = st->map + st->offs;
-+ map = (char *)st->map + st->offs;
- st->s1 -= map[0];
- st->s2 -= osz * map[0];
-
-diff --git a/usr.bin/rsync/downloader.c b/usr.bin/rsync/downloader.c
-index 9ddb8600a73..36b086f74c8 100644
---- a/usr.bin/rsync/downloader.c
-+++ b/usr.bin/rsync/downloader.c
-@@ -495,7 +495,7 @@ again:
- sz = tok == p->blk.blksz - 1 ? p->blk.rem : p->blk.len;
- assert(sz);
- assert(p->map != MAP_FAILED);
-- buf = p->map + (tok * p->blk.len);
-+ buf = (char *)p->map + (tok * p->blk.len);
-
- /*
- * Now we read from our block.
-diff --git a/usr.bin/rsync/io.c b/usr.bin/rsync/io.c
-index 8d113d6d013..181458ced08 100644
---- a/usr.bin/rsync/io.c
-+++ b/usr.bin/rsync/io.c
-@@ -117,7 +117,7 @@ io_write_blocking(int fd, const void *buf, size_t sz)
- ERRX("io_write_nonblocking: short write");
- return 0;
- }
-- buf += wsz;
-+ buf = (char *)buf + wsz;
- sz -= wsz;
- }
-
-@@ -156,7 +156,7 @@ io_write_buf(struct sess *sess, int fd, const void *buf, size_t sz)
- }
- sess->total_write += wsz;
- sz -= wsz;
-- buf += wsz;
-+ buf = (char *)buf + wsz;
- }
-
- return 1;
-@@ -250,7 +250,7 @@ io_read_blocking(int fd, void *buf, size_t sz)
- ERRX("io_read_nonblocking: short read");
- return 0;
- }
-- buf += rsz;
-+ buf = (char *)buf + rsz;
- sz -= rsz;
- }
-
-@@ -367,7 +367,7 @@ io_read_buf(struct sess *sess, int fd, void *buf, size_t sz)
- }
- sz -= rsz;
- sess->mplex_read_remain -= rsz;
-- buf += rsz;
-+ buf = (char *)buf + rsz;
- sess->total_read += rsz;
- continue;
- }
-@@ -463,7 +463,7 @@ io_buffer_buf(void *buf, size_t *bufpos, size_t buflen, const void *val,
- {
-
- assert(*bufpos + valsz <= buflen);
-- memcpy(buf + *bufpos, val, valsz);
-+ memcpy((char *)buf + *bufpos, val, valsz);
- *bufpos += valsz;
- }
-
-@@ -661,7 +661,7 @@ io_unbuffer_buf(const void *buf, size_t *bufpos, size_t bufsz, void *val,
- {
-
- assert(*bufpos + valsz <= bufsz);
-- memcpy(val, buf + *bufpos, valsz);
-+ memcpy(val, (char *)buf + *bufpos, valsz);
- *bufpos += valsz;
- }
-
-diff --git a/usr.bin/rsync/sender.c b/usr.bin/rsync/sender.c
-index 5f9850ee9d2..d6a1f55d1a9 100644
---- a/usr.bin/rsync/sender.c
-+++ b/usr.bin/rsync/sender.c
-@@ -128,7 +128,7 @@ send_up_fsm(struct sess *sess, size_t *phase,
- return 0;
- }
- io_lowbuffer_buf(sess, *wb, &pos, *wbsz,
-- up->stat.map + up->stat.curpos, sz);
-+ (char *)up->stat.map + up->stat.curpos, sz);
-
- up->stat.curpos += sz;
- if (up->stat.curpos == up->stat.curlen)
-@@ -569,7 +569,7 @@ rsync_sender(struct sess *sess, int fdin,
- assert(pfd[2].fd == -1);
- assert(wbufsz - wbufpos);
- ssz = write(fdout,
-- wbuf + wbufpos, wbufsz - wbufpos);
-+ (char *)wbuf + wbufpos, wbufsz - wbufpos);
- if (ssz == -1) {
- ERR("write");
- goto out;
---
-2.23.0
-
diff --git a/pkg/openbsd/patch/0030-pax-Ignore-EOPNOTSUPP-from-fchmodat.patch b/pkg/openbsd/patch/0028-pax-Ignore-EOPNOTSUPP-from-fchmodat.patch
diff --git a/pkg/openbsd/patch/0031-acme-client-Fix-build-with-old-bison-versions.patch b/pkg/openbsd/patch/0029-acme-client-Fix-build-with-old-bison-versions.patch
diff --git a/pkg/openbsd/patch/0032-rsync-Add-implementation-of-MD4.patch b/pkg/openbsd/patch/0030-rsync-Add-implementation-of-MD4.patch
diff --git a/pkg/openbsd/patch/0033-pax-Fix-some-incorrect-format-specifiers.patch b/pkg/openbsd/patch/0031-pax-Fix-some-incorrect-format-specifiers.patch
diff --git a/pkg/openbsd/patch/0034-pax-Use-memcpy-to-set-TMAGIC-and-TVERSION-to-avoid-w.patch b/pkg/openbsd/patch/0032-pax-Use-memcpy-to-set-TMAGIC-and-TVERSION-to-avoid-w.patch
diff --git a/pkg/openbsd/patch/0033-rsync-Fix-some-incorrect-format-specifiers.patch b/pkg/openbsd/patch/0033-rsync-Fix-some-incorrect-format-specifiers.patch
@@ -0,0 +1,25 @@
+From 02cf1f8b022fd8c27eeb312ee3d649f4157899d6 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Thu, 4 Jun 2020 21:36:24 -0700
+Subject: [PATCH] rsync: Fix some incorrect format specifiers
+
+---
+ usr.bin/rsync/uploader.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/usr.bin/rsync/uploader.c b/usr.bin/rsync/uploader.c
+index db8bc626ae2..d1ebb7bcf1b 100644
+--- a/usr.bin/rsync/uploader.c
++++ b/usr.bin/rsync/uploader.c
+@@ -942,7 +942,7 @@ rsync_uploader(struct upload *u, int *fileinfd,
+ init_blk(&blk.blks[i], &blk, offs, i, mbuf, sess);
+ offs += blk.len;
+ LOG3(
+- "i=%ld, offs=%lld, msz=%ld, blk.len=%lu, blk.rem=%lu",
++ "i=%zu, offs=%td, msz=%zd, blk.len=%zu, blk.rem=%zu",
+ i, offs, msz, blk.len, blk.rem);
+ i++;
+ } while (i < blk.blksz);
+--
+2.31.1
+
diff --git a/pkg/openbsd/patch/0036-m4-Declare-dopaste-only-when-it-s-used.patch b/pkg/openbsd/patch/0034-m4-Declare-dopaste-only-when-it-s-used.patch
diff --git a/pkg/openbsd/patch/0035-rsync-Fix-some-incorrect-format-specifiers.patch b/pkg/openbsd/patch/0035-rsync-Fix-some-incorrect-format-specifiers.patch
@@ -1,25 +0,0 @@
-From dbec208559b72489671f119e695a4c340a288803 Mon Sep 17 00:00:00 2001
-From: Michael Forney <mforney@mforney.org>
-Date: Thu, 4 Jun 2020 21:36:24 -0700
-Subject: [PATCH] rsync: Fix some incorrect format specifiers
-
----
- usr.bin/rsync/uploader.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/usr.bin/rsync/uploader.c b/usr.bin/rsync/uploader.c
-index 38d5d24fcc7..bf82896d221 100644
---- a/usr.bin/rsync/uploader.c
-+++ b/usr.bin/rsync/uploader.c
-@@ -945,7 +945,7 @@ rsync_uploader(struct upload *u, int *fileinfd,
- init_blk(&blk.blks[i], &blk, offs, i, mbuf, sess);
- offs += blk.len;
- LOG3(
-- "i=%ld, offs=%lld, msz=%ld, blk.len=%lu, blk.rem=%lu",
-+ "i=%zu, offs=%td, msz=%zd, blk.len=%zu, blk.rem=%zu",
- i, offs, msz, blk.len, blk.rem);
- i++;
- } while (i < blk.blksz);
---
-2.27.0
-
diff --git a/pkg/openbsd/sha256 b/pkg/openbsd/sha256
@@ -1,2 +1,2 @@
-90b76b58040f0ec9a9d08a5c979720d5d91a46f3e69fd710abd1a21b9960c226 src.tar.gz
-e2bf77273a99c8ed4030806c8546bf8dc8ece0cf31e784aed2001e8e8227a8ab sys.tar.gz
+eb06c8c1e0edf003af279ec31f7b67692dbf80aabd99dccde557be523e41761b src.tar.gz
+e1a41a8290a68ff1ffb0851606ce8edf96093b44824136b1d131d0f3a81f4993 sys.tar.gz
diff --git a/pkg/openbsd/url b/pkg/openbsd/url
@@ -1,5 +1,5 @@
remote-name
-url = "https://fastly.cdn.openbsd.org/pub/OpenBSD/6.8/src.tar.gz"
+url = "https://fastly.cdn.openbsd.org/pub/OpenBSD/6.9/src.tar.gz"
remote-name
-url = "https://fastly.cdn.openbsd.org/pub/OpenBSD/6.8/sys.tar.gz"
+url = "https://fastly.cdn.openbsd.org/pub/OpenBSD/6.9/sys.tar.gz"
diff --git a/pkg/openbsd/ver b/pkg/openbsd/ver
@@ -1 +1 @@
-6.8 r2
+6.9 r0