]> git.ipfire.org Git - thirdparty/ulogd2.git/commitdiff
output: SQLITE3: improve mapping of DB columns to fields
authorJeremy Sowden <jeremy@azazel.net>
Tue, 30 Nov 2021 10:55:49 +0000 (10:55 +0000)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 3 Jan 2022 15:08:54 +0000 (16:08 +0100)
Currently, we copy the column-name to a buffer, iterate over it to
replace the underscores with full-stops, using `strchr` from the start
of the buffer on each iteration, then copy the buffer to the field's
`name` member.

Apart from the inefficiency, `strncpy` is used to do the copies, which
leads gcc to complain:

  ulogd_output_SQLITE3.c:341:17: warning: `strncpy` output may be truncated copying 31 bytes from a string of length 31

Furthermore, the buffer is not initialized, which means that there is
also a possible buffer overrun if the column-name is too long, since
`strncpy` will not append a NUL.

Instead, copy the column-name directly to the field using `snprintf`,
and run `strchr` from the last underscore on each iteration.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
output/sqlite3/ulogd_output_SQLITE3.c

index 692ff2bd3e294423fca109fd93639fc0d3924b4a..d2857dfdc48f48da30e1fd020aee55853801ce57 100644 (file)
@@ -301,9 +301,6 @@ static int
 sqlite3_init_db(struct ulogd_pluginstance *pi)
 {
        struct sqlite3_priv *priv = (void *)pi->private;
-       char buf[ULOGD_MAX_KEYLEN + 1];
-       char *underscore;
-       struct field *f;
        sqlite3_stmt *schema_stmt;
        int col, num_cols;
 
@@ -323,24 +320,27 @@ sqlite3_init_db(struct ulogd_pluginstance *pi)
        }
 
        for (col = 0; col < num_cols; col++) {
-               strncpy(buf, sqlite3_column_name(schema_stmt, col), ULOGD_MAX_KEYLEN);
-
-               /* replace all underscores with dots */
-               while ((underscore = strchr(buf, '_')) != NULL)
-                       *underscore = '.';
-
-               DEBUGP("field '%s' found\n", buf);
+               char *underscore;
+               struct field *f;
 
                /* prepend it to the linked list */
                if ((f = calloc(1, sizeof(struct field))) == NULL) {
                        ulogd_log(ULOGD_ERROR, "SQLITE3: out of memory\n");
                        return -1;
                }
-               strncpy(f->name, buf, ULOGD_MAX_KEYLEN);
+               snprintf(f->name, sizeof(f->name),
+                        "%s", sqlite3_column_name(schema_stmt, col));
+
+               /* replace all underscores with dots */
+               for (underscore = f->name;
+                    (underscore = strchr(underscore, '_')) != NULL; )
+                       *underscore = '.';
+
+               DEBUGP("field '%s' found\n", f->name);
 
-               if ((f->key = ulogd_find_key(pi, buf)) == NULL) {
+               if ((f->key = ulogd_find_key(pi, f->name)) == NULL) {
                        ulogd_log(ULOGD_ERROR,
-                                 "SQLITE3: unknown input key: %s\n", buf);
+                                 "SQLITE3: unknown input key: %s\n", f->name);
                        free(f);
                        return -1;
                }