Implement a new magic string for magic symlinks, @ruid, which exapnds to the
real user id of the process and use this magic string for per-user tmp. This should fix PR/35687 Kernel parts reviewed by wrstuden@
This commit is contained in:
parent
fe819e7531
commit
d4a648c345
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: cleartmp,v 1.9 2007/02/15 08:47:38 xtraeme Exp $
|
||||
# $NetBSD: cleartmp,v 1.10 2007/12/04 22:09:01 mjf Exp $
|
||||
#
|
||||
|
||||
# PROVIDE: cleartmp
|
||||
@ -28,7 +28,7 @@ cleartmp_start()
|
||||
tmp_dir="/tmp"
|
||||
# Check if /tmp was created by the perusertmp rc.d
|
||||
# script and recreate it if necessary.
|
||||
if [ "$(/usr/bin/readlink /tmp)" = ${per_user_tmp_dir}/@uid ]; then
|
||||
if [ "$(/usr/bin/readlink /tmp)" = ${per_user_tmp_dir}/@ruid ]; then
|
||||
/bin/rm -rf ${tmp_dir}
|
||||
/bin/mkdir ${tmp_dir}
|
||||
/usr/sbin/chown root:wheel ${tmp_dir}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: perusertmp,v 1.6 2007/02/15 13:27:35 tron Exp $
|
||||
# $NetBSD: perusertmp,v 1.7 2007/12/04 22:09:01 mjf Exp $
|
||||
#
|
||||
|
||||
# PROVIDE: perusertmp
|
||||
@ -40,9 +40,9 @@ perusertmp_start()
|
||||
/bin/chmod 0555 ${per_user_tmp_dir}
|
||||
|
||||
# Create magic link for /tmp.
|
||||
if [ "$(/usr/bin/readlink /tmp)" != ${per_user_tmp_dir}/@uid ]; then
|
||||
if [ "$(/usr/bin/readlink /tmp)" != ${per_user_tmp_dir}/@ruid ]; then
|
||||
/bin/rm -rf /tmp
|
||||
/bin/ln -s ${per_user_tmp_dir}/@uid /tmp
|
||||
/bin/ln -s ${per_user_tmp_dir}/@ruid /tmp
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: login_cap.c,v 1.28 2007/10/06 21:51:22 christos Exp $ */
|
||||
/* $NetBSD: login_cap.c,v 1.29 2007/12/04 22:09:02 mjf Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1995,1997 Berkeley Software Design, Inc. All rights reserved.
|
||||
@ -36,7 +36,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: login_cap.c,v 1.28 2007/10/06 21:51:22 christos Exp $");
|
||||
__RCSID("$NetBSD: login_cap.c,v 1.29 2007/12/04 22:09:02 mjf Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -559,9 +559,11 @@ int
|
||||
setusercontext(login_cap_t *lc, struct passwd *pwd, uid_t uid, u_int flags)
|
||||
{
|
||||
char per_user_tmp[MAXPATHLEN + 1];
|
||||
const char *component_name;
|
||||
login_cap_t *flc;
|
||||
quad_t p;
|
||||
int i;
|
||||
ssize_t len;
|
||||
|
||||
flc = NULL;
|
||||
|
||||
@ -617,27 +619,73 @@ 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";
|
||||
if ((len = readlink("/tmp", per_user_tmp,
|
||||
sizeof(per_user_tmp) - 6)) != -1) {
|
||||
|
||||
static const char atuid[] = "/@ruid";
|
||||
char *lp;
|
||||
|
||||
/* readlink does not nul-terminate the string */
|
||||
per_user_tmp[len] = '\0';
|
||||
|
||||
/* 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) {
|
||||
if (snprintf(lp, 11, "/%u", pwd->pw_uid) > 10) {
|
||||
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);
|
||||
if (chown(per_user_tmp, pwd->pw_uid,
|
||||
pwd->pw_gid)) {
|
||||
component_name = "chown";
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must set sticky bit for tmp directory, some
|
||||
* programs rely on this.
|
||||
*/
|
||||
if(chmod(per_user_tmp, S_IRWXU | S_ISVTX)) {
|
||||
component_name = "chmod";
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
syslog(LOG_ERR, "can't create `%s' directory",
|
||||
per_user_tmp);
|
||||
if (errno != EEXIST) {
|
||||
component_name = "mkdir";
|
||||
goto out;
|
||||
} else {
|
||||
/*
|
||||
* We must ensure that we own the
|
||||
* directory and that is has the correct
|
||||
* permissions, otherwise a DOS attack
|
||||
* is possible.
|
||||
*/
|
||||
struct stat sb;
|
||||
if (stat(per_user_tmp, &sb) == -1) {
|
||||
component_name = "stat";
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sb.st_uid != pwd->pw_uid) {
|
||||
if (chown(per_user_tmp,
|
||||
pwd->pw_uid, pwd->pw_gid)) {
|
||||
component_name = "chown";
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (sb.st_mode != (S_IRWXU | S_ISVTX)) {
|
||||
if (chmod(per_user_tmp,
|
||||
S_IRWXU | S_ISVTX)) {
|
||||
component_name = "chmod";
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -666,6 +714,17 @@ setusercontext(login_cap_t *lc, struct passwd *pwd, uid_t uid, u_int flags)
|
||||
|
||||
login_close(flc);
|
||||
return (0);
|
||||
|
||||
out:
|
||||
if (component_name != NULL) {
|
||||
syslog(LOG_ERR, "%s %s: %m", component_name, per_user_tmp);
|
||||
login_close(flc);
|
||||
return (-1);
|
||||
} else {
|
||||
syslog(LOG_ERR, "%s: %m", per_user_tmp);
|
||||
login_close(flc);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: symlink.7,v 1.12 2007/02/07 06:41:50 wiz Exp $
|
||||
.\" $NetBSD: symlink.7,v 1.13 2007/12/04 22:09:02 mjf Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1992, 1993, 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -432,11 +432,13 @@ or
|
||||
.Fl P
|
||||
options.
|
||||
.Sh MAGIC SYMLINKS
|
||||
Symlinks in file systems with the
|
||||
.Li MNT_MAGICLINKS
|
||||
flag set have
|
||||
Magic symlinks can be enabled by setting
|
||||
.Dq vfs.generic.magiclinks
|
||||
with
|
||||
.Xr sysctl 8 .
|
||||
When magic symlinks are enabled
|
||||
.Dq magic
|
||||
patterns in symlinks expanded.
|
||||
patterns in symlinks are expanded.
|
||||
Those patterns begin with
|
||||
.Dq @
|
||||
.Pq an at-sign ,
|
||||
@ -518,6 +520,8 @@ This will always be
|
||||
on
|
||||
.Nx
|
||||
systems.
|
||||
.It @ruid
|
||||
Exapnds to the real user-id of the process.
|
||||
.It @uid
|
||||
Expands to the effective user-id of the process.
|
||||
.El
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vfs_lookup.c,v 1.100 2007/11/26 19:02:07 pooka Exp $ */
|
||||
/* $NetBSD: vfs_lookup.c,v 1.101 2007/12/04 22:09:02 mjf Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.100 2007/11/26 19:02:07 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.101 2007/12/04 22:09:02 mjf Exp $");
|
||||
|
||||
#include "opt_systrace.h"
|
||||
#include "opt_magiclinks.h"
|
||||
@ -120,6 +120,8 @@ symlink_magic(struct proc *p, char *cp, int *len)
|
||||
char *tmp;
|
||||
int change, i, newlen;
|
||||
int termchar = '/';
|
||||
char uidtmp[11]; /* XXX elad */
|
||||
|
||||
|
||||
tmp = PNBUF_GET();
|
||||
for (change = i = newlen = 0; i < *len; ) {
|
||||
@ -165,11 +167,13 @@ symlink_magic(struct proc *p, char *cp, int *len)
|
||||
SUBSTITUTE("ostype", ostype,
|
||||
strlen(ostype));
|
||||
} else if (MATCH("uid")) {
|
||||
char uidtmp[11]; /* XXX elad */
|
||||
|
||||
(void)snprintf(uidtmp, sizeof(uidtmp), "%u",
|
||||
kauth_cred_geteuid(kauth_cred_get()));
|
||||
SUBSTITUTE("uid", uidtmp, strlen(uidtmp));
|
||||
} else if (MATCH("ruid")) {
|
||||
(void)snprintf(uidtmp, sizeof(uidtmp), "%u",
|
||||
kauth_cred_getuid(kauth_cred_get()));
|
||||
SUBSTITUTE("ruid", uidtmp, strlen(uidtmp));
|
||||
} else {
|
||||
tmp[newlen++] = '@';
|
||||
if (termchar == VC)
|
||||
|
Loading…
Reference in New Issue
Block a user