From 0ab66f4f5f25eb65a7ff606527a0d81f28e9eb8d Mon Sep 17 00:00:00 2001
From: Thomas Hobson <thomas@hexf.me>
Date: Wed, 27 Apr 2022 02:51:10 +1200
Subject: [PATCH 1/2] Cleanup all zombie processes

Prevents process table exhaustion
---
 api/src/job.js | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/api/src/job.js b/api/src/job.js
index eef2ffd..0fc24a1 100644
--- a/api/src/job.js
+++ b/api/src/job.js
@@ -336,14 +336,20 @@ class Job {
                     const [_, ruid, euid, suid, fuid] = uid_line.split(/\s+/);
 
                     const [_1, state, user_friendly] = state_line.split(/\s+/);
+                    
+                    const proc_id_int = parse_int(proc_id);
 
-                    if (state == 'Z')
-                        // Zombie process, just needs to be waited
+                    if (state == 'Z'){
+                        // Zombie process, just needs to be waited, regardless of the user id
+                        if(!to_wait.includes(proc_id_int))
+                            to_wait.push(proc_id_int);
+                        
                         return -1;
+                    }
                     // We should kill in all other state (Sleep, Stopped & Running)
 
                     if (ruid == this.uid || euid == this.uid)
-                        return parse_int(proc_id);
+                        return proc_id_int;
                 } catch {
                     return -1;
                 }

From 81e315609dd2631da8cc1cbbc15fd7e01076cb21 Mon Sep 17 00:00:00 2001
From: Thomas Hobson <thomas@hexf.me>
Date: Wed, 27 Apr 2022 03:05:29 +1200
Subject: [PATCH 2/2] Use `timeout` as fallback for killing process

---
 api/src/job.js | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/api/src/job.js b/api/src/job.js
index 0fc24a1..d561036 100644
--- a/api/src/job.js
+++ b/api/src/job.js
@@ -120,13 +120,18 @@ class Job {
                 '--nofile=' + this.runtime.max_open_files,
                 '--fsize=' + this.runtime.max_file_size,
             ];
+            
+            const timeout_call = [
+                'timeout', '-s', '9', Math.ceil(timeout / 1000),
+            ];
 
             if (memory_limit >= 0) {
                 prlimit.push('--as=' + memory_limit);
             }
 
-            const proc_call = [
+            const proc_call = [ 
                 'nice',
+                ...timeout_call,
                 ...prlimit,
                 ...nonetwork,
                 'bash',