Messages in this thread | | | From | Bear Giles <> | Subject | embedded tripwire (fs white paper) | Date | Sat, 2 Oct 1999 10:24:35 -0600 (MDT) |
| |
The recent discussion on ACLs prompts me to write the following informal white paper. ("green paper"?)
"Embedded Tripwire" in Linux Filesystems
With minor changes, it is now possible to "embed" limited tripwire support into Linux filesystems under the internationalized kernel. (We only require the "digest" functions from the i-kernel.) The basic mechanism is
CREATION:
- creat() a new file. creat sets an internal flag which indicates that this is a new file. - write() data into the file - ioctl()? set extended attributes to include TRIPWIRE. This attribute should only be permitted on new files. - close() the file. Use fs-defined digest functions to compute several strong checksums and store them as extended attributes.
In practice, the TRIPWIRE and IMMUTABLE flags will typically be used together. Even if the flags are kept distinct, it might be best for TRIPWIRE to forcefully clear any write permissions.
USE:
- open() an existing file. If the TRIPWIRE extended attribute is set the file is scanned and the checksums compared. If the checksums match, everything proceeds as before. If the checksums do not match, one of four conditions hold:
- the secure level is zero, the file is opened as before.
- the secure level is non-zero or the STRICT_TRIPWIRE flag is set on the open, the file is not opened and a new error status is returned, ECHKSM
- the IGNORE_TRIPWIRE flag is set on the open and the securelevel is less than 0 or 1, the file is opened as before.
- the IGNORE_TRIPWIRE flag is set on the open and the securelevel is 2 or more, the file is not opened and a new error status is returned, CHKSM.
- close() the file. The checksums are never changed. (To modify a checksummed file you must copy it, modify the copy, then remove the original and replace it with the copy.)
This is a minimal system. One or two additional file_operations can also be productively used:
ssize_t (*digest) (struct dentry *d, int digest_id, char *digest, size_t cnt)
int (*verify_digest) (struct dentry *d, int digest_id)
The first operation computes the specified digest and returns it in the specified buffer. This operation can be implemented immediately without change to any file system.
The second operation computes the specified digest and compares the results with those cached upon file creation. The return code indicates success, failure, unknown digest and uncached digest. This requires extensive changes to the file sytem for the non-trivial handler.
There are two significant benefits to these functions:
1) they eliminate the need to copy the file contents into user space, so they will always be more efficient than user space equivalents.
2) since the file contents are never copied into user space, it is practical to relax the permissions on these functions. In fact, it's not unreasonable to provide file digests in any situation where you would provide attributes for a non-special device. This, in turn, allows a program like tripwire to run without root permission.
The devil is definitely in the details in this proposal. Is the cost of potential DoS worth the benefits of never running a compromised program? Because of these details I don't expect this proposal to appear in the 2.4 kernel as anything other than a "highly experimental" option.
Bear Giles bgiles@coyotesong.com
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |