-
-
Notifications
You must be signed in to change notification settings - Fork 126
Open
Labels
enhancementIssues or PRs that enhance existing featuresIssues or PRs that enhance existing featuresperfIssues and PRs retaining to performance issues and improvements.Issues and PRs retaining to performance issues and improvements.
Description
Bug: PHP memory exhaustion when reading large log files via LogFileModelTraits
Description
The REST API crashes with a PHP fatal error when attempting to read large log files. The read_uncompressed_log() method in LogFileModelTraits.inc uses PHP's file() function which loads the entire file into memory, causing memory exhaustion on large rotated log files.
Environment
- pfSense Version: 2.8.1-RELEASE (amd64)
- REST API Version: pfSense-pkg-RESTAPI-2.6_8
- PHP Memory Limit: 512 MB
Error
PHP Fatal error: Allowed memory size of 536870912 bytes exhausted
(tried to allocate 541402264 bytes) in
/usr/local/pkg/RESTAPI/ModelTraits/LogFileModelTraits.inc on line 38
Root Cause
In LogFileModelTraits.inc, the read_uncompressed_log() method:
private function read_uncompressed_log(string $filepath): array {
$this->check_file_exists($filepath);
return file($filepath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); // Line 38
}This loads the entire file into memory as an array. When log rotation produces large files (500MB+ in my case due to misconfigured log limits), API calls that query logs will crash.
The same issue exists in read_bzip2_log() and read_gzip_log() which decompress entire files into memory.
Steps to Reproduce
- Have a large rotated log file (e.g.,
/var/log/system.log.X> 500MB) - Make an API call that reads system logs
- PHP crashes with memory exhaustion
Suggested Fix
Consider one of:
- Add file size check - Reject files over a threshold with a clear error
- Stream reading - Use
fgets()in a loop with line limit - Generator pattern - Yield lines instead of returning full array
- Pagination - Only read requested line ranges from file
Example size-limited approach:
private function read_uncompressed_log(string $filepath, int $max_bytes = 50000000): array {
$this->check_file_exists($filepath);
if (filesize($filepath) > $max_bytes) {
throw new NotAcceptableError(
message: "Log file too large to read. Size: " . filesize($filepath) . " bytes.",
response_id: 'LOG_FILE_TRAITS_FILE_TOO_LARGE',
);
}
return file($filepath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
}Workaround
Reduce log file size limits in pfSense:
- Status → System Logs → Settings → Set log file size to 500KB or less
- Or add to config.xml:
<logfilesize>512000</logfilesize>
Metadata
Metadata
Assignees
Labels
enhancementIssues or PRs that enhance existing featuresIssues or PRs that enhance existing featuresperfIssues and PRs retaining to performance issues and improvements.Issues and PRs retaining to performance issues and improvements.