From 3024acbfc2f1bca08b0e47e1dd0d4ba86c9c2130 Mon Sep 17 00:00:00 2001 From: delphij Date: Tue, 3 Jun 2014 19:03:11 +0000 Subject: [PATCH] Fix sendmail improper close-on-exec flag handling. [SA-14:11] Fix ktrace memory disclosure. [SA-14:12] Fix incorrect error handling in PAM policy parser. [SA-14:13] Fix triple-fault when executing from a threaded process. [EN-14:06] Approved by: so git-svn-id: svn://svn.freebsd.org/base/releng/9.2@267018 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- UPDATING | 14 +++++++++ contrib/openpam/lib/openpam_configure.c | 40 ++++++++++++++++++++----- contrib/sendmail/src/conf.c | 4 +-- sys/conf/newvers.sh | 2 +- sys/kern/kern_exec.c | 9 ++++++ sys/kern/kern_ktrace.c | 1 + sys/sys/proc.h | 1 + sys/vm/vm_map.c | 4 ++- 8 files changed, 64 insertions(+), 11 deletions(-) diff --git a/UPDATING b/UPDATING index 9d0d2c64..7da0c173 100644 --- a/UPDATING +++ b/UPDATING @@ -11,6 +11,20 @@ handbook: Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. +20140603: p7 FreeBSD-SA-14:11.sendmail + FreeBSD-SA-14:12.ktrace + FreeBSD-SA-14:13.pam + FreeBSD-EN-14:06.exec + + Fix sendmail improper close-on-exec flag handling. [SA-14:11] + + Fix ktrace memory disclosure. [SA-14:12] + + Fix incorrect error handling in PAM policy parser. [SA-14:13] + + Fix triple-fault when executing from a threaded process. + [EN-14:06] + 20140513: p6 FreeBSD-EN-14:03.pkg FreeBSD-EN-14:04.kldxref FreeBSD-EN-14:05.ciss diff --git a/contrib/openpam/lib/openpam_configure.c b/contrib/openpam/lib/openpam_configure.c index 8172a6fd..d85cd8a4 100644 --- a/contrib/openpam/lib/openpam_configure.c +++ b/contrib/openpam/lib/openpam_configure.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2001-2003 Networks Associates Technology, Inc. - * Copyright (c) 2004-2012 Dag-Erling Smørgrav + * Copyright (c) 2004-2014 Dag-Erling Smørgrav * All rights reserved. * * This software was developed for the FreeBSD Project by ThinkSec AS and @@ -194,6 +194,7 @@ openpam_parse_chain(pam_handle_t *pamh, openpam_log(PAM_LOG_ERROR, "%s(%d): missing or invalid facility", filename, lineno); + errno = EINVAL; goto fail; } if (facility != fclt && facility != PAM_FACILITY_ANY) { @@ -209,18 +210,28 @@ openpam_parse_chain(pam_handle_t *pamh, openpam_log(PAM_LOG_ERROR, "%s(%d): missing or invalid service name", filename, lineno); + errno = EINVAL; goto fail; } if (wordv[i] != NULL) { openpam_log(PAM_LOG_ERROR, "%s(%d): garbage at end of line", filename, lineno); + errno = EINVAL; goto fail; } ret = openpam_load_chain(pamh, servicename, fclt); FREEV(wordc, wordv); - if (ret < 0) + if (ret < 0) { + /* + * Bogus errno, but this ensures that the + * outer loop does not just ignore the + * error and keep searching. + */ + if (errno == ENOENT) + errno = EINVAL; goto fail; + } continue; } @@ -230,6 +241,7 @@ openpam_parse_chain(pam_handle_t *pamh, openpam_log(PAM_LOG_ERROR, "%s(%d): missing or invalid control flag", filename, lineno); + errno = EINVAL; goto fail; } @@ -239,6 +251,7 @@ openpam_parse_chain(pam_handle_t *pamh, openpam_log(PAM_LOG_ERROR, "%s(%d): missing or invalid module name", filename, lineno); + errno = EINVAL; goto fail; } @@ -248,8 +261,11 @@ openpam_parse_chain(pam_handle_t *pamh, this->flag = ctlf; /* load module */ - if ((this->module = openpam_load_module(modulename)) == NULL) + if ((this->module = openpam_load_module(modulename)) == NULL) { + if (errno == ENOENT) + errno = ENOEXEC; goto fail; + } /* * The remaining items in wordv are the module's @@ -282,7 +298,11 @@ openpam_parse_chain(pam_handle_t *pamh, * The loop ended because openpam_readword() returned NULL, which * can happen for four different reasons: an I/O error (ferror(f) * is true), a memory allocation failure (ferror(f) is false, - * errno is non-zero) + * feof(f) is false, errno is non-zero), the file ended with an + * unterminated quote or backslash escape (ferror(f) is false, + * feof(f) is true, errno is non-zero), or the end of the file was + * reached without error (ferror(f) is false, feof(f) is true, + * errno is zero). */ if (ferror(f) || errno != 0) goto syserr; @@ -411,6 +431,9 @@ openpam_load_chain(pam_handle_t *pamh, } ret = openpam_load_file(pamh, service, facility, filename, style); + /* success */ + if (ret > 0) + RETURNN(ret); /* the file exists, but an error occurred */ if (ret == -1 && errno != ENOENT) RETURNN(ret); @@ -420,7 +443,8 @@ openpam_load_chain(pam_handle_t *pamh, } /* no hit */ - RETURNN(0); + errno = ENOENT; + RETURNN(-1); } /* @@ -441,8 +465,10 @@ openpam_configure(pam_handle_t *pamh, openpam_log(PAM_LOG_ERROR, "invalid service name"); RETURNC(PAM_SYSTEM_ERR); } - if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0) - goto load_err; + if (openpam_load_chain(pamh, service, PAM_FACILITY_ANY) < 0) { + if (errno != ENOENT) + goto load_err; + } for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt) { if (pamh->chains[fclt] != NULL) continue; diff --git a/contrib/sendmail/src/conf.c b/contrib/sendmail/src/conf.c index edfa0c2b..3d5ff95d 100644 --- a/contrib/sendmail/src/conf.c +++ b/contrib/sendmail/src/conf.c @@ -5265,8 +5265,8 @@ closefd_walk(lowest, fd) */ void -sm_close_on_exec(highest, lowest) - int highest, lowest; +sm_close_on_exec(lowest, highest) + int lowest, highest; { #if HASFDWALK (void) fdwalk(closefd_walk, &lowest); diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index e80e7fc6..a62f97ff 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="9.2" -BRANCH="RELEASE-p6" +BRANCH="RELEASE-p7" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 2fef7c53..a4145f61 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -280,6 +280,7 @@ kern_execve(td, args, mac_p) struct mac *mac_p; { struct proc *p = td->td_proc; + struct vmspace *oldvmspace; int error; AUDIT_ARG_ARGV(args->begin_argv, args->argc, @@ -296,6 +297,8 @@ kern_execve(td, args, mac_p) PROC_UNLOCK(p); } + KASSERT((td->td_pflags & TDP_EXECVMSPC) == 0, ("nested execve")); + oldvmspace = td->td_proc->p_vmspace; error = do_execve(td, args, mac_p); if (p->p_flag & P_HADTHREADS) { @@ -310,6 +313,12 @@ kern_execve(td, args, mac_p) thread_single_end(); PROC_UNLOCK(p); } + if ((td->td_pflags & TDP_EXECVMSPC) != 0) { + KASSERT(td->td_proc->p_vmspace != oldvmspace, + ("oldvmspace still used")); + vmspace_free(oldvmspace); + td->td_pflags &= ~TDP_EXECVMSPC; + } return (error); } diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index a070ef26..7718bcdf 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -119,6 +119,7 @@ static int data_lengths[] = { 0, /* KTR_SYSCTL */ sizeof(struct ktr_proc_ctor), /* KTR_PROCCTOR */ 0, /* KTR_PROCDTOR */ + 0, /* unused */ sizeof(struct ktr_fault), /* KTR_FAULT */ sizeof(struct ktr_faultend), /* KTR_FAULTEND */ }; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 22fc1e89..d08547d4 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -977,4 +977,5 @@ curthread_pflags_restore(int save) #endif /* _KERNEL */ +#define TDP_EXECVMSPC 0x40000000 /* Execve destroyed old vmspace */ #endif /* !_SYS_PROC_H_ */ diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index dc6ed1e4..29ffca99 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -3669,6 +3669,8 @@ vmspace_exec(struct proc *p, vm_offset_t minuser, vm_offset_t maxuser) struct vmspace *oldvmspace = p->p_vmspace; struct vmspace *newvmspace; + KASSERT((curthread->td_pflags & TDP_EXECVMSPC) == 0, + ("vmspace_exec recursed")); newvmspace = vmspace_alloc(minuser, maxuser); if (newvmspace == NULL) return (ENOMEM); @@ -3685,7 +3687,7 @@ vmspace_exec(struct proc *p, vm_offset_t minuser, vm_offset_t maxuser) PROC_VMSPACE_UNLOCK(p); if (p == curthread->td_proc) pmap_activate(curthread); - vmspace_free(oldvmspace); + curthread->td_pflags |= TDP_EXECVMSPC; return (0); } -- 2.45.0