On Mon, May 07, 2001 at 12:51:32PM -0700, Rob Hudson wrote:
> When a security fix comes out, what is the best way to incorporate
> that fix into the current system?
>
> On debian, it's real easy b/c it shows up on security.debian.org and
> the apt-get update files and updates it if you have it installed.
>
> I don't have sources on my FreeBSD box, and CVSing the source files
> and running 'make world' is scary to me. Is there a way to binary
> upgrade so FreeBSD is patched up?
>
> Thanks,
> Rob
>
Actually, I'm working on the concept of binary patches for OpenBSD :)
That's why I've been trying to get people to install OpenBSD, so
I could hopefully persuade some EUGLUGgers to do some testing.
I know there's some work being done in FreeBSD on this, but our approach
is, well, different than any approach I've seen. I also feel that
our approach would work on any BSD, though perhaps no as easily.
URL: http://openbsd.rutgers.edu/openbsd/binarypatch/
This project was started about 2 weeks ago, so there's not much accomplished
yet. I attached a script I wrote, which does a good portion of the work.
<[EMAIL PROTECTED]>
#!/usr/bin/perl -w
# distdiff - compares OpenBSD distributions for changed files
# author - Jacob Meuser <[EMAIL PROTECTED]>
# license - BSD style with NO GUARANTEES
#
# History:
# 0.0.1 2001-04-27 First tests
# 0.0.2 2001-04-28 Added ar extraction
# 0.0.3 2001-04-29 Split binary and text diff output
# 0.0.4 2001-04-29 Added perl packing list modification
# 0.0.5 2001-05-01 Added obsolete file list
# 0.0.9 2001-05-02 A revelation! Compare the release tarballs
# separately, not the whole distribution at once.
# This will make packaging much easier.
#
# To do:
# Test, test, test
# Incorporate support for the X11/XF4 tarballs.
# Deal with /dev special files, and /etc, and /var. Currently
# creating a diff for the "etc" tarball, and diff doesn't know
# much about special files.
# Add some error checking.
# Clean and comment the code.
#
#
# ************************ README **********************************
# Before using this script it is assumed you have been following the
# instructions for making a release as laid out in release(8), and
# you have just finished the "make build" step.
# This script will put the $RELEASEDIR and $DESTDIR from release(8)
# in the directory it is called from. This script will also
# create a "work" directory in the directory is is called from where
# the release tarballs will be unpacked. The files nescesary to make
# the packages will also be put in the "work" directory.
# ******************************************************************
#
# Author's note:
# It may seem a bit overboard to go through the process of making
# the distribution install sets, but AFAIK no one is distributing
# the install sets made from patched (-stable) sources. The 2.8
# sets for i386 on ftp.openbsd.org are all dated Nov 27 2000.
use File::Copy;
use strict;
# need to use 'distdiff first' to prepare for future distdiffs
# This should only be done for the first release!!
my $makerelease = "yes";
my $makediff = "yes";
if ($ARGV[0] eq "first") {
$makediff = "no"; # nothing to compare yet
} elsif ($ARGV[0] eq "diffonly") {
$diffonly = "yes";
}
if ($ARGV[1] eq "skiprelease") {
$makerelease = "no";
}
# get infos for naming purposes
my $startdir = `pwd`;
chomp $startdir;
my $uname = `uname -a`;
chomp $uname;
my ($release, $version, $machine) = (split (/ /, $uname))[2,3,4];
$release =~ s/\.//;
# this is a little weak; uses the build # from the kernel; need to
# decide how the patches will be named
my $build = (split (/\#/, $version))[1];
my $old_build = $build - 1;
my $destdir = "$startdir/dest-$machine-$release-$build";
my $releasedir = "$startdir/release-$machine-$release-$build";
# perl version of the rest of release(8)
if (-d $destdir) {
move ($destdir, "$destdir-");
system ("rm -rf \"$destdir-\"") == 0
or warn "Problem removing old destdir, \"$destdir-\": $?";
}
mkdir $destdir;
if (! (-d $releasedir)) {
mkdir $releasedir;
}
print qq (
makedif = $makediff
startdir = $startdir
uname = $uname
release = $release
version = $version
machine = $machine
build = $build
old_build = $old_build
destdir = $destdir
releasedir = $releasedir
\n);
if ($makerelease ne "no") {
chdir "/usr/src/distrib/crunch";
system ("make clean && make && make install") == 0
or die "Couldn't make and install crunch tools: $?";
chdir "/usr/src/etc";
system ("env DESTDIR=$destdir RELEASEDIR=$releasedir nice make release") == 0
or die "Couldn't make the release: $?";
chdir "/usr/src/distrib/sets";
system ("env DESTDIR=$destdir RELEASEDIR=$releasedir csh checkflist") == 0
or die "Error from checkflist: $?";
chdir "$startdir";
}
# get the names of the tarballs
opendir (RELEASEDIR, "$releasedir") or die "Could not open $releasedir: $!\n";
my @tarball = grep (/\.tgz$/, readdir (RELEASEDIR));
closedir (RELEASEDIR);
# set up a directory to unpack the tar balls in
my $workdir = "$startdir" . "/" . "work-" . "$machine" . "-" . "$release" . "-" .
"$build";
my $old_workdir = "$startdir" . "/" . "work-" . "$machine" . "-" . "$release" . "-" .
"$old_build";
# see if we have something to compare to, let through if "first" release
if ($makediff ne "no") {
if (! (-d $old_workdir)) {
die "There is no old_workdir to compare the release you've made to!\n";
}
}
my $pwd = `pwd`;
chomp $pwd;
print qq (
pwd = $pwd
workdir = $workdir
old_workdir = $old_workdir
tarballs = @tarball
\n);
mkdir $workdir;
chdir $workdir;
# unpack the tarballs and do some prep work for reasons described below
foreach my $tarball (@tarball) {
print `pwd`;
print "$tarball\n";
my $tarball_dir = $tarball;
$tarball_dir =~ s/$release\.tgz$//;
print "$tarball_dir\n";
mkdir "$tarball_dir";
chdir "$tarball_dir";
system ("tar zxf $releasedir/$tarball");
if ($tarball_dir eq "base") {
# fix libdata/perl5 packing list
# $DESTDIR gets added to the front of the paths, producing
# a large and useless diff
print "Making new perl packing list in $workdir/$tarball_dir.\n";
my $perlpack = "./usr/libdata/perl5/$machine-openbsd/5.6.0/.packlist";
my $perlpack_new = "$perlpack" . ".new";
open (PP, "$perlpack") or die "Can't open $perlpack: $!\n";
open (PPTMP, ">$perlpack_new") or die "Can't open $perlpack_new: $!\n";
while (<PP>) {
s|$destdir|/home/dest-$machine|g;
print PPTMP $_;
}
close (PPTMP);
close (PP);
copy ($perlpack_new, $perlpack);
unlink $perlpack_new;
}
# find and extract ar archive random libraries; diff will always
# tell us they differ because ar adds timestamps
# extract and delete original archoives
if (($tarball_dir ne "etc") && ($tarball_dir ne "man")) {
my @endinas = `find . -name \*.a -print`;
foreach (@endinas) {
my $file = `file $_`;
chomp $file;
if ($file =~ s/\: current ar archive random library$//) {
my $extdir = "$file" . "-ar_dir";
print `pwd`;
print "making $extdir\n";
mkdir $extdir;
chdir $extdir;
my $file_path = "$workdir" . "/" . "$tarball_dir" . "/" . "$file";
system ("ar -x $file_path");
unlink "$file_path";
chdir "$workdir/$tarball_dir";
}
}
}
# Option to skip the diff process
if ($makediff eq "yes") {
my $new_tbdir_path = "$workdir/$tarball_dir";
my $old_tbdir_path = "$old_workdir/$tarball_dir";
&dodiff ($old_tbdir_path, $new_tbdir_path, $tarball_dir);
}
chdir "$workdir";
}
sub dodiff {
my ($old_tbdir_path, $new_tbdir_path, $tarballdir) = @_;
my $patchdir = "$new_tbdir_path/../$tarballdir-patch";
mkdir "$patchdir";
chdir "$patchdir";
my $pid = open (DIFFOUT, "diff -u -r $old_tbdir_path $new_tbdir_path |")
or die "Couldn't fork diff for $tarballdir: $!\n";
print "Starting $tarballdir diff with pid $pid\n";
open (DIFFIN, ">difftext.diff") or die "Can't open difftext.diff: $!\n";
open (DIFFBINS, ">diffbins.list") or die "Can't open diffbins.list: $!\n";
open (OBSOLETE, ">obsolete.list") or die "Can't open obsolete.list: $!\n";
open (NEWBINS, ">newbins.list") or die "Can't open newbins.list: $!\n";
my %have;
while (<DIFFOUT>) {
if (! /special file/) { # Need good method to deal with special files
if (s/^Binary files //) {
my $binary = (split (/ /, $_))[0];
$binary =~ s/$old_tbdir_path//;
$binary =~ s|(\.a)_ar_extract_dir/.*|$1|;
if ($have{$binary} ne "yes") { # work around archives where
print DIFFBINS "$binary\n"; # more than one binary changed
$have{$binary} = "yes";
}
} elsif (s/^Only in $old_tbdir_path\://) { # not in the new tball
print OBSOLETE $_;
} elsif (s/^Only in $new_tbdir_path\://) { # NEW binaries
print NEWBINS $_;
} else {
next if (/^diff/); # get rid of the diff command lines
s/^--- $old_tbdir_path/--- /;
s/^\+\+\+ $new_tbdir_path/\+\+\+ /;
print DIFFIN $_;
}
}
}
close (DIFFOUT);
close (DIFFIN);
close (DIFFBINS);
close (OBSOLETE);
close (NEWBINS);
return;
}
print "done\n";
exit (0);