Menu

#161 add sandboxing support to fink (revised approach)

open
nobody
None
5
2016-11-11
2016-11-07
No

The attached patch reworks the previously proposed sandboxing support by...

1) Enabling the sandbox usage by default (except during fink bootstraps)
2) Adding a 'NoSandbox' field for the Info files which can be used to
disable the sandbox on a per package basis.
3) Retaining the --build-in-sandbox/--no-build-in-sandbox fink flags
which override the other settings.

The --no-build-in-sandbox fink flag can be used to disable the sandbox
in any fink build while the --build-in-sandbox fink flag can be used
to override 'NoSandbox: true' in a particular info file.

The attached fink_sandboxing_v3.diff, applied to stock fink-0.41.0,
has been verified to bootstrap on 10.11 and exhibit the behaviors
described above.

Discussion

  • Jack Howarth

    Jack Howarth - 2016-11-07
     

    Last edit: Jack Howarth 2016-11-11
  • Jack Howarth

    Jack Howarth - 2016-11-07
     

    Last edit: Jack Howarth 2016-11-11
  • Jack Howarth

    Jack Howarth - 2016-11-07
     

    Last edit: Jack Howarth 2016-11-11
  • Jack Howarth

    Jack Howarth - 2016-11-09
     

    Last edit: Jack Howarth 2016-11-11
  • Jack Howarth

    Jack Howarth - 2016-11-11

    Note that the actual pull request against fink git master exists at https://github.com/fink/fink/pull/135/files

    The same set of changes appliable against the last fink 0.41.0 release are attached

     
  • Jack Howarth

    Jack Howarth - 2016-11-11

    The changes from the fink 0.41.0 release.are..

    diff -uNr fink-0.41.0.orig/MANIFEST fink-0.41.0/MANIFEST
    --- fink-0.41.0.orig/MANIFEST   2016-09-20 14:16:24.000000000 -0400
    +++ fink-0.41.0/MANIFEST        2016-11-06 18:40:34.000000000 -0500
    @@ -24,6 +24,8 @@
     fink.8.in
     fink.conf.5.in
     fink.csh
    +fink.sb
    +fink.sb.5.in
     fink.sh
     images/finkDoneFailed.png
     images/finkDonePassed.png
    diff -uNr fink-0.41.0.orig/fink.8.in fink-0.41.0/fink.8.in
    --- fink-0.41.0.orig/fink.8.in  2016-09-20 14:16:24.000000000 -0400
    +++ fink-0.41.0/fink.8.in       2016-11-11 08:09:00.000000000 -0500
    @@ -103,6 +103,21 @@
     .It Cm --no-build-as-nobody
     Force the the unpack, patch, compile, and install phases to be 
     performed as root.
    +.It Cm --build-in-sandbox
    +Execute packaging within a sandbox which blacklists read access to 
    +those directories listed in
    +.Pa @PREFIX@/etc/fink.sb.
    +\ This is the default behavior unless overridden by a
    +.Pa NoSandbox: true
    +directive in a .info file, the
    +.Cm --no-build-in-sandbox
    +flag is used, or if the
    +.Pa @PREFIX@/etc/fink.sb
    +file is empty.
    +.It Cm --no-build-in-sandbox
    +Don't execute within a sandbox, opposite of the
    +.Cm --build-in-sandbox
    +flag.
     .It Cm -m, --maintainer
     Perform actions useful to package maintainers: run validation on
     the .info file before building and on the .deb after building a
    diff -uNr fink-0.41.0.orig/fink.sb fink-0.41.0/fink.sb
    --- fink-0.41.0.orig/fink.sb    1969-12-31 19:00:00.000000000 -0500
    +++ fink-0.41.0/fink.sb 2016-11-06 18:40:34.000000000 -0500
    @@ -0,0 +1,2 @@
    +/usr/local
    +/opt/local
    diff -uNr fink-0.41.0.orig/fink.sb.5.in fink-0.41.0/fink.sb.5.in
    --- fink-0.41.0.orig/fink.sb.5.in       1969-12-31 19:00:00.000000000 -0500
    +++ fink-0.41.0/fink.sb.5.in    2016-11-10 09:24:50.000000000 -0500
    @@ -0,0 +1,60 @@
    +.\" -*- nroff -*-
    +.Dd November 2011
    +.Dt FINK.SB 5
    +.Sh NAME
    +.Nm fink.sb
    +.Nd sandboxing configuration file for
    +.Xr fink 8
    +.Sh SYNOPSIS
    +@PREFIX@/etc/fink.sb
    +.\"
    +.\"
    +.\" DESCRIPTION
    +.\"
    +.\"
    +.Sh DESCRIPTION
    +The
    +.Xr fink 8
    +packaging system defaults to compiling packages within a protected sandbox that blacklists 
    +access to directories listed in
    +.Nm
    +In general, modifying the list of blacklisted directories meant for advanced users only.
    +.Pp
    +The default
    +.Nm
    +blacklists the following directories
    +
    +.Bl -tag -width flag -offset indent -compact
    +.It /usr/local
    +.It /opt/local
    +.El
    +.Pp
    +The blacklisted directories appear one per line in the file.
    +
    +Note that an empty
    +.Nm
    +file disables the automatic sandboxing in the fink program.
    +.El
    +.\"
    +.\"
    +.\" AUTHOR
    +.\"
    +.\"
    +.Sh AUTHOR
    +This manpage is maintained by the Fink Core Group <fink-core@lists.sourceforge.net>.
    +.\"
    +.\"
    +.\" ACKNOWLEDGEMENTS
    +.\"
    +.\"
    +.Sh ACKNOWLEDGEMENTS
    +.Nm fink
    +is developed and maintained by The Fink Project (http://www.finkproject.org).
    +.\"
    +.\"
    +.\" SEE ALSO
    +.\"
    +.\"
    +.Sh "SEE ALSO"
    +.Xr apt-get 8 ,
    +.Xr fink 8
    diff -uNr fink-0.41.0.orig/install.sh fink-0.41.0/install.sh
    --- fink-0.41.0.orig/install.sh 2016-09-20 14:16:24.000000000 -0400
    +++ fink-0.41.0/install.sh      2016-11-06 18:40:34.000000000 -0500
    @@ -70,8 +70,10 @@
    
     install -c -p -m 755 postinstall.pl "$basepath/lib/fink/"
     install -c -p -m 644 shlibs.default "$basepath/etc/dpkg/"
    +install -c -p -m 644 fink.sb "$basepath/etc/"
     install -c -p -m 644 fink.8 "$basepath/share/man/man8/"
     install -c -p -m 644 fink.conf.5 "$basepath/share/man/man5/"
    +install -c -p -m 644 fink.sb.5 "$basepath/share/man/man5/"
     install -c -p -m 644 images/*.png "$basepath/share/fink/images/"
    
     # copy executables
    diff -uNr fink-0.41.0.orig/perlmod/Fink/Bootstrap.pm fink-0.41.0/perlmod/Fink/Bootstrap.pm
    --- fink-0.41.0.orig/perlmod/Fink/Bootstrap.pm  2016-09-20 14:16:24.000000000 -0400
    +++ fink-0.41.0/perlmod/Fink/Bootstrap.pm       2016-11-06 18:58:41.000000000 -0500
    @@ -500,6 +500,8 @@
            Fink::Config::set_options( { 'use_binary' => -1 });
            # bootstrap as root
            Fink::Config::set_options( { 'build_as_nobody' => 0 });
    +       # don't use sandbox during bootstrap
    +       Fink::Config::set_options( { 'build_in_sandbox' => 0 });
    
            # make sure we have the package descriptions
            Fink::Package->require_packages();
    @@ -581,6 +583,8 @@
    
            # bootstrap as root
            Fink::Config::set_options( { 'build_as_nobody' => 0 });
    +       # don't use sandbox during bootstrap
    +       Fink::Config::set_options( { 'build_in_sandbox' => 0 });
            # use normal install routines, but do not use buildlocks
            Fink::Config::set_options( { 'no_buildlock' => 1 } );
            Fink::Engine::cmd_install(@elist, @addlist);
    diff -uNr fink-0.41.0.orig/perlmod/Fink/Config.pm fink-0.41.0/perlmod/Fink/Config.pm
    --- fink-0.41.0.orig/perlmod/Fink/Config.pm     2016-09-20 14:16:24.000000000 -0400
    +++ fink-0.41.0/perlmod/Fink/Config.pm  2016-11-06 18:40:34.000000000 -0500
    @@ -219,6 +219,7 @@
            map( { $_ => 0 } qw(dontask interactive verbosity keep_build keep_root
                    maintainermode showversion use_binary) ),
            map( { $_ => 1 } qw(build_as_nobody) ),
    +       map( { $_ => -1 } qw(build_in_sandbox) ),
            map( { $_ => "" } qw(tests validate) ),
            map ( { $_ => [] } qw(include_trees exclude_trees) ),
            map( { $_ => -1 } qw(use_binary) ),
    @@ -272,6 +273,7 @@
                            'download pre-compiled packages from the binary distribution '
                            . 'if available'        ],
                    [ 'build-as-nobody!'   => \$opts{build_as_nobody},      'see man page'  ],
    +               [ 'build-in-sandbox!' => \$opts{build_in_sandbox}, 'see man page'  ],
                    [ 'maintainer|m'       => sub {set_checking_opts(\%opts, @_);}, 'see man page'  ],
                    [ 'tests:s'            => sub {set_checking_opts(\%opts, @_);}, 'see man page'  ],
                    [ 'validate:s'         => sub {set_checking_opts(\%opts, @_);}, 'see man page'  ],
    diff -uNr fink-0.41.0.orig/perlmod/Fink/PkgVersion.pm fink-0.41.0/perlmod/Fink/PkgVersion.pm
    --- fink-0.41.0.orig/perlmod/Fink/PkgVersion.pm 2016-09-20 14:16:24.000000000 -0400
    +++ fink-0.41.0/perlmod/Fink/PkgVersion.pm      2016-11-06 18:40:34.000000000 -0500
    @@ -4036,6 +4036,9 @@
                    }
            }
    
    +       # switch everything back to sandbox builds if we were --build-in-sandbox
    +       my $build_wo_sandbox = $self->get_family_parent()->param_boolean("NoSandbox", 0);
    +
            # put the info file into the debian directory
            if (-d "$destdir/DEBIAN") {
                    my $infofile = $self->get_filename();
    @@ -5218,6 +5221,7 @@
            my $phase = shift;
            my $no_expand = shift || 0;
            my $nonroot_okay = shift || 0;
    +       my $no_sandbox_okay = shift || 0;
            my $ignore_result = shift || 0;
    
            # Expand percent shortcuts
    @@ -5227,10 +5231,13 @@
            my $result;
            # Don't build as nobody if BuildAsNobody: false
            my $build_as_nobody = $self->get_family_parent()->param_boolean("BuildAsNobody", 1);
    +       # Build in sandbox if NoSandbox: false
    +       my $build_wo_sandbox = $self->get_family_parent()->param_boolean("NoSandbox", 0);
            $nonroot_okay = $nonroot_okay && $build_as_nobody;
    +       $no_sandbox_okay = $build_wo_sandbox;
            {
                    local %ENV = %{$self->get_env($phase)};
    -               $result = &execute($script, nonroot_okay=>$nonroot_okay);
    +               $result = &execute($script, nonroot_okay=>$nonroot_okay, no_sandbox_okay=>$no_sandbox_okay);
            }
            if ($result and !$ignore_result) {
                    $self->package_error( phase => $phase );
    diff -uNr fink-0.41.0.orig/perlmod/Fink/Services.pm fink-0.41.0/perlmod/Fink/Services.pm
    --- fink-0.41.0.orig/perlmod/Fink/Services.pm   2016-09-20 14:16:24.000000000 -0400
    +++ fink-0.41.0/perlmod/Fink/Services.pm        2016-11-11 08:15:48.000000000 -0500
    @@ -514,6 +514,11 @@
     the --build-as-nobody flag, drop to user=nobody when running the
     actual commands.
    
    +=item no_sandbox_okay
    +
    +If the value of the option 'no_sandbox_okay' is true, fink was run with
    +the --no-build-in-sandbox flag.
    +
     =item delete_tempfile
    
     Whether to delete temp-files that are created. The following values
    @@ -594,6 +599,32 @@
                    @wrap = map "$_=$ENV{$_}", sort keys %ENV;
                    push @wrap, "__CFPREFERENCES_AVOID_DAEMON=1";
                    unshift @wrap, 'env' if @wrap;
    +               my $runtime_request = Fink::Config::get_option("build_in_sandbox");
    +               my $sandbox_request;
    +               if ($runtime_request == 1) {  # --build-in-sandbox 
    +                       $sandbox_request = 1;
    +               } elsif ($runtime_request == 0) { # -no-build-in-sandbox   
    +                       $sandbox_request = 0;
    +               } elsif ($options{'no_sandbox_okay'}) { # NoSandbox: true in info file
    +                       $sandbox_request = 0;
    +               } else {
    +                       $sandbox_request = 1;
    +               }
    +               if ( !-z "$Fink::Config::basepath/etc/fink.sb" && $sandbox_request ) {
    +                       my $sandbox = "$Fink::Config::basepath/etc/fink.sb";
    +                       if (open my $info, $sandbox) {
    +                               my $sandbox_profile = "(version 1) \n";
    +                               $sandbox_profile .= "(allow default) \n";
    +                               $sandbox_profile .= "(deny file* \n";
    +                               while( my $line = <$info>)  {
    +                                       chomp $line;
    +                                       $sandbox_profile .= "\t(subpath \"".$line."\"\)\n";
    +                               }
    +                               $sandbox_profile .= "\)\n";
    +                               close $info;
    +                               @wrap = (qw| sandbox-exec -p |, $sandbox_profile, @wrap) if -f $sandbox;
    +                       }
    +               }
                    my $sudo_cmd = "sudo -u " . Fink::Config::build_as_user_group()->{'user'};
                    @wrap = (split(' ', $sudo_cmd), @wrap, qw/ sh -c /);
                    $wrap_token = "$sudo_cmd [ENV] sh -c ";
    diff -uNr fink-0.41.0.orig/perlmod/Fink/Validation.pm fink-0.41.0/perlmod/Fink/Validation.pm
    --- fink-0.41.0.orig/perlmod/Fink/Validation.pm 2016-09-20 14:16:24.000000000 -0400
    +++ fink-0.41.0/perlmod/Fink/Validation.pm      2016-11-06 18:40:34.000000000 -0500
    @@ -66,7 +66,7 @@
     # All fields that expect a boolean value
     our %boolean_fields = map {$_, 1}
            (
    -               qw(builddependsonly essential nosourcedirectory updateconfigguess updatelibtool updatepod noperltests usemaxbuildjobs buildasnobody),
    +               qw(builddependsonly essential nosourcedirectory updateconfigguess updatelibtool updatepod noperltests usemaxbuildjobs buildasnobody nosandbox),
                    map {"noset".$_} @set_vars
            );
    
    @@ -198,6 +198,7 @@
                     'noperltests',
                     'usemaxbuildjobs',
                     'buildasnobody',
    +                'nosandbox',
     #  install phase:
                     'updatepod',
                     'installscript',
    diff -uNr fink-0.41.0.orig/setup.sh fink-0.41.0/setup.sh
    --- fink-0.41.0.orig/setup.sh   2016-09-20 14:16:24.000000000 -0400
    +++ fink-0.41.0/setup.sh        2016-11-06 18:40:34.000000000 -0500
    @@ -70,6 +70,10 @@
       | perl -MTime::Local -MPOSIX=strftime -p -e '$d="Date:";if (s/(\.Dd \$$d) (\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+) \$/\1/) {$epochtime = timegm($7,$6,$5,$4,$3-1,$2-1900);$datestr = strftime "%B %e, %Y", localtime($epochtime); s/(\.Dd )\$$d/$1$datestr/;}' \
       >fink.conf.5
    
    +sed "s|@PREFIX@|$basepath|g" <fink.sb.5.in \
    +  | perl -MTime::Local -MPOSIX=strftime -p -e '$d="Date:";if (s/(\.Dd \$$d) (\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+) \$/\1/) {$epochtime = timegm($7,$6,$5,$4,$3-1,$2-1900);$datestr = strftime "%B %e, %Y", localtime($epochtime); s/(\.Dd )\$$d/$1$datestr/;}' \
    +  >fink.sb.5
    +
     echo "Creating shlibs default file..."
     sed "s|@PREFIX@|$basepath|g" <shlibs.default.in >shlibs.default
    
     

Log in to post a comment.