From 302f67a046b8df5afe657ccd5f28201163cfbc62 Mon Sep 17 00:00:00 2001
From: Moe Jette <jette1@llnl.gov>
Date: Fri, 1 May 2009 00:04:15 +0000
Subject: [PATCH] From: Mark A. Grondona <mgrondona@llnl.gov>

Certain SPANK items that are available in local or allocator context
may not be available until after cmdline options have been processed,
or after a job has been allocated. Return ESPANK_NOT_AVAIL to indicate
to plugins that this is the case.

This patch fixes a potential segfault if SPANK plugins call spank_get_item
for these items from early callbacks such as spank_init.
---
 slurm/spank.h          |  3 ++-
 src/common/plugstack.c | 21 +++++++++++++--------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/slurm/spank.h b/slurm/spank.h
index 1e3340d69e8..accf145d161 100644
--- a/slurm/spank.h
+++ b/slurm/spank.h
@@ -166,7 +166,8 @@ enum spank_err {
     ESPANK_NOSPACE     = 6, /* Buffer too small.                             */
     ESPANK_NOT_REMOTE  = 7, /* Function only may be called in remote context */
     ESPANK_NOEXIST     = 8, /* Id/pid doesn't exist on this node             */
-    ESPANK_NOT_EXECD   = 9  /* Lookup by pid requested, but no tasks running */
+    ESPANK_NOT_EXECD   = 9, /* Lookup by pid requested, but no tasks running */
+    ESPANK_NOT_AVAIL   = 10,/* SPANK item not available from this callback   */
 };
 
 typedef enum spank_err spank_err_t;
diff --git a/src/common/plugstack.c b/src/common/plugstack.c
index c3d6d0a0d38..d55ccc77166 100644
--- a/src/common/plugstack.c
+++ b/src/common/plugstack.c
@@ -2,7 +2,7 @@
  *  plugstack.c -- stackable plugin architecture for node job kontrol (SPANK)
  *****************************************************************************
  *  Copyright (C) 2005-2007 The Regents of the University of California.
- *  Copyright (C) 2008 Lawrence Livermore National Security.
+ *  Copyright (C) 2008-2009 Lawrence Livermore National Security.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  *  CODE-OCEC-09-009. All rights reserved.
  *
@@ -1441,7 +1441,7 @@ static int _valid_in_allocator_context (spank_item_t item)
 	}
 }
 
-static spank_err_t _check_spank_item_validity (spank_item_t item)
+static spank_err_t _check_spank_item_validity (spank_item_t item, void *job)
 {
 	/*
 	 *  Valid in all contexts:
@@ -1457,14 +1457,18 @@ static spank_err_t _check_spank_item_validity (spank_item_t item)
 	}
 
 	if (spank_ctx == S_TYPE_LOCAL) {
-		if (_valid_in_local_context (item))
-			return ESPANK_SUCCESS;
-		else
+		if (!_valid_in_local_context (item))
 			return ESPANK_NOT_REMOTE;
+		else if (job == NULL)
+			return ESPANK_NOT_AVAIL;
 	}
 	else if (spank_ctx == S_TYPE_ALLOCATOR) {
-		if (_valid_in_allocator_context (item))
-			return ESPANK_SUCCESS;
+		if (_valid_in_allocator_context (item)) {
+			if (job)
+				return ESPANK_SUCCESS;
+			else
+				return ESPANK_NOT_AVAIL;
+		}
 		else if (_valid_in_local_context (item))
 			return ESPANK_BAD_ARG;
 		else
@@ -1545,7 +1549,8 @@ spank_err_t spank_get_item(spank_t spank, spank_item_t item, ...)
 	/*
 	 *  Check for validity of the given item in the current context
 	 */
-	if ((rc = _check_spank_item_validity (item)) != ESPANK_SUCCESS)
+	rc = _check_spank_item_validity (item, spank->job);
+	if (rc != ESPANK_SUCCESS)
 		return (rc);
 
 	if (spank_ctx == S_TYPE_LOCAL)
-- 
GitLab