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 # Note: end-user configuration files that are moved to another location
# should not be marked "obsolete"; they should just be removed from # 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/nfslocking etc-nfsserver-rc
./etc/rc.d/ntpd etc-ntp-rc ./etc/rc.d/ntpd etc-ntp-rc
./etc/rc.d/ntpdate 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 etc-net-rc
./etc/rc.d/pf_boot etc-net-rc ./etc/rc.d/pf_boot etc-net-rc
./etc/rc.d/pflogd 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 -- # /etc/defaults/rc.conf --
# default configuration of /etc/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=YES savecore_flags="-z"
savecore_dir="/var/crash" 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 clear_tmp=YES # clear /tmp after reboot
update_motd=YES # updates /etc/motd update_motd=YES # updates /etc/motd
dmesg=YES dmesg_flags="" # write /var/run/dmesg.boot 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 # @(#)special 8.2 (Berkeley) 1/23/94
# #
# This file may be overwritten on upgrades. # This file may be overwritten on upgrades.
@ -222,6 +222,7 @@
./etc/rc.d/nfslocking type=file mode=0555 ./etc/rc.d/nfslocking type=file mode=0555
./etc/rc.d/ntpd type=file mode=0555 ./etc/rc.d/ntpd type=file mode=0555
./etc/rc.d/ntpdate 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 type=file mode=0555
./etc/rc.d/pf_boot type=file mode=0555 ./etc/rc.d/pf_boot type=file mode=0555
./etc/rc.d/pflogd 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/racoon.conf type=file mode=0644 optional
./etc/racoon/psk.txt type=file mode=0600 optional tags=nodiff ./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 type=dir mode=0755
./root/.cshrc type=file mode=0644 ./root/.cshrc type=file mode=0644
./root/.klogin type=file mode=0600 optional ./root/.klogin type=file mode=0600 optional

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/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 # PROVIDE: cleartmp
@ -16,13 +16,19 @@ stop_cmd=":"
cleartmp_start() cleartmp_start()
{ {
echo "Clearing /tmp." echo "Clearing temporary files."
# #
# Prune quickly with one rm, then use find to clean up # Prune quickly with one rm, then use find to clean up
# /tmp/[lq]* (this is not needed with mfs /tmp, but # /tmp/[lq]* (this is not needed with mfs /tmp, but
# doesn't hurt anything). # 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 \ find -x . ! -name . ! -name lost+found ! -name quota.user \
! -name quota.group -exec rm -rf -- {} \; -type d -prune) ! -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. * Copyright (c) 1995,1997 Berkeley Software Design, Inc. All rights reserved.
@ -36,13 +36,14 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint) #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 */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/param.h>
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
@ -557,6 +558,7 @@ setclasscontext(const char *class, u_int flags)
int int
setusercontext(login_cap_t *lc, struct passwd *pwd, uid_t uid, u_int flags) setusercontext(login_cap_t *lc, struct passwd *pwd, uid_t uid, u_int flags)
{ {
char per_user_tmp[MAXPATHLEN + 1];
login_cap_t *flc; login_cap_t *flc;
quad_t p; quad_t p;
int i; 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 (flags & LOGIN_SETLOGIN)
if (setlogin(pwd->pw_name) < 0) { if (setlogin(pwd->pw_name) < 0) {
syslog(LOG_ERR, "setlogin(%s) failure: %m", 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 # Remember to update distrib/sets/lists/base/shl.* when changing
# #
major=7 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) 1996 Matthew R. Green
.\" Copyright (c) 1997 Curt J. Sampson .\" Copyright (c) 1997 Curt J. Sampson
@ -32,7 +32,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd December 4, 2006 .Dd February 4, 2007
.Dt RC.CONF 5 .Dt RC.CONF 5
.Os .Os
.Sh NAME .Sh NAME
@ -313,6 +313,18 @@ to trim logfiles before syslogd starts.
Intended for laptop users. Intended for laptop users.
Passes Passes
.Sy newsyslog_flags . .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 .It Sy savecore
.Sq YES .Sq YES
or 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> .\" Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
.\" All rights reserved. .\" All rights reserved.
@ -25,7 +25,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd February 2, 2007 .Dd February 4, 2007
.Dt SECURITY 8 .Dt SECURITY 8
.Os .Os
.Sh NAME .Sh NAME
@ -46,6 +46,10 @@ Veriexec (file integrity)
.It .It
Exploit mitigation Exploit mitigation
.It .It
Per-user
.Pa /tmp
directory
.It
Information filtering Information filtering
.El .El
.Sh VERIEXEC .Sh VERIEXEC
@ -297,6 +301,34 @@ Use of
is especially encouraged on platforms without per-page execute bit granularity is especially encouraged on platforms without per-page execute bit granularity
such as such as
.Em i386 . .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 .Sh INFORMATION FILTERING
.Nx .Nx
provides administrators the ability to restrict information passed from provides administrators the ability to restrict information passed from