From 83c9b7c8a1398d503f34d1c7227bfa7b2d71a032b64b65e099065020191c3f8d Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Tue, 25 Jun 2013 11:12:33 +0000 Subject: [PATCH] Accepting request 180837 from openSUSE:Factory:Staging:perl518 - add latex2html-fix-defined.patch from debian bug tracker to avoid a warning - add apparmor's tex docu for better %check: testfile.tex OBS-URL: https://build.opensuse.org/request/show/180837 OBS-URL: https://build.opensuse.org/package/show/Publishing/latex2html?expand=0&rev=11 --- latex2html-fix-defined.patch | 37 + latex2html.changes | 7 + latex2html.spec | 33 +- testfile.tex | 1303 ++++++++++++++++++++++++++++++++++ 4 files changed, 1352 insertions(+), 28 deletions(-) create mode 100644 latex2html-fix-defined.patch create mode 100644 testfile.tex diff --git a/latex2html-fix-defined.patch b/latex2html-fix-defined.patch new file mode 100644 index 0000000..a3d5107 --- /dev/null +++ b/latex2html-fix-defined.patch @@ -0,0 +1,37 @@ +Description: Fix perl warning about deprecated "defined(%hash)" + latex2html with current perl gives warnings about the deprecation of + "defined(%hash)". This patches removes them by just removing the resp. + keyword. +Author: Roland Stigge + +Index: latex2html-2008-debian1/latex2html.pin +=================================================================== +--- latex2html-2008-debian1.orig/latex2html.pin 2010-07-31 16:13:21.000000000 +0200 ++++ latex2html-2008-debian1/latex2html.pin 2012-04-09 17:21:52.000000000 +0200 +@@ -532,7 +532,7 @@ + # + # If possible, use icons of the same type as generated images + # +-if ($IMAGE_TYPE && defined %{"icons_$IMAGE_TYPE"}) { ++if ($IMAGE_TYPE && %{"icons_$IMAGE_TYPE"}) { + %icons = %{"icons_$IMAGE_TYPE"}; + } + +@@ -2112,7 +2112,7 @@ + "\nCould not find translation function for $default_language.\n\n") + } + ); +- if ($USE_UTF ||(!$NO_UTF &&(defined %unicode_table)&&length(%unicode_table)>2)) { ++ if ($USE_UTF ||(!$NO_UTF &&(%unicode_table)&&length(%unicode_table)>2)) { + &convert_to_unicode($_)}; + } + $_ = join('', @case_processed, $_); undef(@case_processed); +@@ -9117,7 +9117,7 @@ + my ($charset) = "${CHARSET}_character_map_inv"; + $charset =~ s/-/_/g; + # convert upper 8-bit characters +- if (defined %$charset &&($CHARSET =~ /8859[_\-]1$/)) { ++ if (%$charset &&($CHARSET =~ /8859[_\-]1$/)) { + s/([\200-\377])/ + $tmp = $$charset{'&#'.ord($1).';'}; + &mark_string($tmp) if ($tmp =~ m!\{!); diff --git a/latex2html.changes b/latex2html.changes index 47700c8..226d653 100644 --- a/latex2html.changes +++ b/latex2html.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Jun 25 09:47:55 UTC 2013 - coolo@suse.com + +- add latex2html-fix-defined.patch from debian bug tracker to avoid + a warning +- add apparmor's tex docu for better %check: testfile.tex + ------------------------------------------------------------------- Thu Apr 11 07:59:19 UTC 2013 - mmeister@suse.com diff --git a/latex2html.spec b/latex2html.spec index 6cc81a4..837c3c0 100644 --- a/latex2html.spec +++ b/latex2html.spec @@ -44,12 +44,14 @@ Source: http://www.latex2html.org/~latex2ht/current/%{name}-%{version}.t Source1: latex2html-manual.ps.gz Source2: latex2html-manual.tar.bz2 Source3: latex2html-README.SuSE +Source4: testfile.tex Patch: latex2html-%{version}.diff Patch1: latex2html-%{version}-binmode.diff Patch2: latex2html-%{version}-gsout.diff Patch3: latex2html-%{version}-buildroot.diff Patch4: latex2html-%{version}-perl-bindir.diff Patch5: latex2html-%{version}-match-multiline.patch +Patch6: http://patch-tracker.debian.org/patch/series/dl/latex2html/2008-debian1-9/latex2html-fix-defined.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -59,14 +61,6 @@ LaTeX texts. Find documentation in /usr/share/doc/packages/latex2html. - - -Authors: --------- - Jens Lippmann - Nikos Drakos - Ross Moore - %package pngicons Provides: l2h-pngicons Obsoletes: l2h-pngicons @@ -77,14 +71,6 @@ Group: Productivity/Publishing/TeX/Utilities %description pngicons Icons in the PNG format for the LaTeX to HTML Converter. - - -Authors: --------- - Jens Lippmann - Nikos Drakos - Ross Moore - %package doc Summary: LaTeX2HTML Converter License: GPL-2.0+ and LPPL-1.3c @@ -95,16 +81,6 @@ LaTeX2HTML lets you easily convert basic LaTeX documents into the HTML format. This allows both a written and online version even of older LaTeX texts. -Find documentation in /usr/share/doc/packages/latex2html. - - - -Authors: --------- - Jens Lippmann - Nikos Drakos - Ross Moore - %prep %setup %setup -a 2 @@ -114,6 +90,7 @@ Authors: %patch3 %patch4 %patch5 -p1 +%patch6 -p1 cp %{S:1} manual.ps.gz cp %{S:3} README.SuSE @@ -134,8 +111,8 @@ chmod 755 $RPM_BUILD_ROOT%{_datadir}/%{name}/{cweb2html/makemake.pl,cweb2html/cw rm $RPM_BUILD_ROOT/usr/lib/texmf/tex/latex/html/url.sty %fdupes -s $RPM_BUILD_ROOT -%clean -rm -rf $RPM_BUILD_ROOT +%check +LATEX2HTMLDIR=%buildroot/%{share_dir} ./latex2html --test_mode %{S:4} %postun mkdir -p var/adm/SuSEconfig diff --git a/testfile.tex b/testfile.tex new file mode 100644 index 0000000..26f2a56 --- /dev/null +++ b/testfile.tex @@ -0,0 +1,1303 @@ +\documentclass[a4paper]{article} +%\usepackage{graphicx} +%\usepackage{subfigure} +\usepackage[utf8]{inputenc} +\usepackage{url} +%\usepackage{times} + +\usepackage[pdftex, + pdfauthor={Andreas Gruenbacher and Seth Arnold}, + pdftitle={AppArmor Technical Documentation},% +\ifx\fixedpdfdate\@empty\else + pdfcreationdate={\fixedpdfdate}, + pdfmoddate={\fixedpdfdate}, +\fi + pdfsubject={AppArmor}, + pdfkeywords={AppArmor} +]{hyperref} + +\hyphenation{App-Armor} +\hyphenation{name-space} + +\renewcommand{\H}{\hspace{0pt}} + +\title{AppArmor Technical Documentation} +\author{Andreas Gruenbacher and Seth Arnold \\ +\url{{agruen,seth.arnold}@suse.de} \\ +SUSE Labs / Novell} +% don't include the (build!) date +\date{} + +\begin{document} + +\maketitle + +\tableofcontents + +\newpage + +%\begin{abstract} +%\end{abstract} + +\section{Introduction} + +In this paper we describe AppArmor from a technical point of view, +introduce its concepts, and explain the design decisions taken. This +text is intended for people interested in understanding why AppArmor +works the way it does. You may be looking for less detailed, low-level, +or kernel centric documentation; in that case, please refer to the +AppArmor documentation web site~\cite{apparmor}. + +Sections~\ref{sec:overview} and ~\ref{sec:model} discuss the AppArmor +security model, while Section~\ref{sec:walk-through} shows how to use it +from a low-level point of view. Please be aware that lots of details +are discussed here which the higher-level tools hide from the average +user. + + +\section{Overview} +\label{sec:overview} + +AppArmor protects systems from insecure or untrusted processes by +running them in confinement, still allowing them to share files with +other parts of the system, exercising privilege, and communicating with +other processes, but with some restrictions. These restrictions are +mandatory; they are not bound to identity, group membership, or object +ownership. In particular, the restrictions also apply to processes +running with superuser privileges. AppArmor achieves this by plugging +into the Linux Security Module (LSM) framework. The protections +provided are in addition to the kernel's regular access control +mechanisms. + +The AppArmor kernel module and accompanying user-space tools are +available under the GPL license. (The exception is the libapparmor +library, available under the LGPL license, which allows change\_hat(2) +to be used by non-GPL binaries.) + +At the moment, AppArmor knows about two types of resources: files, and +POSIX.1e (draft) capabilities. By controlling access to these +resources, AppArmor can effectively prevent confined processes from +accessing files in unwanted ways, from executing binaries which they are +not meant to execute, and from exercising privileges such as acting on +behalf of another user (which are traditionally restricted to the +superuser). + +One use case for this kind of protection is a network daemon: even if +the daemon is broken into, the additional restrictions imposed by +AppArmor will prevent the attacker from attaining additional privileges +beyond what the daemon is normally allowed to do. Because AppArmor +controls which files a process can access in which ways down to the +individual file level, the potential damage is much limited. + +There is work going on for teaching AppArmor about additional resources +like ulimits, and interprocess and network communication, but at this +time, these resource types are not covered. This is less severe than it +might initially seem: in order to attack another process from a +broken-into process like a network daemon, that other process has to +actively listen. The set of actively listening processes is relatively +small, and this sort of interprocess communication is a natural security +boundary, so listening processes should be validating all their input +already. For protection against bugs in the input validation of those +processes, they should also be confined by AppArmor though, thus further +limiting the potential damage. + +AppArmor protection is selective: it only confines processes for which +policies (referred to as profiles) have been defined. All other +processes will continue to run unrestricted by AppArmor. + +To confine a process, all it takes is to write a profile for it, take an +existing profile, or automatically generate a profile: for the latter, +the process can be run in \textit{learning} or \textit{complain} mode in +which AppArmor allows all accesses, and logs all accesses that are not +allowed by the current profile already. This log can then be used to +automatically generate a suitable new profile, or refine an existing +one. The application does not need to be modified. + +An example profile together with a complete low-level walk-through of +AppArmor can be found in Section~\ref{sec:walk-through}. The +apparmor.d(5) manual page contains further details. + +AppArmor is not based on labeling or label-based access and transition +rules, so it does not stick a label on each each file in the file system +(or more generally, on each object). It identifies files by name rather +than by label, so if a process is granted read access to /etc/shadow and +the system administrator renames /etc/shadow to /etc/shadow.old and +replaces it with a copy (that may have an additional user in it, for +example), the process will have access to the new /etc/shadow, and not +to /etc/shadow.old. + + +\section{The AppArmor Security Model} +\label{sec:model} + +When a file is accessed by name with open(2), mkdir(2), etc., the kernel +looks up the location of the object associated with the specified +pathname in the file system hierarchy. The lookup is relative to the +root directory for pathnames starting with a slash, and to the current +working directory otherwise. Different processes can have have different +working directories as well as different root directories. See +path\_resolution(2) for a detailed discussion of how pathname resolution +works. + +Either way, the result of the lookup is a pair of (dentry, vfsmount) +kernel-internal objects that uniquely identify the location of the file +in the file system hierarchy. The dentry points to the object if the +object already exists, and is a placeholder for the object to be created +otherwise. + +AppArmor uses the (dentry, vfsmount) pair to compute the pathname of the +file within a process's filesystem namespace. The resulting pathname +contains no relative pathname components (``.'' or ``..''), or symlinks. + +AppArmor checks if the current profile contains rules that match this +pathname, and if those rules allow the requested access. Accesses +that are not explicitly allowed are denied. + + +\subsection{Symbolic Links} + +When looking up the (dentry, vfsmount) pair of a file, the kernel +resolves symlinks where appropriate (and fails the lookup where symlink +resolution is inappropriate). + +The pathname that AppArmor computes from a (dentry, vfsmount) pair never +contains symlinks. This also means that if symlinks are used instead of +directories for paths like /tmp, profiles need to be adjusted +accordingly. A future version of AppArmor may have built-in support +for this kind of pathname rewriting. + + +\subsection{Namespaces} + +Linux allows different processes to live in separate namespaces, each of +which forms an independent file system hierarchy. A recent paper by Al +Viro and Ram Pai~\cite{ols06-pai} discusses all the intricate things +possible with namespaces in recent 2.6 kernels. + +From the point of view of a process, an absolute path is a path that +goes all the way up to the root directory of that process. This is +ambiguous if processes have different root directories. Therefore, +instead of paths relative to process root directories, AppArmor uses +paths relative to the namespace root. + +Pathnames are meaningful only within a namespace. Each namespace has a +root where all the files, directories, and mount points are hanging off +from. + +The privilege of creating new namespaces is bound to the +CAP\_{\H}SYS\_{\H}ADMIN capability, which grants a multitude of other +things that would allow a process to break out of AppArmor confinement, +so confined processes are not supposed to have this privilege, and +processes with this capability need to be considered trusted. + +In this setup, privileged processes can still create separate namespaces +and start processes in those namespaces; processes confinement will be +relative to whatever namespace a process ends up in. It is unclear +at this point how AppArmor should support separate namespaces --- either +by computing all pathnames relative to one particular namespace +considered global (assuming that such a globally meaningful namespace +will exist in all setups in which AppArmor is relevant), or by allowing +different sets of profiles to be associated with different namespaces. + + +\subsection{Disconnected Files and Pseudo File Systems} + +In some situations, a process can end up with a file descriptor or +working directory that was looked up by name at some point, but is not +connected to the process's namespace anymore (and hasn't been deleted, +either). This can happen when file descriptors are passed between +processes that do not share the same namespace, or when a file system +has been lazily unmounted (see the MNT\_DETACH flag of umount2(2)). Such +files may still be visible to other processes, and they may become +reconnected. AppArmor cannot compute the pathnames of such files. +Granting unrestricted access would be insecure, and so AppArmor denies +access to disconnected files. + +As a special case, the kernel supports a number of file systems that +users can have file descriptors open for, but that can never be mounted. +Those files are by definition disconnected. Anonymous pipes, futexes, +inotify, and epoll are all examples of that. Accesses to those files +is always allowed. + +Future versions of AppArmor will have better control over disconnected +files by controlling file descriptor passing between processes. + + +\subsection{Mount} + +Mounting can change a process's namespace in almost arbitrary ways. +This is a problem because AppArmor's file access control is pathname +based, and granting a process the right to arbitrarily change its +namespace would subvert this protection mechanism. AppArmor therefore +denies confined processes access to the mount(2), umount(2), and +umount2(2) system calls. + +Future versions of AppArmor may offer fine-grained control over mount, +and may grant confined processes specific mount operations. + + +\subsection{The Kernel NFS Daemon} + +The security model of the various versions of NFS is that files are +looked up by name as usual, but after that lookup, each file is only +identified by a file handle in successive acesses. The file handle at a +minimum includes some sort of filesystem identifier and the file's inode +number. In Linux, the file handles used by most filesystems also +include the inode number of the parent directory; this may change in the +future. File handles are persistent across server restarts. + +This means that when the NFS daemon is presented with a file handle, +clients must get access without having specified a pathname. A pathname +can be computed from a (parent, child) inode pair that identifies the +file down to the directory level if the dentry is properly connected to +the dcache, but multiple hardlinks to the same file within the same +directory cannot be distinguished, and properly connecting dentries +comes at a cost in the NFS daemon. Because of this overhead and the +questionable benefit, most setups do not guarantee that dentries will be +connected, and so pathnames cannot always be computed. (See the +no\_subtree\_check option in exports(5).) + +In addition, the NFS daemon is implemented in the kernel rather than as +a user space process. There is no memory separation or other protection +between the daemon and the rest of the kernel. This means that at best, +the NFS daemon could cooperate with an additional access control +mechanism like AppArmor --- but there would be no enforcement. + +Because of all of this, it makes little sense to put the kernel NFS +daemon under AppArmor control. Administrators are advised to not assign +profiles to the kernel nfsd daemons. + + +\subsection{Why are the computed pathnames meaningful?} + +Whenever a process performs a name-based file access, the pathname or +pathname component always refers to a specific path to that file: the +path is either relative to the chroot if an absolute path is used, or +else relative to the current working directory. The chroot or current +working directory always has a unique pathname up to the namespace root +(even if the process itself has no direct access above the chroot). +This means that each name-based file access maps to a unique, canonical, +absolute pathname. There may be additional paths pointing to the same +file, but a particular name-based access still always refers to only one +of them. These are the pathnames that AppArmor uses for permission +checks. + +If directories along the path get renamed after a process changes into +them (either with chroot(2) or with chdir(2)), the resulting pathname +will differ from the pathnames that the process used. Consider the +following sequence of operations for example: + +\begin{tabbing} +\begin{tabular}{ll} +\textbf{Process 1} & \textbf{Process 2} \\ +chdir("/var/tmp/foo"); & \\ + & rename("/var/tmp/foo", "/var/tmp/bar"); \\ +creat("baz", 0666); & \\ +\end{tabular} +\end{tabbing} + +The creat operation will check against the path +/var/tmp/\textit{bar}/baz, even though Process~1 never used +\textit{bar.} This is the expected behavior; we are interested in the +names of the objects along the path at the time of the access, not in +their previous names. + +As already mentioned, a path lookup results in a pair of (dentry, +vfsmount) kernel-internal objects. The pathname that AppArmor checks +against is computed from these two objects after these objects have been +looked up. The lookup and the pathname computation are not atomic, which +means that pathname components could even be renamed after the lookup +but before the pathname has been computed. + +It matters that the AppArmor access check is performed between the lookup and +the actual access, but atomicity between the lookup and that access +check is not necessary: there is no difference between a rename before +the lookup and a rename after the lookup from AppArmor's point of view; +all we care about is the current pathname at some point between the +lookup and the access. + +A special case occurs when the lookup succeeds, but the file is deleted +before the AppArmor access check. In this case the access is denied and +errno is set to ENOENT, the same behavior as if the lookup had failed. + + +\subsection{Path Permission Checking} + +On UNIX systems, when files are looked up by name, the lookup starts +either at the root or the current working directory of a process. From +there, each directory reached is checked for search permission (x). The +permissions on the directories leading to the current working directory +are not checked. When a file is being created or deleted, the parent +directory of that file is checked for write and search access (wx). +When a file is being accessed, the permissions of that file are checked +for r, w, or x access, or a combination thereof. Each check can result +in a failure with errno set to EACCES (Permission denied). + +In contrast, AppArmor first computes the pathname to a file. If a file +is being created, the name being looked up is the name of the new file +and not the name of the parent directory. + +If the file being looked up is a directory, AppArmor appends a slash to +the pathname so that directory pathnames always end in a slash; +otherwise the pathname will not end in a slash. + +It then checks for file access rules in the process's profile that match +that pathname, and decides based on that. With some exceptions for +execute modes as described in Section~\ref{sec:merging}, the permissions +granted are the union of permissions of all matching rules. + + +\subsection{Profile Permissions} +\label{sec:permissions} + +AppArmor differentiates between slightly more permissions than UNIX +does, as shown in Table~\ref{tab:permissions}: file access rules in +AppArmor support the read (r), write (w), execute (x), memory map as +executable (m), and link (l) permissions. The execute permission +requires a modifier that further specifies which kind of execution is +being granted: inherit the current profile (ix), use the profile defined +for that executable (px), or execute unconfined without a profile (ux). +In addition, the px and ux permissions have Px and Ux forms that will +trigger Secure Execution (see Section~\ref{sec:secure-exec} below). +The different permissions are used as follows: + +\begin{table}[tb] +\center +\begin{tabular}{|l|l|} +\hline +r & Read. \\ +w & Write. \\ +ix & Execute and inherit the current profile. \\ +px & Execute under a specific profile. \\ +Px & Execute secure and under a specific profile. \\ +ux & Execute unconfined. \\ +Ux & Execute secure and unconfined. \\ +m & Memory map as executable. \\ +l & Link. \\ +\hline +\end{tabular} +\caption{File Access Permissions in Profiles} +\label{tab:permissions} +\end{table} + +\begin{description} + +\item[Read.] +The profile read permission is required by all system calls that +require the UNIX read permission. This includes open with +O\_RDONLY, getdents (i.e., readdir), listxattr, getxattr, and +mmap with PROT\_READ. + +\item[Write.] +The profile write permission is required by all system calls +that require the UNIX write permission, except for operations +that create or remove files: while UNIX requires write access to +the parent directory, AppArmor requires write access on the new +file in this case (which does not exist at the time of the +permission check for file creates). Operations that create +files include open with O\_CREAT, creat, mkdir, symlink, and +mknod. Operations that remove files include rename, unlink and +rmdir. + +Operations that require write access in UNIX as well as AppArmor +include open with O\_WRONLY (O\_RDWR requires read and write), +setxattr, removexattr, and mmap with PROT\_WRITE. + +Other system calls such as chmod, chown, utime, and utimes are +bound to file ownership or the respective capabilities in UNIX. +AppArmor also requires profile write access for those operations. + +\item[Execute.] +As mentioned above, AppArmor distinguishes a few different ways +how files may be executed as described above. + +For directories, the UNIX execute permission maps to search +access. AppArmor does not control directory search access. +Traversing directories is always granted. + +\item[Memory map as executable.] +The Linux kernel only requires read access to files in order +to memory map them for execution with the PROT\_EXEC flag. +AppArmor makes a distinction here, and requires the m profile +permission in order for files to be mapped as executable. That way, +it is more obvious in profiles what applications are allowed to do even +if from a security point of view, the m permission provides a similar +level of protection as the ix permission --- execute under the current +profile. + +\item[Link.] +Creating a hardlink requires the profile link permission (l) on the new +path. In addition, the new path must have a subset of the r, w, x, and +m permissions of the old path, and if the new path has the x permission, +the execute flags (i, u, U, p, and P) of the old and the new path must +be equal. + +\item[Rename.] +A rename requires profile read and write access for the source +file, and profile write access for the target file. + +\item[Stat.] +Retrieving information about files is always allowed. We believe +that providing policy for file information retrieval is more +troublesome than the benefit it would provide. + +\end{description} + + +\subsection{System Calls Taking File Handles, At System Calls} + +A number of system calls take file descriptors instead of pathnames as +their parameters (ftruncate, fchmod, etc.), or take directory file +descriptors, and resolve pathnames relative to those directories +(openat, mkdirat, etc.). These system calls are treated like their +non-f and non-at equivalents, and the same access checks are performed. +At the point where AppArmor is asked to validate those file accesses, it +is passed a (dentry, vfsmount) pair no matter which system call variant +is used. + + +\subsection{File Descriptor Passing and Revalidation} + +After a file descriptor has been obtained, the permitted accesses (read +and/or write) are encoded in the file descriptor, and reads and writes +are not revalidated against the profile for each access. This is +consistent with how access checks are done in UNIX; such access checks +would have a severe performance impact. + +The picture changes when a file descriptor is passed between processes +and the other process is running under a different profile, or when a +process switches profiles: in that case, read and write accesses are +revalidated under the new profile. If the new profile does not allow +them, the access is denied and errno is set to EACCES (Permission +denied). + +File descriptors opened by unconfined processes are exempt from this +rule. This is so that processes will still have access to their stdin, +stdout, and stderr without having to list all possible sources of input +and output in all profiles. + + +\subsection{Deleted Files} + +Revalidation is problematic for deleted files for which a process still +has an open file descriptor --- after all, the idea of the pathname of a +deleted file is somewhat peculiar: the file is no longer reachable by +any pathname, and it also cannot become re-attached to the filesystem +namespace again. + +The traditional UNIX behavior is to determine access upon file access, +and to never check again. Applications depend on this, particularly for +temporary files. In addition to temporary files, deleted files can be +used as an interprocess communication mechanism if the file descriptor +is shared among multiple processes. + +AppArmor grants access to deleted files, just like it grants access to +files opened by unconfined processes. It may control interprocess +communication, including file descriptor passing, in a future version. + + +\subsection{The access System Call} + +This system call determines whether a process has a given mode of access +to a file in terms of the read, write, and execute permissions. This is +not a sufficient replacement for performing the access check at the time +of access even under traditional UNIX, because the access system call +and the subsequent access are not atomic, and the permissions might +change between the two operations. Applications are not supposed to rely +on access(2). + +AppArmor introduces additional restrictions, some of which cannot be +modeled in terms of read, write, and execute: for example, an AppArmor +profile may allow a process to create files /tmp/foo-*, but not any +other files in /tmp. + +There is no way to express this with access(2); in traditional UNIX, all +that is required for creating files is write access to the parent +directory. Access(2) will indicate that some accesses are allowed even +when AppArmor will eventually deny them. + + +\subsection{The ptrace System Call} + +The ability to ptrace allows a process to look up information about +another process, read and write the memory of that process, and attach +to (or trace) that process in order to debug it, or analyze its +behavior. This gives total control over the process being traced, and +so the kernel employs some restrictions over which processes may ptrace +with other processes. + +In addition to these restrictions, AppArmor requires that if the tracing +task is confined, it must either have the CAP\_{\H}SYS\_{\H}PTRACE capability, +or be confined by the same profile and sub-profile as the process being +traced. Attempts to switch to another profile or sub-profile by a +process being traced is denied. + + +\subsection{Secure Execution} +\label{sec:secure-exec} + +In this mode, the kernel passes a flag to user space. When glibc finds +this flag set, it unsets environment variables that are considered +dangerous, and it prevents the dynamic loader from loading libraries +controlled by the environment. With non-secure exec, the +LD\_LIBRARY\_PATH environment variable can be used to switch to a +different set of libraries, for example. The secure exec mechanism is +not specific to AppArmor: set-user-id and set-group-id executables also +use it, as well as SELinux, which introduced this glibc feature. + + +\subsection{Exec Mode Merging in Profiles, Exact Matches} +\label{sec:merging} + +When more than one rule in a profile matches a given path, all the +permissions accumulate except for ix, px, Px, ux, and Ux: those +permissions would conflict with each other; it would be unclear how to +execute the new binary if more than one of these flags was set. To deal +with this situation, AppArmor differentiates between rules that define +exact matches and wildcard rules (see Table~\ref{tab:globbing} on +page~\pageref{tab:globbing}). Execute flags in exact matches override +execute flags in wildcard matches. + +If the execute flags of multiple rules still disagree, the profile is +rejected at profile load time. + + +\subsection{Capabilities} + +AppArmor uses the standard Linux capability mechanism. When the kernel +checks if a certain capability can be exercised, AppArmor additionally +checks if the current profile allows the requested capability, and +rejects the use of the capability otherwise. + + +\subsection{The sysctl System Call and /proc/sys} + +The sysctl system call and files below /proc/sys +can be used to read and modify various kernel parameters. Root processes +can easily bring the system down by setting kernel parameters to invalid +values. To prevent against that, AppArmor denies confined processes +that do not have the CAP\_{\H}SYS\_{\H}ADMIN capability write access to kernel +parameters. + + +\subsection{Subprofiles aka. Hats} + +Profiles can contain subprofiles that processes may switch to from the +main profile. Switching from a subprofile into a sibling subprofile or +back to the parent profile is allowed depending on how the subprofile +was entered, and provided that the child knows a magic cookie.\footnote{ + \textbf{A word of warning about change\_hat(2):} When used with a + non-zero magic cookie for changing into a subprofile, that magic + cookie can be used to change back out of the subprofile; in this + mode, change\_hat(2) is not a strong confinement mechanism. If the + code running in the subprofile can guess the magic cookie, it can + break out of the subprofile. Likewise, if that code can manipulate + the processes' behavior beyond the point where the process returns + from the subprofile, it can influence what is done under the parent + profile. Therefore, change\_hat(2) with a non-zero magic cookie is + only safe in combination with restricted code environments, such as + when the subprofile is used for executing Safe Perl (see Safe(3pm)), + etc. +} See the change\_hat(2) manual page for details. + +Each process may consist of multiple tasks. Each task may only change +its own subprofile. The superuser cannot put a task into a different +hat, but he can replace the entire profile and its subprofiles, or he +can put a process in a different top-level profile (see +Section~\ref{sec:association}). + +Internally, change\_hat(2) is implemented by writing to a special +kernel-provided file. This is equivalent to a command like: + +\begin{small} +\begin{verbatim} + $ echo "changehat 123^hat_name" > /proc/$PID/attr/current +\end{verbatim} +\end{small} + +Here, the number is the magic cookie value, and hat\_name obviously is +the name of the hat; either may be replaced by the empty string (but not +both). + + +\subsection{Association of Profiles with Processes} +\label{sec:association} + +Profiles are associated with kernel tasks, which roughly correspond to +threads in user space (see clone(2) for details). Currently there are +two ways how a profile can be associated with a task: when an executable +is started and a profile is defined for that executable, or when the +administrator assigns a profile to a task explicitly. + +In addition to that, once a task is confined by a profile, that profile +determines which other executables may be executed, and under which +profile they may run (under the profile defined for that executable, the +same profile as the current task, or unconfined; see +Section~\ref{sec:permissions}). + +A process will consist of a single task after an exec, so in the exec +case, the entire process will be confined. New tasks (threads as well +as processes) inherit the same profile and subprofile as their parent +task. + +Unconfined processes with the CAP\_{\H}SYS\_{\H}ADMIN privilege may assign a +profile to a task with a command like this: + +\begin{small} +\begin{verbatim} + $ echo "setprofile /name/of/profile" > \ + /proc/$PID/attr/current +\end{verbatim} +\end{small} + +After that, the task will be in the new top-level profile, even if the +process was in a subprofile before. + +Processes with the CAP\_{\H}SYS\_{\H}ADMIN privilege as well as the process itself +can query the profile a process is in by reading from that file: + +\begin{small} +\begin{verbatim} + $ cat /proc/$PID/attr/current + unconfined + + $ cat /proc/$PID/attr/current + /name/of/profile (complain) + + $ cat /proc/$PID/attr/current + /name/of/profile^hat_name (enforce) +\end{verbatim} +\end{small} + +The output includes the name of the profile and subprofile as well as +the mode the active profile is in. (When a task is in a subprofile, +the subprofile is the active profile.) + +\subsection{Profile Loading, Replacement, and Removal} + +Before the kernel can use any profiles, they must be loaded. The +profile sources consist of plain text. This text representation is +converted into in a binary representation that the kernel can more +easily deal with by the user-space profile loader. + +Profiles contain potentially long lists of file access rules that may +include wildcards. In order to make the lookup efficient, the AppArmor +kernel module does not actually go through all the file access rules +when checking for access. Instead, the profile loader takes those rules +and compiles them into transition tables. Pathnames are then looked up +in those tables with a simple and efficient algorithm, the theory behind +which is explained in the Lexical Analysis section of the Dragon +Book~\cite{dragon86}. + +An init script loads all the known profiles into the kernel at an early +boot stage. This happens automatically and the system administrator +tools will take care of loading, reloading, or removing profiles after +they manipulate them, so end users will not usually notice this step. + +Profiles can be replaced at any time during runtime, and all processes +running under old profiles will transparently be switched to the updated +versions. Profiles can also be removed. All processes running under a +profile that is removed will become unconfined. + +Profiles are always replaced together with all their subprofiles. It +may be that an updated profile no longer contains a specific subprofile. +If that happens while processes are using that subprofile, those +processes will be put in a profile that denies all accesses. Such +processes may still change to sibling subprofiles or back to the parent +profile subject to the change\_hat(2) semantics. + + +\section{AppArmor Walk-Through} +\label{sec:walk-through} + +AppArmor consists of a set of kernel patches and accompanying +user-space tools, both of which are available at +\url{http://developer.novell.com/wiki/index.php/Apparmor}. + + +\subsection{Kernel Patches and Configuration} + +The AppArmor kernel patches are provided in a format convenient for use +with quilt,\footnote{ + \url{http://savannah.nongnu.org/projects/quilt} +} however, other tools for applying the patches can be used, too. The +patches are supposed to apply against recent kernel.org git kernels. A +copy of the current git tree can be obtained from +\url{git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git} +with \textit{git clone} (see the \hbox{git-clone(1)} manual page). In +case the the differences between the latest git tree and the tree the +AppArmor patches are based on is too big, the patches won't apply +cleanly. In this case, trying an older git tree may work better. + +After obtaining the AppArmor patches tarball and the git tree which will +end up in the linux-2.6 directory by default, the AppArmor patches can +be applied to the git tree as follows: + +\begin{small} +\begin{verbatim} + $ tar zxvf apparmor.tar.gz + $ cd linux-2.6/ + $ ln -s ../apparmor patches + $ quilt push -a +\end{verbatim} +\end{small} + +When configuring the kernel, make sure that AppArmor is built in or as a +module (CONFIG\_{\H}SECURITY\_{\H}APPARMOR must be 'y' or 'm'). AppArmor +cannot be used together with other Linux Security Modules, so if +CONFIG\_{\H}SECURITY\_{\H}CAPABILITIES or CONFIG\_{\H}SECURITY\_{\H}SELINUX is +set to 'y', they must be disabled by adding \texttt{selinux=0} and/or +\texttt{capability.disable=1} to the kernel command line (grub, lilo, +yaboot, etc.). It is not sufficient to put SELinux into permissive +mode --- at this time, AppArmor cannot be combined with other LSMs. + +\subsection{The securityfs file system} + +AppArmor uses securityfs for configuration and to report information. +The usual mountpoint for securityfs is /sys/{\H}kernel/{\H}security. +Unless your distribution automatically does so, you can mount securityfs +with: + +\begin{small} +\begin{verbatim} + $ mount securityfs -t securityfs /sys/kernel/security +\end{verbatim} +\end{small} + +Once securityfs has been mounted and the apparmor module loaded, +/sys/{\H}kernel/{\H}security/{\H}apparmor/{\H}profiles will show the +profiles loaded into the kernel, as well as mark if the profiles are in +enforcement mode or in learning mode: + +\begin{small} +\begin{verbatim} + $ cat /sys/kernel/security/apparmor/profiles + /usr/bin/opera (complain) + /usr/lib/firefox/firefox.sh (complain) + /sbin/lspci (enforce) + ... +\end{verbatim} +\end{small} + +Profile loading, replacement, and unloading, as well as configuration of +AppArmor is also done via securityfs. + +%/sys/kernel/security/apparmor/control/ control seldom-used features of AppArmor: +% audit if '1', audit all actions by confined processes +% complain if '1', allow all actions by confined processes, report +% accesses not granted by policy +% debug if '1', emit copius debugging +% logsyscall if '1', use audit framework's syscall debugging, if audit +% has been instructed to create per-task contexts.[2] + +\subsection{Profile Loading} + +Profile loading, replacement, and removal is performed by the +apparmor\_parser utility from the apparmor-parser package. The +package can easily be built by running make in the package's top-level +directory. Once that is done and the AppArmor module loaded, you may +use the parser to load profiles with: + +\begin{small} +\begin{verbatim} + $ echo "/tmp/ls { /tmp/ls rm, }" | apparmor_parser +\end{verbatim} +\end{small} + +Once a profile for a program has been loaded into the kernel, you must +use the --replace option for replacing the existing profile with a new +one (this option may be used even if no profile by that name exists): + +\begin{small} +\begin{verbatim} + $ echo "/tmp/ls { /tmp/ls rm, }" | apparmor_parser --replace +\end{verbatim} +\end{small} + +\subsection{Anatomy of a Profile} + +AppArmor profiles use a simple declaritive language, fully described in +the apparmor.d(5) manual page. By convention, profiles are stored in +/etc/{\H}apparmor.d/. The AppArmor parser supports a simple cpp-style +include mechanism to allow sharing pieces of policy. A simple profile +looks like this: + +\begin{small} +\begin{verbatim} + /bin/ls flags=(complain) { + /bin/ls rm, + /lib/ld-2.5.so rmix, + /etc/ld.so.cache rm, + /lib/lib*.so* rm, + + /dev/pts/* w, + + /proc/meminfo r, + /var/run/nscd/socket w, + /var/run/nscd/passwd r, + /var/run/nscd/group r, + + /tmp/ r, + } +\end{verbatim} +\end{small} + +Here, the first /bin/ls is the name of the profile. This profile will be +automatically used whenever an unconfined process executes /bin/ls. The +flags instruct AppArmor to put the profile in complain (aka. learning) +mode: in this mode, all operations are allowed, and any events that +would have been denied are logged. This helps users to incrementally +deploy AppArmor in production environments. The default if no flags are +specified is enforcement mode, in which all operations not allowed by +the profile are logged and denied. + +Complain mode can be enabled individually for profiles as shown above +(followed by reloading the profile), or by globally putting all profiles +in complain mode with: + +\begin{small} +\begin{verbatim} + $ echo 1 > /sys/kernel/security/apparmor/control/complain +\end{verbatim} +\end{small} + +The user-space tools also include two small utilities, enforce and +complain, which will put profiles into enforce or complain mode: + +\begin{small} +\begin{verbatim} + $ enforce firefox + Setting /usr/lib/firefox/firefox.sh to enforce mode. +\end{verbatim} +\end{small} + +Inside the body of the profile are any number of rules consisting of a +pathname expression that may include globbing, and a set of permissions. +Table~\ref{tab:globbing} shows the supported shell-inspired globbing +constructs; Section~\ref{sec:permissions} on +page~\pageref{sec:permissions} describes the permissions. + +\begin{table}[tb] +\center +\begin{tabular}{|l|l|} +\hline +{?} & Any single character except ``/''. \\ +{*} & Any number of characters except ``/''. \\ +{**} & Any number of characters including ``/''. \\ +{[ab]} & One of ``a'' or ``b''. \\ +{[a-c]} & One of ``a'', ``b'', or ``c''. \\ +\{ab,cd\} & Alternation: either ``ab'' or ``cd''. \\ +\hline +\end{tabular} +\caption{Globbing in File Access Rules. Alternation counts as an exact +match in file access rules; all others count as wildcards (see +Section~\ref{sec:merging}).} +\label{tab:globbing} +\end{table} + +When AppArmor looks up a directory the pathname being looked up will end +with a slash (e.g., /var/tmp/), otherwise it will not. Only rules +that match that trailing slash will match directories. Some examples, +none matching the /tmp directory itself, are: + +\begin{tabbing} +\begin{tabular}{ll} +{/tmp/*} & Files directly in /tmp. \\ +{/tmp/*/} & Directories directly in /tmp. \\ +{/tmp/**} & Files and directories anywhere underneath /tmp. \\ +{/tmp/**/} & Directories anywhere underneath /tmp. \\ +\end{tabular} +\end{tabbing} + +As explained in Section~\ref{sec:model}, AppArmor does not require +execute access to allow directory traversal, or write access on a +directory to create or rename files inside the directory. Instead, write +access is required on the specific files that a confined process +attempts to create, remove, rename, etc. Read access is required for +reading the contents of a directory. + +AppArmor also mediates the use of POSIX 1003.1e draft capabilities; +capabilities that a process is allowed to use are listed in the +profile by their name in lower-case (with ``CAP\_'' stripped off), e.g., + +\begin{small} +\begin{verbatim} + #include + + /sbin/lspci { + #include + #include + + capability sys_admin, + + /sbin/lspci mr, + /sys/bus/pci/ r, + /sys/bus/pci/devices/ r, + /sys/devices/** r, + /usr/share/pci.ids r, + } +\end{verbatim} +\end{small} + +This profile uses predefined include files which are part of the +apparmor-profiles package. + +\subsection{Logging} + +AppArmor uses the kernel standard audit facility for reporting. When a +profile is in complain mode, the log messages look like this: + +\begin{small} +\begin{verbatim} + type=APPARMOR msg=audit(1174506429.573:1789): PERMITTING r access + to /home/sarnold/ (ls(16504) profile /tmp/ls active /tmp/ls) +\end{verbatim} +\end{small} + +When a profile is in enforcement mode, the log messages look like this: + +\begin{small} +\begin{verbatim} + type=APPARMOR msg=audit(1174508205.298:1791): REJECTING r access + to /bin/ (ls(16552) profile /tmp/ls active /tmp/ls) +\end{verbatim} +\end{small} + +These log messages are sent to the kernel auditing facility; if auditd +is not running, the kernel will forward these messages to printk for +collection by klogd. Auditd must be configured with --with-apparmor to +enable the \#defines to handle AppArmor's message type correctly. + +AppArmor also logs some important events in the process lifecycle, +such as when processes in learning mode fork and change domain via +exec. These other events, while not strictly related to permissions +requested by the process, help the genprof profile generation tool +reconstruct when specific accesses are required by processes --- this +allows the tool to make more relevant and meaningful policy suggestions. + +\subsection{Generating Profiles By Hand} + +While the majority of our users are expected to generate profiles with +the help of our profile tools, it is possible to write policy by hand. +This final section gives a very quick walkthrough generating a simple +profile for firefox. + +Since the kernel resolves symlinks to their ``final destinations'' before +presenting AppArmor with policy questions, we first must see if +/usr/{\H}bin/{\H}firefox is a symlink or the shell script that starts firefox; +on our system, it is a symlink: + +\begin{small} +\begin{verbatim} + $ ls -l /usr/bin/firefox + lrwxrwxrwx 1 root root 25 Mar 21 13:36 /usr/bin/firefox -> + ../lib/firefox/firefox.sh +\end{verbatim} +\end{small} + +So we will start a profile for /usr/{\H}lib/{\H}firefox/{\H}firefox.sh. This shell +script will execute firefox-bin, as we will see later; when it does so, +we will tell AppArmor to inherit this profile. Thus, firefox-bin will +be executing under the profile for /usr/{\H}lib/{\H}firefox/{\H}firefox.sh. + +To get started, we can make some assumptions about the privileges that +firefox will need (both as a shell script and as a fairly complex GUI +application): + +\begin{small} +\begin{verbatim} + $ cat /etc/apparmor.d/usr.lib.firefox.firefox.sh + /usr/lib/firefox/firefox.sh flags=(complain) { + /usr/lib/firefox/firefox.sh r, + /bin/bash rmix, + /lib/ld-2.5.so rmix, + /etc/ld.so.cache rm, + /lib/lib*.so* rm, + /usr/lib/lib*.so* rm, + } + $ apparmor_parser --reload < \ + /etc/apparmor.d/usr.lib.firefox.firefox.sh + Replacement succeeded for "/usr/lib/firefox/firefox.sh". +\end{verbatim} +\end{small} + +The easiest way to see what accesses AppArmor allows, start a tail -F +/var/{\H}log/{\H}audit/{\H}audit.log (or /var/{\H}log/{\H}messages, or wherever your audit +messages are being sent). In another terminal, start firefox. tail will +show a few hundred PERMITTING audit events like these: + +\begin{small} +\begin{verbatim} + type=APPARMOR msg=audit(1174512269.026:1804): PERMITTING rw access + to /dev/tty (firefox(16950) profile /usr/lib/firefox/firefox.sh + active /usr/lib/firefox/firefox.sh) + + type=APPARMOR msg=audit(1174512269.026:1805): PERMITTING r access + to /usr/share/locale/locale.alias (firefox(16950) profile + /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) + + type=APPARMOR msg=audit(1174512269.026:1806): PERMITTING r access + to /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION (firefox(16950) + profile /usr/lib/firefox/firefox.sh active + /usr/lib/firefox/firefox.sh) +\end{verbatim} +\end{small} + +Because we want this profile to be fairly simple we'll be fairly +permissive, add a few more rules to the profile and reload: + +\begin{small} +\begin{verbatim} + /dev/tty rw, + /usr/share/locale/** r, + /usr/lib/locale/** r, +\end{verbatim} +\end{small} + +Now re-run firefox. There is no need to handle all log entries at once. +In complain mode, AppArmor will only report accesses that are not in the +profile. This makes it fairly easy to add a few rules and re-run the +application to determine what privileges are still necessary. We get a +few more messages: + +\begin{small} +\begin{verbatim} + type=APPARMOR msg=audit(1174512791.236:5356): PERMITTING r access + to /usr/lib/gconv/gconv-modules.cache (firefox(17031) profile + /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) + + type=APPARMOR msg=audit(1174512791.236:5357): PERMITTING r access + to /proc/meminfo (firefox(17031) profile + /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) + + type=APPARMOR msg=audit(1174512791.240:5358): PERMITTING x access + to /bin/basename (firefox(17032) profile + /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) + + type=APPARMOR msg=audit(1174512791.240:5359): LOGPROF-HINT + changing_profile pid=17032 + + type=APPARMOR msg=audit(1174512791.240:5360): PERMITTING r access + to /bin/basename (firefox(17032) profile + null-complain-profile active null-complain-profile) + + ... + + type=APPARMOR msg=audit(1174512791.240:5364): PERMITTING mr access + to /bin/basename (basename(17032) profile + null-complain-profile active null-complain-profile) +\end{verbatim} +\end{small} + + +So now, we add a few more rules: + +\begin{small} +\begin{verbatim} + /usr/lib/gconv/** r, + /proc/meminfo r, + /bin/basename rmix, +\end{verbatim} +\end{small} + +We selected ``rmix'' for /bin/basename --- most small shell utilities +should not have a profile for themselves. There's nothing wrong with +giving basename a profile, but the value of such a profile would be very +limited. Giving other shell utilities their own profiles would be worse: +the profile would need read access to the whole filesystem for shell +scripts to function reliably. In our case, basename simply inherits +privileges from another profile, then it has no more and no fewer +privileges than the calling program --- which is often a fine tradeoff. + +The loader will need r and m access to execute basename, and we use ix +to execute basename in the same profile. The kernel logs only reported +r, m and x access; we have to choose the execute mode ourselves. Again, +the standard user tools would prompt users for this decision and give +consequences of decisions. + +We continue in this fashion, iteratively adding and changing rules as +needed by the logs. Some of the logs report attribute modifications, +such as: + +\begin{small} +\begin{verbatim} + type=APPARMOR msg=audit(1174519157.851:10357): PERMITTING + attribute (mode,ctime,) change to + /home/sarnold/.gnome2_private/ (firefox-bin(17338) profile + /usr/lib/firefox/firefox.sh active /usr/lib/firefox/firefox.sh) +\end{verbatim} +\end{small} + +These need to be represented in the profile with simple w access. + +\begin{small} +\begin{verbatim} + /home/*/.gnome2_private/ w, +\end{verbatim} +\end{small} + +After nine iterations, the profile looks like this --- we have inserted +blank lines between each iteration: + +\begin{small} +\begin{verbatim} + /usr/lib/firefox/firefox.sh flags=(complain) { + /usr/lib/firefox/firefox.sh r, + /bin/bash rmix, + /lib/ld-2.5.so rmix, + /etc/ld.so.cache rm, + /lib/lib*.so* rm, + /usr/lib/lib*.so* rm, + + /dev/tty rw, + /usr/share/locale/** r, + /usr/lib/locale/** r, + + /usr/lib/gconv/** r, + /proc/meminfo r, + /bin/basename rmix, + + /usr/bin/file rmix, + /etc/magic r, + /usr/share/misc/magic.mgc r, + /bin/gawk rmix, + /usr/lib/firefox/firefox-bin rmix, + + /usr/lib/firefox/lib*so rm, + /opt/gnome/lib/lib*so* rm, + /usr/share/X11/locale/* r, + /var/run/nscd/socket w, + /var/run/nscd/passwd r, + + /usr/share/X11/locale/** r, + /home/*/.Xauthority r, + /usr/lib/gconv/*so m, + /home/*/.mozilla/** rw, + /etc/resolv.conf r, + /usr/lib/firefox/**.so rm, + /usr/lib/firefox/** r, + + /etc/opt/gnome/** r, + /var/run/dbus/system_bus_socket w, + /etc/localtime r, + /opt/gnome/lib/**.so rm, + /var/cache/libx11/compose/* r, + /tmp/orbit-*/ w, + /dev/urandom r, + /tmp/ r, + /dev/null rw, + /opt/gnome/lib/GConf/2/gconfd-2 rmix, + + /dev/log w, + /tmp/orbit-*/* w, + /tmp/gconfd-*/ r, + /tmp/gconfd-*/** rwl, + /home/*/.gconf/ r, + /home/*/.gconf/* rw, + /etc/fonts/** r, + /var/cache/fontconfig/* r, + /home/*/.fontconfig/** r, + /usr/share/ghostscript/fonts/** r, + /etc/passwd r, + /var/tmp/ r, + /bin/netstat rmix, + + /home/*/.gnome2_private/ w, + /home/*/.gconfd/* rw, + /proc/net/ r, + /proc/net/* r, + /usr/share/fonts/** r, + /usr/lib/browser-plugins/ r, + /usr/lib/browser-plugins/** rm, + } +\end{verbatim} +\end{small} + +Sorting the entries in the profile can help show areas that can be +collapsed with even more generic rules. After doing that and making a +few rules slightly more generic, we end up with: + +\begin{small} +\begin{verbatim} + /usr/lib/firefox/firefox.sh { + /bin/basename rmix, + /bin/bash rmix, + /bin/gawk rmix, + /bin/netstat rmix, + /dev/log w, + /dev/null rw, + /dev/tty rw, + /dev/urandom r, + /etc/fonts/** r, + /etc/ld.so.cache rm, + /etc/localtime r, + /etc/magic r, + /etc/opt/gnome/** r, + /etc/passwd r, + /etc/resolv.conf r, + /home/*/.fontconfig/** r, + /home/*/.gconfd/* rw, + /home/*/.gconf/ r, + /home/*/.gconf/* rw, + /home/*/.gnome2_private/ w, + /home/*/.mozilla/** rw, + /home/*/.Xauthority r, + /lib/ld-2.5.so rmix, + /lib/lib*.so* rm, + /opt/gnome/lib/GConf/2/gconfd-2 rmix, + /opt/gnome/lib/**.so* rm, + /proc/meminfo r, + /proc/net/ r, + /proc/net/* r, + /tmp/gconfd-*/ r, + /tmp/gconfd-*/** rwl, + /tmp/orbit-*/ w, + /tmp/orbit-*/* w, + /tmp/ r, + /usr/bin/file rmix, + /usr/lib/browser-plugins/ r, + /usr/lib/browser-plugins/** rm, + /usr/lib/firefox/firefox-bin rmix, + /usr/lib/firefox/firefox.sh r, + /usr/lib/firefox/** r, + /usr/lib/firefox/**.so rm, + /usr/lib/gconv/** r, + /usr/lib/gconv/*so m, + /usr/lib/lib*.so* rm, + /usr/lib/locale/** r, + /usr/share/** r, + /var/cache/fontconfig/* r, + /var/cache/libx11/compose/* r, + /var/run/dbus/system_bus_socket w, + /var/run/nscd/passwd r, + /var/run/nscd/socket w, + /var/tmp/ r, + } +\end{verbatim} +\end{small} + + +\begin{thebibliography}{XX} + +\bibitem{apparmor} +AppArmor documentation, +\url{http://www.novell.com/documentation/apparmor/} + +\bibitem{ols06-pai} +Al Viro and Ram Pai: +{\em Shared-Subtree Concept, Implementation and Applications in Linux,} +Ottawa Linux Symposium, July 19-22, 2006, +\url{http://www.linuxsymposium.org/2006/} + +\bibitem{dragon86} +Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman: +{\em Compilers: Principles, Techniques, and Tools} +(The ``Dragon Book''), Addison-Wesley, 1986, ISBN 0-201-10088-6. + +A second edition of this classic is available since August 2006 as +ISBN 0-321-48681-1. + +\end{thebibliography} + +\end{document} +% vim:textwidth=72