chkboot
chkboot copied to clipboard
"chkboot -u" does not update files, causes false positives
After making intended changes to the /boot filesystem, the user is intended to run the command "chkboot -u". However, running this command does effectively nothing. This causes a false positive the next time the system boots.
Proof:
Suppose a user runs "chkboot -u" after making intended changes to the /boot partition.
At the beginning of the script, this causes the $CHANGED variable to be set to "-1":
if [ "$1" = "-u" -o "$1" = "--update" ]; then
CHANGED="-1"
Afterwards, the script generates the hashes for the filesystem to $DISKHEAD and $BOOTFILES.
The following piece of code is NOT run when running "chkboot -u":
if [ ! "$CHANGED" = "-1" ]; then
( diff $BOOTFILES_LAST $BOOTFILES >> "${CHANGES_ALERT}-now" ) || CHANGED="1"
( diff $DISKHEAD_LAST $DISKHEAD >> "${CHANGES_ALERT}-now" ) || CHANGED="1"
fi
Therefore, the $CHANGED variable remains "-1".
Immediately after, the following piece of code runs:
if [ ! $CHANGED = "1" ] ; then
rm -f $DISKHEAD "${CHANGES_ALERT}-now" $BOOTFILES
else
[snip]
fi
Since $CHANGED is not "1" (it is "-1"), this causes the program to remove the generated files (the first branch is chosen), causing a false positive on the next boot, since the last hashes still point to the old files.
Proposed solution
Replace the following lines:
if [ ! -z "$1" ]; then
if [ "$1" = "-u" -o "$1" = "--update" ]; then
CHANGED="-1"
elif [ "$1" = "-h" -o "$1" = "--help" ]; then
help
exit 0
else
echo -e "Invalid argument: ${1}"
help
exit 1
fi
else
CHANGED="0"
fi
With:
if [ ! -z "$1" ]; then
if [ "$1" = "-u" -o "$1" = "--update" ]; then
UPDATEONLY="1"
elif [ "$1" = "-h" -o "$1" = "--help" ]; then
help
exit 0
else
echo -e "Invalid argument: ${1}"
help
exit 1
fi
else
UPDATEONLY="0"
fi
Rationale: The $CHANGED variable should only be used to specify whether the boot hashes have changed, not the running mode of the program.
Replace the following lines:
if [ ! "$CHANGED" = "-1" ]; then
( diff $BOOTFILES_LAST $BOOTFILES >> "${CHANGES_ALERT}-now" ) || CHANGED="1"
( diff $DISKHEAD_LAST $DISKHEAD >> "${CHANGES_ALERT}-now" ) || CHANGED="1"
fi
With:
CHANGED="0"
( diff $BOOTFILES_LAST $BOOTFILES >> "${CHANGES_ALERT}-now" ) || CHANGED="1"
( diff $DISKHEAD_LAST $DISKHEAD >> "${CHANGES_ALERT}-now" ) || CHANGED="1"
Rationale: Independently of the running mode, the $CHANGED variable will be set to "0" if the boot files have changed, and to "1" otherwise.
Replace the following lines:
if [ ! $CHANGED = "1" ] ; then
rm -f $DISKHEAD "${CHANGES_ALERT}-now" $BOOTFILES
else
# create the changes alert file with a heading and the date and the list of changed files
echo -e "List of changed files on `date`:\n" > "${CHANGES_ALERT}"
cat "${CHANGES_ALERT}-now" >> "$CHANGES_ALERT"
# copy the latest changes file to the end of the log
cat "$CHANGES_ALERT" >> "$CHANGES_LOG"
echo >> "$CHANGES_LOG"
# set the latest hashes to the old ones for next time then exit
ln -s -f $BOOTFILES $BOOTFILES_LAST
ln -s -f $DISKHEAD $DISKHEAD_LAST
exit 1
fi
With:
if [ ! $CHANGED = "1" ] ; then
rm -f $DISKHEAD "${CHANGES_ALERT}-now" $BOOTFILES
else
if [ ! $UPDATEONLY = "1" ] ; then
# create the changes alert file with a heading and the date and the list of changed files
echo -e "List of changed files on `date`:\n" > "${CHANGES_ALERT}"
cat "${CHANGES_ALERT}-now" >> "$CHANGES_ALERT"
# copy the latest changes file to the end of the log
cat "$CHANGES_ALERT" >> "$CHANGES_LOG"
echo >> "$CHANGES_LOG"
else
# since we're updating, remove the changes log and just leave the check files
rm -f "${CHANGES_ALERT}-now"
fi
# set the latest hashes to the old ones for next time then exit
ln -s -f $BOOTFILES $BOOTFILES_LAST
ln -s -f $DISKHEAD $DISKHEAD_LAST
exit 1
fi
Rationale: Implement the documented behaviour. If the boot files didn't change, then no changes are made to the filesystem. Otherwise, report changes unless we're in update mode and update the hash files.
DISCLAIMER: The author of this issue does not guarantee, in any way, that the explained changes will result in the solution to the exposed issue and/or will not cause the program to report false positives or false negatives.