This improvement looks up the filename given the file descriptor.
This is supported on Mac and Linux but not presently supported
on other UNIX operating systems. FD-passing is not available on
Windows.
On supported systems, the verdict in the clamd log and the VirusEvent
will show the actual file path instead of something like fd[14].
... | ... |
@@ -23,6 +23,13 @@ ClamAV 0.103.1 is a bug patch release to address the following issues. |
23 | 23 |
|
24 | 24 |
- Fixed freshclam --on-update-execute=EXIT_1 temporary directory cleanup issue. |
25 | 25 |
|
26 |
+- `clamd`'s log output and VirusEvent now provide the scan target's file path |
|
27 |
+ instead of a file descriptor. The clamd socket API for submitting a scan by |
|
28 |
+ FD-passing doesn't include a file path, this feature works by looking up the |
|
29 |
+ file path by file descriptor. This feature works on Mac and Linux but is not |
|
30 |
+ yet implemented for other UNIX operating systems. |
|
31 |
+ FD-passing is not available for Windows. |
|
32 |
+ |
|
26 | 33 |
### Acknowledgements |
27 | 34 |
|
28 | 35 |
The ClamAV team thanks the following individuals for their code submissions: |
... | ... |
@@ -364,7 +364,7 @@ int scan_pathchk(const char *path, struct cli_ftw_cbdata *data) |
364 | 364 |
return 0; |
365 | 365 |
} |
366 | 366 |
|
367 |
-int scanfd( |
|
367 |
+cl_error_t scanfd( |
|
368 | 368 |
const client_conn_t *conn, |
369 | 369 |
unsigned long int *scanned, |
370 | 370 |
const struct cl_engine *engine, |
... | ... |
@@ -373,13 +373,17 @@ int scanfd( |
373 | 373 |
int odesc, |
374 | 374 |
int stream) |
375 | 375 |
{ |
376 |
- int ret, fd = conn->scanfd; |
|
376 |
+ cl_error_t ret = -1; |
|
377 |
+ int fd = conn->scanfd; |
|
377 | 378 |
const char *virname = NULL; |
378 | 379 |
STATBUF statbuf; |
379 | 380 |
struct cb_context context; |
380 | 381 |
char fdstr[32]; |
381 | 382 |
const char *reply_fdstr; |
382 | 383 |
|
384 |
+ char *filepath = NULL; |
|
385 |
+ char *log_filename = fdstr; |
|
386 |
+ |
|
383 | 387 |
UNUSEDPARAM(odesc); |
384 | 388 |
|
385 | 389 |
if (stream) { |
... | ... |
@@ -396,41 +400,60 @@ int scanfd( |
396 | 396 |
} |
397 | 397 |
if (FSTAT(fd, &statbuf) == -1 || !S_ISREG(statbuf.st_mode)) { |
398 | 398 |
logg("%s: Not a regular file. ERROR\n", fdstr); |
399 |
- if (conn_reply(conn, reply_fdstr, "Not a regular file", "ERROR") == -1) |
|
400 |
- return CL_ETIMEOUT; |
|
401 |
- return -1; |
|
399 |
+ if (conn_reply(conn, reply_fdstr, "Not a regular file", "ERROR") == -1) { |
|
400 |
+ ret = CL_ETIMEOUT; |
|
401 |
+ goto done; |
|
402 |
+ } |
|
403 |
+ ret = CL_BREAK; |
|
404 |
+ goto done; |
|
405 |
+ } |
|
406 |
+ |
|
407 |
+ /* Try and get the real filename, for logging purposes */ |
|
408 |
+ if (!stream) { |
|
409 |
+ if (CL_SUCCESS != cli_get_filepath_from_filedesc(fd, &filepath)) { |
|
410 |
+ logg("*%s: Unable to determine the filepath given the file descriptor.\n", fdstr); |
|
411 |
+ } else { |
|
412 |
+ log_filename = filepath; |
|
413 |
+ } |
|
402 | 414 |
} |
403 | 415 |
|
404 | 416 |
thrmgr_setactivetask(fdstr, NULL); |
405 | 417 |
context.filename = fdstr; |
406 | 418 |
context.virsize = 0; |
407 | 419 |
context.scandata = NULL; |
408 |
- ret = cl_scandesc_callback(fd, conn->filename, &virname, scanned, engine, options, &context); |
|
420 |
+ ret = cl_scandesc_callback(fd, log_filename, &virname, scanned, engine, options, &context); |
|
409 | 421 |
thrmgr_setactivetask(NULL, NULL); |
410 | 422 |
|
411 | 423 |
if (thrmgr_group_need_terminate(conn->group)) { |
412 | 424 |
logg("*Client disconnected while scanjob was active\n"); |
413 |
- return ret == CL_ETIMEOUT ? ret : CL_BREAK; |
|
425 |
+ ret = ret == CL_ETIMEOUT ? ret : CL_BREAK; |
|
426 |
+ goto done; |
|
414 | 427 |
} |
415 | 428 |
|
416 | 429 |
if (ret == CL_VIRUS) { |
417 | 430 |
if (conn_reply_virus(conn, reply_fdstr, virname) == -1) |
418 | 431 |
ret = CL_ETIMEOUT; |
419 | 432 |
if (context.virsize && optget(opts, "ExtendedDetectionInfo")->enabled) |
420 |
- logg("%s: %s(%s:%llu) FOUND\n", fdstr, virname, context.virhash, context.virsize); |
|
433 |
+ logg("%s: %s(%s:%llu) FOUND\n", log_filename, virname, context.virhash, context.virsize); |
|
421 | 434 |
else |
422 |
- logg("%s: %s FOUND\n", fdstr, virname); |
|
423 |
- virusaction(reply_fdstr, virname, opts); |
|
435 |
+ logg("%s: %s FOUND\n", log_filename, virname); |
|
436 |
+ virusaction(log_filename, virname, opts); |
|
424 | 437 |
} else if (ret != CL_CLEAN) { |
425 | 438 |
if (conn_reply(conn, reply_fdstr, cl_strerror(ret), "ERROR") == -1) |
426 | 439 |
ret = CL_ETIMEOUT; |
427 |
- logg("%s: %s ERROR\n", fdstr, cl_strerror(ret)); |
|
440 |
+ logg("%s: %s ERROR\n", log_filename, cl_strerror(ret)); |
|
428 | 441 |
} else { |
429 | 442 |
if (conn_reply_single(conn, reply_fdstr, "OK") == CL_ETIMEOUT) |
430 | 443 |
ret = CL_ETIMEOUT; |
431 | 444 |
if (logok) |
432 |
- logg("%s: OK\n", fdstr); |
|
445 |
+ logg("%s: OK\n", log_filename); |
|
433 | 446 |
} |
447 |
+ |
|
448 |
+done: |
|
449 |
+ if (NULL != filepath) { |
|
450 |
+ free(filepath); |
|
451 |
+ } |
|
452 |
+ |
|
434 | 453 |
return ret; |
435 | 454 |
} |
436 | 455 |
|
... | ... |
@@ -65,7 +65,7 @@ struct cb_context { |
65 | 65 |
struct scan_cb_data *scandata; |
66 | 66 |
}; |
67 | 67 |
|
68 |
-int scanfd(const client_conn_t *conn, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, int odesc, int stream); |
|
68 |
+cl_error_t scanfd(const client_conn_t *conn, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, int odesc, int stream); |
|
69 | 69 |
int scanstream(int odesc, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *options, const struct optstruct *opts, char term); |
70 | 70 |
cl_error_t scan_callback(STATBUF *sb, char *filename, const char *msg, enum cli_ftw_reason reason, struct cli_ftw_cbdata *data); |
71 | 71 |
int scan_pathchk(const char *path, struct cli_ftw_cbdata *data); |
... | ... |
@@ -188,6 +188,7 @@ EXPORTS __cli_strnlen @44390 NONAME |
188 | 188 |
EXPORTS __cli_strnstr @44391 NONAME |
189 | 189 |
EXPORTS cli_gentemp_with_prefix @44392 NONAME |
190 | 190 |
EXPORTS cli_basename @44393 NONAME |
191 |
+EXPORTS cli_get_filepath_from_filedesc @44394 NONAME |
|
191 | 192 |
|
192 | 193 |
; compatibility layer, tommath, zlib |
193 | 194 |
EXPORTS w32_srand @44269 NONAME |
... | ... |
@@ -270,4 +271,4 @@ EXPORTS cli_sigperf_events_destroy @44350 NONAME |
270 | 270 |
EXPORTS cli_cache_init @44351 NONAME |
271 | 271 |
EXPORTS cli_cache_destroy @44352 NONAME |
272 | 272 |
EXPORTS cli_strntoul @44353 NONAME |
273 |
-EXPORTS cli_realpath @44354 NONAME |
|
274 | 273 |
\ No newline at end of file |
274 |
+EXPORTS cli_realpath @44354 NONAME |