It looks like the executable mode code was written when clamscan used to provide rich information about errors in its return codes:
/**
* clamscan return values (documented from man clamscan)
* 0 : No virus found.
* 1 : Virus(es) found.
* 40: Unknown option passed.
* 50: Database initialization error.
* 52: Not supported file type.
* 53: Can't open directory.
* 54: Can't open file. (ofm)
* 55: Error reading file. (ofm)
* 56: Can't stat input file / directory.
* 57: Can't get absolute path name of current working directory.
* 58: I/O error, please check your file system.
* 62: Can't initialize logger.
* 63: Can't create temporary files/directories (check permissions).
* 64: Can't write to temporary directory (please specify another one).
* 70: Can't allocate memory (calloc).
* 71: Can't allocate memory (malloc).
*/
...the switch/case based on the return code from the executable is based on the return code being something like the above.
However, it looks like clamscan changed the way it reports errors some time ago:
Looking at the source code for the clamav project itself, the detailed error messages were present in the man page in release 0.95 (from 2009):
https://github.com/vrtadmin/clamav-devel/blob/clamav-0.95/docs/man/clams...
...but they were replaced by the catch-all return code 2 in the next release 0.96 (from 2010):
https://github.com/vrtadmin/clamav-devel/blob/clamav-0.96/docs/man/clams...
The man page now just says this:
RETURN CODES
0 : No virus found.
1 : Virus(es) found.
2 : Some error(s) occured.
Therefore when something goes wrong, the module typically records very little information e.g.
Clamscan reported: [2] - unknown error
The actual output from clamscan is discarded and only the return code is logged:
// exec:
// The lines of text output by clamscan are assigned as an array to $output
// The actual result of clamscan is assigned to $result:
// 0 = clean
// 1 = infected
// x = unchecked
exec($cmd, $output, $result);
// ...snip...
watchdog('clamav', 'Uploaded file %filename could not be scanned. Clamscan reported: [@error_code] - @error_description', array('%filename' => $filename, '@error_code' => $result, '@error_description' => $description), WATCHDOG_WARNING);
It would probably be useful if the full $output was logged when clamscan returns 2.
It may also be an idea to provide an option to do something like try the scan again with some extra options (--verbose --debug perhaps?) and log the output of that. Alternatively just being able to pass extra options to the executable all the time would be a useful addition.
One or more patches on the way.
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | interdiff-2441575-1-5.txt | 1.77 KB | mcdruid |
| #5 | clamav-log_clamscan_errors-2441575-5-D7.patch | 2.95 KB | mcdruid |
| #1 | clamav-log_clamscan_errors-2441575-1-D7.patch | 2.94 KB | mcdruid |
Comments
Comment #1
mcdruid commentedPatch to add logging of the full output of the clamscan executable when it returns something other than 0 or 1.
Perhaps this could be configurable, but without it the logging is fairly useless (unknown error for everything).
Comment #2
adammaloneComment #3
adammaloneComment #4
adammaloneTo ensure we keep the scope of this issue narrow, I've created #2474079: Provide optional parameters to the executable to allow us to continue the discussion about additional parameters there.
Do you have a reliable and repeatable method of triggering one of these errors. Looking at some of the error codes, we could potentially look at corrupting or removing read access from the clam db as one option?
I have executed a quick phpcs over the patch and it's mostly in order with a few nits that I've added in below.
The first index in a multi-value array must be on a new line
The first index in a multi-value array must be on a new line
Function comment short description must end with a full stop
Doc comment for var of does not match actual variable name $output at position 1
Invalid @param data type, expected array but found Array
Parameter comment must be on the next line at position 1
Invalid @return data type, expected string but found String
Comment #5
mcdruid commentedNew patch which hopefully fixes the phpcs issues in the changed code.
As for triggering an error as a test, yes preventing the executable from accessing the virus definition files is a good way of doing this.
For example:
Breaking clamscan like that should work as a test of the new code; without the patch the module will just record a mysterious "unknown error".
Without patch:
With patch:
The latter is obviously a bit messy, but actually contains some potentially useful information.
Comment #6
mcdruid commentedComment #8
adammalone