From owner-svn-src-projects@FreeBSD.ORG Mon Oct 31 23:27:25 2011 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 368B5106566B; Mon, 31 Oct 2011 23:27:25 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2267D8FC13; Mon, 31 Oct 2011 23:27:25 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p9VNRPAn038663; Mon, 31 Oct 2011 23:27:25 GMT (envelope-from brooks@svn.freebsd.org) Received: (from brooks@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p9VNROEf038638; Mon, 31 Oct 2011 23:27:24 GMT (envelope-from brooks@svn.freebsd.org) Message-Id: <201110312327.p9VNROEf038638@svn.freebsd.org> From: Brooks Davis Date: Mon, 31 Oct 2011 23:27:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r226973 - in projects/varsym: . bin/ln lib/libc/sys lib/libutil sys/amd64/conf sys/compat/freebsd32 sys/conf sys/kern sys/sys tools/regression/usr.bin/varsym usr.bin/varsym X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Oct 2011 23:27:25 -0000 Author: brooks Date: Mon Oct 31 23:27:24 2011 New Revision: 226973 URL: http://svn.freebsd.org/changeset/base/226973 Log: Bring in an updated varsym patch from my P4 tree. Added: projects/varsym/TODO projects/varsym/lib/libc/sys/varsym.2 projects/varsym/sys/kern/kern_varsym.c projects/varsym/sys/sys/varsym.h projects/varsym/tools/regression/usr.bin/varsym/ projects/varsym/tools/regression/usr.bin/varsym/Makefile projects/varsym/tools/regression/usr.bin/varsym/regress.all_unset.out projects/varsym/tools/regression/usr.bin/varsym/regress.all_unset_default.out projects/varsym/tools/regression/usr.bin/varsym/regress.disabled_get.out projects/varsym/tools/regression/usr.bin/varsym/regress.disabled_list.out projects/varsym/tools/regression/usr.bin/varsym/regress.disabled_set.out projects/varsym/tools/regression/usr.bin/varsym/regress.list_basic.out projects/varsym/tools/regression/usr.bin/varsym/regress.list_clear_proc.out projects/varsym/tools/regression/usr.bin/varsym/regress.nobody_set.out projects/varsym/tools/regression/usr.bin/varsym/regress.nobody_set_denied.out projects/varsym/tools/regression/usr.bin/varsym/regress.nobody_set_toomany.out projects/varsym/tools/regression/usr.bin/varsym/regress.printenv_override.out projects/varsym/tools/regression/usr.bin/varsym/regress.printenv_proc.out projects/varsym/tools/regression/usr.bin/varsym/regress.printenv_sys.out projects/varsym/tools/regression/usr.bin/varsym/regress.proc_basic.out projects/varsym/tools/regression/usr.bin/varsym/regress.sh projects/varsym/tools/regression/usr.bin/varsym/regress.sys_basic.out projects/varsym/tools/regression/usr.bin/varsym/regress.sys_cleared.out projects/varsym/tools/regression/usr.bin/varsym/regress.sys_deleted.out projects/varsym/tools/regression/usr.bin/varsym/regress.sys_override.out projects/varsym/tools/regression/usr.bin/varsym/regress.t projects/varsym/usr.bin/varsym/ projects/varsym/usr.bin/varsym/Makefile projects/varsym/usr.bin/varsym/varsym.1 projects/varsym/usr.bin/varsym/varsym.c Modified: projects/varsym/bin/ln/ln.1 projects/varsym/lib/libc/sys/Makefile.inc projects/varsym/lib/libc/sys/Symbol.map projects/varsym/lib/libutil/login.conf.5 projects/varsym/lib/libutil/login_cap.h projects/varsym/lib/libutil/login_class.3 projects/varsym/lib/libutil/login_class.c projects/varsym/sys/amd64/conf/GENERIC projects/varsym/sys/compat/freebsd32/freebsd32_misc.c projects/varsym/sys/compat/freebsd32/freebsd32_proto.h projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c projects/varsym/sys/compat/freebsd32/syscalls.master projects/varsym/sys/conf/files projects/varsym/sys/conf/options projects/varsym/sys/kern/init_sysent.c projects/varsym/sys/kern/kern_exec.c projects/varsym/sys/kern/kern_fork.c projects/varsym/sys/kern/syscalls.c projects/varsym/sys/kern/syscalls.master projects/varsym/sys/kern/systrace_args.c projects/varsym/sys/kern/vfs_lookup.c projects/varsym/sys/sys/priv.h projects/varsym/sys/sys/proc.h projects/varsym/sys/sys/syscall.h projects/varsym/sys/sys/syscall.mk projects/varsym/sys/sys/sysproto.h Added: projects/varsym/TODO ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/varsym/TODO Mon Oct 31 23:27:24 2011 (r226973) @@ -0,0 +1,5 @@ +pre-commit: +- get review, tweak as necessicary + +post-commit: +- add jail or vimage support Modified: projects/varsym/bin/ln/ln.1 ============================================================================== --- projects/varsym/bin/ln/ln.1 Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/bin/ln/ln.1 Mon Oct 31 23:27:24 2011 (r226973) @@ -212,6 +212,47 @@ No options may be supplied in this simpl which performs a .Xr link 2 operation using the two passed arguments. +.Sh VARIANT SYMLINKS +.Dx +supports a special kind of dynamic +symbolic link called a +.Em variant symlink . +The +.Ar source_file +of a variant symlink may contain one or more +variable names. Each of these variable +names is enclosed in braces and preceded by a +dollar sign in the style of variable references in +.Xr sh 1 +and +.Xr csh 1 . +.Pp +Whenever a variant symlink is followed, each +variable found in +.Ar source_file +is replaced by its associated value. +In this manner, a variant symlink may resolve to different +paths based on context. The facility +supports per-process, per-user, and system-wide varsyms. +.Pp +Varsym variables can be set with the +.Xr varsym 1 +utility. Regular +.Xr environ 7 +environment variables are +not used to resolve variant symlinks. +.Ss EXAMPLE +.Bd -literal -offset indent +sysctl -w vfs.varsym.enable=1 + +ln -s 'a%{fubar}b' test + +echo 'Hello' > axxb +echo 'Goodbye' > ayyb + +varsym fubar=xx cat test +varsym fubar=yy cat test +.Ed .Sh COMPATIBILITY The .Fl h , @@ -236,7 +277,8 @@ extension and should not be used in port .Xr readlink 2 , .Xr stat 2 , .Xr symlink 2 , -.Xr symlink 7 +.Xr symlink 7 , +.Xr varsym 1 .Sh STANDARDS The .Nm @@ -251,4 +293,4 @@ command conforms to An .Nm command appeared in -.At v1 . +.At v1 . Variant Symlinks appeared in DragonFly BSD . Modified: projects/varsym/lib/libc/sys/Makefile.inc ============================================================================== --- projects/varsym/lib/libc/sys/Makefile.inc Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/lib/libc/sys/Makefile.inc Mon Oct 31 23:27:24 2011 (r226973) @@ -114,7 +114,7 @@ MAN+= sctp_generic_recvmsg.2 sctp_generi swapon.2 symlink.2 sync.2 sysarch.2 syscall.2 \ timer_create.2 timer_delete.2 timer_settime.2 \ truncate.2 umask.2 undelete.2 \ - unlink.2 utimes.2 utrace.2 uuidgen.2 vfork.2 wait.2 write.2 + unlink.2 utimes.2 utrace.2 uuidgen.2 varsym.2 vfork.2 wait.2 write.2 MLINKS+=access.2 eaccess.2 access.2 faccessat.2 MLINKS+=brk.2 sbrk.2 @@ -210,4 +210,5 @@ MLINKS+=truncate.2 ftruncate.2 MLINKS+=unlink.2 unlinkat.2 MLINKS+=utimes.2 futimes.2 utimes.2 futimesat.2 utimes.2 lutimes.2 MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2 -MLINKS+=write.2 pwrite.2 write.2 pwritev.2 write.2 writev.2 +MLINKS+=write.2 pwrite.2 write.2 writev.2 write.2 pwritev.2 +MLINKS+=varsym.2 varsym_set.2 varsym.2 varsym_get.2 varsym.2 varsym_list.2 Modified: projects/varsym/lib/libc/sys/Symbol.map ============================================================================== --- projects/varsym/lib/libc/sys/Symbol.map Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/lib/libc/sys/Symbol.map Mon Oct 31 23:27:24 2011 (r226973) @@ -326,6 +326,9 @@ FBSD_1.0 { pread; pwrite; truncate; + varsym_set; + varsym_get; + varsym_list; }; FBSD_1.1 { Added: projects/varsym/lib/libc/sys/varsym.2 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/varsym/lib/libc/sys/varsym.2 Mon Oct 31 23:27:24 2011 (r226973) @@ -0,0 +1,205 @@ +.\" Copyright (c) 2008 The Aerospace Corporation +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the author nor the names of its contributors may +.\" be used to endorse or promote products derived from this software +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd March 29 2008 +.Dt VARSYM 2 +.Os +.Sh NAME +.Nm varsym +.Nd manipulate variant symlink variables +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In varsym.h +.Ft int +.Fn varsym_set "int scope" "id_t which" "const char *name" "const char *data" +.Ft int +.Fn varsym_get "int scope" "id_t which" "const char *name" "const char *buf" "size_t *size" +.Ft int +.Fn varsym_list "int scope" "id_t which" "const char *buf" "size_t *size" +.Sh DESCRIPTION +The +.Fn varsym_set +function +sets the variable +.Fa name +in the object specifed by +.Fa scope +and +.Fa which +to the value in the null-terminated string pointed to by +.Fa data . +If +.Fa data +is +.Dv NULL +then the variable will be deleted. +If +.Fa name +is +.Dv NULL +then all variables will be deleted. +.Pp +The +.Fn varsym_get +function +writes the value of the variable +.Fa name +in the object specifed by +.Fa scope +and +.Fa which +to the buffer +.Fa buf +as a null-terminated string. +The number of bytes written to +.Fa which +are copied back to the variable pointed to by +.Fa size. +.Pp +The +.Fn varsym_list +function +writes the names and values of variables +in the object specifed by +.Fa scope +and +.Fa which +to the buffer +.Fa buf +with nulls between each entry and a final null indicating end of list. +The number of bytes written to +.Fa which +are copied back to the variable pointed to by +.Fa size. +.Pp +The +.Fa scope +argument may be one of: +.Bl -tag -width VARSYM_PROC +.It Dv VARSYM_SYS +Get or set variables in the global system scope. +.It Dv VARSYM_PROC +Get or set variables for the given process. +.El +.Pp +The following +.Xr sysctl 3 +MIB variables control the operation of variant symlinks: +.Bl -tag -width vfs.varsym.enable +.It Va vfs.varsym.enable +Enables support for variant symlinks when set to a non-zero value. +Defaults to off. +.It Va vfs.varsym.allow_default +If set to a non-zero value, variant symlinks may be created with default +values to be used if no variable is set. +These values are specified by placing a colon after the variable name in the +link. +For example +.Va ${VAR:defaultvalue} . +.Pp +.Sy WARNING : +Default values should not be used in any way that will effect the execution +of setuid programs unless users can not control the values of variant +symlinks. +Administrators are advised to disable default value support when user +control of per-process values is allowed. +.It Va vfs.varsym.max_proc_setsize +Limits the number of per-processes variables that can be set. +The default limit is 32. +This limit is only enforced if unprivleged control is allowed by +.Va security.bsd.unprivileged_varsym_set_proc . +.It Va security.bsd.unprivileged_varsym_set_proc +If set to a non-zero value, non-root users may set per-process variant symlink +variables. +.El +.Sh RETURN VALUES +.Rv -std varsym_set varsym_get varsym_list +.Sh ERRORS +The +.Fn varsym_set , +.Fn varsym_get , +and +.Fn varsym_list +functions will fail and take no action if: +.Bl -tag -width Er +.It Bq Er EINVAL +An invalid value is passed for +.Fa scope +or +.Fa which . +.It Bq Er EPERM +The +.Fa which +variable is set to a value other than 0 or the current processes pid when +.Fa scope +is +.Dv VARSYM_PROC . +.It Bq Er EOVERFLOW +The buffer passed to +.Fn varsym_get +or +.Fn varsym_list +is too small for the data to be returned. +.It Bq Er E2BIG +For the +.Fn varsym_set +function, the maximum number of variant symlinks for this object has been +reached. +.It Bq Er ENOENT +The requested variant symlink variable does not exist. +.It Bq Er ENOSYS +The system does not support variant symlinks or the support has been +disabled by setting the +.Xr sysctl 3 +MIB +.Va vfs.varsym.enable +to 0. +.It Bq Er EFAULT +One of buffers is outside the process's allocated address space. +.It Bq Er ENAMETOOLONG +The value of +.Fa name +is longer than +.Dv MAXVARSYM_NAME +or +the value of +.Fa data +is longer than +.Dv MAXVARSYM_DATA . +.El +.Sh SEE ALSO +.Xr varsym_clear 3 +.Sh HISTORY +This version of variant symlinks is derived from variant symlink support that +first appeared in DragonFlyBSD 1.0. +.Sh BUGS +The +.Fa which +argument is effectivly unused at this time and must be 0 or the current +processes pid. Modified: projects/varsym/lib/libutil/login.conf.5 ============================================================================== --- projects/varsym/lib/libutil/login.conf.5 Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/lib/libutil/login.conf.5 Mon Oct 31 23:27:24 2011 (r226973) @@ -245,6 +245,8 @@ from other means. .It "timezone string Default value of $TZ environment variable. .It "umask number 022 Initial umask. Should always have a leading 0 to ensure octal interpretation. +.It "varsym list A comma-separated list of variant symlink variables and +values to which they are to be set. .It "welcome file /etc/motd File containing welcome message. .El .Sh AUTHENTICATION Modified: projects/varsym/lib/libutil/login_cap.h ============================================================================== --- projects/varsym/lib/libutil/login_cap.h Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/lib/libutil/login_cap.h Mon Oct 31 23:27:24 2011 (r226973) @@ -50,7 +50,8 @@ #define LOGIN_SETMAC 0x0100 /* set user default MAC label */ #define LOGIN_SETCPUMASK 0x0200 /* set user cpumask */ #define LOGIN_SETLOGINCLASS 0x0400 /* set login class in the kernel */ -#define LOGIN_SETALL 0x07ff /* set everything */ +#define LOGIN_SETVARSYM 0x0800 /* set process variant symlink vars */ +#define LOGIN_SETALL 0x0fff /* set everything */ #define BI_AUTH "authorize" /* accepted authentication */ #define BI_REJECT "reject" /* rejected authentication */ @@ -118,6 +119,7 @@ const char *login_setcryptfmt(login_cap_ int setclasscontext(const char *, unsigned int); void setclasscpumask(login_cap_t *); +void setclassvarsyms(login_cap_t *, const struct passwd *); int setusercontext(login_cap_t *, const struct passwd *, uid_t, unsigned int); void setclassresources(login_cap_t *); void setclassenvironment(login_cap_t *, const struct passwd *, int); Modified: projects/varsym/lib/libutil/login_class.3 ============================================================================== --- projects/varsym/lib/libutil/login_class.3 Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/lib/libutil/login_class.3 Mon Oct 31 23:27:24 2011 (r226973) @@ -175,6 +175,9 @@ no action will be taken. .It LOGIN_SETLOGINCLASS Set the login class of the current process using .Xr setloginclass 2 . +.It LOGIN_SETVARSYM +Set process scope variant symlink variables using the list type capability +"varsym=var1=val1,var2=val2..,varN=valN". .It LOGIN_SETALL Enables all of the above settings. .El @@ -214,6 +217,7 @@ with LOG_ERR priority and directed to th .Xr setlogin 2 , .Xr setloginclass 2 , .Xr setuid 2 , +.Xr varsym 2 , .Xr getcap 3 , .Xr initgroups 3 , .Xr login_cap 3 , Modified: projects/varsym/lib/libutil/login_class.c ============================================================================== --- projects/varsym/lib/libutil/login_class.c Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/lib/libutil/login_class.c Mon Oct 31 23:27:24 2011 (r226973) @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -136,9 +137,15 @@ static struct login_vars { }; static char * -substvar(const char * var, const struct passwd * pwd, int hlen, int pch, int nlen) +substvar(const char * var, const struct passwd * pwd) { - char *np = NULL; + char *np = NULL; + int hlen = pwd ? strlen(pwd->pw_dir) : 0; + int nlen = pwd ? strlen(pwd->pw_name) : 0; + char pch = 0; + + if (hlen && pwd->pw_dir[hlen-1] != '/') + ++pch; if (var != NULL) { int tildes = 0; @@ -196,18 +203,12 @@ void setclassenvironment(login_cap_t *lc, const struct passwd * pwd, int paths) { struct login_vars *vars = paths ? pathvars : envars; - int hlen = pwd ? strlen(pwd->pw_dir) : 0; - int nlen = pwd ? strlen(pwd->pw_name) : 0; - char pch = 0; - - if (hlen && pwd->pw_dir[hlen-1] != '/') - ++pch; while (vars->tag != NULL) { const char * var = paths ? login_getpath(lc, vars->tag, NULL) : login_getcapstr(lc, vars->tag, NULL, NULL); - char * np = substvar(var, pwd, hlen, pch, nlen); + char * np = substvar(var, pwd); if (np != NULL) { setenv(vars->var, np, vars->overwrite); @@ -233,7 +234,7 @@ setclassenvironment(login_cap_t *lc, con char *np; *p++ = '\0'; - if ((np = substvar(p, pwd, hlen, pch, nlen)) != NULL) { + if ((np = substvar(p, pwd)) != NULL) { setenv(*set_env, np, 1); free(np); } @@ -347,6 +348,31 @@ setclasscpumask(login_cap_t *lc) } +void +setclassvarsyms(login_cap_t *lc, const struct passwd * pwd) +{ + const char **varsyms = login_getcaplist(lc, "varsym", ","); + + if (varsyms != NULL) { + while (*varsyms != NULL) { + char *p = strchr(*varsyms, '='); + + if (p != NULL) { /* Discard invalid entries */ + char *np; + + *p++ = '\0'; + if ((np = substvar(p, pwd)) != NULL) { + /* XXX: should we only ignore ENOSYS? */ + (void)varsym_set(VARSYM_PROC, 0, *varsyms, np); + free(np); + } + } + ++varsyms; + } + } +} + + /* * setclasscontext() * @@ -400,6 +426,9 @@ setlogincontext(login_cap_t *lc, const s /* Set cpu affinity */ if (flags & LOGIN_SETCPUMASK) setclasscpumask(lc); + /* Set variant symlink variables */ + if (flags & LOGIN_SETVARSYM) + setclassvarsyms(lc, pwd); } return (mymask); } Modified: projects/varsym/sys/amd64/conf/GENERIC ============================================================================== --- projects/varsym/sys/amd64/conf/GENERIC Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/amd64/conf/GENERIC Mon Oct 31 23:27:24 2011 (r226973) @@ -42,6 +42,7 @@ options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options VARSYM # Variant symlink support options GEOM_PART_GPT # GUID Partition Tables. options GEOM_LABEL # Provides labelization options COMPAT_FREEBSD32 # Compatible with i386 binaries Modified: projects/varsym/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- projects/varsym/sys/compat/freebsd32/freebsd32_misc.c Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/compat/freebsd32/freebsd32_misc.c Mon Oct 31 23:27:24 2011 (r226973) @@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -2514,6 +2515,92 @@ freebsd32_nmount(struct thread *td, return error; } +#ifdef VARSYM +int +freebsd32_varsym_set(struct thread *td, struct freebsd32_varsym_set_args *uap) +{ + struct varsym_set_args ap; + + ap.scope = uap->scope; + ap.which = (uap->whichlo | ((id_t)uap->whichhi << 32)); + ap.name = uap->name; + ap.data = uap->data; + + return (varsym_set(td, &ap)); +} + + +int +freebsd32_varsym_get(struct thread *td, struct freebsd32_varsym_get_args *uap) +{ + int error; + id_t which; + size_t bufsize; + uint32_t bufsize32; + + which = (uap->whichlo | ((id_t)uap->whichhi << 32)); + + if ((error = copyin(uap->size, &bufsize32, sizeof(bufsize32))) != 0) + return(error); + bufsize = bufsize32; + + if ((error = kern_varsym_get(td, uap->scope, which, uap->name, + uap->buf, &bufsize)) != 0) + return(error); + + bufsize32 = bufsize; + error = copyout(&bufsize32, uap->size, sizeof(bufsize32)); + + return(error); +} + +int +freebsd32_varsym_list(struct thread *td, struct freebsd32_varsym_list_args *uap) +{ + int error; + id_t which; + size_t bufsize; + uint32_t bufsize32; + + which = (uap->whichlo | ((id_t)uap->whichhi << 32)); + + if ((error = copyin(uap->size, &bufsize32, sizeof(bufsize32))) != 0) + return(error); + bufsize = bufsize32; + + if ((error = kern_varsym_list(td, uap->scope, which, uap->buf, + &bufsize)) != 0) + return(error); + + bufsize32 = bufsize; + error = copyout(&bufsize32, uap->size, sizeof(bufsize32)); + + return(error); +} + +#else /* VARSYM */ +int +freebsd32_varsym_set(struct thread *td, struct freebsd32_varsym_set_args *uap) +{ + + return (ENOSYS); +} + +int +freebsd32_varsym_get(struct thread *td, struct freebsd32_varsym_get_args *uap) +{ + + return (ENOSYS); +} + +int +freebsd32_varsym_list(struct thread *td, struct freebsd32_varsym_list_args *uap) +{ + + return (ENOSYS); +} +#endif /* VARSYM */ + #if 0 int freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) Modified: projects/varsym/sys/compat/freebsd32/freebsd32_proto.h ============================================================================== --- projects/varsym/sys/compat/freebsd32/freebsd32_proto.h Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/compat/freebsd32/freebsd32_proto.h Mon Oct 31 23:27:24 2011 (r226973) @@ -580,6 +580,28 @@ struct freebsd32_posix_fallocate_args { char len1_l_[PADL_(uint32_t)]; uint32_t len1; char len1_r_[PADR_(uint32_t)]; char len2_l_[PADL_(uint32_t)]; uint32_t len2; char len2_r_[PADR_(uint32_t)]; }; +struct freebsd32_varsym_set_args { + char scope_l_[PADL_(int)]; int scope; char scope_r_[PADR_(int)]; + char whichlo_l_[PADL_(uint32_t)]; uint32_t whichlo; char whichlo_r_[PADR_(uint32_t)]; + char whichhi_l_[PADL_(uint32_t)]; uint32_t whichhi; char whichhi_r_[PADR_(uint32_t)]; + char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)]; + char data_l_[PADL_(const char *)]; const char * data; char data_r_[PADR_(const char *)]; +}; +struct freebsd32_varsym_get_args { + char scope_l_[PADL_(int)]; int scope; char scope_r_[PADR_(int)]; + char whichlo_l_[PADL_(uint32_t)]; uint32_t whichlo; char whichlo_r_[PADR_(uint32_t)]; + char whichhi_l_[PADL_(uint32_t)]; uint32_t whichhi; char whichhi_r_[PADR_(uint32_t)]; + char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char size_l_[PADL_(uint32_t *)]; uint32_t * size; char size_r_[PADR_(uint32_t *)]; +}; +struct freebsd32_varsym_list_args { + char scope_l_[PADL_(int)]; int scope; char scope_r_[PADR_(int)]; + char whichlo_l_[PADL_(uint32_t)]; uint32_t whichlo; char whichlo_r_[PADR_(uint32_t)]; + char whichhi_l_[PADL_(uint32_t)]; uint32_t whichhi; char whichhi_r_[PADR_(uint32_t)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char size_l_[PADL_(uint32_t *)]; uint32_t * size; char size_r_[PADR_(uint32_t *)]; +}; #if !defined(PAD64_REQUIRED) && defined(__powerpc__) #define PAD64_REQUIRED #endif @@ -690,6 +712,9 @@ int freebsd32_msgctl(struct thread *, st int freebsd32_shmctl(struct thread *, struct freebsd32_shmctl_args *); int freebsd32_pselect(struct thread *, struct freebsd32_pselect_args *); int freebsd32_posix_fallocate(struct thread *, struct freebsd32_posix_fallocate_args *); +int freebsd32_varsym_set(struct thread *, struct freebsd32_varsym_set_args *); +int freebsd32_varsym_get(struct thread *, struct freebsd32_varsym_get_args *); +int freebsd32_varsym_list(struct thread *, struct freebsd32_varsym_list_args *); #ifdef COMPAT_43 @@ -1065,6 +1090,9 @@ int freebsd7_freebsd32_shmctl(struct thr #define FREEBSD32_SYS_AUE_freebsd32_shmctl AUE_SHMCTL #define FREEBSD32_SYS_AUE_freebsd32_pselect AUE_SELECT #define FREEBSD32_SYS_AUE_freebsd32_posix_fallocate AUE_NULL +#define FREEBSD32_SYS_AUE_freebsd32_varsym_set AUE_NULL +#define FREEBSD32_SYS_AUE_freebsd32_varsym_get AUE_NULL +#define FREEBSD32_SYS_AUE_freebsd32_varsym_list AUE_NULL #undef PAD_ #undef PADL_ Modified: projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h ============================================================================== --- projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/compat/freebsd32/freebsd32_syscall.h Mon Oct 31 23:27:24 2011 (r226973) @@ -424,4 +424,7 @@ #define FREEBSD32_SYS_rctl_add_rule 528 #define FREEBSD32_SYS_rctl_remove_rule 529 #define FREEBSD32_SYS_freebsd32_posix_fallocate 530 -#define FREEBSD32_SYS_MAXSYSCALL 532 +#define FREEBSD32_SYS_freebsd32_varsym_set 532 +#define FREEBSD32_SYS_freebsd32_varsym_get 533 +#define FREEBSD32_SYS_freebsd32_varsym_list 534 +#define FREEBSD32_SYS_MAXSYSCALL 535 Modified: projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c ============================================================================== --- projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/compat/freebsd32/freebsd32_syscalls.c Mon Oct 31 23:27:24 2011 (r226973) @@ -555,4 +555,7 @@ const char *freebsd32_syscallnames[] = { "rctl_remove_rule", /* 529 = rctl_remove_rule */ "freebsd32_posix_fallocate", /* 530 = freebsd32_posix_fallocate */ "#531", /* 531 = posix_fadvise */ + "freebsd32_varsym_set", /* 532 = freebsd32_varsym_set */ + "freebsd32_varsym_get", /* 533 = freebsd32_varsym_get */ + "freebsd32_varsym_list", /* 534 = freebsd32_varsym_list */ }; Modified: projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c ============================================================================== --- projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/compat/freebsd32/freebsd32_sysent.c Mon Oct 31 23:27:24 2011 (r226973) @@ -592,4 +592,7 @@ struct sysent freebsd32_sysent[] = { { AS(rctl_remove_rule_args), (sy_call_t *)sys_rctl_remove_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 529 = rctl_remove_rule */ { AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 531 = posix_fadvise */ + { AS(freebsd32_varsym_set_args), (sy_call_t *)freebsd32_varsym_set, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = freebsd32_varsym_set */ + { AS(freebsd32_varsym_get_args), (sy_call_t *)freebsd32_varsym_get, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = freebsd32_varsym_get */ + { AS(freebsd32_varsym_list_args), (sy_call_t *)freebsd32_varsym_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 534 = freebsd32_varsym_list */ }; Modified: projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c ============================================================================== --- projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/compat/freebsd32/freebsd32_systrace_args.c Mon Oct 31 23:27:24 2011 (r226973) @@ -3034,6 +3034,40 @@ systrace_args(int sysnum, void *params, *n_args = 5; break; } + /* freebsd32_varsym_set */ + case 532: { + struct freebsd32_varsym_set_args *p = params; + iarg[0] = p->scope; /* int */ + uarg[1] = p->whichlo; /* uint32_t */ + uarg[2] = p->whichhi; /* uint32_t */ + uarg[3] = (intptr_t) p->name; /* const char * */ + uarg[4] = (intptr_t) p->data; /* const char * */ + *n_args = 5; + break; + } + /* freebsd32_varsym_get */ + case 533: { + struct freebsd32_varsym_get_args *p = params; + iarg[0] = p->scope; /* int */ + uarg[1] = p->whichlo; /* uint32_t */ + uarg[2] = p->whichhi; /* uint32_t */ + uarg[3] = (intptr_t) p->name; /* const char * */ + uarg[4] = (intptr_t) p->buf; /* char * */ + uarg[5] = (intptr_t) p->size; /* uint32_t * */ + *n_args = 6; + break; + } + /* freebsd32_varsym_list */ + case 534: { + struct freebsd32_varsym_list_args *p = params; + iarg[0] = p->scope; /* int */ + uarg[1] = p->whichlo; /* uint32_t */ + uarg[2] = p->whichhi; /* uint32_t */ + uarg[3] = (intptr_t) p->buf; /* char * */ + uarg[4] = (intptr_t) p->size; /* uint32_t * */ + *n_args = 5; + break; + } default: *n_args = 0; break; @@ -8093,6 +8127,75 @@ systrace_setargdesc(int sysnum, int ndx, break; }; break; + /* freebsd32_varsym_set */ + case 532: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "uint32_t"; + break; + case 2: + p = "uint32_t"; + break; + case 3: + p = "const char *"; + break; + case 4: + p = "const char *"; + break; + default: + break; + }; + break; + /* freebsd32_varsym_get */ + case 533: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "uint32_t"; + break; + case 2: + p = "uint32_t"; + break; + case 3: + p = "const char *"; + break; + case 4: + p = "char *"; + break; + case 5: + p = "uint32_t *"; + break; + default: + break; + }; + break; + /* freebsd32_varsym_list */ + case 534: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "uint32_t"; + break; + case 2: + p = "uint32_t"; + break; + case 3: + p = "char *"; + break; + case 4: + p = "uint32_t *"; + break; + default: + break; + }; + break; default: break; }; Modified: projects/varsym/sys/compat/freebsd32/syscalls.master ============================================================================== --- projects/varsym/sys/compat/freebsd32/syscalls.master Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/compat/freebsd32/syscalls.master Mon Oct 31 23:27:24 2011 (r226973) @@ -992,3 +992,13 @@ uint32_t offset1, uint32_t offset2,\ uint32_t len1, uint32_t len2); } 531 AUE_NULL UNIMPL posix_fadvise +532 AUE_NULL STD { int freebsd32_varsym_set(int scope, \ + uint32_t whichlo, uint32_t whichhi, \ + const char *name, const char *data); } +533 AUE_NULL STD { int freebsd32_varsym_get(int scope, \ + uint32_t whichlo, uint32_t whichhi, \ + const char *name, \ + char *buf, uint32_t *size); } +534 AUE_NULL STD { int freebsd32_varsym_list(int scope, \ + uint32_t whichlo, uint32_t whichhi, \ + char *buf, uint32_t *size); } Modified: projects/varsym/sys/conf/files ============================================================================== --- projects/varsym/sys/conf/files Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/conf/files Mon Oct 31 23:27:24 2011 (r226973) @@ -2358,6 +2358,7 @@ kern/kern_time.c standard kern/kern_timeout.c standard kern/kern_umtx.c standard kern/kern_uuid.c standard +kern/kern_varsym.c standard kern/kern_xxx.c standard kern/link_elf.c standard kern/linker_if.m standard Modified: projects/varsym/sys/conf/options ============================================================================== --- projects/varsym/sys/conf/options Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/conf/options Mon Oct 31 23:27:24 2011 (r226973) @@ -183,6 +183,7 @@ SYSVSEM opt_sysvipc.h SYSVSHM opt_sysvipc.h SW_WATCHDOG opt_watchdog.h TURNSTILE_PROFILING +VARSYM VFS_AIO VERBOSE_SYSINIT opt_global.h WLCACHE opt_wavelan.h Modified: projects/varsym/sys/kern/init_sysent.c ============================================================================== --- projects/varsym/sys/kern/init_sysent.c Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/kern/init_sysent.c Mon Oct 31 23:27:24 2011 (r226973) @@ -566,4 +566,7 @@ struct sysent sysent[] = { { AS(rctl_remove_rule_args), (sy_call_t *)sys_rctl_remove_rule, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 529 = rctl_remove_rule */ { AS(posix_fallocate_args), (sy_call_t *)sys_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = posix_fallocate */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 531 = posix_fadvise */ + { AS(varsym_set_args), (sy_call_t *)sys_varsym_set, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = varsym_set */ + { AS(varsym_get_args), (sy_call_t *)sys_varsym_get, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = varsym_get */ + { AS(varsym_list_args), (sy_call_t *)sys_varsym_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 534 = varsym_list */ }; Modified: projects/varsym/sys/kern/kern_exec.c ============================================================================== --- projects/varsym/sys/kern/kern_exec.c Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/kern/kern_exec.c Mon Oct 31 23:27:24 2011 (r226973) @@ -729,6 +729,14 @@ interpret: change_svgid(newcred, newcred->cr_gid); p->p_ucred = newcred; newcred = NULL; + +#ifdef VARSYM + /* + * Clear local varsym variables. + * Do not clear privleged varsym variables. + */ + varsymset_clean(&p->p_varsymset); +#endif } else { if (oldcred->cr_uid == oldcred->cr_ruid && oldcred->cr_gid == oldcred->cr_rgid) Modified: projects/varsym/sys/kern/kern_fork.c ============================================================================== --- projects/varsym/sys/kern/kern_fork.c Mon Oct 31 21:05:19 2011 (r226972) +++ projects/varsym/sys/kern/kern_fork.c Mon Oct 31 23:27:24 2011 (r226973) @@ -426,6 +426,14 @@ do_fork(struct thread *td, int flags, st else newsigacts = sigacts_alloc(); +#ifdef VARSYM + /* + * Initialize and copy varsyms + */ + varsymset_init(&p2->p_varsymset, &p1->p_varsymset); + varsymset_init(&p2->p_varsymset_priv, &p1->p_varsymset_priv); +#endif + /* * Copy filedesc. */ Added: projects/varsym/sys/kern/kern_varsym.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/varsym/sys/kern/kern_varsym.c Mon Oct 31 23:27:24 2011 (r226973) @@ -0,0 +1,723 @@ +/* + * Copyright (c) 2003,2004 The DragonFly Project. All rights reserved. + * Copyright (c) 2007-2009 The Aerospace Corporation. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of The DragonFly Project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific, prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * $DragonFly: src/sys/kern/kern_varsym.c,v 1.6 2005/01/14 02:25:08 joerg Exp $ + */ + +/* + * This module implements variable storage and management for variant + * symlinks. These variables may also be used for general purposes. + */ + +#include "opt_varsym.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef VARSYM + +SYSCTL_NODE(_vfs, OID_AUTO, varsym, CTLFLAG_RD, NULL, + "Variant symlink managment"); + +int varsym_enable = 0; +SYSCTL_INT(_vfs_varsym, OID_AUTO, enable, CTLFLAG_RW, &varsym_enable, 0, + "Enable Variant Symlinks"); +TUNABLE_INT("vfs.varsym.enable", + &varsym_enable); + +static int varsym_allow_default = 0; +SYSCTL_INT(_vfs_varsym, OID_AUTO, allow_default, CTLFLAG_RW, + &varsym_allow_default, 0, + "allow variables to have default values"); +TUNABLE_INT("vfs.varsym.allow_default", + &varsym_allow_default); + +static int varsym_max_proc_setsize = 32; +SYSCTL_INT(_vfs_varsym, OID_AUTO, max_proc_setsize, CTLFLAG_RW, + &varsym_max_proc_setsize, 0, + "maximum number of varsym variables on a process"); +TUNABLE_INT("vfs.varsym_max_proc_setsize", + &varsym_max_proc_setsize); + +static int unprivileged_varsym_set_proc = 1; +SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_varsym_set_proc, CTLFLAG_RW, + &unprivileged_varsym_set_proc, 0, + "allow unprivileged users to set per-process varsym variables"); +TUNABLE_INT("security.bsd.unprivileged_varsym_set_proc", + &unprivileged_varsym_set_proc); + +MALLOC_DEFINE(M_VARSYM, "varsym", "variable sets for variant symlinks"); +static struct mtx varsym_mutex; +static struct varsymset varsymset_sys; + +static int varsymmake(int scope, const char *name, const char *data); +static void varsymdrop(varsym_t var); +static struct varsyment * varsymlookup(struct varsymset *vss, const char *name, + int namelen); +static int varsym_clear(struct thread *td, int scope, id_t which); +static int vss2buf(struct varsymset *vss, char *buf, int *bytes, + int maxsize); +static varsym_t varsymfind(int scope, const char *name, int namelen); + +/* + * Initialize the variant symlink subsystem + */ +static void +varsym_sysinit(void *dummy) +{ + mtx_init(&varsym_mutex, "varsym", NULL, MTX_DEF); + varsymset_init(&varsymset_sys, NULL); +} +SYSINIT(announce, SI_SUB_INTRINSIC, SI_ORDER_FIRST, varsym_sysinit, NULL); + +/* + * Initialize the varsymset for proc0 + */ +static void +varsym_p0init(void *dummy) +{ + PROC_LOCK(&proc0); + varsymset_init(&proc0.p_varsymset, NULL); + varsymset_init(&proc0.p_varsymset_priv, NULL); + PROC_UNLOCK(&proc0); +} +SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_SECOND, varsym_p0init, NULL); + +/* + * varsymreplace() - called from namei + * + * Do variant symlink variable substitution + */ +int +varsymreplace(char *cp, int linklen, int maxlen) +{ + int rlen; + int xlen; + int nlen; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***