Control: tags -1 + patch Attached is a preliminary patch for this issue.
Regards, Salvatore
Description: CVE-2014-3684: non-root users able to kill any process on any node in a job limit tm_adopt() to only adopt a session id that is owned by the calling user. . Within a TORQUE Resource Manager job, the tm_adopt() TORQUE library call enables a user-built executable calling tm_adopt() to adopt any session id (and its child processes) regardless of the session id owner on any node within a job. When a job that includes the executable calling tm_adopt() exits, the adopted processes are killed along with the job processes during normal job cleanup. This can enable a non-root user to kill processes he/she doesn't own including root-owned ones on any node in a job. Origin: backport, https://github.com/adaptivecomputing/torque/commit/f2f4c950f3d461a249111c8826da3beaafccace9 Bug-Debian: https://bugs.debian.org/763922 Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1149044 Forwarded: not-needed Author: Chad Vizino <cviz...@adaptivecomputing.com> Reviewed-by: Salvatore Bonaccorso <car...@debian.org> Last-Update: 2014-10-21 --- a/src/cmds/pbs_track.c +++ b/src/cmds/pbs_track.c @@ -232,6 +232,12 @@ int main( break; + case TM_EPERM: + + fprintf(stderr, "pbs_track: permission denied: %s (%d)\n", + pbse_to_txt(rc), + rc); + default: /* Unexpected error occurred */ --- a/src/include/tm.h +++ b/src/include/tm.h @@ -195,7 +195,7 @@ int tm_register(tm_whattodo_t *what, /* * DJH 15 Nov 2001. * Generic "out-of-band" task adoption call for tasks parented by - * another job management system. Minor security hole? + * another job management system. * Cannot be called with any other tm call. * 26 Feb 2002. Allows id to be jobid (adoptCmd = TM_ADOPT_JOBID) * or some altid (adoptCmd = TM_ADOPT_ALTID) --- a/src/include/tm_.h +++ b/src/include/tm_.h @@ -133,6 +133,7 @@ typedef unsigned int tm_task_id; #define TM_EBADENVIRONMENT 17005 #define TM_ENOTFOUND 17006 #define TM_BADINIT 17007 +#define TM_EPERM 17008 #define TM_TODO_NOP 5000 /* Do nothing (the nodes value may be new) */ #define TM_TODO_CKPT 5001 /* Checkpoint <what> and continue it */ --- a/src/lib/Libifl/tm.c +++ b/src/lib/Libifl/tm.c @@ -84,6 +84,7 @@ #define _XOPEN_SOURCE #define _XOPEN_SOURCE_EXTENDED 1 +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -94,6 +95,7 @@ #include <errno.h> #include <assert.h> #include <sys/types.h> +#include <sys/stat.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> @@ -173,6 +175,31 @@ static event_info *event_hash[EVENT_HASH static int event_count = 0; /* + * check if the owner of this process matches the owner of pid + * returns TRUE if so, FALSE otherwise + */ +bool ispidowner(pid_t pid) + { + char path[MAXPATHLEN]; + struct stat sbuf; + + /* build path to pid */ + snprintf(path, sizeof(path), "/proc/%d", pid); + + /* do the stat */ + /* if it fails, assume not owner */ + if (stat(path, &sbuf) != 0) + return(FALSE); + + /* see if caller is the owner of pid */ + if (getuid() != sbuf.st_uid) + return(FALSE); + + /* caller is owner */ + return(TRUE); + } + +/* ** Find an event number or return a NULL. */ static event_info * @@ -1648,8 +1675,8 @@ err: * some mpiruns simply use rsh to start remote processes - no AMS * tracking or management facilities are available. * - * This function allows any task (session) to be adopted into a PBS - * job. It is used by: + * This function allows any task (session) owned by the owner + * of the job to be adopted into a PBS job. It is used by: * - "adopter" (which is in turn used by our pvmrun) * - our rmsloader wrapper (a home-brew replacement for RMS' * rmsloader that does some work and then exec()s the real @@ -1683,7 +1710,8 @@ err: * the mom. Returns TM_ENOTFOUND if the mom couldn't find a job * with the given RMS resource id. Returns TM_ESYSTEM or * TM_ENOTCONNECTED if there was some sort of comms error talking - * to the mom + * to the mom. Returns TM_EPERM if an attempt was made to adopt + * a session not owned by the owner of the job. * * Side effects: * Sets the tm_* globals to fake values if tm_init() has never @@ -1701,6 +1729,10 @@ int tm_adopt(char *id, int adoptCmd, pid sid = getsid(pid); + /* do not adopt a sid not owned by caller */ + if (!ispidowner(sid)) + return(TM_EPERM); + /* Must be the only call to call to tm and must only be called once */