summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Sowden <jeremy@azazel.net>2023-03-16 11:07:54 +0000
committerFlorian Westphal <fw@strlen.de>2023-03-16 23:24:55 +0100
commit524ce20b55a2793d380fc1e4b415b1ea5a9512b1 (patch)
tree649623c9d659f10b8f30b41b95f46e0b98d5eae1
parent3994535c1d54028ae0a3268e001c9598c7c335ed (diff)
pcap: prevent crashes when output `FILE *` is null
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>
-rw-r--r--output/pcap/ulogd_output_PCAP.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/output/pcap/ulogd_output_PCAP.c b/output/pcap/ulogd_output_PCAP.c
index 0daa2c9..19ce47f 100644
--- a/output/pcap/ulogd_output_PCAP.c
+++ b/output/pcap/ulogd_output_PCAP.c
@@ -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: