summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/openbsd-compat
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/openbsd-compat')
-rw-r--r--crypto/openssh/openbsd-compat/bsd-misc.c8
-rw-r--r--crypto/openssh/openbsd-compat/bsd-misc.h4
-rw-r--r--crypto/openssh/openbsd-compat/bsd-poll.h4
-rw-r--r--crypto/openssh/openbsd-compat/glob.c1
-rw-r--r--crypto/openssh/openbsd-compat/glob.h8
-rw-r--r--crypto/openssh/openbsd-compat/openbsd-compat.h1
-rw-r--r--crypto/openssh/openbsd-compat/port-solaris.c136
-rw-r--r--crypto/openssh/openbsd-compat/port-solaris.h6
-rw-r--r--crypto/openssh/openbsd-compat/realpath.c61
9 files changed, 208 insertions, 21 deletions
diff --git a/crypto/openssh/openbsd-compat/bsd-misc.c b/crypto/openssh/openbsd-compat/bsd-misc.c
index f7be415..2a788e4 100644
--- a/crypto/openssh/openbsd-compat/bsd-misc.c
+++ b/crypto/openssh/openbsd-compat/bsd-misc.c
@@ -276,3 +276,11 @@ getpgid(pid_t pid)
return -1;
}
#endif
+
+#ifndef HAVE_PLEDGE
+int
+pledge(const char *promises, const char *paths[])
+{
+ return 0;
+}
+#endif
diff --git a/crypto/openssh/openbsd-compat/bsd-misc.h b/crypto/openssh/openbsd-compat/bsd-misc.h
index ff347a2..0d81d17 100644
--- a/crypto/openssh/openbsd-compat/bsd-misc.h
+++ b/crypto/openssh/openbsd-compat/bsd-misc.h
@@ -122,4 +122,8 @@ pid_t getpgid(pid_t);
# define krb5_free_error_message(a,b) do { } while(0)
#endif
+#ifndef HAVE_PLEDGE
+int pledge(const char *promises, const char *paths[]);
+#endif
+
#endif /* _BSD_MISC_H */
diff --git a/crypto/openssh/openbsd-compat/bsd-poll.h b/crypto/openssh/openbsd-compat/bsd-poll.h
index dcbb9ca..17945f5 100644
--- a/crypto/openssh/openbsd-compat/bsd-poll.h
+++ b/crypto/openssh/openbsd-compat/bsd-poll.h
@@ -42,11 +42,11 @@ typedef unsigned int nfds_t;
#define POLLIN 0x0001
#define POLLOUT 0x0004
#define POLLERR 0x0008
+#define POLLHUP 0x0010
+#define POLLNVAL 0x0020
#if 0
/* the following are currently not implemented */
#define POLLPRI 0x0002
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
#define POLLRDNORM 0x0040
#define POLLNORM POLLRDNORM
#define POLLWRNORM POLLOUT
diff --git a/crypto/openssh/openbsd-compat/glob.c b/crypto/openssh/openbsd-compat/glob.c
index 742b4b9..7c97e67 100644
--- a/crypto/openssh/openbsd-compat/glob.c
+++ b/crypto/openssh/openbsd-compat/glob.c
@@ -59,6 +59,7 @@
*/
#include "includes.h"
+#include "glob.h"
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/crypto/openssh/openbsd-compat/glob.h b/crypto/openssh/openbsd-compat/glob.h
index f8a7fa5..f069a05 100644
--- a/crypto/openssh/openbsd-compat/glob.h
+++ b/crypto/openssh/openbsd-compat/glob.h
@@ -42,11 +42,15 @@
!defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \
defined(BROKEN_GLOB)
-#ifndef _GLOB_H_
-#define _GLOB_H_
+#ifndef _COMPAT_GLOB_H_
+#define _COMPAT_GLOB_H_
#include <sys/stat.h>
+# define glob_t _ssh_compat_glob_t
+# define glob(a, b, c, d) _ssh__compat_glob(a, b, c, d)
+# define globfree(a) _ssh__compat_globfree(a)
+
struct stat;
typedef struct {
int gl_pathc; /* Count of total paths so far. */
diff --git a/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h
index 1ff7114..8cc8a11 100644
--- a/crypto/openssh/openbsd-compat/openbsd-compat.h
+++ b/crypto/openssh/openbsd-compat/openbsd-compat.h
@@ -39,7 +39,6 @@
/* OpenBSD function replacements */
#include "base64.h"
#include "sigact.h"
-#include "glob.h"
#include "readpassphrase.h"
#include "vis.h"
#include "getrrsetbyname.h"
diff --git a/crypto/openssh/openbsd-compat/port-solaris.c b/crypto/openssh/openbsd-compat/port-solaris.c
index 25382f1..e36e412 100644
--- a/crypto/openssh/openbsd-compat/port-solaris.c
+++ b/crypto/openssh/openbsd-compat/port-solaris.c
@@ -227,3 +227,139 @@ solaris_set_default_project(struct passwd *pw)
}
}
#endif /* USE_SOLARIS_PROJECTS */
+
+#ifdef USE_SOLARIS_PRIVS
+# ifdef HAVE_PRIV_H
+# include <priv.h>
+# endif
+
+priv_set_t *
+solaris_basic_privset(void)
+{
+ priv_set_t *pset;
+
+#ifdef HAVE_PRIV_BASICSET
+ if ((pset = priv_allocset()) == NULL) {
+ error("priv_allocset: %s", strerror(errno));
+ return NULL;
+ }
+ priv_basicset(pset);
+#else
+ if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) {
+ error("priv_str_to_set: %s", strerror(errno));
+ return NULL;
+ }
+#endif
+ return pset;
+}
+
+void
+solaris_drop_privs_pinfo_net_fork_exec(void)
+{
+ priv_set_t *pset = NULL, *npset = NULL;
+
+ /*
+ * Note: this variant avoids dropping DAC filesystem rights, in case
+ * the process calling it is running as root and should have the
+ * ability to read/write/chown any file on the system.
+ *
+ * We start with the basic set, then *add* the DAC rights to it while
+ * taking away other parts of BASIC we don't need. Then we intersect
+ * this with our existing PERMITTED set. In this way we keep any
+ * DAC rights we had before, while otherwise reducing ourselves to
+ * the minimum set of privileges we need to proceed.
+ *
+ * This also means we drop any other parts of "root" that we don't
+ * need (e.g. the ability to kill any process, create new device nodes
+ * etc etc).
+ */
+
+ if ((pset = priv_allocset()) == NULL)
+ fatal("priv_allocset: %s", strerror(errno));
+ if ((npset = solaris_basic_privset()) == NULL)
+ fatal("solaris_basic_privset: %s", strerror(errno));
+
+ if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 ||
+ priv_addset(npset, PRIV_FILE_DAC_READ) != 0 ||
+ priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 ||
+ priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 ||
+ priv_addset(npset, PRIV_FILE_OWNER) != 0)
+ fatal("priv_addset: %s", strerror(errno));
+
+ if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
+ priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
+#endif
+ priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
+ priv_delset(npset, PRIV_PROC_FORK) != 0 ||
+ priv_delset(npset, PRIV_PROC_INFO) != 0 ||
+ priv_delset(npset, PRIV_PROC_SESSION) != 0)
+ fatal("priv_delset: %s", strerror(errno));
+
+ if (getppriv(PRIV_PERMITTED, pset) != 0)
+ fatal("getppriv: %s", strerror(errno));
+
+ priv_intersect(pset, npset);
+
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 ||
+ setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 ||
+ setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0)
+ fatal("setppriv: %s", strerror(errno));
+
+ priv_freeset(pset);
+ priv_freeset(npset);
+}
+
+void
+solaris_drop_privs_root_pinfo_net(void)
+{
+ priv_set_t *pset = NULL;
+
+ /* Start with "basic" and drop everything we don't need. */
+ if ((pset = solaris_basic_privset()) == NULL)
+ fatal("solaris_basic_privset: %s", strerror(errno));
+
+ if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
+ priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
+#endif
+ priv_delset(pset, PRIV_PROC_INFO) != 0 ||
+ priv_delset(pset, PRIV_PROC_SESSION) != 0)
+ fatal("priv_delset: %s", strerror(errno));
+
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
+ setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
+ setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
+ fatal("setppriv: %s", strerror(errno));
+
+ priv_freeset(pset);
+}
+
+void
+solaris_drop_privs_root_pinfo_net_exec(void)
+{
+ priv_set_t *pset = NULL;
+
+
+ /* Start with "basic" and drop everything we don't need. */
+ if ((pset = solaris_basic_privset()) == NULL)
+ fatal("solaris_basic_privset: %s", strerror(errno));
+
+ if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
+ priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
+#endif
+ priv_delset(pset, PRIV_PROC_EXEC) != 0 ||
+ priv_delset(pset, PRIV_PROC_INFO) != 0 ||
+ priv_delset(pset, PRIV_PROC_SESSION) != 0)
+ fatal("priv_delset: %s", strerror(errno));
+
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 ||
+ setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 ||
+ setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0)
+ fatal("setppriv: %s", strerror(errno));
+
+ priv_freeset(pset);
+}
+
+#endif
diff --git a/crypto/openssh/openbsd-compat/port-solaris.h b/crypto/openssh/openbsd-compat/port-solaris.h
index cd442e7..3a41ea8 100644
--- a/crypto/openssh/openbsd-compat/port-solaris.h
+++ b/crypto/openssh/openbsd-compat/port-solaris.h
@@ -26,5 +26,11 @@ void solaris_contract_pre_fork(void);
void solaris_contract_post_fork_child(void);
void solaris_contract_post_fork_parent(pid_t pid);
void solaris_set_default_project(struct passwd *);
+# ifdef USE_SOLARIS_PRIVS
+priv_set_t *solaris_basic_privset(void);
+void solaris_drop_privs_pinfo_net_fork_exec(void);
+void solaris_drop_privs_root_pinfo_net(void);
+void solaris_drop_privs_root_pinfo_net_exec(void);
+# endif /* USE_SOLARIS_PRIVS */
#endif
diff --git a/crypto/openssh/openbsd-compat/realpath.c b/crypto/openssh/openbsd-compat/realpath.c
index ba4cea9..a2f090e 100644
--- a/crypto/openssh/openbsd-compat/realpath.c
+++ b/crypto/openssh/openbsd-compat/realpath.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: realpath.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
+/* $OpenBSD: realpath.c,v 1.20 2015/10/13 20:55:37 millert Exp $ */
/*
* Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
*
@@ -42,6 +42,13 @@
#include <stddef.h>
#include <string.h>
#include <unistd.h>
+#include <limits.h>
+
+#ifndef SYMLOOP_MAX
+# define SYMLOOP_MAX 32
+#endif
+
+/* A slightly modified copy of this file exists in libexec/ld.so */
/*
* char *realpath(const char *path, char resolved[PATH_MAX]);
@@ -51,16 +58,30 @@
* in which case the path which caused trouble is left in (resolved).
*/
char *
-realpath(const char *path, char resolved[PATH_MAX])
+realpath(const char *path, char *resolved)
{
struct stat sb;
char *p, *q, *s;
size_t left_len, resolved_len;
unsigned symlinks;
- int serrno, slen;
+ int serrno, slen, mem_allocated;
char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
+ if (path[0] == '\0') {
+ errno = ENOENT;
+ return (NULL);
+ }
+
serrno = errno;
+
+ if (resolved == NULL) {
+ resolved = malloc(PATH_MAX);
+ if (resolved == NULL)
+ return (NULL);
+ mem_allocated = 1;
+ } else
+ mem_allocated = 0;
+
symlinks = 0;
if (path[0] == '/') {
resolved[0] = '/';
@@ -71,7 +92,10 @@ realpath(const char *path, char resolved[PATH_MAX])
left_len = strlcpy(left, path + 1, sizeof(left));
} else {
if (getcwd(resolved, PATH_MAX) == NULL) {
- strlcpy(resolved, ".", PATH_MAX);
+ if (mem_allocated)
+ free(resolved);
+ else
+ strlcpy(resolved, ".", PATH_MAX);
return (NULL);
}
resolved_len = strlen(resolved);
@@ -79,7 +103,7 @@ realpath(const char *path, char resolved[PATH_MAX])
}
if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
errno = ENAMETOOLONG;
- return (NULL);
+ goto err;
}
/*
@@ -94,7 +118,7 @@ realpath(const char *path, char resolved[PATH_MAX])
s = p ? p : left + left_len;
if (s - left >= (ptrdiff_t)sizeof(next_token)) {
errno = ENAMETOOLONG;
- return (NULL);
+ goto err;
}
memcpy(next_token, left, s - left);
next_token[s - left] = '\0';
@@ -104,7 +128,7 @@ realpath(const char *path, char resolved[PATH_MAX])
if (resolved[resolved_len - 1] != '/') {
if (resolved_len + 1 >= PATH_MAX) {
errno = ENAMETOOLONG;
- return (NULL);
+ goto err;
}
resolved[resolved_len++] = '/';
resolved[resolved_len] = '\0';
@@ -135,23 +159,23 @@ realpath(const char *path, char resolved[PATH_MAX])
resolved_len = strlcat(resolved, next_token, PATH_MAX);
if (resolved_len >= PATH_MAX) {
errno = ENAMETOOLONG;
- return (NULL);
+ goto err;
}
if (lstat(resolved, &sb) != 0) {
if (errno == ENOENT && p == NULL) {
errno = serrno;
return (resolved);
}
- return (NULL);
+ goto err;
}
if (S_ISLNK(sb.st_mode)) {
- if (symlinks++ > MAXSYMLINKS) {
+ if (symlinks++ > SYMLOOP_MAX) {
errno = ELOOP;
- return (NULL);
+ goto err;
}
slen = readlink(resolved, symlink, sizeof(symlink) - 1);
if (slen < 0)
- return (NULL);
+ goto err;
symlink[slen] = '\0';
if (symlink[0] == '/') {
resolved[1] = 0;
@@ -174,15 +198,15 @@ realpath(const char *path, char resolved[PATH_MAX])
if (slen + 1 >=
(ptrdiff_t)sizeof(symlink)) {
errno = ENAMETOOLONG;
- return (NULL);
+ goto err;
}
symlink[slen] = '/';
symlink[slen + 1] = 0;
}
- left_len = strlcat(symlink, left, sizeof(left));
- if (left_len >= sizeof(left)) {
+ left_len = strlcat(symlink, left, sizeof(symlink));
+ if (left_len >= sizeof(symlink)) {
errno = ENAMETOOLONG;
- return (NULL);
+ goto err;
}
}
left_len = strlcpy(left, symlink, sizeof(left));
@@ -196,5 +220,10 @@ realpath(const char *path, char resolved[PATH_MAX])
if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
resolved[resolved_len - 1] = '\0';
return (resolved);
+
+err:
+ if (mem_allocated)
+ free(resolved);
+ return (NULL);
}
#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */
OpenPOWER on IntegriCloud