On Wednesday, 9 November 2016 22:38:55 CET Matteo Cafasso wrote: > The internal_yara_scan runs the Yara engine with the previously loaded > rules against the given file. > > For each rule matching against the scanned file, a struct containing > the file name and the rule identifier is returned. > > The gathered list of yara_detection structs is serialised into XDR format > and written to a file. > > Signed-off-by: Matteo Cafasso <noxda...@gmail.com> > --- > daemon/yara.c | 87 > ++++++++++++++++++++++++++++++++ > generator/actions.ml | 10 ++++ > generator/structs.ml | 9 ++++ > gobject/Makefile.inc | 2 + > java/Makefile.inc | 1 + > java/com/redhat/et/libguestfs/.gitignore | 1 + > src/MAX_PROC_NR | 2 +- > 7 files changed, 111 insertions(+), 1 deletion(-) > > diff --git a/daemon/yara.c b/daemon/yara.c > index fe1f69a..8e7d328 100644 > --- a/daemon/yara.c > +++ b/daemon/yara.c > @@ -52,6 +52,8 @@ static int upload_rules_file (char *); > static int compile_rules_file (const char *); > static int write_callback (void *, const void *, size_t); > static void compile_error_callback (int, const char *, int, const char *, > void *); > +static int yara_rules_callback (int , void *, void *); > +static int send_detection_info (const char *, YR_RULE *); > > /* Has one FileIn parameter. */ > int > @@ -107,6 +109,39 @@ do_yara_destroy (void) > return 0; > } > > +/* Has one FileOut parameter. */ > +int > +do_internal_yara_scan (const char *path) > +{ > + int ret = 0; > + CLEANUP_CLOSE int fd = 0;
This must be initialized as -1, otherwise the CLEANUP_CLOSE handler will close the fd 0, which is stdin of the daemon. > + > + if (rules == NULL) { > + reply_with_error ("no yara rules loaded"); > + return -1; > + } > + > + CHROOT_IN; > + fd = open (path, O_RDONLY|O_CLOEXEC); > + CHROOT_OUT; > + > + if (fd < 0) { > + reply_with_perror ("%s", path); > + yr_finalize (); I don't think that's the right place for yr_finalize. > + return -1; > + } > + > + reply (NULL, NULL); /* Reply message. */ > + > + ret = yr_rules_scan_fd (rules, fd, 0, yara_rules_callback, (void *) path, > 0); > + if (ret == ERROR_SUCCESS) > + ret = send_file_end (0); /* File transfer end. */ > + else > + send_file_end (1); /* Cancel file transfer. */ > + > + return 0; > +} > + > /* Upload rules file on a temporary file. > * Return 0 on success, -1 on error. > */ > @@ -209,6 +244,58 @@ compile_error_callback(int level, const char *name, int > line, > fprintf (stderr, "(%d): Yara warning: %s\n", line, message); > } > > +/* Yara scan callback, called by yr_rules_scan_file. > + * Return 0 on success, -1 on error. > + */ > +static int > +yara_rules_callback (int code, void *message, void *data) > +{ > + int ret = 0; > + > + if (code == CALLBACK_MSG_RULE_MATCHING) > + ret = send_detection_info ((const char *)data, (YR_RULE *) message); > + > + return (ret == 0) ? CALLBACK_CONTINUE : CALLBACK_ERROR; > +} > + > +/* Serialize file path and rule name and send it out. > + * Return 0 on success, -1 on error. > + */ > +static int > +send_detection_info (const char *name, YR_RULE *rule) > +{ > + XDR xdr; > + int ret = 0; > + size_t len = 0; > + struct guestfs_int_yara_detection detection; > + CLEANUP_FREE char *buf = NULL, *fname = NULL; fname is not used here -- I suggest passing --enable-werror to autogen.sh or configure, so any compiler warning is turned to error. > + > + detection.name = (char *) name; > + detection.rule = (char *) rule->identifier; > + > + /* Serialize detection struct. */ > + buf = malloc (GUESTFS_MAX_CHUNK_SIZE); > + if (buf == NULL) { > + perror ("malloc"); > + return -1; > + } > + > + xdrmem_create (&xdr, buf, GUESTFS_MAX_CHUNK_SIZE, XDR_ENCODE); > + > + ret = xdr_guestfs_int_yara_detection (&xdr, &detection); > + if (ret == 0) { > + perror ("xdr_guestfs_int_yara_detection"); > + return -1; > + } > + > + len = xdr_getpos (&xdr); > + > + xdr_destroy (&xdr); > + > + /* Send serialised tsk_detection out. */ Typo in comment. > + return send_file_write (buf, len); > +} > + > /* Clean up yara handle on daemon exit. */ > void yara_finalize (void) __attribute__((destructor)); > void > diff --git a/generator/actions.ml b/generator/actions.ml > index 152c651..d9006f2 100644 > --- a/generator/actions.ml > +++ b/generator/actions.ml > @@ -13280,6 +13280,16 @@ Previously loaded rules will be destroyed." }; > shortdesc = "destroy previously loaded yara rules"; > longdesc = "\ > Destroy previously loaded Yara rules in order to free libguestfs resources." > }; > + > + { defaults with > + name = "internal_yara_scan"; added = (1, 35, 15); > + style = RErr, [Pathname "path"; FileOut "filename";], []; > + proc_nr = Some 473; > + visibility = VInternal; > + optional = Some "libyara"; > + shortdesc = "scan a file with the loaded yara rules"; > + longdesc = "Internal function for yara_scan." }; > + > ] > > (* Non-API meta-commands available only in guestfish. > diff --git a/generator/structs.ml b/generator/structs.ml > index 029bc3a..3fa2ebc 100644 > --- a/generator/structs.ml > +++ b/generator/structs.ml > @@ -468,6 +468,15 @@ let structs = [ > ]; > s_camel_name = "TSKDirent" }; > > + (* Yara detection information. *) > + { defaults with > + s_name = "yara_detection"; > + s_cols = [ > + "name", FString; > + "rule", FString; yara_load supports loading rules already compiled, which could have a namespace set -- I guess it should be reported here as well. That triggers another question: should the yara support allow to load more rules one after each other (with namespaces as well), instead of just one? Thanks, -- Pino Toscano
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs