[Libguestfs] [PATCH v8 4/8] New API: yara_load

Richard W.M. Jones rjones at redhat.com
Tue Apr 25 08:43:28 UTC 2017


On Tue, Apr 25, 2017 at 12:20:02AM +0300, Matteo Cafasso wrote:
> The yara_load API allows to load a set of Yara rules contained within a
> file on the host.
> 
> Rules can be in binary format, as when compiled with yarac command, or
> in source code format. In the latter case, the rules will be first
> compiled and then loaded.
> 
> Subsequent calls of the yara_load API will result in the discard of the
> previously loaded rules.
> 
> Signed-off-by: Matteo Cafasso <noxdafox at gmail.com>
> ---
>  daemon/Makefile.am         |   1 +
>  daemon/cleanups.c          |   9 ++
>  daemon/cleanups.h          |   2 +
>  daemon/yara.c              | 213 +++++++++++++++++++++++++++++++++++++++++++++
>  generator/Makefile.am      |   3 +
>  generator/actions.ml       |   3 +-
>  generator/actions_yara.ml  |  48 ++++++++++
>  generator/actions_yara.mli |  21 +++++
>  generator/proc_nr.ml       |   1 +
>  lib/MAX_PROC_NR            |   2 +-
>  10 files changed, 301 insertions(+), 2 deletions(-)
>  create mode 100644 daemon/yara.c
>  create mode 100644 generator/actions_yara.ml
>  create mode 100644 generator/actions_yara.mli
> 
> diff --git a/daemon/Makefile.am b/daemon/Makefile.am
> index ca01aeb4e..68f863bcd 100644
> --- a/daemon/Makefile.am
> +++ b/daemon/Makefile.am
> @@ -170,6 +170,7 @@ guestfsd_SOURCES = \
>  	wc.c \
>  	xattr.c \
>  	xfs.c \
> +	yara.c \
>  	zero.c \
>  	zerofree.c
> 
> diff --git a/daemon/cleanups.c b/daemon/cleanups.c
> index 092e493d7..3102cf94b 100644
> --- a/daemon/cleanups.c
> +++ b/daemon/cleanups.c
> @@ -62,6 +62,15 @@ cleanup_close (void *ptr)
>  }
> 
>  void
> +cleanup_fclose (void *ptr)
> +{
> +  FILE *f = * (FILE **) ptr;
> +
> +  if (f)
> +    fclose (f);
> +}
> +
> +void
>  cleanup_aug_close (void *ptr)
>  {
>    augeas *aug = * (augeas **) ptr;
> diff --git a/daemon/cleanups.h b/daemon/cleanups.h
> index 6746e2744..a791244cb 100644
> --- a/daemon/cleanups.h
> +++ b/daemon/cleanups.h
> @@ -26,6 +26,7 @@ extern void cleanup_free (void *ptr);
>  extern void cleanup_free_string_list (void *ptr);
>  extern void cleanup_unlink_free (void *ptr);
>  extern void cleanup_close (void *ptr);
> +extern void cleanup_fclose (void *ptr);
>  extern void cleanup_aug_close (void *ptr);
>  extern void cleanup_free_stringsbuf (void *ptr);
> 
> @@ -35,6 +36,7 @@ extern void cleanup_free_stringsbuf (void *ptr);
>      __attribute__((cleanup(cleanup_free_string_list)))
>  #define CLEANUP_UNLINK_FREE __attribute__((cleanup(cleanup_unlink_free)))
>  #define CLEANUP_CLOSE __attribute__((cleanup(cleanup_close)))
> +#define CLEANUP_FCLOSE __attribute__((cleanup(cleanup_fclose)))
>  #define CLEANUP_AUG_CLOSE __attribute__((cleanup(cleanup_aug_close)))
>  #define CLEANUP_FREE_STRINGSBUF __attribute__((cleanup(cleanup_free_stringsbuf)))
>  #else
> diff --git a/daemon/yara.c b/daemon/yara.c
> new file mode 100644
> index 000000000..3c80b1123
> --- /dev/null
> +++ b/daemon/yara.c
> @@ -0,0 +1,213 @@
> +/* libguestfs - the guestfsd daemon
> + * Copyright (C) 2016 Red Hat Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <config.h>
> +
> +#include <stdio.h>
> +#include <fcntl.h>
> +#include <stdlib.h>
> +#include <inttypes.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <stdbool.h>
> +#include <rpc/xdr.h>
> +#include <rpc/types.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +
> +#include "daemon.h"
> +#include "actions.h"
> +#include "optgroups.h"
> +#include "guestfs_protocol.h"
> +
> +#ifdef HAVE_YARA
> +
> +#include <yara.h>
> +
> +#ifdef HAVE_ATTRIBUTE_CLEANUP
> +#define CLEANUP_DESTROY_YARA_COMPILER                           \
> +  __attribute__((cleanup(cleanup_destroy_yara_compiler)))
> +#else
> +#define CLEANUP_DESTROY_YARA_COMPILER
> +#endif
> +
> +struct write_callback_data {
> +  int fd;
> +  uint64_t written;
> +};
> +
> +/* Yara compiled rules. */
> +static YR_RULES *rules = NULL;
> +static bool initialized = false;
> +
> +static int compile_rules_file (const char *);
> +static void compile_error_callback (int, const char *, int, const char *, void *);
> +static void cleanup_destroy_yara_compiler (void *ptr);
> +
> +/* Has one FileIn parameter.
> + * Takes optional arguments, consult optargs_bitmask.
> + */
> +int
> +do_yara_load (void)
> +{
> +  int r = 0;

This should not be initialized.  Initializing it means that GCC cannot
catch code paths where r is used without being assigned to.

There are other instances of this in the same file in later patches
so please fix those too.

> +/* Compile source code rules and load them.
> + * Return ERROR_SUCCESS on success, Yara error code type on error.
> + */
> +static int
> +compile_rules_file (const char *rules_path)
> +{
> +  int ret = 0;
> +  CLEANUP_FCLOSE FILE *rule_file = NULL;
> +  CLEANUP_DESTROY_YARA_COMPILER YR_COMPILER *compiler = NULL;
> +
> +  ret = yr_compiler_create (&compiler);
> +  if (ret != ERROR_SUCCESS) {
> +    reply_with_error ("yr_compiler_create");
> +    return ret;
> +  }
> +
> +  yr_compiler_set_callback (compiler, compile_error_callback, NULL);
> +
> +  rule_file = fopen (rules_path, "r");
> +  if (rule_file == NULL) {
> +    reply_with_error ("unable to open rules file");

This should call reply_with_perror otherwise the errno from fopen will
be lost.

> +/* Yara compilation error callback.
> + * Reports back the compilation error message.
> + * Prints compilation warnings if verbose.
> + */
> +static void
> +compile_error_callback (int level, const char *name, int line,
> +                        const char *message, void *data)
> +{
> +  if (level == YARA_ERROR_LEVEL_ERROR)
> +    reply_with_error ("Yara error (line %d): %s", line, message);

It seems unlike that calling reply_with_error is safe here.
How do you avoid calling reply_with_error twice along error paths?

> +  else if (verbose)
> +    fprintf (stderr, "Yara warning (line %d): %s\n", line, message);
> +}
> +
> +/* Clean up yara handle on daemon exit. */
> +void yara_finalize (void) __attribute__((destructor));
> +
> +void
> +yara_finalize (void)
> +{
> +  int r = 0;

Shouldn't be initialized.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine.  Supports Linux and Windows.
http://people.redhat.com/~rjones/virt-df/




More information about the Libguestfs mailing list