Add support for per-user /tmp.

Enabled via per_user_tmp in /etc/rc.conf (default off).

See security(8) and rc.conf(5) for more details.

Lots of input from thorpej@ & christos@, thanks!
This commit is contained in:
elad 2007-02-04 08:19:26 +00:00
parent 3044852cc5
commit 5e2e282f9c
9 changed files with 148 additions and 14 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.184 2006/11/12 03:02:50 christos Exp $
# $NetBSD: mi,v 1.185 2007/02/04 08:19:26 elad Exp $
#
# Note: end-user configuration files that are moved to another location
# should not be marked "obsolete"; they should just be removed from
@ -206,6 +206,7 @@
./etc/rc.d/nfslocking etc-nfsserver-rc
./etc/rc.d/ntpd etc-ntp-rc
./etc/rc.d/ntpdate etc-ntp-rc
./etc/rc.d/perusertmp etc-sys-rc
./etc/rc.d/pf etc-net-rc
./etc/rc.d/pf_boot etc-net-rc
./etc/rc.d/pflogd etc-net-rc

View File

@ -1,4 +1,4 @@
# $NetBSD: rc.conf,v 1.82 2006/12/30 11:06:04 elad Exp $
# $NetBSD: rc.conf,v 1.83 2007/02/04 08:19:26 elad Exp $
#
# /etc/defaults/rc.conf --
# default configuration of /etc/rc.conf
@ -103,6 +103,8 @@ lkm=NO # Run /etc/rc.lkm. /usr needs to be part of /, or
savecore=YES savecore_flags="-z"
savecore_dir="/var/crash"
per_user_tmp=NO # per-user /tmp directories
per_user_tmp_dir="/private/tmp" # real storage for /tmp
clear_tmp=YES # clear /tmp after reboot
update_motd=YES # updates /etc/motd
dmesg=YES dmesg_flags="" # write /var/run/dmesg.boot

View File

@ -1,4 +1,4 @@
# $NetBSD: special,v 1.108 2006/12/14 02:28:30 reed Exp $
# $NetBSD: special,v 1.109 2007/02/04 08:19:26 elad Exp $
# @(#)special 8.2 (Berkeley) 1/23/94
#
# This file may be overwritten on upgrades.
@ -222,6 +222,7 @@
./etc/rc.d/nfslocking type=file mode=0555
./etc/rc.d/ntpd type=file mode=0555
./etc/rc.d/ntpdate type=file mode=0555
./etc/rc.d/perusertmp type=file mode=0555
./etc/rc.d/pf type=file mode=0555
./etc/rc.d/pf_boot type=file mode=0555
./etc/rc.d/pflogd type=file mode=0555
@ -311,6 +312,9 @@
./etc/racoon/racoon.conf type=file mode=0644 optional
./etc/racoon/psk.txt type=file mode=0600 optional tags=nodiff
./private type=dir mode=0755 optional
./private/tmp type=dir mode=0111 optional ignore
./root type=dir mode=0755
./root/.cshrc type=file mode=0644
./root/.klogin type=file mode=0600 optional

View File

@ -1,6 +1,6 @@
#!/bin/sh
#
# $NetBSD: cleartmp,v 1.7 2006/10/07 23:08:03 elad Exp $
# $NetBSD: cleartmp,v 1.8 2007/02/04 08:19:26 elad Exp $
#
# PROVIDE: cleartmp
@ -16,13 +16,19 @@ stop_cmd=":"
cleartmp_start()
{
echo "Clearing /tmp."
echo "Clearing temporary files."
#
# Prune quickly with one rm, then use find to clean up
# /tmp/[lq]* (this is not needed with mfs /tmp, but
# doesn't hurt anything).
#
(cd /tmp && rm -rf [a-km-pr-zA-Z]* &&
if [ \( X"${per_user_tmp}" = X"YES" \) -a \( -d ${per_user_tmp_dir} \) ]; then
tmp_dir=${per_user_tmp_dir}
else
tmp_dir="/tmp"
fi
(cd ${tmp_dir} && rm -rf [a-km-pr-zA-Z]* &&
find -x . ! -name . ! -name lost+found ! -name quota.user \
! -name quota.group -exec rm -rf -- {} \; -type d -prune)
}

48
etc/rc.d/perusertmp Executable file
View File

@ -0,0 +1,48 @@
#!/bin/sh
#
# $NetBSD: perusertmp,v 1.1 2007/02/04 08:19:26 elad Exp $
#
# PROVIDE: perusertmp
# REQUIRE: mountall
# BEFORE: cleartmp
$_rc_subr_loaded . /etc/rc.subr
name="perusertmp"
rcvar="per_user_tmp"
start_cmd="perusertmp_start"
stop_cmd=":"
perusertmp_start()
{
echo "Preparing per-user /tmp."
# If /tmp is a mount point, we can't do anything.
if [ -d "/tmp" ]; then
local mount_point
mount_point=$(cd /tmp && /bin/df . | /usr/bin/tail -1 | /usr/bin/awk '{print $6}')
if [ X"${mount_point}" = X"/tmp" ]; then
echo "WARNING: /tmp is mounted."
exit 1
fi
fi
# Enable magic symlinks.
/sbin/sysctl -qw vfs.generic.magiclinks=1
# Fixup real temporary directory.
if [ ! -d ${per_user_tmp_dir} ]; then
/bin/mkdir ${per_user_tmp_dir}
fi
/usr/sbin/chown root:wheel ${per_user_tmp_dir}
/bin/chmod 0111 ${per_user_tmp_dir}
# Create magic link for /tmp.
/bin/rm -rf /tmp
/bin/ln -s ${per_user_tmp_dir}/@uid /tmp
}
load_rc_config $name
run_rc_command "$1"

View File

@ -1,4 +1,4 @@
/* $NetBSD: login_cap.c,v 1.26 2006/12/20 16:47:13 christos Exp $ */
/* $NetBSD: login_cap.c,v 1.27 2007/02/04 08:19:26 elad Exp $ */
/*-
* Copyright (c) 1995,1997 Berkeley Software Design, Inc. All rights reserved.
@ -36,13 +36,14 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: login_cap.c,v 1.26 2006/12/20 16:47:13 christos Exp $");
__RCSID("$NetBSD: login_cap.c,v 1.27 2007/02/04 08:19:26 elad Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/param.h>
#include <assert.h>
#include <ctype.h>
@ -557,6 +558,7 @@ setclasscontext(const char *class, u_int flags)
int
setusercontext(login_cap_t *lc, struct passwd *pwd, uid_t uid, u_int flags)
{
char per_user_tmp[MAXPATHLEN + 1];
login_cap_t *flc;
quad_t p;
int i;
@ -606,6 +608,33 @@ setusercontext(login_cap_t *lc, struct passwd *pwd, uid_t uid, u_int flags)
}
}
/* Create per-user temporary directories if needed. */
if (readlink("/tmp", per_user_tmp, sizeof(per_user_tmp)) != -1) {
static const char atuid[] = "/@uid";
char *lp;
/* Check if it's magic symlink. */
lp = strstr(per_user_tmp, atuid);
if (lp != NULL && *(lp + (sizeof(atuid) - 1)) == '\0') {
lp++;
if ((sizeof(per_user_tmp) - (lp - per_user_tmp)) < 64) {
syslog(LOG_ERR, "real temporary path too long");
login_close(flc);
return (-1);
}
(void)sprintf(lp, "/%u", pwd->pw_uid); /* safe */
if (mkdir(per_user_tmp, S_IRWXU) != -1) {
(void)chown(per_user_tmp, pwd->pw_uid,
pwd->pw_gid);
} else {
syslog(LOG_ERR, "can't create `%s' directory",
per_user_tmp);
}
}
}
errno = 0;
if (flags & LOGIN_SETLOGIN)
if (setlogin(pwd->pw_name) < 0) {
syslog(LOG_ERR, "setlogin(%s) failure: %m",

View File

@ -1,5 +1,5 @@
# $NetBSD: shlib_version,v 1.42 2006/12/14 20:09:36 he Exp $
# $NetBSD: shlib_version,v 1.43 2007/02/04 08:19:26 elad Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
major=7
minor=12
minor=13

View File

@ -1,4 +1,4 @@
.\" $NetBSD: rc.conf.5,v 1.111 2006/12/23 09:12:35 wiz Exp $
.\" $NetBSD: rc.conf.5,v 1.112 2007/02/04 08:19:26 elad Exp $
.\"
.\" Copyright (c) 1996 Matthew R. Green
.\" Copyright (c) 1997 Curt J. Sampson
@ -32,7 +32,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd December 4, 2006
.Dd February 4, 2007
.Dt RC.CONF 5
.Os
.Sh NAME
@ -313,6 +313,18 @@ to trim logfiles before syslogd starts.
Intended for laptop users.
Passes
.Sy newsyslog_flags .
.It Sy per_user_tmp
.Sq YES
or
.Sq NO .
Enables a per-user
.Pa /tmp
directory.
.Sy per_user_tmp_dir
can be used to override the default location of the
.Dq real
temporary directories,
.Dq Pa /private/tmp .
.It Sy savecore
.Sq YES
or

View File

@ -1,4 +1,4 @@
.\" $NetBSD: security.8,v 1.13 2007/02/02 02:42:00 elad Exp $
.\" $NetBSD: security.8,v 1.14 2007/02/04 08:19:26 elad Exp $
.\"
.\" Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
.\" All rights reserved.
@ -25,7 +25,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd February 2, 2007
.Dd February 4, 2007
.Dt SECURITY 8
.Os
.Sh NAME
@ -46,6 +46,10 @@ Veriexec (file integrity)
.It
Exploit mitigation
.It
Per-user
.Pa /tmp
directory
.It
Information filtering
.El
.Sh VERIEXEC
@ -297,6 +301,34 @@ Use of
is especially encouraged on platforms without per-page execute bit granularity
such as
.Em i386 .
.Sh PER-USER TEMPORARY STORAGE
It is possible to configure per-user temporary storage to avoid potential
security issues (race conditions, etc.) in programs that do not make secure
usage of
.Pa /tmp .
.Pp
To enable per-user temporary storage, add the following line to
.Xr rc.conf 5 :
.Bd -literal -offset indent
per_user_tmp=YES
.Ed
.Pp
If
.Pa /tmp
is a mount point, you will also need to update its
.Xr fstab 5
entry to use
.Dq /private/tmp
(or whatever directory you want, if you override the default using the
.Dq per_user_tmp_dir
.Xr rc.conf 5
keyword) instead of
.Dq /tmp .
.Pp
Following that, run:
.Bd -literal -offset indent
# /etc/rc.d/perusertmp start
.Ed
.Sh INFORMATION FILTERING
.Nx
provides administrators the ability to restrict information passed from