Page MenuHomeFreeBSD

D18930.diff
No OneTemporary

D18930.diff

Index: include/pthread_np.h
===================================================================
--- include/pthread_np.h
+++ include/pthread_np.h
@@ -51,6 +51,7 @@
int pthread_attr_setaffinity_np(pthread_attr_t *, size_t, const cpuset_t *);
void pthread_get_name_np(pthread_t, char *, size_t);
int pthread_getaffinity_np(pthread_t, size_t, cpuset_t *);
+int pthread_getcred_np(uid_t *, int *, gid_t *);
int pthread_getthreadid_np(void);
int pthread_main_np(void);
int pthread_multi_np(void);
@@ -63,8 +64,10 @@
int pthread_mutex_isowned_np(pthread_mutex_t *mutex);
void pthread_resume_all_np(void);
int pthread_resume_np(pthread_t);
+int pthread_revertcred_np(void);
void pthread_set_name_np(pthread_t, const char *);
int pthread_setaffinity_np(pthread_t, size_t, const cpuset_t *);
+int pthread_setcred_np(uid_t , int , gid_t *);
int pthread_single_np(void);
void pthread_suspend_all_np(void);
int pthread_suspend_np(pthread_t);
Index: include/unistd.h
===================================================================
--- include/unistd.h
+++ include/unistd.h
@@ -505,6 +505,7 @@
int execvP(const char *, const char *, char * const *);
int feature_present(const char *);
char *fflagstostr(u_long);
+int getcred(uid_t *, int *, gid_t *);
int getdomainname(char *, int);
int getentropy(void *, size_t);
int getgrouplist(const char *, gid_t, gid_t *, int *);
@@ -550,6 +551,7 @@
char *re_comp(const char *);
int re_exec(const char *);
int reboot(int);
+int revertcred(void);
int revoke(const char *);
pid_t rfork(int);
pid_t rfork_thread(int, void *, int (*)(void *), void *);
@@ -562,6 +564,7 @@
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
#endif
#endif
+int setcred(uid_t, int, const gid_t *);
int setdomainname(const char *, int);
int setgroups(int, const gid_t *);
void sethostid(long);
Index: lib/libc/include/namespace.h
===================================================================
--- lib/libc/include/namespace.h
+++ lib/libc/include/namespace.h
@@ -138,6 +138,7 @@
#define pthread_getaffinity_np _pthread_getaffinity_np
#define pthread_getconcurrency _pthread_getconcurrency
#define pthread_getcpuclockid _pthread_getcpuclockid
+#define pthread_getcred_np _pthread_getcred_np
#define pthread_getprio _pthread_getprio
#define pthread_getschedparam _pthread_getschedparam
#define pthread_getspecific _pthread_getspecific
@@ -172,6 +173,7 @@
#define pthread_once _pthread_once
#define pthread_resume_all_np _pthread_resume_all_np
#define pthread_resume_np _pthread_resume_np
+#define pthread_revertcred_np _pthread_revertcred_np
#define pthread_rwlock_destroy _pthread_rwlock_destroy
#define pthread_rwlock_init _pthread_rwlock_init
#define pthread_rwlock_rdlock _pthread_rwlock_rdlock
@@ -191,6 +193,7 @@
#define pthread_setcancelstate _pthread_setcancelstate
#define pthread_setcanceltype _pthread_setcanceltype
#define pthread_setconcurrency _pthread_setconcurrency
+#define pthread_setcred_np _pthread_setcred_np
#define pthread_setprio _pthread_setprio
#define pthread_setschedparam _pthread_setschedparam
#define pthread_setspecific _pthread_setspecific
Index: lib/libc/include/un-namespace.h
===================================================================
--- lib/libc/include/un-namespace.h
+++ lib/libc/include/un-namespace.h
@@ -119,6 +119,7 @@
#undef pthread_getaffinity_np
#undef pthread_getconcurrency
#undef pthread_getcpuclockid
+#undef pthread_getcred_np
#undef pthread_getprio
#undef pthread_getschedparam
#undef pthread_getspecific
@@ -153,6 +154,7 @@
#undef pthread_once
#undef pthread_resume_all_np
#undef pthread_resume_np
+#undef pthread_revertcred_np
#undef pthread_rwlock_destroy
#undef pthread_rwlock_init
#undef pthread_rwlock_rdlock
@@ -172,6 +174,7 @@
#undef pthread_setcancelstate
#undef pthread_setcanceltype
#undef pthread_setconcurrency
+#undef pthread_setcred_np
#undef pthread_setprio
#undef pthread_setschedparam
#undef pthread_setspecific
Index: lib/libc/sys/Makefile.inc
===================================================================
--- lib/libc/sys/Makefile.inc
+++ lib/libc/sys/Makefile.inc
@@ -297,6 +297,7 @@
semget.2 \
semop.2 \
send.2 \
+ setcred.2 \
setfib.2 \
sendfile.2 \
setgroups.2 \
@@ -463,6 +464,8 @@
select.2 FD_ZERO.3
MLINKS+=send.2 sendmsg.2 \
send.2 sendto.2
+MLINKS+=setcred.2 getcred.2 \
+ setcred.2 revertcred.2
MLINKS+=setpgid.2 setpgrp.2
MLINKS+=setresuid.2 getresgid.2 \
setresuid.2 getresuid.2 \
Index: lib/libc/sys/Symbol.map
===================================================================
--- lib/libc/sys/Symbol.map
+++ lib/libc/sys/Symbol.map
@@ -406,6 +406,9 @@
fhlinkat;
fhreadlink;
getfhat;
+ getcred;
+ setcred;
+ revertcred;
};
FBSDprivate_1.0 {
Index: lib/libc/sys/setcred.2
===================================================================
--- /dev/null
+++ lib/libc/sys/setcred.2
@@ -0,0 +1,119 @@
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2019 Gandi
+.\"
+.\" 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.
+.\"
+.\" 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 January 23, 2019
+.Dt SETCRED 2
+.Os
+.Sh NAME
+.Nm setcred ,
+.Nm getcred ,
+.Nm revertcred
+.Nd control per-thread user credentials
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In unistd.h
+.In sys/param.h
+.Ft int
+.Fn setcred "uid_t uid" "int gidsetlen" "const gid_t *gidset"
+.Ft int
+.Fn getcred "uid_t *uid" "int *gidsetlen" "const gid_t *gidset"
+.Ft int
+.Fn revertcred "void"
+.Sh Description
+The
+.Fn setcred
+system call sets the real, effective, and saved UIDs and GIDs,
+along with supplementary group access list of the current thread.
+.Pp
+The
+.Fa uid
+parameter can be any UID.
+The
+.Fa gidsetlen
+parameter indicates the number of entries in the array and must be no more
+than NGROUPS. The
+.Fa gidset
+parameter is an array of GIDs, the first being the primary GID to set.
+This call will replace all supplementary groups in the credential.
+.Pp
+The
+.Fn getcred
+system call retrieves the real user ID of the calling thread and stores it in
+.Fa uid .
+It also retrieves the current group access list of the calling thread and
+stores it in
+.Fa gidset .
+The gidsetlen argument indicates the number of entries that may be placed in
+gidset.
+.Pp
+The
+.Fn getcred
+system call sets this variable to the actual number of groups returned in
+gidset, even on error.
+.Pp
+The
+.Fn revertcred
+system call reverts the thread's credential, including the real, effective and
+saved UIDs and GIDs, to the per-process credential.
+.Pp
+These system calls may only be called if the process has super-user privileges.
+.Sh RETURN VALUES
+.Rv -std
+.Sh ERRORS
+The
+.Fn revertcred
+system call will only fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The user is not the super user.
+.El
+.Pp
+In addition to the error returned by
+.Fn revertcred ,
+the
+.Fn setcred
+and
+.Fn getcred
+system calls may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value of
+.Fa gidsetlen
+is not valid.
+.It Bq Er ENOENT
+The per-thread credential has not yet been explicitly set with
+.Fn setcred ,
+or it has been reverted with
+.Fn revertcred .
+.It Bq Er ERANGE
+The incoming
+.Fa gidsetlen
+is less than the number of groups in the credential.
+.It Bq Er EFAULT
+One of the parameters points to an invalid address.
+.El
Index: lib/libthr/pthread.map
===================================================================
--- lib/libthr/pthread.map
+++ lib/libthr/pthread.map
@@ -325,3 +325,9 @@
FBSD_1.5 {
pthread_get_name_np;
};
+
+FBSD_1.6 {
+ pthread_getcred_np;
+ pthread_setcred_np;
+ pthread_revertcred_np;
+};
Index: lib/libthr/thread/Makefile.inc
===================================================================
--- lib/libthr/thread/Makefile.inc
+++ lib/libthr/thread/Makefile.inc
@@ -14,6 +14,7 @@
thr_cond.c \
thr_condattr.c \
thr_create.c \
+ thr_cred_np.c \
thr_ctrdtr.c \
thr_detach.c \
thr_equal.c \
Index: lib/libthr/thread/thr_cred_np.c
===================================================================
--- /dev/null
+++ lib/libthr/thread/thr_cred_np.c
@@ -0,0 +1,58 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018 Gandi
+ *
+ * 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.
+ *
+ * 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
+#include <unistd.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include "un-namespace.h"
+
+__weak_reference(_pthread_getcred_np, pthread_getcred_np);
+__weak_reference(_pthread_setcred_np, pthread_setcred_np);
+__weak_reference(_pthread_revertcred_np, pthread_revertcred_np);
+
+int _pthread_getcred_np(uid_t *uid, int *gidsetlen, gid_t *gidset)
+{
+
+ return (getcred(uid, gidsetlen, gidset));
+}
+
+int _pthread_setcred_np(uid_t uid, int gidsetlen, gid_t *gidset)
+{
+
+ return (setcred(uid, gidsetlen, gidset));
+}
+
+int _pthread_revertcred_np(void)
+{
+
+ return (revertcred());
+}
Index: share/man/man3/Makefile
===================================================================
--- share/man/man3/Makefile
+++ share/man/man3/Makefile
@@ -275,6 +275,7 @@
pthread_rwlock_wrlock.3 \
pthread_schedparam.3 \
pthread_self.3 \
+ pthread_setcred_np.3 \
pthread_set_name_np.3 \
pthread_setspecific.3 \
pthread_sigmask.3 \
@@ -339,6 +340,8 @@
PTHREAD_MLINKS+=pthread_rwlock_wrlock.3 pthread_rwlock_trywrlock.3
PTHREAD_MLINKS+=pthread_schedparam.3 pthread_getschedparam.3 \
pthread_schedparam.3 pthread_setschedparam.3
+PTHREAD_MLINKS+=pthread_setcred_np.3 pthread_getcred_np.3 \
+ pthread_setcred_np.3 pthread_revertcred_np.3
PTHREAD_MLINKS+=pthread_set_name_np.3 pthread_get_name_np.3
PTHREAD_MLINKS+=pthread_spin_init.3 pthread_spin_destroy.3 \
pthread_spin_lock.3 pthread_spin_trylock.3 \
Index: share/man/man3/pthread_setcred_np.3
===================================================================
--- /dev/null
+++ share/man/man3/pthread_setcred_np.3
@@ -0,0 +1,124 @@
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2019 Gandi
+.\"
+.\" 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.
+.\"
+.\" 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 January 23, 2019
+.Dt pthread_setcred_np 3
+.Os
+.Sh NAME
+.Nm pthread_setcred_np ,
+.Nm pthread_getcred_np ,
+.Nm pthread_revertcred_np
+.Nd control per-thread user credentials
+.Sh LIBRARY
+.Lb libpthread
+.Sh SYNOPSIS
+.In pthread_np.h
+.In sys/param.h
+.Ft int
+.Fn pthread_setcred_np "uid_t uid" "int gidsetlen" "const gid_t *gidset"
+.Ft int
+.Fn pthread_getcred_np "uid_t *uid" "int *gidsetlen" "const gid_t *gidset"
+.Ft int
+.Fn pthread_revertcred_np "void"
+.Sh Description
+The
+.Fn pthread_setcred_np
+function sets the real, effective, and saved UIDs and GIDs,
+along with supplementary group access list of the current thread.
+.Pp
+The
+.Fa uid
+parameter can be any UID. The
+.Fa gidsetlen
+parameter indicates the number of entries in the array and must be no more
+than NGROUPS. The
+.Fa gidset
+parameter is an array of GIDs, the first being the primary GID to set.
+This call will replace all supplementary groups in the credential.
+.Pp
+The
+.Fn pthread_getcred_np
+function retrieves the real user ID of the calling thread and stores it in
+.Fa uid .
+It also retrieves the current group access list of the calling thread and
+stores it in
+.Fa gidset .
+The gidsetlen argument indicates the number of entries that may be placed in
+gidset.
+.Pp
+The
+.Fn pthread_getcred_np
+sets this variable to the actual number of groups returned in
+gidset, even on error.
+.Pp
+The
+.Fn pthread_revertcred_np
+function reverts the thread's credential, including the real, effective and
+saved UIDs and GIDs, to the per-process credential.
+.Pp
+These functions may only be called if the process has super-user privileges.
+.Sh RETURN VALUES
+.Rv -std
+.Sh ERRORS
+The
+.Fn pthread_revertcred_np
+function will only fail if:
+.Bl -tag -width Er
+.It Bq Er EPERM
+The user is not the super user.
+.El
+.Pp
+In addition to the error returned by
+.Fn pthread_revertcred_np ,
+the
+.Fn pthread_setcred_np
+and
+.Fn pthread_getcred_np
+functions calls may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value of
+.Fa gidsetlen
+is not valid.
+.It Bq Er ENOENT
+The per-thread credential has not yet been explicitly set with
+.Fn pthread_setcred_np ,
+or it has been reverted with
+.Fn pthread_revertcred_np .
+.It Bq Er ERANGE
+The incoming
+.Fa gidsetlen
+is less than the number of groups in the credential.
+.It Bq Er EFAULT
+One of the parameters points to an invalid address.
+.El
+.Sh STANDARDS
+These functions are non standard extensions.
+.Sh SEE ALSO
+.Xr setcred 2 ,
+.Xr getcred 2 ,
+.Xr revertcred 2 ,
Index: sys/bsm/audit_kevents.h
===================================================================
--- sys/bsm/audit_kevents.h
+++ sys/bsm/audit_kevents.h
@@ -644,6 +644,9 @@
#define AUE_SETLOGINCLASS 43238 /* FreeBSD-specific. */
#define AUE_POSIX_FADVISE 43239 /* FreeBSD-specific. */
#define AUE_SCTP_GENERIC_SENDMSG_IOV 43240 /* FreeBSD-specific. */
+#define AUE_GETCRED 43263 /* FreeBSD-specific. */
+#define AUE_SETCRED 43264 /* FreeBSD-specific. */
+#define AUE_REVERTCRED 43265 /* FreeBSD-specific. */
/*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
Index: sys/compat/freebsd32/syscalls.master
===================================================================
--- sys/compat/freebsd32/syscalls.master
+++ sys/compat/freebsd32/syscalls.master
@@ -1145,5 +1145,10 @@
const char *to); }
567 AUE_NULL NOPROTO { int fhreadlink( struct fhandle *fhp, char *buf, \
size_t bufsize); }
+568 AUE_SETCRED NOPROTO { int setcred( uid_t uid, int gidsetlen, \
+ const gid_t *gidset); }
+569 AUE_GETCRED NOPROTO { int getcred( uid_t *uid, int *gidsetlen, \
+ gid_t *gidset); }
+570 AUE_REVERTCRED NOPROTO { int revertcred(void); }
; vim: syntax=off
Index: sys/ddb/db_ps.c
===================================================================
--- sys/ddb/db_ps.c
+++ sys/ddb/db_ps.c
@@ -257,7 +257,11 @@
void *wchan;
if (all) {
- db_printf("%6d ", td->td_tid);
+ db_printf("%6d ", td->td_tid);
+ if (TD_IS_SUGID(td))
+ db_printf("%5d ", td->td_ucred->cr_ruid);
+ else
+ db_printf(" ");
switch (td->td_state) {
case TDS_RUNNING:
snprintf(state, sizeof(state), "Run");
@@ -340,6 +344,7 @@
struct lock_object *lock;
bool comma;
int delta;
+ int i;
/* Determine which thread to examine. */
if (have_addr)
@@ -350,6 +355,15 @@
db_printf("Thread %d at %p:\n", td->td_tid, td);
db_printf(" proc (pid %d): %p\n", td->td_proc->p_pid, td->td_proc);
+ if (TD_IS_SUGID(td)) {
+ db_printf(" uid: %d gids: ", td->td_ucred->cr_uid);
+ for (i = 0; i < td->td_ucred->cr_ngroups; i++) {
+ db_printf("%d", td->td_ucred->cr_groups[i]);
+ if (i < (td->td_ucred->cr_ngroups - 1))
+ db_printf(", ");
+ }
+ db_printf("\n");
+ }
if (td->td_name[0] != '\0')
db_printf(" name: %s\n", td->td_name);
db_printf(" stack: %p-%p\n", (void *)td->td_kstack,
Index: sys/fs/unionfs/union_subr.c
===================================================================
--- sys/fs/unionfs/union_subr.c
+++ sys/fs/unionfs/union_subr.c
@@ -772,7 +772,7 @@
*/
chgproccnt(cred->cr_ruidinfo, 1, 0);
change_euid(cred, rootinfo);
- change_ruid(cred, rootinfo);
+ change_ruid(cred, rootinfo, 1);
change_svuid(cred, (uid_t)0);
uifree(rootinfo);
cnp->cn_cred = cred;
Index: sys/kern/kern_proc.c
===================================================================
--- sys/kern/kern_proc.c
+++ sys/kern/kern_proc.c
@@ -954,7 +954,6 @@
struct thread *td0;
struct tty *tp;
struct session *sp;
- struct ucred *cred;
struct sigacts *ps;
struct timeval boottime;
@@ -974,34 +973,6 @@
kp->ki_vmspace = p->p_vmspace;
kp->ki_flag = p->p_flag;
kp->ki_flag2 = p->p_flag2;
- cred = p->p_ucred;
- if (cred) {
- kp->ki_uid = cred->cr_uid;
- kp->ki_ruid = cred->cr_ruid;
- kp->ki_svuid = cred->cr_svuid;
- kp->ki_cr_flags = 0;
- if (cred->cr_flags & CRED_FLAG_CAPMODE)
- kp->ki_cr_flags |= KI_CRF_CAPABILITY_MODE;
- /* XXX bde doesn't like KI_NGROUPS */
- if (cred->cr_ngroups > KI_NGROUPS) {
- kp->ki_ngroups = KI_NGROUPS;
- kp->ki_cr_flags |= KI_CRF_GRP_OVERFLOW;
- } else
- kp->ki_ngroups = cred->cr_ngroups;
- bcopy(cred->cr_groups, kp->ki_groups,
- kp->ki_ngroups * sizeof(gid_t));
- kp->ki_rgid = cred->cr_rgid;
- kp->ki_svgid = cred->cr_svgid;
- /* If jailed(cred), emulate the old P_JAILED flag. */
- if (jailed(cred)) {
- kp->ki_flag |= P_JAILED;
- /* If inside the jail, use 0 as a jail ID. */
- if (cred->cr_prison != curthread->td_ucred->cr_prison)
- kp->ki_jid = cred->cr_prison->pr_id;
- }
- strlcpy(kp->ki_loginclass, cred->cr_loginclass->lc_name,
- sizeof(kp->ki_loginclass));
- }
ps = p->p_sigacts;
if (ps) {
mtx_lock(&ps->ps_mtx);
@@ -1107,6 +1078,7 @@
fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread)
{
struct proc *p;
+ struct ucred *cred;
p = td->td_proc;
kp->ki_tdaddr = td;
@@ -1115,6 +1087,34 @@
if (preferthread)
PROC_STATLOCK(p);
thread_lock(td);
+ cred = td->td_ucred;
+ if (cred) {
+ kp->ki_uid = cred->cr_uid;
+ kp->ki_ruid = cred->cr_ruid;
+ kp->ki_svuid = cred->cr_svuid;
+ kp->ki_cr_flags = 0;
+ if (cred->cr_flags & CRED_FLAG_CAPMODE)
+ kp->ki_cr_flags |= KI_CRF_CAPABILITY_MODE;
+ /* XXX bde doesn't like KI_NGROUPS */
+ if (cred->cr_ngroups > KI_NGROUPS) {
+ kp->ki_ngroups = KI_NGROUPS;
+ kp->ki_cr_flags |= KI_CRF_GRP_OVERFLOW;
+ } else
+ kp->ki_ngroups = cred->cr_ngroups;
+ bcopy(cred->cr_groups, kp->ki_groups,
+ kp->ki_ngroups * sizeof(gid_t));
+ kp->ki_rgid = cred->cr_rgid;
+ kp->ki_svgid = cred->cr_svgid;
+ /* If jailed(cred), emulate the old P_JAILED flag. */
+ if (jailed(cred)) {
+ kp->ki_flag |= P_JAILED;
+ /* If inside the jail, use 0 as a jail ID. */
+ if (cred->cr_prison != curthread->td_ucred->cr_prison)
+ kp->ki_jid = cred->cr_prison->pr_id;
+ }
+ strlcpy(kp->ki_loginclass, cred->cr_loginclass->lc_name,
+ sizeof(kp->ki_loginclass));
+ }
if (td->td_wmesg != NULL)
strlcpy(kp->ki_wmesg, td->td_wmesg, sizeof(kp->ki_wmesg));
else
Index: sys/kern/kern_prot.c
===================================================================
--- sys/kern/kern_prot.c
+++ sys/kern/kern_prot.c
@@ -87,6 +87,11 @@
static void crsetgroups_locked(struct ucred *cr, int ngrp,
gid_t *groups);
+static int kern_setresuid(struct thread *td,
+ struct ucred *newcred, struct ucred *oldcred,
+ uid_t ruid, uid_t euid, uid_t suid,
+ struct uidinfo *euip, struct uidinfo *ruip,
+ int chgproccnt);
#ifndef _SYS_SYSPROTO_H_
struct getpid_args {
@@ -219,9 +224,9 @@
sys_getuid(struct thread *td, struct getuid_args *uap)
{
- td->td_retval[0] = td->td_ucred->cr_ruid;
+ td->td_retval[0] = td->td_pucred->cr_ruid;
#if defined(COMPAT_43)
- td->td_retval[1] = td->td_ucred->cr_uid;
+ td->td_retval[1] = td->td_pucred->cr_uid;
#endif
return (0);
}
@@ -236,7 +241,7 @@
sys_geteuid(struct thread *td, struct geteuid_args *uap)
{
- td->td_retval[0] = td->td_ucred->cr_uid;
+ td->td_retval[0] = td->td_pucred->cr_uid;
return (0);
}
@@ -250,9 +255,9 @@
sys_getgid(struct thread *td, struct getgid_args *uap)
{
- td->td_retval[0] = td->td_ucred->cr_rgid;
+ td->td_retval[0] = td->td_pucred->cr_rgid;
#if defined(COMPAT_43)
- td->td_retval[1] = td->td_ucred->cr_groups[0];
+ td->td_retval[1] = td->td_pucred->cr_groups[0];
#endif
return (0);
}
@@ -272,7 +277,7 @@
sys_getegid(struct thread *td, struct getegid_args *uap)
{
- td->td_retval[0] = td->td_ucred->cr_groups[0];
+ td->td_retval[0] = td->td_pucred->cr_groups[0];
return (0);
}
@@ -289,7 +294,7 @@
u_int ngrp;
int error;
- cred = td->td_ucred;
+ cred = td->td_pucred;
ngrp = cred->cr_ngroups;
if (uap->gidsetsize == 0) {
@@ -538,7 +543,7 @@
* Set the real uid and transfer proc count to new user.
*/
if (uid != oldcred->cr_ruid) {
- change_ruid(newcred, uip);
+ change_ruid(newcred, uip, 1);
setsugid(p);
}
/*
@@ -792,6 +797,8 @@
int
sys_setgroups(struct thread *td, struct setgroups_args *uap)
{
+ struct ucred *newcred, *oldcred;
+ struct proc *p = td->td_proc;
gid_t smallgroups[XU_NGROUPS];
gid_t *groups;
u_int gidsetsize;
@@ -807,37 +814,43 @@
groups = smallgroups;
error = copyin(uap->gidset, groups, gidsetsize * sizeof(gid_t));
- if (error == 0)
- error = kern_setgroups(td, gidsetsize, groups);
+ if (error != 0)
+ goto out;
+ MPASS(gidsetsize <= ngroups_max + 1);
+ AUDIT_ARG_GROUPSET(groups, gidsetsize);
+
+ newcred = crget();
+ crextend(newcred, gidsetsize);
+ PROC_LOCK(p);
+ oldcred = crcopysafe(p, newcred);
+ error = kern_setgroups(td, newcred, oldcred, gidsetsize, groups);
+ if (error == 0)
+ proc_set_cred(p, newcred);
+ PROC_UNLOCK(p);
+ crfree(error ? newcred : oldcred);
+out:
if (gidsetsize > XU_NGROUPS)
free(groups, M_TEMP);
return (error);
}
int
-kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
+kern_setgroups(struct thread *td, struct ucred *newcred, struct ucred *oldcred,
+ u_int ngrp, gid_t *groups)
{
struct proc *p = td->td_proc;
- struct ucred *newcred, *oldcred;
int error;
- MPASS(ngrp <= ngroups_max + 1);
- AUDIT_ARG_GROUPSET(groups, ngrp);
- newcred = crget();
- crextend(newcred, ngrp);
- PROC_LOCK(p);
- oldcred = crcopysafe(p, newcred);
-
#ifdef MAC
error = mac_cred_check_setgroups(oldcred, ngrp, groups);
if (error)
- goto fail;
+ goto out;
#endif
error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS);
if (error)
- goto fail;
+ goto out;
if (ngrp == 0) {
/*
@@ -851,14 +864,8 @@
crsetgroups_locked(newcred, ngrp, groups);
}
setsugid(p);
- proc_set_cred(p, newcred);
- PROC_UNLOCK(p);
- crfree(oldcred);
- return (0);
-fail:
- PROC_UNLOCK(p);
- crfree(newcred);
+out:
return (error);
}
@@ -906,7 +913,7 @@
setsugid(p);
}
if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
- change_ruid(newcred, ruip);
+ change_ruid(newcred, ruip, 1);
setsugid(p);
}
if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) &&
@@ -1030,10 +1037,45 @@
PROC_LOCK(p);
oldcred = crcopysafe(p, newcred);
+ error = kern_setresuid(td, newcred, oldcred, ruid, euid, suid,
+ euip, ruip, 1);
+ if (error != 0)
+ goto fail;
+ proc_set_cred(p, newcred);
+#ifdef RACCT
+ racct_proc_ucred_changed(p, oldcred, newcred);
+ crhold(newcred);
+#endif
+ PROC_UNLOCK(p);
+#ifdef RCTL
+ rctl_proc_ucred_changed(p, newcred);
+ crfree(newcred);
+#endif
+ uifree(ruip);
+ uifree(euip);
+ crfree(oldcred);
+ return (0);
+
+fail:
+ PROC_UNLOCK(p);
+ uifree(ruip);
+ uifree(euip);
+ crfree(newcred);
+ return (error);
+
+}
+
+static int __always_inline
+kern_setresuid(struct thread *td, struct ucred *newcred, struct ucred *oldcred,
+ uid_t ruid, uid_t euid, uid_t suid,
+ struct uidinfo *euip, struct uidinfo *ruip, int chgproccnt)
+{
+ int error;
+
#ifdef MAC
error = mac_cred_check_setresuid(oldcred, ruid, euid, suid);
if (error)
- goto fail;
+ return (error);
#endif
if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid &&
@@ -1046,42 +1088,22 @@
suid != oldcred->cr_svuid &&
suid != oldcred->cr_uid)) &&
(error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID)) != 0)
- goto fail;
+ return (error);
if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
change_euid(newcred, euip);
- setsugid(p);
+ setsugid(td->td_proc);
}
if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) {
- change_ruid(newcred, ruip);
- setsugid(p);
+ change_ruid(newcred, ruip, chgproccnt);
+ setsugid(td->td_proc);
}
if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) {
change_svuid(newcred, suid);
- setsugid(p);
+ setsugid(td->td_proc);
}
- proc_set_cred(p, newcred);
-#ifdef RACCT
- racct_proc_ucred_changed(p, oldcred, newcred);
- crhold(newcred);
-#endif
- PROC_UNLOCK(p);
-#ifdef RCTL
- rctl_proc_ucred_changed(p, newcred);
- crfree(newcred);
-#endif
- uifree(ruip);
- uifree(euip);
- crfree(oldcred);
- return (0);
-
-fail:
- PROC_UNLOCK(p);
- uifree(ruip);
- uifree(euip);
- crfree(newcred);
- return (error);
+ return (0);
}
/*
@@ -1169,7 +1191,7 @@
struct ucred *cred;
int error1 = 0, error2 = 0, error3 = 0;
- cred = td->td_ucred;
+ cred = td->td_pucred;
if (uap->ruid)
error1 = copyout(&cred->cr_ruid,
uap->ruid, sizeof(cred->cr_ruid));
@@ -1196,7 +1218,7 @@
struct ucred *cred;
int error1 = 0, error2 = 0, error3 = 0;
- cred = td->td_ucred;
+ cred = td->td_pucred;
if (uap->rgid)
error1 = copyout(&cred->cr_rgid,
uap->rgid, sizeof(cred->cr_rgid));
@@ -2219,15 +2241,16 @@
* duration of the call.
*/
void
-change_ruid(struct ucred *newcred, struct uidinfo *ruip)
+change_ruid(struct ucred *newcred, struct uidinfo *ruip, int do_chgproccnt)
{
-
- (void)chgproccnt(newcred->cr_ruidinfo, -1, 0);
+ if (do_chgproccnt != 0)
+ (void)chgproccnt(newcred->cr_ruidinfo, -1, 0);
newcred->cr_ruid = ruip->ui_uid;
uihold(ruip);
uifree(newcred->cr_ruidinfo);
newcred->cr_ruidinfo = ruip;
- (void)chgproccnt(newcred->cr_ruidinfo, 1, 0);
+ if (do_chgproccnt != 0)
+ (void)chgproccnt(newcred->cr_ruidinfo, 1, 0);
}
/*-
@@ -2268,3 +2291,118 @@
newcred->cr_svgid = svgid;
}
+
+/*
+ * Set credentials.
+ */
+#ifndef _SYS_SYSPROTO_H_
+struct setcred_args {
+ uid_t uid;
+ int gidsetlen;
+ const gid_t *gidset;
+};
+#endif
+/* ARGSUSED */
+int
+sys_setcred(struct thread *td, struct setcred_args *uap)
+{
+ struct ucred *newcred, *oldcred;
+ struct uidinfo *uip;
+ gid_t smallgroups[XU_NGROUPS];
+ gid_t *groups;
+ int gidsetlen;
+ int error;
+
+ gidsetlen = uap->gidsetlen;
+ if (gidsetlen > ngroups_max + 1)
+ return (EINVAL);
+ AUDIT_ARG_UID(uap->uid);
+ error = priv_check_cred(td->td_pucred, PRIV_CRED_SETUID);
+ if (error != 0)
+ return (error);
+ oldcred = td->td_ucred;
+ newcred = crdup(oldcred);
+ crextend(newcred, gidsetlen);
+ uip = uifind(uap->uid);
+ if (gidsetlen > XU_NGROUPS)
+ groups = malloc(gidsetlen * sizeof(gid_t), M_TEMP, M_WAITOK);
+ else
+ groups = smallgroups;
+ error = copyin(uap->gidset, groups, gidsetlen * sizeof(gid_t));
+ if (error != 0)
+ goto out;
+
+ AUDIT_ARG_GROUPSET(groups, gidsetlen);
+ PROC_LOCK(td->td_proc);
+ error = kern_setresuid(td, newcred, td->td_pucred, uap->uid,
+ uap->uid, uap->uid, uip, uip, 0);
+ if (error != 0)
+ goto unlock;
+ error = kern_setgroups(td, newcred, td->td_pucred, gidsetlen,
+ groups);
+ td->td_ucred = newcred;
+ td->td_pflags |= TDP_SUGID;
+
+unlock:
+ PROC_UNLOCK(td->td_proc);
+out:
+ if (gidsetlen > XU_NGROUPS)
+ free(groups, M_TEMP);
+ uifree(uip);
+ crfree(error ? newcred : oldcred);
+ return (error);
+}
+
+/*
+ * Get credentials.
+ */
+#ifndef _SYS_SYSPROTO_H_
+struct getcred_args {
+ uid_t *uid;
+ int *gidsetlen;
+ gid_t *gidset;
+};
+#endif
+/* ARGSUSED */
+int
+sys_getcred(struct thread *td, struct getcred_args *uap)
+{
+ struct ucred *cred;
+ int gidsetlen = 0;
+ int error;
+ const int zero = 0;
+
+ error = copyin(uap->gidsetlen, &gidsetlen, sizeof(int));
+ if (error != 0)
+ return (error);
+ error = copyout(&zero, uap->gidsetlen, sizeof(*uap->gidsetlen));
+ if (error != 0)
+ return (error);
+ if (!TD_IS_SUGID(td))
+ return (ENOENT);
+ cred = td->td_ucred;
+ error = copyout(&cred->cr_ruid, uap->uid, sizeof(*uap->uid));
+ if (gidsetlen < cred->cr_ngroups)
+ return (ERANGE);
+ error = copyout(cred->cr_groups, uap->gidset,
+ cred->cr_ngroups * sizeof(*uap->gidset));
+ if (error != 0)
+ return (error);
+ error = copyout(&cred->cr_ngroups, uap->gidsetlen,
+ sizeof(*uap->gidsetlen));
+ return (error);
+}
+
+int
+sys_revertcred(struct thread *td, struct revertcred_args *uap)
+{
+ int error;
+
+ error = priv_check_cred(td->td_proc->p_ucred, PRIV_CRED_SETUID);
+ if (error != 0)
+ return (error);
+ td->td_pflags &= ~TDP_SUGID;
+ crfree(td->td_ucred);
+ td->td_ucred = crhold(td->td_pucred);
+ return (0);
+}
Index: sys/kern/kern_thread.c
===================================================================
--- sys/kern/kern_thread.c
+++ sys/kern/kern_thread.c
@@ -40,6 +40,8 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/jail.h>
+#include <sys/loginclass.h>
#include <sys/epoch.h>
#include <sys/rangelock.h>
#include <sys/resourcevar.h>
@@ -61,6 +63,8 @@
#endif
#include <security/audit/audit.h>
+#include <security/mac/mac_framework.h>
+#include <security/mac/mac_internal.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -82,9 +86,9 @@
"struct thread KBI td_flags");
_Static_assert(offsetof(struct thread, td_pflags) == 0x104,
"struct thread KBI td_pflags");
-_Static_assert(offsetof(struct thread, td_frame) == 0x478,
+_Static_assert(offsetof(struct thread, td_frame) == 0x480,
"struct thread KBI td_frame");
-_Static_assert(offsetof(struct thread, td_emuldata) == 0x530,
+_Static_assert(offsetof(struct thread, td_emuldata) == 0x538,
"struct thread KBI td_emuldata");
_Static_assert(offsetof(struct proc, p_flag) == 0xb0,
"struct proc KBI p_flag");
@@ -453,6 +457,7 @@
{
PROC_LOCK_ASSERT(p, MA_OWNED);
+ newtd->td_pucred = crhold(p->p_ucred);
newtd->td_ucred = crhold(p->p_ucred);
newtd->td_limit = lim_hold(p->p_limit);
newtd->td_cowgen = p->p_cowgen;
@@ -463,6 +468,7 @@
{
newtd->td_ucred = crhold(td->td_ucred);
+ newtd->td_pucred = crhold(td->td_pucred);
newtd->td_limit = lim_hold(td->td_limit);
newtd->td_cowgen = td->td_cowgen;
}
@@ -473,6 +479,8 @@
if (td->td_ucred != NULL)
crfree(td->td_ucred);
+ if (td->td_pucred != NULL)
+ crfree(td->td_pucred);
if (td->td_limit != NULL)
lim_free(td->td_limit);
}
@@ -481,16 +489,15 @@
thread_cow_update(struct thread *td)
{
struct proc *p;
- struct ucred *oldcred;
- struct plimit *oldlimit;
+ struct ucred *oldcred = NULL;
+ struct plimit *oldlimit = NULL;
+ struct ucred *tcred, *pcred;
p = td->td_proc;
- oldcred = NULL;
- oldlimit = NULL;
PROC_LOCK(p);
- if (td->td_ucred != p->p_ucred) {
- oldcred = td->td_ucred;
- td->td_ucred = crhold(p->p_ucred);
+ if (td->td_pucred != p->p_ucred) {
+ oldcred = td->td_pucred;
+ td->td_pucred = crhold(p->p_ucred);
}
if (td->td_limit != p->p_limit) {
oldlimit = td->td_limit;
@@ -502,6 +509,36 @@
crfree(oldcred);
if (oldlimit != NULL)
lim_free(oldlimit);
+ if (td->td_ucred != td->td_pucred) {
+ if (!TD_IS_SUGID(td)) {
+ crfree(td->td_ucred);
+ td->td_ucred = crhold(td->td_pucred);
+ } else {
+ tcred = td->td_ucred;
+ pcred = td->td_pucred;
+#ifdef MAC
+ if (tcred->cr_label != pcred->cr_label) {
+ mac_cred_label_free(tcred->cr_label);
+ mac_cred_relabel(tcred, pcred->cr_label);
+ }
+#endif /* MAC */
+ if (tcred->cr_loginclass != pcred->cr_loginclass) {
+ loginclass_free(tcred->cr_loginclass);
+ loginclass_hold(pcred->cr_loginclass);
+ tcred->cr_loginclass = pcred->cr_loginclass;
+ }
+ if (tcred->cr_prison != pcred->cr_prison) {
+ prison_free(tcred->cr_prison);
+ prison_hold(pcred->cr_prison);
+ tcred->cr_prison = pcred->cr_prison;
+ }
+#ifdef AUDIT
+ audit_cred_destroy(tcred);
+ audit_cred_copy(pcred, tcred);
+#endif /* AUDIT */
+ tcred->cr_flags = pcred->cr_flags;
+ }
+ }
}
/*
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -3167,6 +3167,23 @@
size_t bufsize
);
}
+568 AUE_GETCRED STD {
+ int getcred(
+ _Out_ uid_t *uid,
+ _Inout_ int *gidsetlen,
+ _Out_writes_(*gidsetlen) gid_t *gidset
+ );
+ }
+569 AUE_SETCRED STD {
+ int setcred(
+ uid_t uid,
+ int gidsetlen,
+ _In_reads_(gidsetlen) const gid_t *gidset
+ );
+ }
+570 AUE_REVERTCRED STD {
+ int revertcred(void);
+ }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Index: sys/security/audit/audit_bsm.c
===================================================================
--- sys/security/audit/audit_bsm.c
+++ sys/security/audit/audit_bsm.c
@@ -1466,6 +1466,29 @@
}
break;
+ case AUE_SETCRED:
+ if (ARG_IS_VALID(kar, ARG_UID)) {
+ tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
+ kau_write(rec, tok);
+ }
+ if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
+ for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
+ {
+ tok = au_to_arg32(1, "gidset",
+ ar->ar_arg_groups.gidset[ctr]);
+ kau_write(rec, tok);
+ }
+ }
+ break;
+
+ case AUE_GETCRED:
+ case AUE_REVERTCRED:
+
+ /*
+ * Header, subject, and return tokens added at end.
+ */
+ break;
+
case AUE_SETLOGIN:
if (ARG_IS_VALID(kar, ARG_LOGIN)) {
tok = au_to_text(ar->ar_arg_login);
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -265,7 +265,8 @@
struct lock_list_entry *td_sleeplocks; /* (k) Held sleep locks. */
int td_intr_nesting_level; /* (k) Interrupt recursion. */
int td_pinned; /* (k) Temporary cpu pin count. */
- struct ucred *td_ucred; /* (k) Reference to credentials. */
+ struct ucred *td_pucred; /* (k) Reference to process creds. */
+ struct ucred *td_ucred; /* (k) Reference to thread creds. */
struct plimit *td_limit; /* (k) Resource limits. */
int td_slptick; /* (t) Time at sleep. */
int td_blktick; /* (t) Time spent blocked. */
@@ -492,6 +493,7 @@
#define TDP_UIOHELD 0x10000000 /* Current uio has pages held in td_ma */
#define TDP_FORKING 0x20000000 /* Thread is being created through fork() */
#define TDP_EXECVMSPC 0x40000000 /* Execve destroyed old vmspace */
+#define TDP_SUGID 0x80000000 /* Thread is tainted by setcred(2) */
/*
* Reasons that the current thread can not be run yet.
@@ -514,7 +516,8 @@
#define TD_CAN_RUN(td) ((td)->td_state == TDS_CAN_RUN)
#define TD_IS_INHIBITED(td) ((td)->td_state == TDS_INHIBITED)
#define TD_ON_UPILOCK(td) ((td)->td_flags & TDF_UPIBLOCKED)
-#define TD_IS_IDLETHREAD(td) ((td)->td_flags & TDF_IDLETD)
+#define TD_IS_IDLETHREAD(td) ((td)->td_flags & TDF_IDLETD)
+#define TD_IS_SUGID(td) ((td)->td_pflags & TDP_SUGID)
#define KTDSTATE(td) \
(((td)->td_inhibitors & TDI_SLEEPING) != 0 ? "sleep" : \
Index: sys/sys/syscallsubr.h
===================================================================
--- sys/sys/syscallsubr.h
+++ sys/sys/syscallsubr.h
@@ -238,7 +238,8 @@
fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits);
int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
struct mbuf *control, enum uio_seg segflg);
-int kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups);
+int kern_setgroups(struct thread *td, struct ucred *newcred,
+ struct ucred *oldcred, u_int ngrp, gid_t *groups);
int kern_setitimer(struct thread *, u_int, struct itimerval *,
struct itimerval *);
int kern_setrlimit(struct thread *, u_int, struct rlimit *);
Index: sys/sys/ucred.h
===================================================================
--- sys/sys/ucred.h
+++ sys/sys/ucred.h
@@ -62,13 +62,13 @@
struct prison *cr_prison; /* jail(2) */
struct loginclass *cr_loginclass; /* login class */
u_int cr_flags; /* credential flags */
- void *cr_pspare2[2]; /* general use 2 */
+ void *cr_pspare2[2]; /* general use 2 */
#define cr_endcopy cr_label
struct label *cr_label; /* MAC label */
struct auditinfo_addr cr_audit; /* Audit properties. */
gid_t *cr_groups; /* groups */
int cr_agroups; /* Available groups */
- gid_t cr_smallgroups[XU_NGROUPS]; /* storage for small groups */
+ gid_t cr_smallgroups[XU_NGROUPS]; /* storage for small groups */
};
#define NOCRED ((struct ucred *)0) /* no credential available */
#define FSCRED ((struct ucred *)-1) /* filesystem credential */
@@ -101,7 +101,7 @@
void change_egid(struct ucred *newcred, gid_t egid);
void change_euid(struct ucred *newcred, struct uidinfo *euip);
void change_rgid(struct ucred *newcred, gid_t rgid);
-void change_ruid(struct ucred *newcred, struct uidinfo *ruip);
+void change_ruid(struct ucred *newcred, struct uidinfo *ruip, int do_chgproccnt);
void change_svgid(struct ucred *newcred, gid_t svgid);
void change_svuid(struct ucred *newcred, uid_t svuid);
void crcopy(struct ucred *dest, struct ucred *src);
Index: usr.bin/procstat/procstat_cred.c
===================================================================
--- usr.bin/procstat/procstat_cred.c
+++ usr.bin/procstat/procstat_cred.c
@@ -43,19 +43,53 @@
static const char *get_umask(struct procstat *procstat,
struct kinfo_proc *kipp);
+static void procstat_emit(struct procstat *procstat,
+ struct kinfo_proc *kipp);
void
procstat_cred(struct procstat *procstat, struct kinfo_proc *kipp)
{
- unsigned int i, ngroups;
- gid_t *groups;
+ struct kinfo_proc *kip;
+ unsigned int i, count;
if ((procstat_opts & PS_OPT_NOHEADER) == 0)
- xo_emit("{T:/%5s %-16s %5s %5s %5s %5s %5s %5s %5s %5s %-15s}\n",
- "PID", "COMM", "EUID", "RUID", "SVUID", "EGID", "RGID",
+ xo_emit("{T:/%5s %6s %-16s %5s %5s %5s %5s %5s %5s %5s %5s %-15s}\n",
+ "PID", "TID", "COMM", "EUID", "RUID", "SVUID", "EGID", "RGID",
"SVGID", "UMASK", "FLAGS", "GROUPS");
- xo_emit("{k:process_id/%5d/%d} ", kipp->ki_pid);
+ kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
+ kipp->ki_pid, &count);
+ if (kip == NULL)
+ return;
+ kinfo_proc_sort(kip, count);
+ for (i = 0; i < count; i++) {
+ kipp = &kip[i];
+ procstat_emit(procstat, kipp);
+ }
+
+}
+
+static const char *
+get_umask(struct procstat *procstat, struct kinfo_proc *kipp)
+{
+ u_short fd_cmask;
+ static char umask[4];
+
+ if (procstat_getumask(procstat, kipp, &fd_cmask) == 0) {
+ snprintf(umask, 4, "%03o", fd_cmask);
+ return (umask);
+ } else {
+ return ("-");
+ }
+}
+
+static void procstat_emit(struct procstat *procstat, struct kinfo_proc *kipp)
+{
+ unsigned int i, ngroups;
+ gid_t *groups;
+
+ xo_emit("{d:process_id/%5d/%d} ", kipp->ki_pid);
+ xo_emit("{dk:thread_id/%6d/%d} ", kipp->ki_tid);
xo_emit("{:command/%-16s/%s} ", kipp->ki_comm);
xo_emit("{:uid/%5d} ", kipp->ki_uid);
xo_emit("{:ruid/%5d} ", kipp->ki_ruid);
@@ -89,17 +123,3 @@
xo_close_list("groups");
xo_emit("\n");
}
-
-static const char *
-get_umask(struct procstat *procstat, struct kinfo_proc *kipp)
-{
- u_short fd_cmask;
- static char umask[4];
-
- if (procstat_getumask(procstat, kipp, &fd_cmask) == 0) {
- snprintf(umask, 4, "%03o", fd_cmask);
- return (umask);
- } else {
- return ("-");
- }
-}

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 16, 1:12 AM (13 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16667481
Default Alt Text
D18930.diff (41 KB)

Event Timeline