Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix buffer overflow when handling slot type in a jobspec #548

Merged
merged 4 commits into from Dec 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions resource/evaluators/edge_eval_api.cpp
Expand Up @@ -149,6 +149,11 @@ unsigned int evals_t::qualified_count () const
return m_qual_count;
}

unsigned int evals_t::qualified_granules () const
{
return m_eval_egroups.size ();
}

unsigned int evals_t::total_count () const
{
return m_total_count;
Expand Down
1 change: 1 addition & 0 deletions resource/evaluators/edge_eval_api.hpp
Expand Up @@ -73,6 +73,7 @@ class evals_t {
// This can throw out_of_range exception
const eval_egroup_t &at (unsigned int i) const;
unsigned int qualified_count () const;
unsigned int qualified_granules () const;
unsigned int total_count () const;
int64_t cutline () const;
int64_t set_cutline (int64_t cutline);
Expand Down
8 changes: 8 additions & 0 deletions resource/evaluators/scoring_api.cpp
Expand Up @@ -180,6 +180,14 @@ unsigned int scoring_api_t::qualified_count (const subsystem_t &s,
return res_evals->qualified_count ();
}

unsigned int scoring_api_t::qualified_granules (const subsystem_t &s,
const std::string &r)
{
handle_new_keys (s, r);
auto res_evals = (*m_ssys_map[s])[r];
return res_evals->qualified_granules ();
}

unsigned int scoring_api_t::total_count (const subsystem_t &s,
const std::string &r)
{
Expand Down
1 change: 1 addition & 0 deletions resource/evaluators/scoring_api.hpp
Expand Up @@ -58,6 +58,7 @@ class scoring_api_t {
const eval_egroup_t &at (const subsystem_t &s, const std::string &r,
unsigned int i);
unsigned int qualified_count (const subsystem_t &s, const std::string &r);
unsigned int qualified_granules (const subsystem_t &s, const std::string &r);
unsigned int total_count (const subsystem_t &s, const std::string &r);
unsigned int best_k (const subsystem_t &s, const std::string &r);
unsigned int best_i (const subsystem_t &s, const std::string &r);
Expand Down
12 changes: 12 additions & 0 deletions resource/traversers/dfu_impl.cpp
Expand Up @@ -449,17 +449,29 @@ int dfu_impl_t::cnt_slot (const std::vector<Resource> &slot_shape,
scoring_api_t &dfu_slot)
{
unsigned int qc = 0;
unsigned int qg = 0;
unsigned int fit = 0;
unsigned int count = 0;
unsigned int qual_num_slots = UINT_MAX;
const subsystem_t &dom = m_match->dom_subsystem ();

// qualifed slot count is determined by the most constrained resource type
// both in terms of the amounts available as well as the number of edges into
// that resource because that represent the match granularity.
// Say you have 128 units of memory available across two memory resource
// vertices each with 64 units of memory and you request 1 unit of memory.
// In this case, you don't have 128 slots available because the match
// granularity is 64 units. Instead, you have only 2 slots available each
// with 64 units, and your request will get 1 whole resource vertex.
qual_num_slots = UINT_MAX;
for (auto &slot_elem : slot_shape) {
qc = dfu_slot.qualified_count (dom, slot_elem.type);
qg = dfu_slot.qualified_granules (dom, slot_elem.type);
count = m_match->calc_count (slot_elem, qc);
// constraint check against qualified amounts
fit = (count == 0)? count : (qc / count);
// constraint check against qualified granules
fit = (fit > qg)? qg : fit;
qual_num_slots = (qual_num_slots > fit)? fit : qual_num_slots;
dfu_slot.rewind_iter_cur (dom, slot_elem.type);
}
Expand Down
1 change: 1 addition & 0 deletions t/Makefile.am
Expand Up @@ -51,6 +51,7 @@ TESTS = \
t3014-resource-var-aware.t \
t3015-resource-basic-jgf.t \
t3016-resource-power-jgf.t \
t3017-resource-granule.t \
t4000-match-params.t \
t4001-match-allocate.t \
t4002-match-reserve.t \
Expand Down
8 changes: 8 additions & 0 deletions t/data/resource/commands/granule/cmds01.in
@@ -0,0 +1,8 @@
# 5x cluster[1]->rack[1]->node[1]->socket[1]->slot[4]->core[1]
# ->memory[1]
match allocate @TEST_SRCDIR@/data/resource/jobspecs/granule/test001.yaml
match allocate @TEST_SRCDIR@/data/resource/jobspecs/granule/test001.yaml
match allocate @TEST_SRCDIR@/data/resource/jobspecs/granule/test001.yaml
match allocate @TEST_SRCDIR@/data/resource/jobspecs/granule/test001.yaml
match allocate @TEST_SRCDIR@/data/resource/jobspecs/granule/test001.yaml
quit
72 changes: 72 additions & 0 deletions t/data/resource/expected/granule/001.R.out
@@ -0,0 +1,72 @@
---------------core32[1:x]
---------------core33[1:x]
---------------core34[1:x]
---------------core35[1:x]
---------------memory4[2:x]
---------------memory5[2:x]
---------------memory6[2:x]
---------------memory7[2:x]
------------socket1[1:s]
---------node1[1:s]
------rack0[1:s]
---tiny0[1:s]
INFO: =============================
INFO: JOBID=1
INFO: RESOURCES=ALLOCATED
INFO: SCHEDULED AT=Now
INFO: =============================
---------------core14[1:x]
---------------core15[1:x]
---------------core16[1:x]
---------------core17[1:x]
---------------memory0[2:x]
---------------memory1[2:x]
---------------memory2[2:x]
---------------memory3[2:x]
------------socket0[1:s]
---------node1[1:s]
------rack0[1:s]
---tiny0[1:s]
INFO: =============================
INFO: JOBID=2
INFO: RESOURCES=ALLOCATED
INFO: SCHEDULED AT=Now
INFO: =============================
---------------core32[1:x]
---------------core33[1:x]
---------------core34[1:x]
---------------core35[1:x]
---------------memory4[2:x]
---------------memory5[2:x]
---------------memory6[2:x]
---------------memory7[2:x]
------------socket1[1:s]
---------node0[1:s]
------rack0[1:s]
---tiny0[1:s]
INFO: =============================
INFO: JOBID=3
INFO: RESOURCES=ALLOCATED
INFO: SCHEDULED AT=Now
INFO: =============================
---------------core14[1:x]
---------------core15[1:x]
---------------core16[1:x]
---------------core17[1:x]
---------------memory0[2:x]
---------------memory1[2:x]
---------------memory2[2:x]
---------------memory3[2:x]
------------socket0[1:s]
---------node0[1:s]
------rack0[1:s]
---tiny0[1:s]
INFO: =============================
INFO: JOBID=4
INFO: RESOURCES=ALLOCATED
INFO: SCHEDULED AT=Now
INFO: =============================
INFO: =============================
INFO: No matching resources found
INFO: JOBID=5
INFO: =============================
72 changes: 72 additions & 0 deletions t/data/resource/expected/granule/002.R.out
@@ -0,0 +1,72 @@
---------------core0[1:x]
---------------core1[1:x]
---------------core2[1:x]
---------------core3[1:x]
---------------memory0[2:x]
---------------memory1[2:x]
---------------memory2[2:x]
---------------memory3[2:x]
------------socket0[1:s]
---------node0[1:s]
------rack0[1:s]
---tiny0[1:s]
INFO: =============================
INFO: JOBID=1
INFO: RESOURCES=ALLOCATED
INFO: SCHEDULED AT=Now
INFO: =============================
---------------core18[1:x]
---------------core19[1:x]
---------------core20[1:x]
---------------core21[1:x]
---------------memory4[2:x]
---------------memory5[2:x]
---------------memory6[2:x]
---------------memory7[2:x]
------------socket1[1:s]
---------node0[1:s]
------rack0[1:s]
---tiny0[1:s]
INFO: =============================
INFO: JOBID=2
INFO: RESOURCES=ALLOCATED
INFO: SCHEDULED AT=Now
INFO: =============================
---------------core0[1:x]
---------------core1[1:x]
---------------core2[1:x]
---------------core3[1:x]
---------------memory0[2:x]
---------------memory1[2:x]
---------------memory2[2:x]
---------------memory3[2:x]
------------socket0[1:s]
---------node1[1:s]
------rack0[1:s]
---tiny0[1:s]
INFO: =============================
INFO: JOBID=3
INFO: RESOURCES=ALLOCATED
INFO: SCHEDULED AT=Now
INFO: =============================
---------------core18[1:x]
---------------core19[1:x]
---------------core20[1:x]
---------------core21[1:x]
---------------memory4[2:x]
---------------memory5[2:x]
---------------memory6[2:x]
---------------memory7[2:x]
------------socket1[1:s]
---------node1[1:s]
------rack0[1:s]
---tiny0[1:s]
INFO: =============================
INFO: JOBID=4
INFO: RESOURCES=ALLOCATED
INFO: SCHEDULED AT=Now
INFO: =============================
INFO: =============================
INFO: No matching resources found
INFO: JOBID=5
INFO: =============================
26 changes: 26 additions & 0 deletions t/data/resource/jobspecs/granule/test001.yaml
@@ -0,0 +1,26 @@
version: 1
resources:
- type: node
count: 1
with:
- type: socket
count: 1
with:
- type: slot
count: 4
label: default
with:
- type: core
count: 1
- type: memory
count: 1

# a comment
attributes:
system:
duration: 3600
tasks:
- command: app
slot: default
count:
per_slot: 1
39 changes: 39 additions & 0 deletions t/t3017-resource-granule.t
@@ -0,0 +1,39 @@
#!/bin/sh

test_description='Test Scheduling Correctness on Vertex Granularity'

. $(dirname $0)/sharness.sh

cmd_dir="${SHARNESS_TEST_SRCDIR}/data/resource/commands/granule"
exp_dir="${SHARNESS_TEST_SRCDIR}/data/resource/expected/granule"
grugs="${SHARNESS_TEST_SRCDIR}/data/resource/grugs/tiny.graphml"
query="../../resource/utilities/resource-query"

#
# Selection Policy -- High ID first (-P high)
# The resource vertex with higher ID is preferred among its kind
# (e.g., node1 is preferred over node0 if available)
#

cmds001="${cmd_dir}/cmds01.in"
test001_desc="memory granularity keeps last jobspec from being matched (pol=hi)"
test_expect_success "${test001_desc}" '
sed "s~@TEST_SRCDIR@~${SHARNESS_TEST_SRCDIR}~g" ${cmds001} > cmds001 &&
${query} -L ${grugs} -S CA -P high -t 001.R.out < cmds001 &&
test_cmp 001.R.out ${exp_dir}/001.R.out
'

## Selection Policy -- Low ID first (-P low)
## The resource vertex with lower ID is preferred among its kind
## (e.g., node0 is preferred over node1 if available)
##

cmds002="${cmd_dir}/cmds01.in"
test002_desc="memory granularity keeps last jobspec from being matched (pol=hi)"
test_expect_success "${test002_desc}" '
sed "s~@TEST_SRCDIR@~${SHARNESS_TEST_SRCDIR}~g" ${cmds002} > cmds002 &&
${query} -L ${grugs} -S CA -P low -t 002.R.out < cmds002 &&
test_cmp 002.R.out ${exp_dir}/002.R.out
'

test_done