[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