Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
openssh-askpass-gnome.10219
openssh-6.6p1-restrict_pkcs11-modules.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File openssh-6.6p1-restrict_pkcs11-modules.patch of Package openssh-askpass-gnome.10219
# HG changeset patch # Parent 177ed550d926f6201af723fbe07f04bdb95b415a whitelist paths for loading of PKCS#11 modules in ssh-agent CVE-2016-10009 bsc#1016366 upstream commit 786d5994da79151180cb14a6cf157ebbba61c0cc diff --git a/openssh-6.6p1/ssh-agent.1 b/openssh-6.6p1/ssh-agent.1 --- a/openssh-6.6p1/ssh-agent.1 +++ b/openssh-6.6p1/ssh-agent.1 @@ -41,16 +41,17 @@ .Nm ssh-agent .Nd authentication agent .Sh SYNOPSIS .Nm ssh-agent .Op Fl c | s .Op Fl d .Op Fl a Ar bind_address .Op Fl t Ar life +.Op Fl P Ar pkcs11_whitelist .Op Ar command Op Ar arg ... .Nm ssh-agent .Op Fl c | s .Fl k .Sh DESCRIPTION .Nm is a program to hold private keys used for public key authentication (RSA, DSA, ECDSA, ED25519). @@ -83,16 +84,28 @@ looks like it's a csh style of shell. Debug mode. When this option is specified .Nm will not fork. .It Fl k Kill the current agent (given by the .Ev SSH_AGENT_PID environment variable). +.It Fl P +Specify a pattern-list of acceptable paths for PKCS#11 shared libraries +that may be added using the +.Fl s +option to +.Xr ssh-add 1 . +The default is to allow loading PKCS#11 libraries from +.Dq /usr/lib/*,/usr/local/lib/* . +PKCS#11 libraries that do not match the whitelist will be refused. +See PATTERNS in +.Xr ssh_config 5 +for a description of pattern-list syntax. .It Fl s Generate Bourne shell commands on .Dv stdout . This is the default if .Ev SHELL does not look like it's a csh style of shell. .It Fl t Ar life Set a default value for the maximum lifetime of identities added to the agent. diff --git a/openssh-6.6p1/ssh-agent.c b/openssh-6.6p1/ssh-agent.c --- a/openssh-6.6p1/ssh-agent.c +++ b/openssh-6.6p1/ssh-agent.c @@ -70,25 +70,30 @@ #include "rsa.h" #include "buffer.h" #include "key.h" #include "authfd.h" #include "compat.h" #include "log.h" #include "misc.h" #include "digest.h" +#include "match.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" #endif #if defined(HAVE_SYS_PRCTL_H) #include <sys/prctl.h> /* For prctl() and PR_SET_DUMPABLE */ #endif +#ifndef DEFAULT_PKCS11_WHITELIST +# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*" +#endif + typedef enum { AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION } sock_type; typedef struct { int fd; @@ -123,16 +128,19 @@ int max_fd = 0; /* pid of shell == parent of agent */ pid_t parent_pid = -1; time_t parent_alive_interval = 0; /* pathname and directory for AUTH_SOCKET */ char socket_name[MAXPATHLEN]; char socket_dir[MAXPATHLEN]; +/* PKCS#11 path whitelist */ +static char *pkcs11_whitelist; + /* locking */ #define LOCK_SIZE 32 #define LOCK_SALT_SIZE 16 #define LOCK_ROUNDS 1 int locked = 0; char lock_passwd[LOCK_SIZE]; char lock_salt[LOCK_SALT_SIZE]; @@ -611,17 +619,17 @@ no_identities(SocketEntry *e, u_int type buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); buffer_free(&msg); } #ifdef ENABLE_PKCS11 static void process_add_smartcard_key(SocketEntry *e) { - char *provider = NULL, *pin; + char *provider = NULL, *pin, canonical_provider[PATH_MAX]; int i, type, version, count = 0, success = 0, confirm = 0; time_t death = 0; Key **keys = NULL, *k; Identity *id; Idtab *tab; provider = buffer_get_string(&e->request, NULL); pin = buffer_get_string(&e->request, NULL); @@ -635,29 +643,41 @@ process_add_smartcard_key(SocketEntry *e confirm = 1; break; default: error("process_add_smartcard_key: " "Unknown constraint type %d", type); goto send; } } + if (realpath(provider, canonical_provider) == NULL) { + verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", + provider, strerror(errno)); + goto send; + } + if (match_pattern_list(canonical_provider, pkcs11_whitelist, + strlen(pkcs11_whitelist), 0) != 1) { + verbose("refusing PKCS#11 add of \"%.100s\": " + "provider not whitelisted", canonical_provider); + goto send; + } + debug("%s: add %.100s", __func__, canonical_provider); if (lifetime && !death) death = monotime() + lifetime; - count = pkcs11_add_provider(provider, pin, &keys); + count = pkcs11_add_provider(canonical_provider, pin, &keys); for (i = 0; i < count; i++) { k = keys[i]; version = k->type == KEY_RSA1 ? 1 : 2; tab = idtab_lookup(version); if (lookup_identity(k, version) == NULL) { id = xcalloc(1, sizeof(Identity)); id->key = k; - id->provider = xstrdup(provider); - id->comment = xstrdup(provider); /* XXX */ + id->provider = xstrdup(canonical_provider); + id->comment = xstrdup(canonical_provider); /* XXX */ id->death = death; id->confirm = confirm; TAILQ_INSERT_TAIL(&tab->idlist, id, next); tab->nentries++; success = 1; } else { key_free(k); } @@ -1031,16 +1051,18 @@ usage(void) __progname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -c Generate C-shell commands on stdout.\n"); fprintf(stderr, " -s Generate Bourne shell commands on stdout.\n"); fprintf(stderr, " -k Kill the current agent.\n"); fprintf(stderr, " -d Debug mode.\n"); fprintf(stderr, " -a socket Bind agent socket to given name.\n"); fprintf(stderr, " -t life Default identity lifetime (seconds).\n"); + fprintf(stderr, " -P pkcs11_whitelist\n"); + fprintf(stderr, " whitelist of directories for loading PKCS#11 modules from.\n"); exit(1); } int main(int ac, char **av) { int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; int sock, fd, ch, result, saved_errno; @@ -1071,26 +1093,31 @@ main(int ac, char **av) prctl(PR_SET_DUMPABLE, 0); #endif OpenSSL_add_all_algorithms(); __progname = ssh_get_progname(av[0]); seed_rng(); - while ((ch = getopt(ac, av, "cdksa:t:")) != -1) { + while ((ch = getopt(ac, av, "cdksa:P:t:")) != -1) { switch (ch) { case 'c': if (s_flag) usage(); c_flag++; break; case 'k': k_flag++; break; + case 'P': + if (pkcs11_whitelist != NULL) + fatal("-P option already specified"); + pkcs11_whitelist = xstrdup(optarg); + break; case 's': if (c_flag) usage(); s_flag++; break; case 'd': if (d_flag) usage(); @@ -1110,16 +1137,19 @@ main(int ac, char **av) } } ac -= optind; av += optind; if (ac > 0 && (c_flag || k_flag || s_flag || d_flag)) usage(); + if (pkcs11_whitelist == NULL) + pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST); + if (ac == 0 && !c_flag && !s_flag) { shell = getenv("SHELL"); if (shell != NULL && (len = strlen(shell)) > 2 && strncmp(shell + len - 3, "csh", 3) == 0) c_flag = 1; } if (k_flag) { const char *errstr = NULL;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor