AddThis Social Bookmark Button


OpenBSD PF Developer Interview, Part 2
Pages: 1, 2, 3, 4

Federico: What type of bpf security extensions have been introduced?

CEA: bpf is a device designed to capture packets from an interface. It has a filter language for selecting a subset of packets to be read, used mainly for performance reasons. bpf also contains some functionality for injecting packets into the network.

Programs use bpf by opening one of the /dev/bpfX devices, and obtaining a file descriptor. The access to the devices is restricted to root by default (through file permissions). The problem happens when a program wishes to drop privileges, or use privilege separation, after obtaining a bpf descriptor.

Even with dropped privileges, a program can change the filters, and the interface and, thus sniff any interface on the host. Furthermore, if the descriptor was opened with write access (some daemons require this, and libpcap does this by default) it is possible to inject packets to any of the available interfaces.

This had to be solved before any bpf-using program can be safely privilege separated. Two security mechanisms were introduced:

  1. write filtering allows setting bpf filters for write operations

  2. locking prevents "dangerous" changes to the descriptor such as modifying the read/write filters, and changing the interface. Obviously the descriptor cannot be unlocked once it is locked.

If the descriptor is properly configured and locked before dropping privileges, an exploit will not be able to further compromise the system through the bpf descriptor.

Federico: I've read this thread on the misc@ mailing list and I'm wondering what are the advantages of tcpdump privilege separation?

CEA: Network data is untrusted, and parsing them into a readable form is difficult and error-prone, especially for complex or obscure protocols, thus tcpdump (and most other sniffers) are complex and potentially dangerous pieces of code. A look at recently discovered vulnerabilities in such programs should give an idea. Even saved binary files may not be safe, and could act as time bombs. Privilege separation is used in these programs to isolate the dangerous packet parsing code into an unprivileged chroot jail.

At this point running tcpdump as root in OpenBSD is much more safer than running it unprivileged, since being root allows it to properly privsep. Hopefully this will be improved to cover unprivileged use, possibly using setuid after we resolve some signal issues. Yes, there is an irony here, making a program setuid root to make it safer :)

Federico: Can, could you provide a short history of pflogd?

CEA: The logging mechanism in pf is ingenious. Saving the raw packet dumps loses minimum information, (usually) uses less space than ASCII logs, and allows the logs to be analyzed using a variety of tools, including passive OS fingerprinting recently added to our tcpdump, and all the other cool analyzers/sniffers available.

The first version of pflogd is imported into the three about 2 months after the pflog interface. It had a basic functionality: dump the logs to a file in binary tcpdump format, make sure the existing file has the correct header before appending, handle SIGALRM for flushing logs, and SIGHUP for re-opening the log files for working correctly with log rotation.

At the last hackathon, right after OpenBSD 3.3 is released I have added support for the new pflog format. pflogd supports both, but refuses to overwrite an old file and outputs a 'Move away' warning to the syslog.

After OpenBSD 3.4 is released, the bpf extensions was ready, so pflogd was privilege separated. The privileged parent handled the bpf descriptor stuff and opening/positioning of log files, while the child running chrooted under _pflogd user is used for logging.

Later, (January 2004) it was noticed that the pflogd files may become corrupted if the partition gets full, or after an unclean shutdown. In this case some or all of the appended logs would become unreadable. pflogd now scans the complete log file, and detects corruption, and gives the "Move away" warning, refusing to append until the log is moved or rotated away.

Future: I have a (half forgotten) diff that handles the infamous "move away" part by renaming the existing log if a problem is detected. I have also not yet abandoned my plans for having ASCII pflogs. tcpdump is safe, and more powerful than anything I could put into pflogd, but lacks the rotation functionality.

Federico: Can, could you provide a short history of the PF logs format?

CEA: The pf logs contain a header and the logged packet itself. In the initial version, the header length was fixed, and very simple. It contained "interface, direction, action, a rule number" and a sub reason (why passed or dropped). This old format contained an unofficial link type (an identifier that determines the interface type and header format) and having a fixed length with no empty fields, it was not extendable.

After 3.3, we have improved the format to contain anchor and ruleset names and a header length field which will allow the format to be extended later as required. We have also changed the link type to the official id obtained from the libpcap/tcpdump maintainers.

Federico: The PF log format has changed over time. Do other operating systems or common software such as ethereal and the standard tcpdump support this format?

CEA: I have contributed patches to ethereal, and snort also supports the format. The standard tcpdump includes support to the new format since tcpdump_3_8rel2 (although they dropped backward compatibility to the old format).

Pages: 1, 2, 3, 4

Next Pagearrow