]> git.ipfire.org Git - thirdparty/ulogd2.git/commitdiff
pcap: prevent crashes when output `FILE *` is null
authorJeremy Sowden <jeremy@azazel.net>
Thu, 16 Mar 2023 11:07:54 +0000 (11:07 +0000)
committerFlorian Westphal <fw@strlen.de>
Thu, 16 Mar 2023 22:24:55 +0000 (23:24 +0100)
If ulogd2 receives a signal it will attempt to re-open the pcap output
file.  If this fails (because the permissions or ownership have changed
for example), the FILE pointer will be null and when the next packet
comes in, the null pointer will be passed to fwrite and ulogd will
crash.

Instead, assign the return value of `fopen` to a local variable, and
only close the existing stream if `fopen` succeeded.

Link: https://bugs.launchpad.net/ubuntu/+source/ulogd2/+bug/1429778
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
output/pcap/ulogd_output_PCAP.c

index 0daa2c920c322013c295f6ba8776b9dff5d804bb..19ce47f9ae7c5db4201a73cb013c7c9e6224b6d7 100644 (file)
@@ -221,14 +221,20 @@ static int append_create_outfile(struct ulogd_pluginstance *upi)
        struct pcap_instance *pi = (struct pcap_instance *) &upi->private;
        char *filename = upi->config_kset->ces[0].u.string;
        struct stat st_of;
+       FILE *of;
 
-       pi->of = fopen(filename, "a");
-       if (!pi->of) {
+       of = fopen(filename, "a");
+       if (!of) {
                ulogd_log(ULOGD_ERROR, "can't open pcap file %s: %s\n",
                          filename,
                          strerror(errno));
                return -EPERM;
        }
+
+       if (pi->of)
+               fclose(pi->of);
+       pi->of = of;
+
        if (fstat(fileno(pi->of), &st_of) == 0 && st_of.st_size == 0 &&
            !write_pcap_header(pi)) {
                ulogd_log(ULOGD_ERROR, "can't write pcap header: %s\n",
@@ -241,12 +247,9 @@ static int append_create_outfile(struct ulogd_pluginstance *upi)
 
 static void signal_pcap(struct ulogd_pluginstance *upi, int signal)
 {
-       struct pcap_instance *pi = (struct pcap_instance *) &upi->private;
-
        switch (signal) {
        case SIGHUP:
                ulogd_log(ULOGD_NOTICE, "reopening capture file\n");
-               fclose(pi->of);
                append_create_outfile(upi);
                break;
        default: