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 */
 

Reply via email to