diff --git a/src/afs/AIX/osi_gcpags.c b/src/afs/AIX/osi_gcpags.c index 416b299ea3..32fa25b45c 100644 --- a/src/afs/AIX/osi_gcpags.c +++ b/src/afs/AIX/osi_gcpags.c @@ -22,7 +22,7 @@ * table, calling afs_GCPAGs_perproc_func() for each process. */ - #ifdef AFS_AIX51_ENV +#ifdef AFS_AIX51_ENV #define max_proc v.ve_proc #endif void diff --git a/src/afs/DARWIN/osi_gcpags.c b/src/afs/DARWIN/osi_gcpags.c index c19ce92228..79209b08b1 100644 --- a/src/afs/DARWIN/osi_gcpags.c +++ b/src/afs/DARWIN/osi_gcpags.c @@ -22,7 +22,7 @@ */ -#if (defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN80_ENV) +#if (defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN80_ENV)) void afs_osi_TraverseProcTable(void) { diff --git a/src/afs/FBSD/osi_gcpags.c b/src/afs/FBSD/osi_gcpags.c index ef0e08797f..7b6d20146d 100644 --- a/src/afs/FBSD/osi_gcpags.c +++ b/src/afs/FBSD/osi_gcpags.c @@ -21,7 +21,7 @@ * table, calling afs_GCPAGs_perproc_func() for each process. */ - void +void afs_osi_TraverseProcTable(void) { afs_proc_t *p; @@ -43,13 +43,26 @@ afs_osi_TraverseProcTable(void) const afs_ucred_t * afs_osi_proc2cred(afs_proc_t * pr) { - /* - * This whole function is kind of an ugly hack. For one, the - * 'const' is a lie. Also, we should probably be holding the - * proc mutex around all accesses to the credentials structure, - * but the present API does not allow this. - */ - return pr->p_ucred; + afs_ucred_t *rv = NULL; + static afs_ucred_t cr; + + if (pr == NULL) { + return NULL; + } + + if ((pr->p_stat == SSLEEP) || (pr->p_stat == SRUN) + || (pr->p_stat == SSTOP)) { + pcred_readlock(pr); + cr.cr_ref = 1; + afs_set_cr_uid(&cr, afs_cr_uid(pr->p_cred->pc_ucred)); + cr.cr_ngroups = pr->p_cred->pc_ucred->cr_ngroups; + memcpy(cr.cr_groups, pr->p_cred->pc_ucred->cr_groups, + NGROUPS * sizeof(gid_t)); + pcred_unlock(pr); + rv = &cr; + } + + return rv; } #endif /* AFS_GCPAGS */ diff --git a/src/afs/LINUX/osi_gcpags.c b/src/afs/LINUX/osi_gcpags.c index f5e761862a..ada11e5e86 100644 --- a/src/afs/LINUX/osi_gcpags.c +++ b/src/afs/LINUX/osi_gcpags.c @@ -22,7 +22,6 @@ */ -#if defined(AFS_LINUX22_ENV) #ifdef EXPORTED_TASKLIST_LOCK extern rwlock_t tasklist_lock __attribute__((weak)); #endif @@ -122,21 +121,4 @@ afs_osi_proc2cred(afs_proc_t * pr) } #endif -#else - -const afs_ucred_t * -afs_osi_proc2cred(afs_proc_t * pr) -{ - afs_ucred_t *rv = NULL; - - if (pr == NULL) { - return NULL; - } - rv = pr->p_cred; - - return rv; -} - -#endif /* AFS_LINUX22_ENV */ - #endif /* AFS_GCPAGS */ diff --git a/src/afs/LINUX24/osi_gcpags.c b/src/afs/LINUX24/osi_gcpags.c index 96ebfe4564..ff04176e34 100644 --- a/src/afs/LINUX24/osi_gcpags.c +++ b/src/afs/LINUX24/osi_gcpags.c @@ -16,23 +16,87 @@ #if AFS_GCPAGS +/* afs_osi_TraverseProcTable() - Walk through the systems process + * table, calling afs_GCPAGs_perproc_func() for each process. + */ + +#ifdef EXPORTED_TASKLIST_LOCK +extern rwlock_t tasklist_lock __attribute__((weak)); +#endif +void +afs_osi_TraverseProcTable(void) +{ +#if !defined(LINUX_KEYRING_SUPPORT) && (!defined(STRUCT_TASK_HAS_CRED) || defined(EXPORTED_RCU_READ_LOCK)) + struct task_struct *p; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) && defined(EXPORTED_TASKLIST_LOCK) + if (&tasklist_lock) + read_lock(&tasklist_lock); +#endif /* EXPORTED_TASKLIST_LOCK */ + +#ifdef DEFINED_FOR_EACH_PROCESS + for_each_process(p) if (p->pid) { +#ifdef STRUCT_TASK_STRUCT_HAS_EXIT_STATE + if (p->exit_state) + continue; +#else + if (p->state & TASK_ZOMBIE) + continue; +#endif + afs_GCPAGs_perproc_func(p); + } +#else + for_each_task(p) if (p->pid) { +#ifdef STRUCT_TASK_STRUCT_HAS_EXIT_STATE + if (p->exit_state) + continue; +#else + if (p->state & TASK_ZOMBIE) + continue; +#endif + afs_GCPAGs_perproc_func(p); + } +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) && defined(EXPORTED_TASKLIST_LOCK) + if (&tasklist_lock) + read_unlock(&tasklist_lock); +#endif /* EXPORTED_TASKLIST_LOCK */ +#endif +} + /* return a pointer (sometimes a static copy ) to the cred for a * given afs_proc_t. * subsequent calls may overwrite the previously returned value. */ - const afs_ucred_t * afs_osi_proc2cred(afs_proc_t * pr) { - afs_ucred_t *rv = NULL; + afs_ucred_t *rv = NULL; + static afs_ucred_t cr; - if (pr == NULL) { - return NULL; - } - rv = pr->p_cred; + if (pr == NULL) { + return NULL; + } - return rv; + if ((pr->state == TASK_RUNNING) || (pr->state == TASK_INTERRUPTIBLE) + || (pr->state == TASK_UNINTERRUPTIBLE) + || (pr->state == TASK_STOPPED)) { + + /* This is dangerous. If anyone ever crfree's the cred that's + * returned from here, we'll go boom, because it's statically + * allocated. */ + + atomic_set(&cr.cr_ref, 1); + afs_set_cr_uid(&cr, task_uid(pr)); + + cr.cr_ngroups = pr->ngroups; + memcpy(cr.cr_groups, pr->groups, NGROUPS * sizeof(gid_t)); + + rv = &cr; + } + + return rv; } #endif /* AFS_GCPAGS */ diff --git a/src/afs/SOLARIS/osi_gcpags.c b/src/afs/SOLARIS/osi_gcpags.c index 0df5db6c0b..1b12cab944 100644 --- a/src/afs/SOLARIS/osi_gcpags.c +++ b/src/afs/SOLARIS/osi_gcpags.c @@ -16,6 +16,19 @@ #if AFS_GCPAGS +/* afs_osi_TraverseProcTable() - Walk through the systems process + * table, calling afs_GCPAGs_perproc_func() for each process. + */ + +void +afs_osi_TraverseProcTable(void) +{ + afs_proc_t *prp; + for (prp = practive; prp != NULL; prp = prp->p_next) { + afs_GCPAGs_perproc_func(prp); + } +} + /* return a pointer (sometimes a static copy ) to the cred for a * given afs_proc_t. * subsequent calls may overwrite the previously returned value. diff --git a/src/afs/SUNOS/osi_gcpags.c b/src/afs/SUNOS/osi_gcpags.c deleted file mode 100644 index 31110601b0..0000000000 --- a/src/afs/SUNOS/osi_gcpags.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2000, International Business Machines Corporation and others. - * All Rights Reserved. - * - * This software has been released under the terms of the IBM Public - * License. For details, see the LICENSE file in the top-level source - * directory or online at http://www.openafs.org/dl/license10.html - */ - -#include -#include "afs/param.h" - -#include "afs/sysincludes.h" /* Standard vendor system headers */ -#include "afsincludes.h" /* Afs-based standard headers */ -#include "afs/afs_stats.h" /* afs statistics */ - -#if AFS_GCPAGS - -#if defined(AFS_SUN5_ENV) -void -afs_osi_TraverseProcTable(void) -{ - afs_proc_t *prp; - for (prp = practive; prp != NULL; prp = prp->p_next) { - afs_GCPAGs_perproc_func(prp); - } -} -#endif - -/* return a pointer (sometimes a static copy ) to the cred for a - * given afs_proc_t. - * subsequent calls may overwrite the previously returned value. - */ - - -const afs_ucred_t * -afs_osi_proc2cred(afs_proc_t * pr) -{ - afs_ucred_t *rv = NULL; - - if (pr == NULL) { - return NULL; - } - rv = pr->p_cred; - - return rv; -} - -#endif /* AFS_GCPAGS */ diff --git a/src/libafs/MakefileProto.LINUX.in b/src/libafs/MakefileProto.LINUX.in index f2cdaf112f..773fdd18de 100644 --- a/src/libafs/MakefileProto.LINUX.in +++ b/src/libafs/MakefileProto.LINUX.in @@ -53,6 +53,7 @@ AFS_OS_OBJS = \ AFS_OS_PAGOBJS = \ osi_alloc.o \ osi_cred.o \ + osi_gcpags.o \ osi_groups.o \ osi_inode.o \ osi_misc.o \