Copyright © 2001 Data Deliverance Pty Ltd
This README, patch and associated utility programs (if any) are released under the GNU Public License Version 2.
Files which are marked immutable may not be written to, even by root, and regardless of the file permissions. Similarly, append-only files may be written to only in append mode. Log files are good candidates for append-only files, allowing only new logs to be added.
Devices files for things like raw disks and kernel memory are good candidates for immutable files, since this stops fiddling with the disk or memory images, subverting security.
In current kernels, attributes such as immutable and append-only appear to be implemented only for the ext2 filesystem, as a local addition. Furthermore, setting attributes on device files is not implemented. This patch provides a standard system-call interface for setting and getting attributes, and extends the ext2 support to allow applying attributes on any file.
Note: As it stands, on a standard system, the immutable and append-only support that Linux provides is not as useful as it might be, since root can still turn off these attributes and do whatever is necessary to the file. The splitting of privileges into different capabilities can alleviate this problem, but user-level capability support is still fairly immature.
Our company's Fort of Deliverance firewall and secure application server platform makes good use of immutable and append-only files, but adds additional checks to ensure that immutable and append-only files cannot be tampered with when the system has fully booted.
The installation process involves three steps:
At time of writing very few, if any, linux distributions are shipping with 2.4 kernels. If you have not been using and compiling the 2.4 kernel, you will need to download the latest 2.4 kernel source from www.kernel.org. This is not something to be undertaken lightly. Alternatively, you may download the 2.2 kernel version here, when it is available.
A C compilerTry typing "gcc". If you get something like "gcc: No input files" you have a C compiler. Again, this should be available as part of a package in your Linux distribution. Under RedHat, for example there is an rpm called "egcs-version-number".
The "patch" utility.Try "patch --help" and see if you get a verbose list of options. If not, try looking for a "patch" package. RedHat has "patch-version-num".
To install, do the following:
# patch -p1 < path-to-patch-file
This may generate quite a few messages. If you get any errors indicating that patches have been rejected, your kernel is not fully compatible with the patch. If you do not have good knowledge of the inside workings of the kernel, you may be advised to upgrade to a kernel which is supported. See also our consulting services.
Configure the kernelIf you have not customised or compiled your kernel before, you will need to do this step. Type:
# make xconfig
Type these commands to set up and compile the kernel and modules:
# make dep # make bzImage modules
NOTE: These instructions relate to systems running lilo (if you get the "lilo:" prompt when your system boots). For other systems you will need to find out how to safely replace the kernel.
First, rename the old kernel. It should live in /boot, and should be called something like "vmlinuz-some-version" - e.g. "vmlinuz-2.4.0". Rename it to have the extension ".old". It is safe to do this while the system is running. For example:
# cd /boot # mv vmlinuz-2.4.0 vmlinuz-2.4.0.old
Now copy the new kernel into the /boot directory. It should live in your "/usr/src/linux" directory under the "arch/i386/boot" subdirectory (or "arch/something-else/boot" if you are not using a PC), and should be called "bzImage". Copy it over and call it "vmlinuz-2.4.0". Make sure that you have renamed the old kernel first, if it had the same name. Also make the "vmlinuz" kernel link point to the new kernel. For example:
# cd /usr/src/linux/arch/i386/boot # cp -i bzImage /boot/vmlinuz-2.4.0 # mv /boot/vmlinuz /boot/vmlinuz.old # ln -s vmlinuz-2.4.0 /boot/vmlinuz
Now time to install and set up the kernel modules. Check to see if you have a directory called "2.4.0" in /lib/modules. If so, rename it to "2.4.0.old". Similarly, if you have a file called "/boot/System.map-2.4.0", rename it as well. Copy the file called "System.map" in your kernel build directory to "/boot/System.map-2.4.0". For example:
# cd /usr/src/linux/ # cp -i System.map /boot/System.map-2.4.0
# make modules_install
# cd /boot # mv System.map System.map.old # ln -s System.map-2.4.0 System.map # depmod -a -i -m /boot/System.map-2.4.0 2.4.0
Now back up the file "/etc/lilo.conf" - call it "/etc/lilo.conf.orig" or something like that. This is a critical system file and you are about to make changes in it. If is safe to do this, but make sure you have a backup first. The file should look something like this, plus or minus a few lines:
boot=/dev/hda map=/boot/map install=/boot/boot.b prompt timeout=50 linear default=linux image=/boot/vmlinuz-2.4.0 label=linux initrd=/boot/initrd-2.4.0.img read-only root=/dev/hda5
There may be more than one section starting "image=". If so, find the one with a "label=" parameter matching the "default=" near the top. So for example if your file has "default=linux", you should search for an image section with "label=linux" in it. Normally you will have only one image section anyway. Duplicate the section starting "image=" to the end of the file, or until the next "image=" line.
Edit the old image section, adding ".old" onto the end of the label, and onto the end of the image line. In the example, the file would now look like this:
boot=/dev/hda map=/boot/map install=/boot/boot.b prompt timeout=50 linear default=linux image=/boot/vmlinuz-2.4.0.old label=linux.old read-only root=/dev/hda5 image=/boot/vmlinuz-2.4.0 label=linux read-only root=/dev/hda5
Finally, run the command "lilo". If you get any errors, make sure you have copied the file with the correct name, and that there are no mistakes in the /etc/lilo.conf file.
If you cannot get it to work, do not reboot the computer without doing the following:
# rm /etclilo.conf # mv /etc/lilo.conf.old /etc/lilo.conf # cd /boot # rm vmlinuz System.map # mv vmlinuz.old vmlinuz # mv System.map System.map.old # lilo
Assuming you have it working, now reboot your system. If it fails to boot, you can back out of the patch by doing the following:
The fsck command for the ext2 filesystem is patched so that it does not clear the immutable and append-only flags on devices. The patch is based on the e2fprogs package (version 1.19), obtainable from e2fsprogs.sourceforge.net.
Make sure you don't download an earlier version of e2fsprogs from what you are using on your system. The latest version should generally be safe. If you are using RPMs, you can find out what version you currently have using a command such as this:
# rpm -q -f /sbin/e2fsck
Before going further, make sure that you can back out of this installation if anything goes wrong. You should have ideally backed up your system, or at least have access to the version of the e2fsprogs package that is installed on your system so you can reinstall it later if necessary.
If you downloaded the RPM version (make sure it is the source RPM), install the source, then patch it. On a RedHat system, you might do that like this:
# rpm -i e2fsprogs-1.19-0.src.rpm # rpm -bp /usr/src/redhat/SPECS/e2fsprogs.spec # cd /usr/src/redhat/BUILD/e2fsprogs-1.19 # patch -p1 < path-to-patch-file/e2fsprogs-patch-1.19-attr
Now, for an RPM, build and install with commands like this:
# rpm -bi /usr/src/redhat/SPECS/e2fsprogs.spec
To compile and install the utilities, go to the "progs" subdirectory in the patch distribution. If you have not patched the files for the current kernel, or /usr/include/linux does not point to the kernel source you patched, then uncomment the CFLAGS= line in the Makefile to point to your kernel include directory root (e.g. /usr/src/linux/include). Finally, just type "make install" to create and install two binaries - lsattr and chattr. The old lsattr and chattr should be renamed to lsattr.ext2 and chattr.ext2. They may still be useful, as described below.
chattr and lsattr work in much the same as their ext2 counterparts, as described by the manual pages. Only the generic attributes A, a, i and S flags are supported by chattr. Only -R is supported as a flag by lsattr and chattr.
Note that lsattr.ext2 and chattr.ext2 are quite compatible with the generic ones: using chattr.ext2 to set a flag on a plain file has the same effect as using the generic chattr. chattr.ext2 can be used to set flags that are specific to the ext2 filesystem, not available with the generic chattr, and lsattr.ext2 can be used to list these flags.