Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F110202475
D18930.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
41 KB
Referenced Files
None
Subscribers
None
D18930.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D18930: Per-thread credentials
Attached
Detach File
Event Timeline
Log In to Comment