about summary refs log tree commit diff
path: root/nixpkgs/pkgs/tools/backup/store-backup
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/tools/backup/store-backup')
-rw-r--r--nixpkgs/pkgs/tools/backup/store-backup/CVE-2020-7040.patch23
-rw-r--r--nixpkgs/pkgs/tools/backup/store-backup/default.nix116
2 files changed, 139 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/tools/backup/store-backup/CVE-2020-7040.patch b/nixpkgs/pkgs/tools/backup/store-backup/CVE-2020-7040.patch
new file mode 100644
index 000000000000..9b78f9bab95f
--- /dev/null
+++ b/nixpkgs/pkgs/tools/backup/store-backup/CVE-2020-7040.patch
@@ -0,0 +1,23 @@
+Index: storeBackup/lib/fileDir.pl
+===================================================================
+--- storeBackup.orig/lib/fileDir.pl
++++ storeBackup/lib/fileDir.pl
+@@ -21,7 +21,7 @@
+ 
+ 
+ use Digest::MD5 qw(md5_hex);
+-use Fcntl qw(O_RDWR O_CREAT);
++use Fcntl qw(O_RDWR O_CREAT O_WRONLY O_EXCL);
+ use Fcntl ':mode';
+ use POSIX;
+ use Cwd 'abs_path';
+@@ -482,7 +482,7 @@ sub checkLockFile
+ 		  '-str' => ["creating lock file <$lockFile>"]);
+ 
+     &::checkDelSymLink($lockFile, $prLog, 0x01);
+-    open(FILE, '>', $lockFile) or
++    sysopen(FILE, $lockFile, O_WRONLY | O_CREAT | O_EXCL) or
+ 	$prLog->print('-kind' => 'E',
+ 		      '-str' => ["cannot create lock file <$lockFile>"],
+ 		      '-exit' => 1);
+
diff --git a/nixpkgs/pkgs/tools/backup/store-backup/default.nix b/nixpkgs/pkgs/tools/backup/store-backup/default.nix
new file mode 100644
index 000000000000..506ea600cbcb
--- /dev/null
+++ b/nixpkgs/pkgs/tools/backup/store-backup/default.nix
@@ -0,0 +1,116 @@
+{lib, stdenv, which, coreutils, perl, fetchurl, makeWrapper, diffutils , writeScriptBin, bzip2}:
+
+# quick usage:
+# storeBackup.pl --sourceDir /home/user --backupDir /tmp/my_backup_destination
+# Its slow the first time because it compresses all files bigger than 1k (default setting)
+# The backup tool is bookkeeping which files got compressed
+
+# btrfs warning: you may run out of hardlinks soon
+
+# known impurity: test cases seem to bu using /tmp/storeBackup.lock ..
+
+let dummyMount = writeScriptBin "mount" "#!${stdenv.shell}";
+in
+
+stdenv.mkDerivation rec {
+
+  version = "3.5.2";
+
+  pname = "store-backup";
+
+  enableParallelBuilding = true;
+
+  nativeBuildInputs = [ makeWrapper ];
+  buildInputs = [ perl ];
+
+  src = fetchurl {
+    url = "https://download.savannah.gnu.org/releases/storebackup/storeBackup-${version}.tar.bz2";
+    hash = "sha256-Ki1DT2zypFFiiMVd9Y8eSX7T+yr8moWMoALmAexjqWU=";
+  };
+
+  patches = [
+    # https://www.openwall.com/lists/oss-security/2020/01/20/3
+    ./CVE-2020-7040.patch
+  ];
+
+  installPhase = ''
+    mkdir -p $out/scripts
+    mv * $out
+    mv $out/_ATTENTION_ $out/doc
+    mv $out/{correct.sh,cron-storebackup} $out/scripts
+
+    find $out -name "*.pl" | xargs sed -i \
+      -e 's@/bin/pwd@${coreutils}/bin/pwd@' \
+      -e 's@/bin/sync@${coreutils}/bin/sync@' \
+      -e '1 s@/usr/bin/env perl@${perl.withPackages (p: [ p.DBFile ])}/bin/perl@'
+
+    for p in $out/bin/*
+      do wrapProgram "$p" --prefix PATH ":" "${lib.makeBinPath [ which bzip2 ]}"
+    done
+
+    patchShebangs $out
+    # do a dummy test ensuring this works
+
+    PATH=$PATH:${dummyMount}/bin
+
+    export USER=test
+    export HOME=$(mktemp -d)
+    { # simple sanity test, test backup/restore of simple store paths
+
+      mkdir backup
+
+      backupRestore(){
+        source="$2"
+        echo =========
+        echo RUNNING TEST "$1" source: "$source"
+        mkdir restored
+
+        $out/bin/storeBackup.pl --sourceDir "$source" --backupDir backup
+        latestBackup=backup/default/$(ls -1 backup/default | sort | tail -n 1)
+        $out/bin/storeBackupRecover.pl -b "$latestBackup" -t restored -r /
+        ${diffutils}/bin/diff -r "$source" restored
+
+        # storeBackupCheckSource should return 0
+        $out/bin/storeBackupCheckSource.pl -s "$source" -b "$latestBackup"
+        # storeBackupCheckSource should return not 0 when using different source
+        ! $out/bin/storeBackupCheckSource.pl -s $TMP -b "$latestBackup"
+
+        # storeBackupCheckBackup should return 0
+        $out/bin/storeBackupCheckBackup.pl -c "$latestBackup"
+
+        chmod -R +w restored
+        rm -fr restored
+      }
+
+      testDir=$TMP/testDir
+
+      mkdir $testDir
+      echo X > $testDir/X
+      ln -s ./X $testDir/Y
+
+      backupRestore 'test 1: backup, restore' $testDir
+
+      # test huge blocks, according to docs files bigger than 100MB get split
+      # into pieces
+      dd if=/dev/urandom bs=100M of=block-1 count=1
+      dd if=/dev/urandom bs=100M of=block-2 count=1
+      cat block-1 block-2 > $testDir/block
+      backupRestore 'test 1 with huge block' $testDir
+
+      cat block-2 block-1 > $testDir/block
+      backupRestore 'test 1 with huge block reversed' $testDir
+
+      backupRestore 'test 2: backup, restore' $out
+      backupRestore 'test 3: backup, restore' $out
+      backupRestore 'test 4: backup diffutils to same backup locations, restore' ${diffutils}
+    }
+  '';
+
+  meta = {
+    description = "A backup suite that stores files on other disks";
+    homepage = "https://savannah.nongnu.org/projects/storebackup";
+    license = lib.licenses.gpl3Plus;
+    maintainers = [lib.maintainers.marcweber];
+    platforms = lib.platforms.linux;
+  };
+}