From 2f603cc73ede7e3926d9eda73f109eeedbcd187c Mon Sep 17 00:00:00 2001 From: John Johansen Date: Tue, 20 Mar 2012 11:45:13 -0700 Subject: [PATCH] Add the aa-exec command line utility The aa-exec command can be used to launch an application under a specified confinement, which may be different for what regular profile attachment would apply. Signed-off-by: John Johansen --- utils/Makefile | 2 +- utils/aa-exec | 124 ++++++++++++++++++++++++++++++++++++++++++++++ utils/aa-exec.pod | 95 +++++++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 utils/aa-exec create mode 100644 utils/aa-exec.pod diff --git a/utils/Makefile b/utils/Makefile index f7338289d..f4f8707f3 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -28,7 +28,7 @@ endif MODDIR = Immunix PERLTOOLS = aa-genprof aa-logprof aa-autodep aa-audit aa-complain aa-enforce \ - aa-unconfined aa-notify aa-disable + aa-unconfined aa-notify aa-disable aa-exec TOOLS = ${PERLTOOLS} aa-decode aa-status MODULES = ${MODDIR}/AppArmor.pm ${MODDIR}/Repository.pm \ ${MODDIR}/Config.pm ${MODDIR}/Severity.pm diff --git a/utils/aa-exec b/utils/aa-exec new file mode 100644 index 000000000..f1e09b48b --- /dev/null +++ b/utils/aa-exec @@ -0,0 +1,124 @@ +#!/usr/bin/perl +# ------------------------------------------------------------------ +# +# Copyright (C) 2011 Canonical Ltd. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License published by the Free Software Foundation. +# +# ------------------------------------------------------------------ + +use strict; +use warnings; +use Errno; + +require LibAppArmor; +require POSIX; +require Time::Local; +require File::Basename; + +my $opt_d = ''; +my $opt_h = ''; +my $opt_p = ''; +my $opt_n = ''; +my $opt_i = ''; +my $opt_v = ''; +my $opt_f = ''; + +sub _warn { + my $msg = $_[0]; + print STDERR "aa-exec: WARN: $msg\n"; +} +sub _error { + my $msg = $_[0]; + print STDERR "aa-exec: ERROR: $msg\n"; + exit 1 +} + +sub _debug { + $opt_d or return; + my $msg = $_[0]; + print STDERR "aa-exec: DEBUG: $msg\n"; +} + +sub _verbose { + $opt_v or return; + my $msg = $_[0]; + print STDERR "$msg\n"; +} + +sub usage() { + my $s = <<'EOF'; +USAGE: aa-exec [OPTIONS] + +Confine with the specified PROFILE. + +OPTIONS: + -p PROFILE, --profile=PROFILE PROFILE to confine with + -n NAMESPACE, --namespace=NAMESPACE NAMESPACE to confine in + -f FILE, --file FILE profile file to load + -i, --immediate change profile immediately instead of at exec + -v, --verbose show messages with stats + -h, --help display this help + +EOF + print $s; +} + +use Getopt::Long; + +GetOptions( + 'debug|d' => \$opt_d, + 'help|h' => \$opt_h, + 'profile|p=s' => \$opt_p, + 'namespace|n=s' => \$opt_n, + 'file|f=s' => \$opt_f, + 'immediate|i' => \$opt_i, + 'verbose|v' => \$opt_v, +); + +if ($opt_h) { + usage(); + exit(0); +} + +if ($opt_n || $opt_p) { + my $test; + my $prof; + + if ($opt_n) { + $prof = ":$opt_n:"; + } + + $prof .= $opt_p; + + if ($opt_f) { + system("apparmor_parser", "-r", "$opt_f") == 0 + or _error("\'aborting could not load $opt_f\'"); + } + + if ($opt_i) { + _verbose("aa_change_profile(\"$prof\")"); + $test = LibAppArmor::aa_change_profile($prof); + _debug("$test = aa_change_profile(\"$prof\"); $!"); + } else { + _verbose("aa_change_onexec(\"$prof\")"); + $test = LibAppArmor::aa_change_onexec($prof); + _debug("$test = aa_change_onexec(\"$prof\"); $!"); + } + + if ($test != 0) { + if ($!{ENOENT} || $!{EACCESS}) { + my $pre = ($opt_p) ? "profile" : "namespace"; + _error("$pre \'$prof\' does not exist\n"); + } elsif ($!{EINVAL}) { + _error("AppArmor interface not available\n"); + } else { + _error("$!\n"); + } + } +} + +_verbose("exec @ARGV"); +exec @ARGV; diff --git a/utils/aa-exec.pod b/utils/aa-exec.pod new file mode 100644 index 000000000..496468cfe --- /dev/null +++ b/utils/aa-exec.pod @@ -0,0 +1,95 @@ +# This publication is intellectual property of Canonical Ltd. Its contents +# can be duplicated, either in part or in whole, provided that a copyright +# label is visibly located on each copy. +# +# All information found in this book has been compiled with utmost +# attention to detail. However, this does not guarantee complete accuracy. +# Neither Canonical Ltd, the authors, nor the translators shall be held +# liable for possible errors or the consequences thereof. +# +# Many of the software and hardware descriptions cited in this book +# are registered trademarks. All trade names are subject to copyright +# restrictions and may be registered trade marks. Canonical Ltd +# essentially adheres to the manufacturer's spelling. +# +# Names of products and trademarks appearing in this book (with or without +# specific notation) are likewise subject to trademark and trade protection +# laws and may thus fall under copyright restrictions. +# + + +=pod + +=head1 NAME + +aa-exec - confine a program with the specified AppArmor profile + +=head1 SYNOPSIS + +B [options] [--] [IcommandE> ...] + +=head1 DESCRIPTION + +B is used to launch a program confined by the specified profile +and or namespace. If both a profile and namespace are specified command +will be confined by profile in the new policy namespace. If only a namespace +is specified, the profile name of the current confinement will be used. If +neither a profile or namespace is specified command will be run using +standard profile attachment (ie. as if run without the aa-exec command). + +If the arguments are to be pasted to the IcommandE> being invoked +by aa-exec then -- should be used to separate aa-exec arguments from the +command. + aa-exec -p profile1 -- ls -l + +=head1 OPTIONS +B accepts the following arguments: + +=over 4 + +=item -p PROFILE, --profile=PROFILE + +confine IcommandE> with PROFILE. If the PROFILE is not specified +use the current profile name (likely unconfined). + +=item -n NAMESPACE, --namespace=NAMESPACE + +use profiles in NAMESPACE. This will result in confinement transitioning +to using the new profile namespace. + +=item -f FILE, --file=FILE + +a file or directory containing profiles to load before confining the program. + +=item -i, --immediate + +transition to PROFILE before doing executing IcommandE>. This +subjects the running of IcommandE> to the exec transition rules +of the current profile. + +=item -v, --verbose + +show commands being performed + +=item -d, --debug + +show commands and error codes + +=item -- + +Signal the end of options and disables further option processing. Any +arguments after the -- are treated as arguments of the command. This is +useful when passing arguments to the IcommandE> being invoked by +aa-exec. + +=head1 BUGS + +If you find any bugs, please report them at +L. + +=head1 SEE ALSO + +aa-stack(8), aa-namespace(8), apparmor(7), apparmor.d(5), aa_change_profile(3), +aa_change_onexec(3) and L. + +=cut