From d52fcf7521b8f9b1ec7bbeaaf93840af37d363cf Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Mon, 11 May 2009 14:51:22 +0100 Subject: [PATCH] Be more careful about removing files in fakeroot during minimization. Added febootstrap-install program. --- .gitignore | 1 + Makefile.am | 20 ++++++++++++++++++ febootstrap-install.pod | 49 +++++++++++++++++++++++++++++++++++++++++++++ febootstrap-install.sh | 45 +++++++++++++++++++++++++++++++++++++++++ febootstrap-minimize.sh | 42 +++++++++++++++++++++----------------- febootstrap-run.pod | 16 ++++----------- febootstrap-to-initramfs.sh | 2 ++ febootstrap.pod | 19 +++++++++++++----- 8 files changed, 159 insertions(+), 35 deletions(-) create mode 100644 febootstrap-install.pod create mode 100755 febootstrap-install.sh diff --git a/.gitignore b/.gitignore index db68bd9..24fc34d 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ config.status configure febootstrap febootstrap-run +febootstrap-install febootstrap-minimize febootstrap-to-initramfs install-sh diff --git a/Makefile.am b/Makefile.am index c23498b..b239bbf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,6 +22,7 @@ SUBDIRS = examples bin_SCRIPTS = \ febootstrap \ febootstrap-run \ + febootstrap-install \ febootstrap-minimize \ febootstrap-to-initramfs DISTCLEANFILES = $(bin_SCRIPTS) @@ -38,6 +39,12 @@ febootstrap-run: febootstrap-run.sh chmod 0555 $@-t mv $@-t $@ +febootstrap-install: febootstrap-install.sh + rm -f $@ + cp $< $@-t + chmod 0555 $@-t + mv $@-t $@ + febootstrap-minimize: febootstrap-minimize.sh rm -f $@ cp $< $@-t @@ -53,6 +60,7 @@ febootstrap-to-initramfs: febootstrap-to-initramfs.sh man_MANS = \ febootstrap.8 \ febootstrap-run.8 \ + febootstrap-install.8 \ febootstrap-minimize.8 \ febootstrap-to-initramfs.8 @@ -78,6 +86,16 @@ febootstrap-run.8: febootstrap-run.pod febootstrap-run.txt: febootstrap-run.pod pod2text $< > $@ +febootstrap-install.8: febootstrap-install.pod + pod2man \ + --section 8 \ + -c "Virtualization Support" \ + --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \ + $< > $@ + +febootstrap-install.txt: febootstrap-install.pod + pod2text $< > $@ + febootstrap-minimize.8: febootstrap-minimize.pod pod2man \ --section 8 \ @@ -107,6 +125,8 @@ EXTRA_DIST = \ febootstrap.sh \ febootstrap-run.8 febootstrap-run.txt febootstrap-run.pod \ febootstrap-run.sh \ + febootstrap-install.8 febootstrap-install.txt febootstrap-install.pod \ + febootstrap-install.sh \ febootstrap-minimize.8 febootstrap-minimize.txt \ febootstrap-minimize.pod \ febootstrap-minimize.sh \ diff --git a/febootstrap-install.pod b/febootstrap-install.pod new file mode 100644 index 0000000..f48d217 --- /dev/null +++ b/febootstrap-install.pod @@ -0,0 +1,49 @@ +=head1 NAME + +febootstrap-install - Install a file in an febootstrap root filesystem + +=head1 SYNOPSIS + + febootstrap-install ROOT LOCALFILE TARGETPATH MODE OWNER[.GROUP] + +=head1 DESCRIPTION + +This can be used to safely install a new file in an febootstrap +root filesystem. + +Just copying a file in isn't usually safe, for reasons which are to do +with the L command. + +=head1 EXAMPLE + + febootstrap-install initramfs new-fstab /etc/fstab ugo=rw root.root + +=head1 SEE ALSO + +L, +L, +L, +L. + +=head1 AUTHORS + +Richard W.M. Jones + +=head1 COPYRIGHT + +(C) Copyright 2009 Red Hat Inc., +L. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. diff --git a/febootstrap-install.sh b/febootstrap-install.sh new file mode 100755 index 0000000..76b99b7 --- /dev/null +++ b/febootstrap-install.sh @@ -0,0 +1,45 @@ +#!/bin/bash - +# febootstrap-install +# (C) Copyright 2009 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# Written by Richard W.M. Jones + +unset CDPATH + +usage () +{ + echo "Usage: febootstrap-install ROOT LOCALFILE TARGETPATH MODE OWNER[.GROUP]" + echo "Please read febootstrap-install(8) man page for more information." +} + +if [ $# != 5 ]; then + usage + exit 1 +fi + +set -e + +# This is a carefully chosen sequence of commands which +# tries not to disturb any inode numbers apart from the +# one for the new file. +cp "$2" "$1"/"$3" +ino=$(ls -i "$1"/"$3" | awk '{print $1}') +cp "$1"/fakeroot.log "$1"/fakeroot.log.old +grep -v "ino=$ino," "$1"/fakeroot.log.old > "$1"/fakeroot.log +rm "$1"/fakeroot.log.old +febootstrap-run "$1" -- chmod "$4" "$3" +febootstrap-run "$1" -- chown "$5" "$3" diff --git a/febootstrap-minimize.sh b/febootstrap-minimize.sh index 148de5c..efee844 100755 --- a/febootstrap-minimize.sh +++ b/febootstrap-minimize.sh @@ -176,43 +176,48 @@ trap remove_tmpdir EXIT #---------------------------------------------------------------------- +# ***NOTE*** Wildcards cannot be passed to febootstrap-run. + if [ "$keep_locales" != "yes" ]; then - rm -rf "$target"/usr/lib/locale/* - rm -rf "$target"/usr/share/locale - rm -rf "$target"/usr/lib*/gconv - rm -f "$target"/usr/bin/localedef - rm -f "$target"/usr/sbin/build-locale-archive + febootstrap-run "$target" -- rm -rf usr/lib/locale + febootstrap-run "$target" -- rm -rf usr/share/locale + febootstrap-run "$target" -- rm -rf usr/lib/gconv usr/lib64/gconv + febootstrap-run "$target" -- rm -f usr/bin/localedef + febootstrap-run "$target" -- rm -f usr/sbin/build-locale-archive fi if [ "$keep_docs" != "yes" ]; then - rm -rf "$target"/usr/share/man - rm -rf "$target"/usr/share/doc - rm -rf "$target"/usr/share/info - rm -rf "$target"/usr/share/gnome/help + febootstrap-run "$target" -- rm -rf usr/share/man + febootstrap-run "$target" -- rm -rf usr/share/doc + febootstrap-run "$target" -- rm -rf usr/share/info + febootstrap-run "$target" -- rm -rf usr/share/gnome/help fi if [ "$keep_cracklib" != "yes" ]; then - rm -rf "$target"/usr/share/cracklib + febootstrap-run "$target" -- rm -rf usr/share/cracklib fi if [ "$keep_i18n" != "yes" ]; then - rm -rf "$target"/usr/share/i18n + febootstrap-run "$target" -- rm -rf usr/share/i18n fi if [ "$keep_zoneinfo" != "yes" ]; then mv "$target"/usr/share/zoneinfo/{UCT,UTC,Universal,Zulu,GMT*,*.tab} \ "$target" - rm -rf "$target"/usr/share/zoneinfo/* + febootstrap-run "$target" -- rm -rf usr/share/zoneinfo + febootstrap-run "$target" -- mkdir -p --mode=0755 usr/share/zoneinfo mv "$target"/{UCT,UTC,Universal,Zulu,GMT*,*.tab} \ "$target"/usr/share/zoneinfo/ fi if [ "$keep_rpmdb" != "yes" ]; then - rm -rf "$target"/var/lib/rpm/* + febootstrap-run "$target" -- rm -rf var/lib/rpm + febootstrap-run "$target" -- mkdir -p --mode=0755 var/lib/rpm fi if [ "$keep_yum_cache" != "yes" ]; then - rm -rf "$target"/var/cache/yum/* + febootstrap-run "$target" -- rm -rf var/cache/yum + febootstrap-run "$target" -- mkdir -p --mode=0755 var/cache/yum fi if [ "$keep_services" != "yes" ]; then @@ -270,13 +275,14 @@ __EOF__ fi if [ "$keep_sln" != "yes" ]; then - rm -f "$target"/sbin/sln + febootstrap-run "$target" -- rm -f sbin/sln fi if [ "$keep_ldconfig" != "yes" ]; then - rm -f "$target"/sbin/ldconfig - rm -f "$target"/etc/ld.so.cache - rm -rf "$target"/var/cache/ldconfig/* + febootstrap-run "$target" -- rm -f sbin/ldconfig + febootstrap-run "$target" -- rm -f etc/ld.so.cache + febootstrap-run "$target" -- rm -rf var/cache/ldconfig + febootstrap-run "$target" -- mkdir -p --mode=0755 var/cache/ldconfig fi if [ "$pack_executables" = "yes" ]; then diff --git a/febootstrap-run.pod b/febootstrap-run.pod index 9072f5a..d6440ca 100644 --- a/febootstrap-run.pod +++ b/febootstrap-run.pod @@ -39,20 +39,11 @@ contents still happen). =head1 EXAMPLES -One way to create a new file with specific ownership and permissions -from a script is to create new content for a file as C: +Remove a directory subtree safely: - #!/bin/bash - - echo blah > root/file.new - -then "install" it with the correct ownership and permissions. - - febootstrap-run root -- install -m 0644 -o root -g root /file.new /file - rm root/file.new + febootstrap-run initramfs -- rm -r /etc -(This requires that the C command from coreutils -exists inside the root.) +(This requires that you have a compatible 'rm' command in the root). Another way to do complex operations from a script is to export a function: @@ -76,6 +67,7 @@ particular you may want to set: =head1 SEE ALSO L, +L, L, L. diff --git a/febootstrap-to-initramfs.sh b/febootstrap-to-initramfs.sh index 6dfc3f9..849aa7b 100755 --- a/febootstrap-to-initramfs.sh +++ b/febootstrap-to-initramfs.sh @@ -32,6 +32,8 @@ if [ ! -f fakeroot.log -a $(id -u) -ne 0 ]; then exit 1 fi +set -e + if [ -f fakeroot.log ]; then fakeroot -i fakeroot.log \ sh -c 'find -not -name fakeroot.log -a -print0 | cpio -o0c | gzip --best' diff --git a/febootstrap.pod b/febootstrap.pod index 109f6a2..e208603 100644 --- a/febootstrap.pod +++ b/febootstrap.pod @@ -129,8 +129,8 @@ so that yum thinks it is running as root. Fakeroot keeps track of directory as C/fakeroot.log>. This logfile is indexed by inode number, which makes certain -operations safe and other operations unsafe. For example, deleting -files is usually safe. Files should be replaced only by doing: +operations safe and other operations unsafe. +Files should be replaced only by doing: echo updated-content > old-file @@ -139,9 +139,12 @@ files is usually safe. Files should be replaced only by doing: Deleting files and then creating new ones (even with a different name) is usually unsafe, because the new files might reuse inodes claimed by the old files, and so appear with peculiar permissions -(eg. unreadable, or as a symbolic link). (XXX We need an -C utility to automate installing new files safely -into a filesystem). +(eg. unreadable, or as a symbolic link). + +Deleting files is also usually unsafe, although the reasons are more +subtle. If you just use C then the inode number is not deleted +from C which means it can be reused by another file +later on. In most cases it's usually safest to use C. @@ -156,6 +159,11 @@ permissions. =item * +Use L to install a file with permissions +in the root filesystem. + +=item * + Generate an initramfs (compressed cpio) file containing the correct permissions using the tool C. @@ -218,6 +226,7 @@ L L, L, L, +L, L, L, L, -- 1.8.3.1