Fix CRITICAL: ImunifyAV scan detection bug - was scanning 0 files

Problem:
ImunifyAV scans were completing instantly with 0 files scanned because
our monitoring logic was fundamentally broken.

Root Cause:
1. We ran: imunify-antivirus malware on-demand start --path="/" &
2. This command returns IMMEDIATELY (doesn't block)
3. ImunifyAV starts scan asynchronously in its own background process
4. Our shell's $SCAN_PID exits right away (command finished)
5. Monitoring loop: while kill -0 $SCAN_PID exits immediately
6. We read results before scan actually started/finished
7. Result: 0 files scanned, scan marked as "stopped"

Example of broken output:
  ✓ Scanned 0 files
  ⏱  Duration: 7s
  [ImunifyAV scan complete - Found: 0]

This is WRONG - should scan thousands of files!

The Fix:

Changed from monitoring shell PID to monitoring scan STATUS:

OLD (BROKEN):
- imunify-antivirus ... &  # Background the COMMAND
- SCAN_PID=$!
- while kill -0 $SCAN_PID  # Check if command still running
  This fails because command exits immediately!

NEW (FIXED):
- imunify-antivirus ...  # Run in foreground (returns immediately anyway)
- while scan_running:
    - Poll: imunify-antivirus malware on-demand list
    - Check SCAN_STATUS field (running/completed/stopped/failed)
    - Check CREATED timestamp (is this our scan?)
    - Monitor until status = completed/stopped/failed
  This works because we monitor the actual scan, not the command!

Changes Made:

1. Removed & from command execution (line 829)
   - Command returns immediately anyway
   - No need to background it

2. Changed monitoring from PID-based to status-based (lines 846-895)
   - Poll scan list every 3 seconds
   - Check SCAN_STATUS field (field 7)
   - Check CREATED timestamp to identify our scan
   - Exit loop when status changes to terminal state

3. Added proper status handling:
   - completed: Success, read results
   - stopped: Warning, scan incomplete
   - failed: Error, skip this path

4. Added scan stop on timeout (line 892)
   - imunify-antivirus malware on-demand stop --path="$path"
   - Cleanly stops runaway scans

5. Better timestamp validation (line 856)
   - Only monitor scans created after SCAN_START
   - Prevents reading old/wrong scan results

Status Field Values:
- running: Scan in progress
- completed: Scan finished successfully
- stopped: Scan was interrupted/stopped
- failed: Scan encountered error

Impact:
BEFORE: ImunifyAV scanned 0 files (broken)
AFTER: ImunifyAV will properly scan thousands of files

Testing Needed:
- Run full server scan with ImunifyAV
- Verify file count increases during scan
- Verify scan completes with realistic file counts
- Check that progress updates appear
This commit is contained in:
cschantz
2025-12-22 19:18:26 -05:00
parent eeffd30650
commit 5b3ecbb2ae
+41 -21
View File
@@ -825,55 +825,75 @@ for scanner in "${AVAILABLE_SCANNERS[@]}"; do
echo " ⏳ Scanner: ImunifyAV (monitoring progress...)"
echo ""
# Start scan in background
imunify-antivirus malware on-demand start --path="$path" &>> "$LOG_DIR/imunify.log" &
SCAN_PID=$!
# Start scan (ImunifyAV runs async, command returns immediately)
imunify-antivirus malware on-demand start --path="$path" &>> "$LOG_DIR/imunify.log"
START_EXIT=$?
# Monitor progress by polling scan list
sleep 2 # Give scan time to start
if [ $START_EXIT -ne 0 ]; then
log_message "ERROR: ImunifyAV scan failed to start for $path (exit code: $START_EXIT)"
echo " ✗ Scan failed to start for $path (check logs)"
continue
fi
# Monitor progress by polling scan status
# ImunifyAV runs scans asynchronously, we poll the status
sleep 3 # Give scan time to initialize
last_count=0
timeout_counter=0
max_timeout=7200 # 2 hour timeout
scan_running=true
while kill -0 $SCAN_PID 2>/dev/null; do
# Get current scan status
while [ "$scan_running" = true ]; do
# Get current scan status from most recent scan
scan_info=$(imunify-antivirus malware on-demand list 2>/dev/null | tail -n +2 | head -1)
if [ -n "$scan_info" ]; then
current_files=$(echo "$scan_info" | awk '{print $11}')
status=$(echo "$scan_info" | awk '{print $2}')
current_status=$(echo "$scan_info" | awk '{print $7}') # Field 7 is SCAN_STATUS
created_time=$(echo "$scan_info" | awk '{print $2}') # Field 2 is CREATED
# Check if this is our scan (created after scan start)
if [ "$created_time" -ge "$SCAN_START" ]; then
# Check status
if [[ "$current_status" =~ ^(completed|stopped|failed)$ ]]; then
scan_running=false
echo "" # New line after progress
if [ "$current_status" = "failed" ]; then
log_message "ERROR: ImunifyAV scan failed for $path"
echo " ✗ Scan failed for $path"
continue 2
elif [ "$current_status" = "stopped" ]; then
log_message "WARNING: ImunifyAV scan was stopped for $path"
echo " ⚠️ Scan was stopped (may be incomplete)"
fi
break
fi
# Update progress if file count changed
if [[ "$current_files" =~ ^[0-9]+$ ]]; then
if [ "$current_files" != "$last_count" ]; then
elapsed=$(($(date +%s) - SCAN_START))
printf "\r Files scanned: %s | Elapsed: %s | Status: %s " \
"$current_files" "$(format_time $elapsed)" "$status"
"$current_files" "$(format_time $elapsed)" "$current_status"
last_count=$current_files
timeout_counter=0
fi
fi
fi
fi
sleep 3
timeout_counter=$((timeout_counter + 3))
if [ $timeout_counter -ge $max_timeout ]; then
kill $SCAN_PID 2>/dev/null
log_message "ERROR: ImunifyAV scan timed out after 2 hours for $path"
echo -e "\n ⏱️ Scan timed out (exceeded 2 hour limit)"
# Try to stop the scan
imunify-antivirus malware on-demand stop --path="$path" &>/dev/null
continue 2
fi
done
# Wait for scan to complete
wait $SCAN_PID
SCAN_EXIT=$?
echo "" # New line after progress
if [ $SCAN_EXIT -ne 0 ]; then
log_message "ERROR: ImunifyAV scan failed for $path (exit code: $SCAN_EXIT)"
echo " ✗ Scan failed for $path (check logs)"
continue
fi
# Get final scan results
LAST_SCAN=$(imunify-antivirus malware on-demand list 2>/dev/null | tail -n +2 | head -1)
FILES_SCANNED=$(echo "$LAST_SCAN" | awk '{print $11}')