mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-01 14:55:10 +00:00
Compare commits
2 Commits
git-conver
...
apparmor-2
Author | SHA1 | Date | |
---|---|---|---|
|
ffa6034243 | ||
|
446f3fc533 |
187
.bzrignore
187
.bzrignore
@@ -1,187 +0,0 @@
|
||||
apparmor-*
|
||||
parser/po/*.mo
|
||||
parser/af_names.h
|
||||
parser/cap_names.h
|
||||
parser/tst_lib
|
||||
parser/tst_misc
|
||||
parser/tst_regex
|
||||
parser/tst_symtab
|
||||
parser/tst_variable
|
||||
parser/tst/simple_tests/generated_*/*
|
||||
parser/parser_lex.c
|
||||
parser/parser_version.h
|
||||
parser/parser_yacc.c
|
||||
parser/parser_yacc.h
|
||||
parser/pod2htm*.tmp
|
||||
parser/*.7
|
||||
parser/*.5
|
||||
parser/*.8
|
||||
parser/*.7.html
|
||||
parser/*.5.html
|
||||
parser/*.8.html
|
||||
parser/apparmor_parser
|
||||
parser/libapparmor_re/parse.cc
|
||||
parser/libapparmor_re/regexp.cc
|
||||
parser/techdoc.aux
|
||||
parser/techdoc.log
|
||||
parser/techdoc.pdf
|
||||
parser/techdoc.toc
|
||||
profiles/apparmor.d/local/*.*
|
||||
libraries/libapparmor/Makefile
|
||||
libraries/libapparmor/Makefile.in
|
||||
libraries/libapparmor/aclocal.m4
|
||||
libraries/libapparmor/audit.log
|
||||
libraries/libapparmor/autom4te.cache
|
||||
libraries/libapparmor/compile
|
||||
libraries/libapparmor/config.guess
|
||||
libraries/libapparmor/config.log
|
||||
libraries/libapparmor/config.status
|
||||
libraries/libapparmor/config.sub
|
||||
libraries/libapparmor/configure
|
||||
libraries/libapparmor/depcomp
|
||||
libraries/libapparmor/install-sh
|
||||
libraries/libapparmor/libtool
|
||||
libraries/libapparmor/ltmain.sh
|
||||
libraries/libapparmor/missing
|
||||
libraries/libapparmor/test-driver
|
||||
libraries/libapparmor/ylwrap
|
||||
libraries/libapparmor/doc/Makefile
|
||||
libraries/libapparmor/doc/Makefile.in
|
||||
libraries/libapparmor/doc/*.2
|
||||
libraries/libapparmor/doc/aa_*.3
|
||||
libraries/libapparmor/include/Makefile
|
||||
libraries/libapparmor/include/Makefile.in
|
||||
libraries/libapparmor/include/sys/Makefile
|
||||
libraries/libapparmor/include/sys/Makefile.in
|
||||
libraries/libapparmor/src/.deps
|
||||
libraries/libapparmor/src/.libs
|
||||
libraries/libapparmor/src/Makefile
|
||||
libraries/libapparmor/src/Makefile.in
|
||||
libraries/libapparmor/src/af_protos.h
|
||||
libraries/libapparmor/src/change_hat.lo
|
||||
libraries/libapparmor/src/features.lo
|
||||
libraries/libapparmor/src/grammar.lo
|
||||
libraries/libapparmor/src/kernel.lo
|
||||
libraries/libapparmor/src/kernel_interface.lo
|
||||
libraries/libapparmor/src/libaalogparse.lo
|
||||
libraries/libapparmor/src/libimmunix_warning.lo
|
||||
libraries/libapparmor/src/policy_cache.lo
|
||||
libraries/libapparmor/src/private.lo
|
||||
libraries/libapparmor/src/scanner.lo
|
||||
libraries/libapparmor/src/libapparmor.pc
|
||||
libraries/libapparmor/src/libapparmor.la
|
||||
libraries/libapparmor/src/libimmunix.la
|
||||
libraries/libapparmor/src/grammar.c
|
||||
libraries/libapparmor/src/grammar.h
|
||||
libraries/libapparmor/src/scanner.c
|
||||
libraries/libapparmor/src/scanner.h
|
||||
libraries/libapparmor/src/tst_aalogmisc
|
||||
libraries/libapparmor/swig/Makefile
|
||||
libraries/libapparmor/swig/Makefile.in
|
||||
libraries/libapparmor/swig/perl/LibAppArmor.bs
|
||||
libraries/libapparmor/swig/perl/LibAppArmor.pm
|
||||
libraries/libapparmor/swig/perl/Makefile
|
||||
libraries/libapparmor/swig/perl/Makefile.PL
|
||||
libraries/libapparmor/swig/perl/Makefile.in
|
||||
libraries/libapparmor/swig/perl/Makefile.perl
|
||||
libraries/libapparmor/swig/perl/Makefile.perle
|
||||
libraries/libapparmor/swig/perl/MYMETA.json
|
||||
libraries/libapparmor/swig/perl/MYMETA.yml
|
||||
libraries/libapparmor/swig/perl/blib
|
||||
libraries/libapparmor/swig/perl/libapparmor_wrap.c
|
||||
libraries/libapparmor/swig/perl/pm_to_blib
|
||||
libraries/libapparmor/swig/python/LibAppArmor.py
|
||||
libraries/libapparmor/swig/python/build/
|
||||
libraries/libapparmor/swig/python/libapparmor_wrap.c
|
||||
libraries/libapparmor/swig/python/Makefile
|
||||
libraries/libapparmor/swig/python/Makefile.in
|
||||
libraries/libapparmor/swig/python/setup.py
|
||||
libraries/libapparmor/swig/python/test/Makefile
|
||||
libraries/libapparmor/swig/python/test/Makefile.in
|
||||
libraries/libapparmor/swig/ruby/Makefile
|
||||
libraries/libapparmor/swig/ruby/Makefile.in
|
||||
libraries/libapparmor/testsuite/.deps
|
||||
libraries/libapparmor/testsuite/.libs
|
||||
libraries/libapparmor/testsuite/Makefile
|
||||
libraries/libapparmor/testsuite/Makefile.in
|
||||
libraries/libapparmor/testsuite/libaalogparse.log
|
||||
libraries/libapparmor/testsuite/libaalogparse.sum
|
||||
libraries/libapparmor/testsuite/site.exp
|
||||
libraries/libapparmor/testsuite/test_multi.multi
|
||||
libraries/libapparmor/testsuite/config/Makefile
|
||||
libraries/libapparmor/testsuite/config/Makefile.in
|
||||
libraries/libapparmor/testsuite/lib/Makefile
|
||||
libraries/libapparmor/testsuite/lib/Makefile.in
|
||||
libraries/libapparmor/testsuite/libaalogparse.test/Makefile
|
||||
libraries/libapparmor/testsuite/libaalogparse.test/Makefile.in
|
||||
libraries/libapparmor/testsuite/test_multi/out
|
||||
changehat/mod_apparmor/.libs
|
||||
utils/*.8
|
||||
utils/*.8.html
|
||||
utils/*.5
|
||||
utils/*.5.html
|
||||
utils/*.tmp
|
||||
utils/po/*.mo
|
||||
tests/regression/apparmor/access
|
||||
tests/regression/apparmor/changehat
|
||||
tests/regression/apparmor/changehat_fail
|
||||
tests/regression/apparmor/changehat_fork
|
||||
tests/regression/apparmor/changehat_misc
|
||||
tests/regression/apparmor/changehat_misc2
|
||||
tests/regression/apparmor/changehat_pthread
|
||||
tests/regression/apparmor/changehat_twice
|
||||
tests/regression/apparmor/changehat_wrapper
|
||||
tests/regression/apparmor/changeprofile
|
||||
tests/regression/apparmor/chdir
|
||||
tests/regression/apparmor/chgrp
|
||||
tests/regression/apparmor/chmod
|
||||
tests/regression/apparmor/chown
|
||||
tests/regression/apparmor/clone
|
||||
tests/regression/apparmor/deleted
|
||||
tests/regression/apparmor/env_check
|
||||
tests/regression/apparmor/environ
|
||||
tests/regression/apparmor/exec
|
||||
tests/regression/apparmor/exec_qual
|
||||
tests/regression/apparmor/exec_qual2
|
||||
tests/regression/apparmor/fchdir
|
||||
tests/regression/apparmor/fchgrp
|
||||
tests/regression/apparmor/fchmod
|
||||
tests/regression/apparmor/fchown
|
||||
tests/regression/apparmor/fork
|
||||
tests/regression/apparmor/link
|
||||
tests/regression/apparmor/link_subset
|
||||
tests/regression/apparmor/mkdir
|
||||
tests/regression/apparmor/mmap
|
||||
tests/regression/apparmor/mount
|
||||
tests/regression/apparmor/named_pipe
|
||||
tests/regression/apparmor/net_raw
|
||||
tests/regression/apparmor/open
|
||||
tests/regression/apparmor/openat
|
||||
tests/regression/apparmor/pipe
|
||||
tests/regression/apparmor/ptrace
|
||||
tests/regression/apparmor/ptrace_helper
|
||||
tests/regression/apparmor/pwrite
|
||||
tests/regression/apparmor/readdir
|
||||
tests/regression/apparmor/rename
|
||||
tests/regression/apparmor/rw
|
||||
tests/regression/apparmor/swap
|
||||
tests/regression/apparmor/symlink
|
||||
tests/regression/apparmor/syscall_chroot
|
||||
tests/regression/apparmor/syscall_mknod
|
||||
tests/regression/apparmor/syscall_mlockall
|
||||
tests/regression/apparmor/syscall_ptrace
|
||||
tests/regression/apparmor/syscall_reboot
|
||||
tests/regression/apparmor/syscall_setdomainname
|
||||
tests/regression/apparmor/syscall_sethostname
|
||||
tests/regression/apparmor/syscall_setpriority
|
||||
tests/regression/apparmor/syscall_setscheduler
|
||||
tests/regression/apparmor/syscall_sysctl
|
||||
tests/regression/apparmor/sysctl_proc
|
||||
tests/regression/apparmor/tcp
|
||||
tests/regression/apparmor/unix_fd_client
|
||||
tests/regression/apparmor/unix_fd_server
|
||||
tests/regression/apparmor/unlink
|
||||
tests/regression/apparmor/xattrs
|
||||
tests/regression/apparmor/coredump
|
||||
**/__pycache__/
|
||||
*.orig
|
94
Makefile
94
Makefile
@@ -1,88 +1,38 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
.PHONY: all
|
||||
all:
|
||||
@echo "*** See README for information how to build AppArmor ***"
|
||||
exit 1
|
||||
OVERRIDE_TARBALL=yes
|
||||
|
||||
COMMONDIR=common
|
||||
include ${COMMONDIR}/Make.rules
|
||||
include common/Make.rules
|
||||
|
||||
DIRS=libraries/libapparmor \
|
||||
binutils \
|
||||
parser \
|
||||
DIRS=parser \
|
||||
profiles \
|
||||
utils \
|
||||
changehat/libapparmor \
|
||||
changehat/mod_apparmor \
|
||||
changehat/pam_apparmor \
|
||||
profiles \
|
||||
management/apparmor-dbus \
|
||||
management/applets/apparmorapplet-gnome \
|
||||
management/yastui \
|
||||
common \
|
||||
tests
|
||||
|
||||
#REPO_URL?=lp:apparmor
|
||||
# --per-file-timestamps is failing over SSH, https://bugs.launchpad.net/bzr/+bug/1257078
|
||||
REPO_URL?=https://code.launchpad.net/~apparmor-dev/apparmor/master
|
||||
# alternate possibilities to export from
|
||||
#REPO_URL=.
|
||||
#REPO_URL="bzr+ssh://bazaar.launchpad.net/~sbeattie/+junk/apparmor-dev/"
|
||||
|
||||
COVERITY_DIR=cov-int
|
||||
RELEASE_DIR=apparmor-${VERSION}
|
||||
__SETUP_DIR?=.
|
||||
|
||||
# We create a separate version for tags because git can't handle tags
|
||||
# with embedded ~s in them. No spaces around '-' or they'll get
|
||||
# embedded in ${VERSION}
|
||||
TAG_VERSION=$(subst ~,-,${VERSION})
|
||||
|
||||
# Add exclusion entries arguments for tar here, of the form:
|
||||
# --exclude dir_to_exclude --exclude other_dir
|
||||
TAR_EXCLUSIONS=
|
||||
RELEASE_DIR=apparmor-${VERSION}-${REPO_VERSION}
|
||||
|
||||
.PHONY: tarball
|
||||
tarball: clean
|
||||
REPO_VERSION=`$(value REPO_VERSION_CMD)` && \
|
||||
make export_dir __EXPORT_DIR=${RELEASE_DIR} __REPO_VERSION=$${REPO_VERSION} && \
|
||||
make setup __SETUP_DIR=${RELEASE_DIR} && \
|
||||
tar ${TAR_EXCLUSIONS} -cvzf ${RELEASE_DIR}.tar.gz ${RELEASE_DIR}
|
||||
tarball: _dist
|
||||
tar cvzf ${RELEASE_DIR}.tar.gz ${RELEASE_DIR}
|
||||
|
||||
.PHONY: snapshot
|
||||
snapshot: clean
|
||||
$(eval REPO_VERSION:=$(shell $(value REPO_VERSION_CMD)))
|
||||
$(eval SNAPSHOT_NAME=apparmor-$(VERSION)~$(REPO_VERSION))
|
||||
make export_dir __EXPORT_DIR=${SNAPSHOT_NAME} __REPO_VERSION=${REPO_VERSION} && \
|
||||
make setup __SETUP_DIR=${SNAPSHOT_NAME} && \
|
||||
tar ${TAR_EXCLUSIONS} -cvzf ${SNAPSHOT_NAME}.tar.gz ${SNAPSHOT_NAME}
|
||||
${RELEASE_DIR}:
|
||||
mkdir ${RELEASE_DIR}
|
||||
|
||||
.PHONY: coverity
|
||||
coverity: snapshot
|
||||
cd $(SNAPSHOT_NAME)/libraries/libapparmor && ./configure --with-python
|
||||
$(foreach dir, $(filter-out utils profiles tests, $(DIRS)), \
|
||||
cov-build --dir $(COVERITY_DIR) -- make -C $(SNAPSHOT_NAME)/$(dir);)
|
||||
tar -cvzf $(SNAPSHOT_NAME)-$(COVERITY_DIR).tar.gz $(COVERITY_DIR)
|
||||
.PHONY: _dist
|
||||
.PHONY: ${DIRS}
|
||||
|
||||
.PHONY: export_dir
|
||||
export_dir:
|
||||
mkdir $(__EXPORT_DIR)
|
||||
/usr/bin/bzr export --per-file-timestamps -r $(__REPO_VERSION) $(__EXPORT_DIR) $(REPO_URL)
|
||||
echo "$(REPO_URL) $(__REPO_VERSION)" > $(__EXPORT_DIR)/common/.stamp_rev
|
||||
_dist: clean ${DIRS}
|
||||
|
||||
${DIRS}: ${RELEASE_DIR}
|
||||
svn export -r $(REPO_VERSION) $(REPO_URL)/$@ $(RELEASE_DIR)/$@ ; \
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -rf ${RELEASE_DIR} ./apparmor-${VERSION}~* ${COVERITY_DIR}
|
||||
for dir in $(DIRS); do \
|
||||
make -C $$dir clean; \
|
||||
done
|
||||
|
||||
.PHONY: setup
|
||||
setup:
|
||||
cd $(__SETUP_DIR)/libraries/libapparmor && ./autogen.sh
|
||||
# parser has an extra doc to build
|
||||
make -C $(__SETUP_DIR)/parser extra_docs
|
||||
# libraries/libapparmor needs configure to have run before
|
||||
# building docs
|
||||
$(foreach dir, $(filter-out libraries/libapparmor tests, $(DIRS)), \
|
||||
make -C $(__SETUP_DIR)/$(dir) docs;)
|
||||
|
||||
.PHONY: tag
|
||||
tag:
|
||||
bzr tag apparmor_${TAG_VERSION}
|
||||
|
||||
-rm -rf ${RELEASE_DIR}
|
||||
|
241
README
241
README
@@ -1,241 +0,0 @@
|
||||
------------
|
||||
Introduction
|
||||
------------
|
||||
AppArmor protects systems from insecure or untrusted processes by
|
||||
running them in restricted confinement, while still allowing processes
|
||||
to share files, exercise privilege and communicate with other processes.
|
||||
AppArmor is a Mandatory Access Control (MAC) mechanism which uses the
|
||||
Linux Security Module (LSM) framework. The confinement's restrictions
|
||||
are mandatory and are not bound to identity, group membership, or object
|
||||
ownership. The protections provided are in addition to the kernel's
|
||||
regular access control mechanisms (including DAC) and can be used to
|
||||
restrict the superuser.
|
||||
|
||||
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)
|
||||
and change_profile(2) to be used by non-GPL binaries).
|
||||
|
||||
For more information, you can read the techdoc.pdf (available after
|
||||
building the parser) and by visiting the http://apparmor.net/ web
|
||||
site.
|
||||
|
||||
|
||||
-------------
|
||||
Source Layout
|
||||
-------------
|
||||
|
||||
AppArmor consists of several different parts:
|
||||
|
||||
binutils/ source for basic utilities written in compiled languages
|
||||
changehat/ source for using changehat with Apache, PAM and Tomcat
|
||||
common/ common makefile rules
|
||||
desktop/ empty
|
||||
kernel-patches/ compatibility patches for various kernel versions
|
||||
libraries/ libapparmor source and language bindings
|
||||
parser/ source for parser/loader and corresponding documentation
|
||||
profiles/ configuration files, reference profiles and abstractions
|
||||
tests/ regression and stress testsuites
|
||||
utils/ high-level utilities for working with AppArmor
|
||||
|
||||
--------------------------------------
|
||||
Important note on AppArmor kernel code
|
||||
--------------------------------------
|
||||
|
||||
While most of the kernel AppArmor code has been accepted in the
|
||||
upstream Linux kernel, a few important pieces were not included. These
|
||||
missing pieces unfortunately are important bits for AppArmor userspace
|
||||
and kernel interaction; therefore we have included compatibility
|
||||
patches in the kernel-patches/ subdirectory, versioned by upstream
|
||||
kernel (2.6.37 patches should apply cleanly to 2.6.38 source).
|
||||
|
||||
Without these patches applied to the kernel, the AppArmor userspace
|
||||
will not function correctly.
|
||||
|
||||
------------------------------------------
|
||||
Building and Installing AppArmor Userspace
|
||||
------------------------------------------
|
||||
|
||||
To build and install AppArmor userspace on your system, build and install in
|
||||
the following order.
|
||||
|
||||
|
||||
libapparmor:
|
||||
$ cd ./libraries/libapparmor
|
||||
$ sh ./autogen.sh
|
||||
$ sh ./configure --prefix=/usr --with-perl --with-python # see below
|
||||
$ make
|
||||
$ make check
|
||||
$ make install
|
||||
|
||||
[an additional optional argument to libapparmor's configure is --with-ruby, to
|
||||
generate Ruby bindings to libapparmor.]
|
||||
|
||||
|
||||
Binary Utilities:
|
||||
$ cd binutils
|
||||
$ make
|
||||
$ make check
|
||||
$ make install
|
||||
|
||||
|
||||
Utilities:
|
||||
$ cd utils
|
||||
$ make
|
||||
$ make check
|
||||
$ make install
|
||||
|
||||
|
||||
parser:
|
||||
$ cd parser
|
||||
$ make # depends on libapparmor having been built first
|
||||
$ make check
|
||||
$ make install
|
||||
|
||||
|
||||
Apache mod_apparmor:
|
||||
$ cd changehat/mod_apparmor
|
||||
$ make # depends on libapparmor having been built first
|
||||
$ make install
|
||||
|
||||
|
||||
PAM AppArmor:
|
||||
$ cd changehat/pam_apparmor
|
||||
$ make # depends on libapparmor having been built first
|
||||
$ make install
|
||||
|
||||
|
||||
Profiles:
|
||||
$ cd profiles
|
||||
$ make
|
||||
$ make check # depends on the parser having been built first
|
||||
$ make install
|
||||
|
||||
|
||||
[Note that for the parser, binutils, and utils, if you only wish to build/use
|
||||
some of the locale languages, you can override the default by passing
|
||||
the LANGS arguments to make; e.g. make all install "LANGS=en_US fr".]
|
||||
|
||||
-------------------
|
||||
AppArmor Testsuites
|
||||
-------------------
|
||||
|
||||
A number of testsuites are in the AppArmor sources. Most have documentation on
|
||||
usage and how to update and add tests. Below is a quick overview of their
|
||||
location and how to run them.
|
||||
|
||||
|
||||
Regression tests
|
||||
----------------
|
||||
For details on structure and adding tests, see
|
||||
tests/regression/apparmor/README.
|
||||
|
||||
To run:
|
||||
$ cd tests/regression/apparmor (requires root)
|
||||
$ make
|
||||
$ sudo make tests
|
||||
$ sudo bash open.sh -r # runs and saves the last testcase from open.sh
|
||||
|
||||
|
||||
Parser tests
|
||||
------------
|
||||
For details on structure and adding tests, see parser/tst/README.
|
||||
|
||||
To run:
|
||||
$ cd parser/tst
|
||||
$ make
|
||||
$ make tests
|
||||
|
||||
|
||||
Libapparmor
|
||||
-----------
|
||||
For details on structure and adding tests, see libraries/libapparmor/README.
|
||||
$ cd libraries/libapparmor
|
||||
$ make check
|
||||
|
||||
Utils
|
||||
-----
|
||||
Tests for the Python utilities exist in the test/ subdirectory.
|
||||
$ cd utils
|
||||
$ make check
|
||||
|
||||
The aa-decode utility to be tested can be overridden by
|
||||
setting up environment variable APPARMOR_DECODE; e.g.:
|
||||
|
||||
$ APPARMOR_DECODE=/usr/bin/aa-decode make check
|
||||
|
||||
Profile checks
|
||||
--------------
|
||||
A basic consistency check to ensure that the parser and aa-logprof parse
|
||||
successfully the current set of shipped profiles. The system or other
|
||||
parser and logprof can be passed in by overriding the PARSER and LOGPROF
|
||||
variables.
|
||||
$ cd profiles
|
||||
$ make && make check
|
||||
|
||||
Stress Tests
|
||||
------------
|
||||
To run AppArmor stress tests:
|
||||
$ make all
|
||||
|
||||
Use these:
|
||||
$ ./change_hat
|
||||
$ ./child
|
||||
$ ./kill.sh
|
||||
$ ./open
|
||||
$ ./s.sh
|
||||
|
||||
Or run all at once:
|
||||
$ ./stress.sh
|
||||
|
||||
Please note that the above will stress the system so much it may end up
|
||||
invoking the OOM killer.
|
||||
|
||||
To run parser stress tests (requires /usr/bin/ruby):
|
||||
$ ./stress.sh
|
||||
|
||||
(see stress.sh -h for options)
|
||||
|
||||
Coverity Support
|
||||
----------------
|
||||
Coverity scans are available to AppArmor developers at
|
||||
https://scan.coverity.com/projects/apparmor.
|
||||
|
||||
In order to submit a Coverity build for analysis, the cov-build binary
|
||||
must be discoverable from your PATH. See the "To Setup" section of
|
||||
https://scan.coverity.com/download?tab=cxx to obtain a pre-built copy of
|
||||
cov-build.
|
||||
|
||||
To generate a compressed tarball of an intermediate Coverity directory:
|
||||
$ make coverity
|
||||
|
||||
The compressed tarball is written to
|
||||
apparmor-<SNAPSHOT_VERSION>-cov-int.tar.gz, where <SNAPSHOT_VERSION>
|
||||
is something like 2.10.90~3328, and must be uploaded to
|
||||
https://scan.coverity.com/projects/apparmor/builds/new for analysis. You must
|
||||
include the snapshot version in Coverity's project build submission form, in
|
||||
the "Project Version" field, so that it is quickly obvious to all AppArmor
|
||||
developers what snapshot of the AppArmor repository was used for the analysis.
|
||||
|
||||
-----------------------------------------------
|
||||
Building and Installing AppArmor Kernel Patches
|
||||
-----------------------------------------------
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
-----------------
|
||||
Required versions
|
||||
-----------------
|
||||
|
||||
The AppArmor userspace utilities are written with some assumptions about
|
||||
installed and available versions of other tools. This is a (possibly
|
||||
incomplete) list of known version dependencies:
|
||||
|
||||
The Python utilities require a minimum of Python 2.7 (deprecated) or Python 3.3.
|
||||
Python 3.x is recommended. Python 2.x support is deprecated since AppArmor 2.11.
|
||||
|
||||
Some utilities (aa-exec, aa-notify and aa-decode) require Perl 5.10.1 or newer.
|
||||
|
||||
Most shell scripts are written for POSIX-compatible sh. aa-decode expects
|
||||
bash, probably version 3.2 and higher.
|
@@ -1,157 +0,0 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2015
|
||||
# Canonical Ltd. (All rights reserved)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# ----------------------------------------------------------------------
|
||||
NAME=aa-binutils
|
||||
all:
|
||||
COMMONDIR=../common/
|
||||
|
||||
include $(COMMONDIR)/Make.rules
|
||||
|
||||
DESTDIR=/
|
||||
BINDIR=${DESTDIR}/usr/bin
|
||||
LOCALEDIR=/usr/share/locale
|
||||
MANPAGES=aa-enabled.1 aa-exec.1
|
||||
|
||||
WARNINGS = -Wall
|
||||
EXTRA_WARNINGS = -Wsign-compare -Wmissing-field-initializers -Wformat-security -Wunused-parameter
|
||||
CPP_WARNINGS =
|
||||
ifndef CFLAGS
|
||||
CFLAGS = -g -O2 -pipe
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += -pg -D DEBUG
|
||||
endif
|
||||
ifdef COVERAGE
|
||||
CFLAGS = -g -pg -fprofile-arcs -ftest-coverage
|
||||
endif
|
||||
endif #CFLAGS
|
||||
|
||||
EXTRA_CFLAGS = ${CFLAGS} ${CPPFLAGS} ${EXTRA_CXXFLAGS} ${CPP_WARNINGS}
|
||||
|
||||
#INCLUDEDIR = /usr/src/linux/include
|
||||
INCLUDEDIR =
|
||||
|
||||
ifdef INCLUDEDIR
|
||||
CFLAGS += -I$(INCLUDEDIR)
|
||||
endif
|
||||
|
||||
# Internationalization support. Define a package and a LOCALEDIR
|
||||
EXTRA_CFLAGS+=-DPACKAGE=\"${NAME}\" -DLOCALEDIR=\"${LOCALEDIR}\"
|
||||
|
||||
SRCS = aa_enabled.c
|
||||
HDRS =
|
||||
TOOLS = aa-enabled aa-exec
|
||||
|
||||
AALIB = -Wl,-Bstatic -lapparmor -Wl,-Bdynamic -lpthread
|
||||
|
||||
ifdef USE_SYSTEM
|
||||
# Using the system libapparmor so Makefile dependencies can't be used
|
||||
LIBAPPARMOR_A =
|
||||
INCLUDE_APPARMOR =
|
||||
APPARMOR_H =
|
||||
LIBAPPARMOR_LDFLAGS =
|
||||
else
|
||||
LIBAPPARMOR_SRC = ../libraries/libapparmor/
|
||||
LOCAL_LIBAPPARMOR_INCLUDE = $(LIBAPPARMOR_SRC)/include
|
||||
LOCAL_LIBAPPARMOR_LDPATH = $(LIBAPPARMOR_SRC)/src/.libs
|
||||
|
||||
LIBAPPARMOR_A = $(LOCAL_LIBAPPARMOR_LDPATH)/libapparmor.a
|
||||
INCLUDE_APPARMOR = -I$(LOCAL_LIBAPPARMOR_INCLUDE)
|
||||
APPARMOR_H = $(LOCAL_LIBAPPARMOR_INCLUDE)/sys/apparmor.h
|
||||
LIBAPPARMOR_LDFLAGS = -L$(LOCAL_LIBAPPARMOR_LDPATH)
|
||||
endif
|
||||
EXTRA_CFLAGS += $(INCLUDE_APPARMOR)
|
||||
LDFLAGS += $(LIBAPPARMOR_LDFLAGS)
|
||||
|
||||
ifdef V
|
||||
VERBOSE = 1
|
||||
endif
|
||||
ifndef VERBOSE
|
||||
VERBOSE = 0
|
||||
endif
|
||||
ifeq ($(VERBOSE),1)
|
||||
BUILD_OUTPUT =
|
||||
Q =
|
||||
else
|
||||
BUILD_OUTPUT = > /dev/null 2>&1
|
||||
Q = @
|
||||
endif
|
||||
export Q VERBOSE BUILD_OUTPUT
|
||||
|
||||
po/%.pot: %.c
|
||||
$(MAKE) -C po $(@F) NAME=$* SOURCES=$*.c
|
||||
|
||||
# targets arranged this way so that people who don't want full docs can
|
||||
# pick specific targets they want.
|
||||
arch: $(TOOLS)
|
||||
|
||||
manpages: $(MANPAGES)
|
||||
|
||||
docs: manpages
|
||||
|
||||
indep: docs
|
||||
$(Q)$(MAKE) -C po all
|
||||
|
||||
all: arch indep
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
$(MAKE) clean $(TOOLS) COVERAGE=1
|
||||
|
||||
ifndef USE_SYSTEM
|
||||
$(LIBAPPARMOR_A):
|
||||
@if [ ! -f $@ ]; then \
|
||||
echo "error: $@ is missing. Pick one of these possible solutions:" 1>&2; \
|
||||
echo " 1) Build against the in-tree libapparmor by building it first and then trying again. See the top-level README for help." 1>&2; \
|
||||
echo " 2) Build against the system libapparmor by adding USE_SYSTEM=1 to your make command." 1>&2;\
|
||||
return 1; \
|
||||
fi
|
||||
endif
|
||||
|
||||
aa-enabled: aa_enabled.c $(LIBAPPARMOR_A)
|
||||
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
|
||||
|
||||
aa-exec: aa_exec.c $(LIBAPPARMOR_A)
|
||||
$(CC) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $< $(LIBS) $(AALIB)
|
||||
|
||||
.SILENT: check
|
||||
.PHONY: check
|
||||
check: check_pod_files tests
|
||||
|
||||
.SILENT: tests
|
||||
tests: $(TOOLS) $(TESTS)
|
||||
echo "no tests atm"
|
||||
|
||||
.PHONY: install
|
||||
install: install-indep install-arch
|
||||
|
||||
.PHONY: install-arch
|
||||
install-arch: arch
|
||||
install -m 755 -d ${BINDIR}
|
||||
install -m 755 ${TOOLS} ${BINDIR}
|
||||
|
||||
.PHONY: install-indep
|
||||
install-indep: indep
|
||||
$(MAKE) -C po install NAME=${NAME} DESTDIR=${DESTDIR}
|
||||
$(MAKE) install_manpages DESTDIR=${DESTDIR}
|
||||
|
||||
ifndef VERBOSE
|
||||
.SILENT: clean
|
||||
endif
|
||||
.PHONY: clean
|
||||
clean: pod_clean
|
||||
rm -f core core.* *.o *.s *.a *~ *.gcda *.gcno
|
||||
rm -f gmon.out
|
||||
rm -f $(TOOLS) $(TESTS)
|
||||
$(MAKE) -s -C po clean
|
||||
|
@@ -1,94 +0,0 @@
|
||||
# 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-enabled - test whether AppArmor is enabled
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<aa-enabled> [options]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<aa-enabled> is used to determine if AppArmor is enabled.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
B<aa-enabled> accepts the following arguments:
|
||||
|
||||
=over 4
|
||||
|
||||
=item -h, --help
|
||||
|
||||
Display a brief usage guide.
|
||||
|
||||
=item -q, --quiet
|
||||
|
||||
Do not output anything to stdout. This option is intended to be used by
|
||||
scripts that simply want to use the exit code to determine if AppArmor is
|
||||
enabled.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
||||
Upon exiting, B<aa-enabled> will set its exit status to the following values:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<0>
|
||||
|
||||
if AppArmor is enabled.
|
||||
|
||||
=item B<1>
|
||||
|
||||
if AppArmor is not enabled/loaded.
|
||||
|
||||
=item B<2>
|
||||
|
||||
intentionally not used as an B<aa-enabled> exit status.
|
||||
|
||||
=item B<3>
|
||||
|
||||
if the AppArmor control files aren't available under /sys/kernel/security/.
|
||||
|
||||
=item B<4>
|
||||
|
||||
if B<aa-enabled> doesn't have enough privileges to read the apparmor control files.
|
||||
|
||||
=item B<64>
|
||||
|
||||
if any unexpected error or condition is encountered.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
If you find any bugs, please report them at
|
||||
L<https://bugs.launchpad.net/apparmor/+filebug>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), apparmor.d(5), aa_is_enabled(2), and L<http://wiki.apparmor.net>.
|
||||
|
||||
=cut
|
@@ -1,93 +0,0 @@
|
||||
# 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<aa-exec> [options] [--] [I<E<lt>commandE<gt>> ...]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<aa-exec> 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 I<E<lt>commandE<gt>> 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<aa-exec> accepts the following arguments:
|
||||
|
||||
=over 4
|
||||
|
||||
=item -p PROFILE, --profile=PROFILE
|
||||
|
||||
confine I<E<lt>commandE<gt>> 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 -i, --immediate
|
||||
|
||||
transition to PROFILE before doing executing I<E<lt>commandE<gt>>. This
|
||||
subjects the running of I<E<lt>commandE<gt>> 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 I<E<lt>commandE<gt>> being invoked by
|
||||
aa-exec.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
If you find any bugs, please report them at
|
||||
L<https://bugs.launchpad.net/apparmor/+filebug>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
aa-stack(8), aa-namespace(8), apparmor(7), apparmor.d(5), aa_change_profile(3),
|
||||
aa_change_onexec(3) and L<http://wiki.apparmor.net>.
|
||||
|
||||
=cut
|
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <libintl.h>
|
||||
#define _(s) gettext(s)
|
||||
|
||||
#include <sys/apparmor.h>
|
||||
|
||||
void print_help(const char *command)
|
||||
{
|
||||
printf(_("%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"),
|
||||
command);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* Exit statuses and meanings are documented in the aa-enabled.pod file */
|
||||
static void exit_with_error(int saved_errno, int quiet)
|
||||
{
|
||||
int err;
|
||||
|
||||
switch(saved_errno) {
|
||||
case ENOSYS:
|
||||
if (!quiet)
|
||||
printf(_("No - not available on this system.\n"));
|
||||
exit(1);
|
||||
case ECANCELED:
|
||||
if (!quiet)
|
||||
printf(_("No - disabled at boot.\n"));
|
||||
exit(1);
|
||||
case ENOENT:
|
||||
if (!quiet)
|
||||
printf(_("Maybe - policy interface not available.\n"));
|
||||
exit(3);
|
||||
case EPERM:
|
||||
case EACCES:
|
||||
if (!quiet)
|
||||
printf(_("Maybe - insufficient permissions to determine availability.\n"));
|
||||
exit(4);
|
||||
}
|
||||
|
||||
if (!quiet)
|
||||
printf(_("Error - %s\n"), strerror(saved_errno));
|
||||
exit(64);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int enabled;
|
||||
int quiet = 0;
|
||||
|
||||
setlocale(LC_MESSAGES, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
if (argc > 2) {
|
||||
printf(_("unknown or incompatible options\n"));
|
||||
print_help(argv[0]);
|
||||
} else if (argc == 2) {
|
||||
if (strcmp(argv[1], "--quiet") == 0 ||
|
||||
strcmp(argv[1], "-q") == 0) {
|
||||
quiet = 1;
|
||||
} else if (strcmp(argv[1], "--help") == 0 ||
|
||||
strcmp(argv[1], "-h") == 0) {
|
||||
print_help(argv[0]);
|
||||
} else {
|
||||
printf(_("unknown option '%s'\n"), argv[1]);
|
||||
print_help(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
enabled = aa_is_enabled();
|
||||
if (!enabled)
|
||||
exit_with_error(errno, quiet);
|
||||
|
||||
if (!quiet)
|
||||
printf(_("Yes\n"));
|
||||
exit(0);
|
||||
}
|
@@ -1,218 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015
|
||||
* Canonical, Ltd. (All rights reserved)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc. or Canonical
|
||||
* Ltd.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <libintl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/apparmor.h>
|
||||
#include <unistd.h>
|
||||
#define _(s) gettext(s)
|
||||
|
||||
static const char *opt_profile = NULL;
|
||||
static const char *opt_namespace = NULL;
|
||||
static bool opt_debug = false;
|
||||
static bool opt_immediate = false;
|
||||
static bool opt_verbose = false;
|
||||
|
||||
static void usage(const char *name, bool error)
|
||||
{
|
||||
FILE *stream = stdout;
|
||||
int status = EXIT_SUCCESS;
|
||||
|
||||
if (error) {
|
||||
stream = stderr;
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
fprintf(stream,
|
||||
_("USAGE: %s [OPTIONS] <prog> <args>\n"
|
||||
"\n"
|
||||
"Confine <prog> with the specified PROFILE.\n"
|
||||
"\n"
|
||||
"OPTIONS:\n"
|
||||
" -p PROFILE, --profile=PROFILE PROFILE to confine <prog> with\n"
|
||||
" -n NAMESPACE, --namespace=NAMESPACE NAMESPACE to confine <prog> in\n"
|
||||
" -d, --debug show messages with debugging information\n"
|
||||
" -i, --immediate change profile immediately instead of at exec\n"
|
||||
" -v, --verbose show messages with stats\n"
|
||||
" -h, --help display this help\n"
|
||||
"\n"), name);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
#define error(fmt, args...) _error(_("aa-exec: ERROR: " fmt "\n"), ## args)
|
||||
static void _error(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#define debug(fmt, args...) _debug(_("aa-exec: DEBUG: " fmt "\n"), ## args)
|
||||
static void _debug(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!opt_debug)
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#define verbose(fmt, args...) _verbose(_(fmt "\n"), ## args)
|
||||
static void _verbose(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!opt_verbose)
|
||||
return;
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void verbose_print_argv(char **argv)
|
||||
{
|
||||
if (!opt_verbose)
|
||||
return;
|
||||
|
||||
fprintf(stderr, _("exec"));
|
||||
for (; *argv; argv++)
|
||||
fprintf(stderr, " %s", *argv);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static char **parse_args(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
struct option long_opts[] = {
|
||||
{"debug", no_argument, 0, 'd'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"profile", required_argument, 0, 'p'},
|
||||
{"namespace", required_argument, 0, 'n'},
|
||||
{"immediate", no_argument, 0, 'i'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
};
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "+dhp:n:iv", long_opts, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
opt_debug = true;
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0], false);
|
||||
break;
|
||||
case 'p':
|
||||
opt_profile = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
opt_namespace = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
opt_immediate = true;
|
||||
break;
|
||||
case 'v':
|
||||
opt_verbose = true;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0], true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
usage(argv[0], true);
|
||||
|
||||
return argv + optind;
|
||||
}
|
||||
|
||||
static void build_name(char *name, size_t name_len,
|
||||
const char *namespace, const char *profile)
|
||||
{
|
||||
size_t required_len = 1; /* reserve 1 byte for NUL-terminator */
|
||||
|
||||
if (namespace)
|
||||
required_len += 1 + strlen(namespace) + 3; /* :<NAMESPACE>:// */
|
||||
|
||||
if (profile)
|
||||
required_len += strlen(profile);
|
||||
|
||||
if (required_len > name_len)
|
||||
error("name too long (%zu > %zu)", required_len, name_len);
|
||||
|
||||
name[0] = '\0';
|
||||
|
||||
if (namespace) {
|
||||
strcat(name, ":");
|
||||
strcat(name, namespace);
|
||||
strcat(name, "://");
|
||||
}
|
||||
|
||||
if (profile)
|
||||
strcat(name, profile);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char name[PATH_MAX];
|
||||
int rc = 0;
|
||||
|
||||
argv = parse_args(argc, argv);
|
||||
|
||||
if (opt_namespace || opt_profile)
|
||||
build_name(name, sizeof(name), opt_namespace, opt_profile);
|
||||
else
|
||||
goto exec;
|
||||
|
||||
if (opt_immediate) {
|
||||
verbose("aa_change_profile(\"%s\")", name);
|
||||
rc = aa_change_profile(name);
|
||||
debug("%d = aa_change_profile(\"%s\")", rc, name);
|
||||
} else {
|
||||
verbose("aa_change_onexec(\"%s\")", name);
|
||||
rc = aa_change_onexec(name);
|
||||
debug("%d = aa_change_onexec(\"%s\")", rc, name);
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
if (errno == ENOENT || errno == EACCES) {
|
||||
error("%s '%s' does not exist\n",
|
||||
opt_profile ? "profile" : "namespace", name);
|
||||
} else if (errno == EINVAL) {
|
||||
error("AppArmor interface not available");
|
||||
} else {
|
||||
error("%m");
|
||||
}
|
||||
}
|
||||
|
||||
exec:
|
||||
verbose_print_argv(argv);
|
||||
execvp(argv[0], argv);
|
||||
error("Failed to execute \"%s\": %m", argv[0]);
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2015 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.
|
||||
# ----------------------------------------------------------------------
|
||||
all:
|
||||
|
||||
# As translations get added, they will automatically be included, unless
|
||||
# the lang is explicitly added to DISABLED_LANGS; e.g. DISABLED_LANGS=en es
|
||||
|
||||
DISABLED_LANGS=
|
||||
|
||||
COMMONDIR=../../common
|
||||
include $(COMMONDIR)/Make-po.rules
|
||||
|
||||
XGETTEXT_ARGS+=--language=C --keyword=_ $(shell if [ -f ${NAME}.pot ] ; then echo -n -j ; fi)
|
||||
|
@@ -1,66 +0,0 @@
|
||||
# Copyright (C) 2015 Canonical Ltd
|
||||
# This file is distributed under the same license as the AppArmor package.
|
||||
# John Johansen <john.johansen@canonical.com>, 2015.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: apparmor@lists.ubuntu.com\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr ""
|
@@ -1,68 +0,0 @@
|
||||
# German translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2017-03-31 10:44+0000\n"
|
||||
"Last-Translator: Tobias Bannert <tobannert@gmail.com>\n"
|
||||
"Language-Team: German <de@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2017-04-05 05:23+0000\n"
|
||||
"X-Generator: Launchpad (build 18335)\n"
|
||||
"Language: de\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "unbekannte oder nicht kompatible Optionen\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "unbekannte Option »%s«\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Ja\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Nein – auf diesem System nicht verfügbar.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Nein – beim Start deaktiviert.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Fehler - »%s«\n"
|
@@ -1,72 +0,0 @@
|
||||
# English (United Kingdom) translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2016-02-18 06:22+0000\n"
|
||||
"Last-Translator: Andi Chandler <Unknown>\n"
|
||||
"Language-Team: English (United Kingdom) <en_GB@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 18053)\n"
|
||||
"Language: en_GB\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "unknown or incompatible options\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "unknown option '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Yes\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "No - not available on this system.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "No - disabled at boot.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Maybe - policy interface not available.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr "Maybe - insufficient permissions to determine availability.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Error - '%s'\n"
|
@@ -1,72 +0,0 @@
|
||||
# Indonesian translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2016-01-20 08:59+0000\n"
|
||||
"Last-Translator: Ari Setyo Wibowo <mr.a.contact@gmail.com>\n"
|
||||
"Language-Team: Indonesian <id@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 18053)\n"
|
||||
"Language: id\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [options]\n"
|
||||
" pilihan:\n"
|
||||
" -q | --quiet Jangan tampilkan pesan apapun\n"
|
||||
" -h | --help Tampilkan bantuan\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "pilihan yang tidak dikenali atau tidak kompatibel\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "pilihan tidak dikenali '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Ya\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Tidak - tidak tersedia di sistem ini.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Tidak - nonaktifkan saat boot.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Mungkin - kebijakan antarmuka tidak tersedia.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr "Mungkin - izin tidak memadai untuk menentukan ketersediaan.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Kesalahan - '%s'\n"
|
@@ -1,72 +0,0 @@
|
||||
# Portuguese translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2016-03-03 08:34+0000\n"
|
||||
"Last-Translator: Ivo Xavier <ivoxavier.8@gmail.com>\n"
|
||||
"Language-Team: Portuguese <pt@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 18053)\n"
|
||||
"Language: pt\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [opções]\n"
|
||||
" opções:\n"
|
||||
" -q | --silencioso Não mostrar mensagens\n"
|
||||
" -h | --ajuda Mostar ajuda\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "opções desconhecidas ou incompatíveis\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "opção desconhecida '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Sim\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Não - não disponível neste sistema.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Não - desligado ao iniciar.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Talvez - política de interface não disponível.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr "Talvez - permissões insuficientes para determinar disponibilidade.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Erro - '%s'\n"
|
@@ -1,72 +0,0 @@
|
||||
# Russian translation for apparmor
|
||||
# Copyright (c) 2016 Rosetta Contributors and Canonical Ltd 2016
|
||||
# This file is distributed under the same license as the apparmor package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: apparmor\n"
|
||||
"Report-Msgid-Bugs-To: AppArmor list <apparmor@lists.ubuntu.com>\n"
|
||||
"POT-Creation-Date: 2015-11-28 10:23-0800\n"
|
||||
"PO-Revision-Date: 2016-03-29 14:46+0000\n"
|
||||
"Last-Translator: Eugene Marshal <Unknown>\n"
|
||||
"Language-Team: Russian <ru@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2016-06-01 05:15+0000\n"
|
||||
"X-Generator: Launchpad (build 18053)\n"
|
||||
"Language: ru\n"
|
||||
|
||||
#: ../aa_enabled.c:26
|
||||
#, c-format
|
||||
msgid ""
|
||||
"%s: [options]\n"
|
||||
" options:\n"
|
||||
" -q | --quiet Don't print out any messages\n"
|
||||
" -h | --help Print help\n"
|
||||
msgstr ""
|
||||
"%s: [параметры]\n"
|
||||
" параметры:\n"
|
||||
" -q | --quiet не выводить никакие сообщения\n"
|
||||
" -h | --help вывести справку\n"
|
||||
|
||||
#: ../aa_enabled.c:45
|
||||
#, c-format
|
||||
msgid "unknown or incompatible options\n"
|
||||
msgstr "неизвестные или несовместимые параметры\n"
|
||||
|
||||
#: ../aa_enabled.c:55
|
||||
#, c-format
|
||||
msgid "unknown option '%s'\n"
|
||||
msgstr "неизвестный параметр '%s'\n"
|
||||
|
||||
#: ../aa_enabled.c:64
|
||||
#, c-format
|
||||
msgid "Yes\n"
|
||||
msgstr "Да\n"
|
||||
|
||||
#: ../aa_enabled.c:71
|
||||
#, c-format
|
||||
msgid "No - not available on this system.\n"
|
||||
msgstr "Нет - недоступно на этой системе.\n"
|
||||
|
||||
#: ../aa_enabled.c:74
|
||||
#, c-format
|
||||
msgid "No - disabled at boot.\n"
|
||||
msgstr "Нет - выключено при загрузке.\n"
|
||||
|
||||
#: ../aa_enabled.c:77
|
||||
#, c-format
|
||||
msgid "Maybe - policy interface not available.\n"
|
||||
msgstr "Возможно - интерфейс политики недоступен.\n"
|
||||
|
||||
#: ../aa_enabled.c:81
|
||||
#, c-format
|
||||
msgid "Maybe - insufficient permissions to determine availability.\n"
|
||||
msgstr "Возможно - недостаточно разрешений для определения доступности.\n"
|
||||
|
||||
#: ../aa_enabled.c:84
|
||||
#, c-format
|
||||
msgid "Error - '%s'\n"
|
||||
msgstr "Ошибка - '%s'\n"
|
@@ -1,6 +1,6 @@
|
||||
# $Id$
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
|
||||
# Copyright (c) 2016 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
|
||||
@@ -18,7 +18,13 @@ NAME:=apache2-mod_apparmor
|
||||
all:
|
||||
COMMONDIR=../../common/
|
||||
|
||||
include $(COMMONDIR)/Make.rules
|
||||
include common/Make.rules
|
||||
|
||||
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
|
||||
ifeq ($(COMMONDIR_EXISTS), true)
|
||||
common/Make.rules: $(COMMONDIR)/Make.rules
|
||||
ln -sf $(COMMONDIR) .
|
||||
endif
|
||||
|
||||
TARGET:=mod_apparmor.so
|
||||
MANPAGES=mod_apparmor.8
|
||||
@@ -36,51 +42,16 @@ APXS:=$(shell if [ -x "/usr/sbin/apxs2" ] ; then \
|
||||
fi )
|
||||
APXS_INSTALL_DIR=$(shell ${APXS} -q LIBEXECDIR)
|
||||
DESTDIR=
|
||||
ifdef USE_SYSTEM
|
||||
LIBAPPARMOR = $(shell if pkg-config --exists libapparmor ; then \
|
||||
pkg-config --silence-errors --libs libapparmor ; \
|
||||
elif ldconfig -p | grep -q libapparmor\.so$$ ; then \
|
||||
echo -lapparmor ; \
|
||||
fi )
|
||||
ifeq ($(strip $(LIBAPPARMOR)),)
|
||||
ERROR_MESSAGE = $(error ${nl}\
|
||||
************************************************************************${nl}\
|
||||
Unable to find libapparmor installed on this system; either${nl}\
|
||||
install libapparmor devel packages, set the LIBAPPARMOR variable${nl}\
|
||||
manually, or build against in-tree libapparmor.${nl}\
|
||||
************************************************************************${nl})
|
||||
endif # LIBAPPARMOR not set
|
||||
LDLIBS += $(LIBAPPARMOR)
|
||||
else
|
||||
LIBAPPARMOR_SRC := ../../libraries/libapparmor/
|
||||
LIBAPPARMOR_INCLUDE = $(LIBAPPARMOR_SRC)/include
|
||||
LIBAPPARMOR_PATH := $(LIBAPPARMOR_SRC)/src/.libs/
|
||||
ifeq ($(realpath $(LIBAPPARMOR_PATH)/libapparmor.a),)
|
||||
ERROR_MESSAGE = $(error ${nl}\
|
||||
************************************************************************${nl}\
|
||||
$(LIBAPPARMOR_PATH)/libapparmor.a is missing; either build against${nl}\
|
||||
the in-tree libapparmor by building it first and then trying again${nl}\
|
||||
(see the top-level README for help) or build against the system${nl}\
|
||||
libapparmor by adding USE_SYSTEM=1 to your make command.${nl}\
|
||||
************************************************************************${nl})
|
||||
endif
|
||||
# Need to pass -Wl twice here to get past both apxs2 and libtool, as
|
||||
# libtool will add the path to the RPATH of the library if passed -L/some/path
|
||||
LIBAPPARMOR_FLAGS = -I$(LIBAPPARMOR_INCLUDE) -Wl,-Wl,-L$(LIBAPPARMOR_PATH)
|
||||
LDLIBS = -lapparmor
|
||||
endif
|
||||
LIBAPPARMOR_FLAGS=$(shell if [ -f /usr/lib/libapparmor.so -o -f /usr/lib64/libapparmor.so ] ; then \
|
||||
echo -lapparmor ; \
|
||||
else \
|
||||
echo -DUSE_COMPAT_IMMUNIX_H -limmunix ;\
|
||||
fi)
|
||||
|
||||
.PHONY: libapparmor_check
|
||||
.SILENT: libapparmor_check
|
||||
libapparmor_check: ; $(ERROR_MESSAGE)
|
||||
|
||||
all: libapparmor_check $(TARGET) docs
|
||||
|
||||
.PHONY: docs
|
||||
docs: ${MANPAGES} ${HTMLMANPAGES}
|
||||
all: $(TARGET) ${MANPAGES} ${HTMLMANPAGES}
|
||||
|
||||
%.so: %.c
|
||||
${APXS} ${LIBAPPARMOR_FLAGS} -c $< ${LDLIBS}
|
||||
${APXS} ${LIBAPPARMOR_FLAGS} -c $<
|
||||
mv .libs/$@ .
|
||||
|
||||
.PHONY: install
|
||||
@@ -90,9 +61,6 @@ install: ${TARGET} ${MANPAGES}
|
||||
make install_manpages DESTDIR=${DESTDIR}
|
||||
|
||||
.PHONY: clean
|
||||
clean: pod_clean
|
||||
clean: _clean
|
||||
rm -rf .libs
|
||||
rm -f *.la *.lo *.so *.o *.slo
|
||||
|
||||
.PHONY: check
|
||||
check: check_pod_files
|
||||
rm -f *.la *.lo *.so *.o *.slo Make.rules
|
||||
|
216
changehat/mod_apparmor/apache2-mod_apparmor.spec.in
Normal file
216
changehat/mod_apparmor/apache2-mod_apparmor.spec.in
Normal file
@@ -0,0 +1,216 @@
|
||||
# $Id$
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
# norootforbuild
|
||||
|
||||
# Check first to see if distro is already defined.
|
||||
# I hate rpm macros
|
||||
%if ! %{?distro:1}0
|
||||
%if %{?suse_version:1}0
|
||||
%define distro suse
|
||||
%endif
|
||||
%if %{?fedora_version:1}0
|
||||
%define distro redhat
|
||||
%endif
|
||||
%endif
|
||||
%if ! %{?distro:1}0
|
||||
%define distro suse
|
||||
%endif
|
||||
|
||||
# this is required to be underscore
|
||||
%define module_name mod_apparmor
|
||||
|
||||
Summary: AppArmor module for apache2.
|
||||
Name: apache2-mod_apparmor
|
||||
Version: @@immunix_version@@
|
||||
Release: @@repo_version@@
|
||||
Group: Applications/System
|
||||
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
|
||||
License: LGPL
|
||||
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
|
||||
Url: http://forge.novell.com/modules/xfmod/project/?apparmor
|
||||
Obsoletes: mod_change_hat mod-change-hat mod-apparmor apache2-mod-apparmor
|
||||
Provides: mod_change_hat mod-change-hat mod-apparmor apache2-mod-apparmor
|
||||
|
||||
%if %{distro} == "suse"
|
||||
%if 0%{?suse_version} < 1010
|
||||
BuildRequires: libimmunix
|
||||
%else
|
||||
%if 0%{?suse_version} < 1030
|
||||
BuildRequires: libapparmor
|
||||
%else
|
||||
BuildRequires: libapparmor-devel
|
||||
%endif
|
||||
%endif
|
||||
%else
|
||||
BuildRequires: libapparmor-devel
|
||||
%endif
|
||||
|
||||
%if %{distro} == "suse"
|
||||
%define apxs /usr/sbin/apxs2
|
||||
%define apache_mmn %(MMN=$(%{apxs} -q LIBEXECDIR)_MMN; test -x $MMN && $MMN)
|
||||
Prereq: apache2-prefork
|
||||
Prereq: apparmor-parser
|
||||
BuildRequires: apache2-devel
|
||||
Requires: apache2 %{apache_mmn}
|
||||
%else
|
||||
%if %{distro} == "redhat" || %{distro} == "rhel4"
|
||||
%define apxs /usr/sbin/apxs
|
||||
Prereq: httpd
|
||||
BuildRequires: httpd-devel
|
||||
%endif
|
||||
%endif
|
||||
%define module_path %(%{apxs} -q LIBEXECDIR)
|
||||
%define apache_sysconfdir %(%{apxs} -q SYSCONFDIR)
|
||||
|
||||
%description
|
||||
apache2-mod_apparmor adds support to apache2 to provide AppArmor confinement
|
||||
to individual cgi scripts handled by apache modules like mod_php and
|
||||
mod_perl.
|
||||
This package is part of a suite of tools that used to be named SubDomain.
|
||||
|
||||
%prep
|
||||
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
make APXS=%{apxs}
|
||||
|
||||
%install
|
||||
make install DESTDIR=${RPM_BUILD_ROOT} DISTRO=%{distro} MANDIR=%{_mandir}
|
||||
|
||||
%if %{distro} == "suse"
|
||||
mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/apache2-prefork/
|
||||
ln -s %{module_path}/%{module_name}.so ${RPM_BUILD_ROOT}%{_libdir}/apache2-prefork/%{module_name}.so
|
||||
%else
|
||||
%if %{distro} == "redhat" || %{distro} == "rhel4"
|
||||
mkdir -p ${RPM_BUILD_ROOT}/%{apache_sysconfdir}.d/
|
||||
install -m 644 %{module_name}.conf ${RPM_BUILD_ROOT}/%{apache_sysconfdir}.d/
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%clean
|
||||
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%{module_path}
|
||||
%if %{distro} == "suse"
|
||||
%{_libdir}/apache2-prefork/%{module_name}.so
|
||||
%else
|
||||
%if %{distro} == "redhat" || %{distro} == "rhel4"
|
||||
%{apache_sysconfdir}.d/%{module_name}.conf
|
||||
%endif
|
||||
%endif
|
||||
%doc COPYING.LGPL
|
||||
%{_mandir}/man*/*
|
||||
%doc *.[0-9].html
|
||||
%doc common/apparmor.css
|
||||
|
||||
%post
|
||||
%if %{distro} == "suse"
|
||||
/usr/sbin/a2enmod apparmor
|
||||
%endif
|
||||
|
||||
%preun
|
||||
%if %{distro} == "suse"
|
||||
if [ $1 = 0 ] ; then
|
||||
/usr/sbin/a2dismod apparmor
|
||||
fi
|
||||
%endif
|
||||
|
||||
%triggerpostun -- mod_change_hat mod-change-hat
|
||||
%if %{distro} == "suse"
|
||||
/usr/sbin/a2enmod apparmor
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Sun Jul 29 2007 - sbeattie@suse.de
|
||||
- Convert builddep on libapparmor to libapparmor-devel
|
||||
* Tue Apr 3 2007 - sbeattie@suse.de
|
||||
- Add mod_apparmor manpage to package
|
||||
* Wed Sep 06 2006 - poeml@suse.de
|
||||
- rename to apache2-mod_apparmor
|
||||
- use a2enmod instead of frob_sysconfig
|
||||
- remove SuSEconfig calls
|
||||
* Fri May 26 2006 - schwab@suse.de
|
||||
- Don't strip binaries.
|
||||
* Wed Apr 12 2006 - Steve Beattie <sbeattie@suse.de>
|
||||
- Move to novell forge svn repo; fix build issue with new layout
|
||||
* Thu Mar 30 2006 - Seth Arnold <seth.arnold@suse.de> 2.0-7.2
|
||||
- Relicense to LGPL
|
||||
* Mon Jan 30 2006 - Steve Beattie <sbeattie@suse.de> 2.0-7.1
|
||||
- Renamed apache config options:
|
||||
ImmhatName -> AAHatName
|
||||
ImmDefaultHatName -> AADefaultHatName
|
||||
* Mon Jan 30 2006 - poeml@suse.de
|
||||
- removed libapr-util1-devel from BuildRequires (apache2-devel does
|
||||
require it)
|
||||
* Fri Jan 27 2006 Steve Beattie <sbeattie@suse.de> 2.0-6.1
|
||||
- No more neededforbuild in STABLE
|
||||
* Wed Jan 25 2006 Steve Beattie <sbeattie@suse.de> 2.0-6
|
||||
- Fix linking against libapparmor.so
|
||||
* Sun Jan 8 2006 Steve Beattie <sbeattie@suse.de> 2.0-5
|
||||
- More SUSE autobuild fixups.
|
||||
* Wed Jan 4 2006 Steve Beattie <sbeattie@suse.de> 2.0-4
|
||||
- Fixup SUSE autobuild require on apache-devel-packages
|
||||
- Add svn revision to the source tarball
|
||||
* Sun Dec 18 2005 Steve Beattie <sbeattie@novell.com> 2.0-3
|
||||
- Include symlink in %{_libdir}/apache2-prefork/
|
||||
* Thu Dec 8 2005 Steve Beattie <sbeattie@novell.com> 2.0-2
|
||||
- Rename to apache2-mod-apparmor for consistency w/SUSE packages
|
||||
- Rename module to mod_apparmor.so
|
||||
* Wed Dec 7 2005 Steve Beattie <sbeattie@novell.com> 2.0-1
|
||||
- Reset version for inclusion in SUSE autobuild
|
||||
* Mon Dec 5 2005 Steve Beattie <sbeattie@novell.com> 1.99-9
|
||||
- Rename package to mod-apparmor
|
||||
* Wed Nov 30 2005 Steve Beattie <sbeattie@novell.com> 1.99-8
|
||||
- Minor packaging cleanups
|
||||
* Wed Nov 30 2005 Steve Beattie <sbeattie@novell.com> 1.99-7_imnx
|
||||
- Convert license to GPL
|
||||
* Thu Jun 23 2005 Steve Beattie <sbeattie@novell.com> 1.99-6_imnx
|
||||
- Add trigger for mod_change_hat => mod-change-hat upgrades
|
||||
- Don't run SuSEconfig on SuSE 9.3 or newer
|
||||
* Mon May 23 2005 Steve Beattie <sbeattie@novell.com> 1.99-5_imnx
|
||||
- Fix package uninstall on RHEL4.
|
||||
* Fri Mar 11 2005 Steve Beattie <steve@immunix.com> 1.99-4_imnx
|
||||
- Rename to be consistent with other packages
|
||||
* Fri Feb 18 2005 Steve Beattie <steve@immunix.com> 1.99-3_imnx
|
||||
- Cleanup some non-64bit clean code, sigh.
|
||||
- Fix install locations on 64-bit platform.
|
||||
* Fri Feb 4 2005 Seth Arnold <sarnold@immunix.coM> 1.99-1_imnx
|
||||
- Reversion to 1.99
|
||||
* Fri Nov 12 2004 Steve Beattie <steve@immunix.com> 1.2-2_imnx
|
||||
- Add configuration file for redhat build
|
||||
* Tue Oct 12 2004 Steve Beattie <steve@immunix.com> 1.2-1_imnx
|
||||
- Bump version after shass-1.1 branched off
|
||||
* Mon Sep 20 2004 Dominic Reynolds <dominic@immunix.com> 1.0-7_imnx_(redhat|suse)
|
||||
- Modified to build separate versions for suse/redhat (EL3).
|
||||
- Note:RH version does not currently setup the module configuraiton
|
||||
- in apache.
|
||||
* Tue Aug 31 2004 Steve Beattie <steve@immunix.com> 1.0-6_imnx
|
||||
- Got location and per server config directives working somewhat
|
||||
correctly :-)
|
||||
- copyright fixups.
|
||||
* Fri Aug 20 2004 Steve Beattie <steve@immunix.com> 1.0-5_imnx
|
||||
- added support for <Location> hatname </Location>
|
||||
* Wed Jul 21 2004 Steve Beattie <steve@immunix.com> 1.0-4_imnx
|
||||
- reduced loglevel of some debug messages
|
||||
- add change_hat to list of apache modules
|
||||
* Tue Jul 20 2004 Steve Beattie <steve@immunix.com> 1.0-2_imnx
|
||||
- got module actually working, at least in simple cases.
|
||||
* Thu Jul 15 2004 Steve Beattie <steve@immunix.com> 1.0-1_imnx
|
||||
- Initial package creation.
|
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# $Id: frob_sysconfig 5910 2005-12-09 03:41:29Z steve $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2004, 2005 NOVELL (All rights reserved)
|
||||
#
|
||||
|
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
/* $Id$
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2006 NOVELL (All rights reserved)
|
||||
* Copyright (c) 2014 Canonical, Ltd. (All rights reserved)
|
||||
*
|
||||
* The mod_apparmor module is licensed under the terms of the GNU
|
||||
* Lesser General Public License, version 2.1. Please see the file
|
||||
* COPYING.LGPL.
|
||||
*
|
||||
* mod_apparmor - (apache 2.0.x)
|
||||
* Author: Steve Beattie <steve@nxnw.org>
|
||||
* Author: Steve Beattie <sbeattie@suse.de>
|
||||
*
|
||||
* This currently only implements change_hat functionality, but could be
|
||||
* extended for other stuff we decide to do.
|
||||
@@ -18,240 +18,187 @@
|
||||
#include "http_config.h"
|
||||
#include "http_request.h"
|
||||
#include "http_log.h"
|
||||
#include "http_main.h"
|
||||
#include "http_protocol.h"
|
||||
#include "util_filter.h"
|
||||
#include "apr.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_lib.h"
|
||||
|
||||
#ifndef USE_COMPAT_IMMUNIX_H
|
||||
#include <sys/apparmor.h>
|
||||
#else
|
||||
#include <sys/immunix.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
/* #define DEBUG */
|
||||
#ifndef __unused
|
||||
#define __unused __attribute__((unused))
|
||||
#endif
|
||||
|
||||
/* should the following be configurable? */
|
||||
#define DEFAULT_HAT "HANDLING_UNTRUSTED_INPUT"
|
||||
#define DEFAULT_URI_HAT "DEFAULT_URI"
|
||||
|
||||
/* Compatibility with apache 2.2 */
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER < 3
|
||||
#define APLOG_TRACE1 APLOG_DEBUG
|
||||
server_rec *ap_server_conf = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef APLOG_USE_MODULE
|
||||
APLOG_USE_MODULE(apparmor);
|
||||
#endif
|
||||
module AP_MODULE_DECLARE_DATA apparmor_module;
|
||||
|
||||
static unsigned long magic_token = 0;
|
||||
static unsigned int magic_token = 0;
|
||||
static int inside_default_hat = 0;
|
||||
|
||||
typedef struct {
|
||||
const char *hat_name;
|
||||
char *path;
|
||||
} apparmor_dir_cfg;
|
||||
const char * hat_name;
|
||||
char * path;
|
||||
} immunix_dir_cfg;
|
||||
|
||||
typedef struct {
|
||||
const char *hat_name;
|
||||
int is_initialized;
|
||||
} apparmor_srv_cfg;
|
||||
const char * hat_name;
|
||||
int is_initialized;
|
||||
} immunix_srv_cfg;
|
||||
|
||||
/* aa_init() gets invoked in the post_config stage of apache.
|
||||
/* immunix_init() gets invoked in the post_config stage of apache.
|
||||
* Unfortunately, apache reads its config once when it starts up, then
|
||||
* it re-reads it when goes into its restart loop, where it starts it's
|
||||
* children. This means we cannot call change_hat here, as the modules
|
||||
* memory will be wiped out, and the magic_token will be lost, so apache
|
||||
* wouldn't be able to change_hat back out. */
|
||||
static int
|
||||
aa_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
|
||||
static int
|
||||
immunix_init (apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
|
||||
{
|
||||
apr_file_t *file;
|
||||
apr_size_t size = sizeof(magic_token);
|
||||
apr_file_t * file;
|
||||
apr_size_t size = sizeof (magic_token);
|
||||
int ret;
|
||||
|
||||
ret = apr_file_open (&file, "/dev/urandom", APR_READ, APR_OS_DEFAULT, p);
|
||||
if (!ret) {
|
||||
apr_file_read(file, (void *) &magic_token, &size);
|
||||
apr_file_close(file);
|
||||
apr_file_read (file, (void *) &magic_token, &size);
|
||||
apr_file_close (file);
|
||||
} else {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
|
||||
"Failed to open /dev/urandom");
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Failed to open /dev/urandom");
|
||||
}
|
||||
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
|
||||
"Opened /dev/urandom successfully");
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "Opened /dev/urandom successfully");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/* As each child starts up, we'll change_hat into a default hat, mostly
|
||||
* to protect ourselves from bugs in parsing network input, but before
|
||||
* we change_hat to the uri specific hat. */
|
||||
static void
|
||||
aa_child_init(apr_pool_t *p, server_rec *s)
|
||||
static void
|
||||
immunix_child_init (apr_pool_t *p, server_rec *s)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
|
||||
"init: calling change_hat with '%s'", DEFAULT_HAT);
|
||||
ret = aa_change_hat(DEFAULT_HAT, magic_token);
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "init: calling change_hat");
|
||||
ret = change_hat (DEFAULT_HAT, magic_token);
|
||||
if (ret < 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf,
|
||||
"Failed to change_hat to '%s'", DEFAULT_HAT);
|
||||
change_hat (NULL, magic_token);
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Failed to change_hat to '%s'",
|
||||
DEFAULT_HAT);
|
||||
} else {
|
||||
inside_default_hat = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
debug_dump_uri(request_rec *r)
|
||||
debug_dump_uri (apr_uri_t * uri)
|
||||
{
|
||||
apr_uri_t *uri = &r->parsed_uri;
|
||||
if (uri)
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Dumping uri info "
|
||||
"scheme='%s' host='%s' path='%s' query='%s' fragment='%s'",
|
||||
uri->scheme, uri->hostname, uri->path, uri->query,
|
||||
uri->fragment);
|
||||
if (uri)
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Dumping uri info "
|
||||
"scheme='%s' host='%s' path='%s' query='%s' fragment='%s'",
|
||||
uri->scheme, uri->hostname, uri->path, uri->query,
|
||||
uri->fragment);
|
||||
else
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Asked to dump NULL uri");
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Asked to dump NULL uri");
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
aa_enter_hat will attempt to change_hat in the following order:
|
||||
#else
|
||||
static void
|
||||
debug_dump_uri (apr_uri_t * __unused uri) { }
|
||||
#endif
|
||||
|
||||
/*
|
||||
immunix_enter_hat will attempt to change_hat in the following order:
|
||||
(1) to a hatname in a location directive
|
||||
(2) to the server name or a defined per-server default
|
||||
(3) to the server name + "-" + uri
|
||||
(4) to the uri
|
||||
(5) to DEFAULT_URI
|
||||
(6) back to the parent profile
|
||||
(2) to the uri
|
||||
(3) to a per-server default
|
||||
(4) to DEFAULT_URI
|
||||
(5) back to the parent profile
|
||||
*/
|
||||
static int
|
||||
aa_enter_hat(request_rec *r)
|
||||
static int
|
||||
immunix_enter_hat (request_rec *r)
|
||||
{
|
||||
int aa_ret = -1;
|
||||
apparmor_dir_cfg *dcfg = (apparmor_dir_cfg *)
|
||||
ap_get_module_config(r->per_dir_config, &apparmor_module);
|
||||
apparmor_srv_cfg *scfg = (apparmor_srv_cfg *)
|
||||
ap_get_module_config(r->server->module_config, &apparmor_module);
|
||||
const char *aa_hat_array[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
int i = 0;
|
||||
char *aa_label, *aa_mode, *aa_hat;
|
||||
const char *vhost_uri;
|
||||
int sd_ret = -1;
|
||||
immunix_dir_cfg * dcfg = (immunix_dir_cfg *)
|
||||
ap_get_module_config (r->per_dir_config, &apparmor_module);
|
||||
immunix_srv_cfg * scfg = (immunix_srv_cfg *)
|
||||
ap_get_module_config (r->server->module_config, &apparmor_module);
|
||||
|
||||
debug_dump_uri(r);
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "aa_enter_hat (%s) n:0x%lx p:0x%lx main:0x%lx",
|
||||
dcfg->path, (unsigned long) r->next, (unsigned long) r->prev,
|
||||
(unsigned long) r->main);
|
||||
debug_dump_uri (&r->parsed_uri);
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_enter_hat (%s) n:0x%lx p:0x%lx main:0x%lx",
|
||||
dcfg->path, (unsigned long) r->next, (unsigned long) r->prev,
|
||||
(unsigned long) r->main);
|
||||
|
||||
/* We only call change_hat for the main request, not subrequests */
|
||||
if (r->main)
|
||||
return OK;
|
||||
if (r->main)
|
||||
return OK;
|
||||
|
||||
if (inside_default_hat) {
|
||||
aa_change_hat(NULL, magic_token);
|
||||
inside_default_hat = 0;
|
||||
change_hat (NULL, magic_token);
|
||||
inside_default_hat = 0;
|
||||
}
|
||||
|
||||
if (dcfg != NULL && dcfg->hat_name != NULL) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
|
||||
"[dcfg] adding hat '%s' to aa_change_hat vector", dcfg->hat_name);
|
||||
aa_hat_array[i++] = dcfg->hat_name;
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat [dcfg] %s", dcfg->hat_name);
|
||||
sd_ret = change_hat (dcfg->hat_name, magic_token);
|
||||
if (sd_ret < 0) {
|
||||
change_hat (NULL, magic_token);
|
||||
} else {
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (scfg) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "Dumping scfg info: "
|
||||
"scfg='0x%lx' scfg->hat_name='%s'",
|
||||
(unsigned long) scfg, scfg->hat_name);
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat [uri] %s", r->uri);
|
||||
sd_ret = change_hat (r->uri, magic_token);
|
||||
if (sd_ret < 0) {
|
||||
change_hat (NULL, magic_token);
|
||||
} else {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "scfg is null");
|
||||
}
|
||||
if (scfg != NULL) {
|
||||
if (scfg->hat_name != NULL) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
|
||||
"[scfg] adding hat '%s' to aa_change_hat vector", scfg->hat_name);
|
||||
aa_hat_array[i++] = scfg->hat_name;
|
||||
} else {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
|
||||
"[scfg] adding server_name '%s' to aa_change_hat vector",
|
||||
r->server->server_hostname);
|
||||
aa_hat_array[i++] = r->server->server_hostname;
|
||||
}
|
||||
|
||||
vhost_uri = apr_pstrcat(r->pool, r->server->server_hostname, "-", r->uri, NULL);
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
|
||||
"[vhost+uri] adding vhost+uri '%s' to aa_change_hat vector", vhost_uri);
|
||||
aa_hat_array[i++] = vhost_uri;
|
||||
return OK;
|
||||
}
|
||||
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
|
||||
"[uri] adding uri '%s' to aa_change_hat vector", r->uri);
|
||||
aa_hat_array[i++] = r->uri;
|
||||
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
|
||||
"[default] adding '%s' to aa_change_hat vector", DEFAULT_URI_HAT);
|
||||
aa_hat_array[i++] = DEFAULT_URI_HAT;
|
||||
|
||||
aa_ret = aa_change_hatv(aa_hat_array, magic_token);
|
||||
if (aa_ret < 0) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, errno, r, "aa_change_hatv call failed");
|
||||
if (scfg != NULL && scfg->hat_name != NULL) {
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat [scfg] %s", scfg->hat_name);
|
||||
sd_ret = change_hat (scfg->hat_name, magic_token);
|
||||
if (sd_ret < 0) {
|
||||
change_hat (NULL, magic_token);
|
||||
} else {
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if a defined AAHatName or AADefaultHatName would
|
||||
* apply, but wasn't the hat we landed up in; report a warning if
|
||||
* that's the case. */
|
||||
aa_ret = aa_getcon(&aa_label, &aa_mode);
|
||||
if (aa_ret < 0) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, errno, r, "aa_getcon call failed");
|
||||
} else {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
|
||||
"AA checks: aa_getcon result is '%s', mode '%s'", aa_label, aa_mode);
|
||||
/* TODO: use libapparmor get hat_name fn here once it is implemented */
|
||||
aa_hat = strstr(aa_label, "//");
|
||||
if (aa_hat != NULL && strcmp(aa_mode, "enforce") == 0) {
|
||||
aa_hat += 2; /* skip "//" */
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
|
||||
"AA checks: apache is in hat '%s', mode '%s'", aa_hat, aa_mode);
|
||||
if (dcfg != NULL && dcfg->hat_name != NULL) {
|
||||
if (strcmp(aa_hat, dcfg->hat_name) != 0)
|
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
|
||||
"AAHatName '%s' applies, but does not appear to be a hat in the apache apparmor policy",
|
||||
dcfg->hat_name);
|
||||
} else if (scfg != NULL && scfg->hat_name != NULL) {
|
||||
if (strcmp(aa_hat, scfg->hat_name) != 0 &&
|
||||
strcmp(aa_hat, r->uri) != 0)
|
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
|
||||
"AADefaultHatName '%s' applies, but does not appear to be a hat in the apache apparmor policy",
|
||||
scfg->hat_name);
|
||||
}
|
||||
}
|
||||
free(aa_label);
|
||||
}
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "calling change_hat DEFAULT_URI");
|
||||
sd_ret = change_hat (DEFAULT_URI_HAT, magic_token);
|
||||
if (sd_ret < 0) change_hat (NULL, magic_token);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
aa_exit_hat(request_rec *r)
|
||||
static int
|
||||
immunix_exit_hat (request_rec *r)
|
||||
{
|
||||
int aa_ret;
|
||||
apparmor_dir_cfg *dcfg = (apparmor_dir_cfg *)
|
||||
ap_get_module_config(r->per_dir_config, &apparmor_module);
|
||||
/* apparmor_srv_cfg *scfg = (apparmor_srv_cfg *)
|
||||
ap_get_module_config(r->server->module_config, &apparmor_module); */
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "exiting change_hat: dir hat %s dir path %s",
|
||||
dcfg->hat_name, dcfg->path);
|
||||
int sd_ret;
|
||||
immunix_dir_cfg * dcfg = (immunix_dir_cfg *)
|
||||
ap_get_module_config (r->per_dir_config, &apparmor_module);
|
||||
/* immunix_srv_cfg * scfg = (immunix_srv_cfg *)
|
||||
ap_get_module_config (r->server->module_config, &apparmor_module); */
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "exiting change_hat - dir hat %s path %s", dcfg->hat_name, dcfg->path);
|
||||
change_hat (NULL, magic_token);
|
||||
|
||||
/* can convert the following back to aa_change_hat() when the
|
||||
* aa_change_hat() bug addressed in trunk commit 2329 lands in most
|
||||
* system libapparmors */
|
||||
aa_change_hatv(NULL, magic_token);
|
||||
|
||||
aa_ret = aa_change_hat(DEFAULT_HAT, magic_token);
|
||||
if (aa_ret < 0) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, r,
|
||||
"Failed to change_hat to '%s'", DEFAULT_HAT);
|
||||
sd_ret = change_hat (DEFAULT_HAT, magic_token);
|
||||
if (sd_ret < 0) {
|
||||
change_hat (NULL, magic_token);
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "Failed to change_hat to '%s'",
|
||||
DEFAULT_HAT);
|
||||
} else {
|
||||
inside_default_hat = 1;
|
||||
}
|
||||
@@ -260,15 +207,15 @@ aa_exit_hat(request_rec *r)
|
||||
}
|
||||
|
||||
static const char *
|
||||
aa_cmd_ch_path(cmd_parms *cmd, void *mconfig, const char *parm1)
|
||||
aa_cmd_ch_path (cmd_parms * cmd, void * mconfig, const char * parm1)
|
||||
{
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, "directory config change hat %s",
|
||||
parm1 ? parm1 : "DEFAULT");
|
||||
apparmor_dir_cfg *dcfg = mconfig;
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "config change hat %s",
|
||||
parm1 ? parm1 : "DEFAULT");
|
||||
immunix_dir_cfg * dcfg = mconfig;
|
||||
if (parm1 != NULL) {
|
||||
dcfg->hat_name = parm1;
|
||||
dcfg->hat_name = parm1;
|
||||
} else {
|
||||
dcfg->hat_name = "DEFAULT";
|
||||
dcfg->hat_name = "DEFAULT";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -276,27 +223,26 @@ aa_cmd_ch_path(cmd_parms *cmd, void *mconfig, const char *parm1)
|
||||
static int path_warn_once;
|
||||
|
||||
static const char *
|
||||
immunix_cmd_ch_path(cmd_parms *cmd, void *mconfig, const char *parm1)
|
||||
immunix_cmd_ch_path (cmd_parms * cmd, void * mconfig, const char * parm1)
|
||||
{
|
||||
if (path_warn_once == 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, "ImmHatName is "
|
||||
"deprecated, please use AAHatName instead");
|
||||
path_warn_once = 1;
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "ImmHatName is "
|
||||
"deprecated, please use AAHatName instead");
|
||||
path_warn_once = 1;
|
||||
}
|
||||
return aa_cmd_ch_path(cmd, mconfig, parm1);
|
||||
}
|
||||
|
||||
static const char *
|
||||
aa_cmd_ch_srv(cmd_parms *cmd, void *mconfig, const char *parm1)
|
||||
aa_cmd_ch_srv (cmd_parms * cmd, void * mconfig, const char * parm1)
|
||||
{
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, "server config change hat %s",
|
||||
parm1 ? parm1 : "DEFAULT");
|
||||
apparmor_srv_cfg *scfg = (apparmor_srv_cfg *)
|
||||
ap_get_module_config(cmd->server->module_config, &apparmor_module);
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "config change hat %s",
|
||||
parm1 ? parm1 : "DEFAULT");
|
||||
immunix_srv_cfg * scfg = mconfig;
|
||||
if (parm1 != NULL) {
|
||||
scfg->hat_name = parm1;
|
||||
scfg->hat_name = parm1;
|
||||
} else {
|
||||
scfg->hat_name = "DEFAULT";
|
||||
scfg->hat_name = "DEFAULT";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -304,29 +250,27 @@ aa_cmd_ch_srv(cmd_parms *cmd, void *mconfig, const char *parm1)
|
||||
static int srv_warn_once;
|
||||
|
||||
static const char *
|
||||
immunix_cmd_ch_srv(cmd_parms *cmd, void *mconfig, const char *parm1)
|
||||
immunix_cmd_ch_srv (cmd_parms * cmd, void * mconfig, const char * parm1)
|
||||
{
|
||||
if (srv_warn_once == 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, "ImmDefaultHatName is "
|
||||
"deprecated, please use AADefaultHatName instead");
|
||||
srv_warn_once = 1;
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "ImmDefaultHatName is "
|
||||
"deprecated, please use AADefaultHatName instead");
|
||||
srv_warn_once = 1;
|
||||
}
|
||||
return aa_cmd_ch_srv(cmd, mconfig, parm1);
|
||||
}
|
||||
|
||||
static void *
|
||||
aa_create_dir_config(apr_pool_t *p, char *path)
|
||||
immunix_create_dir_config (apr_pool_t * p, char * path)
|
||||
{
|
||||
apparmor_dir_cfg *newcfg = (apparmor_dir_cfg *) apr_pcalloc(p, sizeof(*newcfg));
|
||||
immunix_dir_cfg * newcfg = (immunix_dir_cfg *) apr_pcalloc(p, sizeof(* newcfg));
|
||||
|
||||
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
|
||||
"aa_create_dir_cfg (%s)", path ? path : ":no path:");
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_create_dir (%s)", path ? path : ":no path:");
|
||||
if (newcfg == NULL) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
|
||||
"aa_create_dir_config: couldn't alloc dir config");
|
||||
return NULL;
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "immunix_create_dir: couldn't alloc dir config");
|
||||
return NULL;
|
||||
}
|
||||
newcfg->path = apr_pstrdup(p, path ? path : ":no path:");
|
||||
newcfg->path = apr_pstrdup (p, path ? path : ":no path:");
|
||||
|
||||
return newcfg;
|
||||
}
|
||||
@@ -334,85 +278,83 @@ aa_create_dir_config(apr_pool_t *p, char *path)
|
||||
/* XXX: Should figure out an appropriate action to take here, if any
|
||||
|
||||
static void *
|
||||
aa_merge_dir_config(apr_pool_t *p, void *parent, void *child)
|
||||
immunix_merge_dir_config (apr_pool_t * p, void * parent, void * child)
|
||||
{
|
||||
apparmor_dir_cfg *newcfg = (apparmor_dir_cfg *) apr_pcalloc(p, sizeof(*newcfg));
|
||||
immunix_dir_cfg * newcfg = (immunix_dir_cfg *) apr_pcalloc(p, sizeof(* newcfg));
|
||||
|
||||
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf, "in immunix_merge_dir ()");
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_merge_dir ()");
|
||||
if (newcfg == NULL)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
return newcfg;
|
||||
}
|
||||
*/
|
||||
|
||||
static void *
|
||||
aa_create_srv_config(apr_pool_t *p, server_rec *srv)
|
||||
immunix_create_srv_config (apr_pool_t * p, server_rec * srv)
|
||||
{
|
||||
apparmor_srv_cfg *newcfg = (apparmor_srv_cfg *) apr_pcalloc(p, sizeof(*newcfg));
|
||||
immunix_srv_cfg * newcfg = (immunix_srv_cfg *) apr_pcalloc(p, sizeof(* newcfg));
|
||||
|
||||
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
|
||||
"in aa_create_srv_config");
|
||||
ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, NULL, "in immunix_create_srv");
|
||||
if (newcfg == NULL) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf,
|
||||
"aa_create_srv_config: couldn't alloc srv config");
|
||||
return NULL;
|
||||
ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL, "immunix_create_srv: couldn't alloc srv config");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newcfg;
|
||||
}
|
||||
|
||||
|
||||
static const command_rec mod_apparmor_cmds[] = {
|
||||
static const command_rec immunix_cmds[] = {
|
||||
|
||||
AP_INIT_TAKE1(
|
||||
AP_INIT_TAKE1 (
|
||||
"ImmHatName",
|
||||
immunix_cmd_ch_path,
|
||||
NULL,
|
||||
ACCESS_CONF,
|
||||
""
|
||||
immunix_cmd_ch_path,
|
||||
NULL,
|
||||
ACCESS_CONF,
|
||||
""
|
||||
),
|
||||
AP_INIT_TAKE1(
|
||||
AP_INIT_TAKE1 (
|
||||
"ImmDefaultHatName",
|
||||
immunix_cmd_ch_srv,
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
""
|
||||
immunix_cmd_ch_srv,
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
""
|
||||
),
|
||||
AP_INIT_TAKE1(
|
||||
AP_INIT_TAKE1 (
|
||||
"AAHatName",
|
||||
aa_cmd_ch_path,
|
||||
NULL,
|
||||
ACCESS_CONF,
|
||||
""
|
||||
aa_cmd_ch_path,
|
||||
NULL,
|
||||
ACCESS_CONF,
|
||||
""
|
||||
),
|
||||
AP_INIT_TAKE1(
|
||||
AP_INIT_TAKE1 (
|
||||
"AADefaultHatName",
|
||||
aa_cmd_ch_srv,
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
""
|
||||
aa_cmd_ch_srv,
|
||||
NULL,
|
||||
RSRC_CONF,
|
||||
""
|
||||
),
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
register_hooks(apr_pool_t *p)
|
||||
static void
|
||||
register_hooks (apr_pool_t *p)
|
||||
{
|
||||
ap_hook_post_config(aa_init, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_child_init(aa_child_init, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_access_checker(aa_enter_hat, NULL, NULL, APR_HOOK_FIRST);
|
||||
/* ap_hook_post_read_request(aa_enter_hat, NULL, NULL, APR_HOOK_FIRST); */
|
||||
ap_hook_log_transaction(aa_exit_hat, NULL, NULL, APR_HOOK_LAST);
|
||||
ap_hook_post_config (immunix_init, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_child_init (immunix_child_init, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_access_checker(immunix_enter_hat, NULL, NULL, APR_HOOK_FIRST);
|
||||
/* ap_hook_post_read_request(immunix_enter_hat, NULL, NULL, APR_HOOK_FIRST); */
|
||||
ap_hook_log_transaction(immunix_exit_hat, NULL, NULL, APR_HOOK_LAST);
|
||||
}
|
||||
|
||||
module AP_MODULE_DECLARE_DATA apparmor_module = {
|
||||
STANDARD20_MODULE_STUFF,
|
||||
aa_create_dir_config, /* dir config creater */
|
||||
NULL, /* dir merger --- default is to override */
|
||||
/* immunix_merge_dir_config, */ /* dir merger --- default is to override */
|
||||
aa_create_srv_config, /* server config */
|
||||
NULL, /* merge server config */
|
||||
mod_apparmor_cmds, /* command table */
|
||||
register_hooks /* register hooks */
|
||||
immunix_create_dir_config, /* dir config creater */
|
||||
NULL, /* dir merger --- default is to override */
|
||||
/* immunix_merge_dir_config, */ /* dir merger --- default is to override */
|
||||
immunix_create_srv_config, /* server config */
|
||||
NULL, /* merge server config */
|
||||
immunix_cmds, /* command table */
|
||||
register_hooks /* register hooks */
|
||||
};
|
||||
|
@@ -1,145 +1,96 @@
|
||||
# This publication is intellectual property of Novell Inc. and Canonical
|
||||
# Ltd. Its contents can be duplicated, either in part or in whole, provided
|
||||
# that a copyright label is visibly located on each copy.
|
||||
# $Id$
|
||||
# This publication is intellectual property of Novell Inc. 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 SUSE LINUX GmbH, Canonical Ltd, the authors, nor the translators
|
||||
# shall be held liable for possible errors or the consequences thereof.
|
||||
# Neither SUSE LINUX GmbH, 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. SUSE LINUX GmbH
|
||||
# and Canonical Ltd. essentially adhere to the manufacturer's spelling.
|
||||
# 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.
|
||||
#
|
||||
# Please direct suggestions and comments to apparmor-general@forge.novell.com.
|
||||
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
mod_apparmor - fine-grained AppArmor confinement for Apache
|
||||
mod_apparmor - fine-grained AppArmor confinement for apache
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
An AppArmor profile applies to an executable program; if a portion of
|
||||
the program needs different access permissions than other portions,
|
||||
the program can "change hats" via aa_change_hat(2) to a different role,
|
||||
also known as a subprofile. The mod_apparmor Apache module uses the
|
||||
aa_change_hat(2) mechanism to offer more fine-grained confinement of dynamic
|
||||
elements within Apache such as individual php and perl scripts, while
|
||||
the program can "change hats" via change_hat(2) to a different role,
|
||||
also known as a subprofile. The mod_apparmor apache module uses the
|
||||
change_hat(2) mechanism to offer more fine-grained confinement of dynamic
|
||||
elements within apache such as individual php and perl scripts, while
|
||||
still allowing the performance benefits of using mod_php and mod_perl.
|
||||
|
||||
To use mod_apparmor with Apache, ensure that mod_apparmor is configured to
|
||||
be loaded into Apache, either via a2enmod, yast or manual editing of the
|
||||
apache2(8)/httpd(8) configuration files, and restart Apache. Make sure that
|
||||
apparmor is also functioning.
|
||||
To use mod_apparmor with apache, ensure that mod_apparmor is configured to
|
||||
be loaded into apache, either via yast or manual editing of the httpd(8)
|
||||
configuration files, and restart apache. Make sure that apparmor is also
|
||||
functioning.
|
||||
|
||||
Once mod_apparmor is loaded within Apache, all requests to Apache will
|
||||
cause mod_apparmor to attempt to change into a hat that matches the
|
||||
ServerName for the server/vhost. If no such hat is found, it will
|
||||
first fall back by attempting to change into a hat composed of the
|
||||
ServerName-URI (e.g. "www.example.com-/app/some.cgi"). If that hat
|
||||
is not found, it will fall back to attempting to use the hat named
|
||||
by the URI (e.g. "/app/some.cgi"). If that hat is not found, it will
|
||||
fall back to attempting to use the hat DEFAULT_URI; if that also does
|
||||
not exist, it will fall back to using the global Apache profile. Most
|
||||
static web pages can simply make use of the DEFAULT_URI hat.
|
||||
Once mod_apparmor is loaded within apache, all requests to apache will
|
||||
cause mod_apparmor to attempt to change into a hat named by the URI
|
||||
(e.g. /app/some.cgi). If no such hat is found, it will fall back to
|
||||
attempting to use the hat DEFAULT_URI; if that also does not exist,
|
||||
it will fall back to using the global apache profile. Most static web
|
||||
pages can simply make use of the DEFAULT_URI hat.
|
||||
|
||||
Additionally, before any requests come in to Apache, mod_apparmor
|
||||
will attempt to change hat into the HANDLING_UNTRUSTED_INPUT hat.
|
||||
mod_apparmor will attempt to use this hat while Apache is doing the
|
||||
initial parsing of a given http request, before its given to a specific
|
||||
handler (like mod_php) for processing.
|
||||
|
||||
Because defining hats for every URI/URL often becomes tedious, mod_apparmor
|
||||
provides the AAHatName and AADefaultHatName Apache configuration options.
|
||||
However, defining hats for every URI/URL would become tedious, so there
|
||||
are a couple of configuration options that mod_apparmor supports:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<AAHatName>
|
||||
|
||||
AAHatName allows you to specify a hat to be used for a given Apache
|
||||
E<lt>DirectoryE<gt>, E<lt>DirectoryMatchE<gt>, E<lt>LocationE<gt> or
|
||||
E<lt>LocationMatchE<gt> directive (see the Apache documentation for more
|
||||
AAHatName allows you to specify a hat to be used for a given apache
|
||||
directory or location directive (see the apache documenation for more
|
||||
details). Note that mod_apparmor behavior can become confused if
|
||||
E<lt>Directory*E<gt> and E<lt>Location*E<gt> directives are intermingled
|
||||
and it is recommended to use one type of directive. If the hat specified by
|
||||
AAHatName does not exist in the Apache profile, then it falls back to the
|
||||
behavior described above.
|
||||
directory and location directives are intermingled; it's preferred to
|
||||
stick to one type of directive. If the hat specified by AAHatName does
|
||||
not exist in the apache profile, then it falls back to the behavior
|
||||
above.
|
||||
|
||||
=item B<AADefaultHatName>
|
||||
|
||||
AADefaultHatName allows you to specify a default hat to be used for
|
||||
virtual hosts and other Apache server directives, so that you can have
|
||||
vhosts and other apache server directives, so that you can have
|
||||
different defaults for different virtual hosts. This can be overridden
|
||||
by the AAHatName directive and is checked for only if there isn't
|
||||
a matching AAHatName. The default value of AADefaultHatName is the
|
||||
ServerName for the server/vhost configuration. If the AADefaultHatName
|
||||
hat does not exist, then it falls back to the behavior described above.
|
||||
by an AAHatName directive. If the AADefaultHatName hat does not exist,
|
||||
it falls back to the behavior described above.
|
||||
|
||||
=back
|
||||
|
||||
=head1 URI REQUEST SUMMARY
|
||||
|
||||
When profiling with mod_apparmor, it is helpful to keep the following order
|
||||
of operations in mind:
|
||||
|
||||
On each URI request, mod_apparmor will first aa_change_hat(2) into
|
||||
^HANDLING_UNTRUSTED_INPUT, if it exists.
|
||||
|
||||
Then, after performing the initial parsing of the request, mod_apparmor
|
||||
will:
|
||||
|
||||
=over 4
|
||||
|
||||
=item 1
|
||||
|
||||
try to aa_change_hat(2) into a matching AAHatName hat if it exists and
|
||||
applies, otherwise it will
|
||||
|
||||
=item 2
|
||||
|
||||
try to aa_change_hat(2) into an AADefaultHatName hat, either the
|
||||
ServerName (the default) or the configuration value specified by the
|
||||
AADefaultHatName directive, for the server/vhost, otherwise it will
|
||||
|
||||
=item 3
|
||||
|
||||
try to aa_change_hat(2) into the ServerName-URI, otherwise it will
|
||||
|
||||
=item 4
|
||||
|
||||
try to aa_change_hat(2) into the URI itself, otherwise it will
|
||||
|
||||
=item 5
|
||||
|
||||
try to aa_change_hat(2) into the DEFAULT_URI hat, if it exists, otherwise it
|
||||
will
|
||||
|
||||
=item 6
|
||||
|
||||
fall back to the global Apache policy
|
||||
|
||||
=back
|
||||
Additionally, before any requests come in to apache, mod_apparmor
|
||||
will attempt to change hat into the HANDLING_UNTRUSTED_INPUT hat.
|
||||
mod_apparmor will attempt to use this hat while apache is doing the
|
||||
initial parsing of a given http request, before its given to a specific
|
||||
handler (like mod_php) for processing.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
mod_apparmor() currently only supports apache2, and has only been tested
|
||||
with the prefork MPM configuration -- threaded configurations of Apache
|
||||
may not work correctly. For Apache 2.4 users, you should enable the mpm_prefork
|
||||
module.
|
||||
with the prefork MPM configuration -- threaded configurations of apache
|
||||
may not work correctly.
|
||||
|
||||
There are likely other bugs lurking about; if you find any, please report
|
||||
them at L<https://bugs.launchpad.net/apparmor/+filebug>.
|
||||
them to bugzilla at L<http://bugzilla.novell.com>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
apparmor(7), subdomain.conf(5), apparmor_parser(8), aa_change_hat(2) and
|
||||
L<http://wiki.apparmor.net>.
|
||||
apparmor(7), subdomain.conf(5), apparmor_parser(8), and
|
||||
L<http://forge.novell.com/modules/xfmod/project/?apparmor>.
|
||||
|
||||
=cut
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# $Id$
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 1999, 2004, 2005 NOVELL (All rights reserved)
|
||||
# Copyright (c) 2016 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
|
||||
@@ -17,57 +17,22 @@
|
||||
NAME=pam_apparmor
|
||||
all:
|
||||
COMMONDIR=../../common/
|
||||
MAKE_RULES=common/Make.rules
|
||||
|
||||
include $(COMMONDIR)/Make.rules
|
||||
include ${MAKE_RULES}
|
||||
|
||||
ifdef USE_SYSTEM
|
||||
LIBAPPARMOR = $(shell if pkg-config --exists libapparmor ; then \
|
||||
pkg-config --silence-errors --libs libapparmor ; \
|
||||
elif ldconfig -p | grep -q libapparmor\.so$$ ; then \
|
||||
echo -lapparmor ; \
|
||||
fi )
|
||||
ifeq ($(strip $(LIBAPPARMOR)),)
|
||||
ERROR_MESSAGE = $(error ${nl}\
|
||||
************************************************************************${nl}\
|
||||
Unable to find libapparmor installed on this system; either${nl}\
|
||||
install libapparmor devel packages, set the LIBAPPARMOR variable${nl}\
|
||||
manually, or build against in-tree libapparmor.${nl}\
|
||||
************************************************************************${nl})
|
||||
endif
|
||||
LIBAPPARMOR_INCLUDE =
|
||||
AA_LDLIBS = $(LIBAPPARMOR)
|
||||
AA_LINK_FLAGS =
|
||||
else
|
||||
LIBAPPARMOR_SRC := ../../libraries/libapparmor/
|
||||
LIBAPPARMOR_INCLUDE_PATH = $(LIBAPPARMOR_SRC)/include
|
||||
LIBAPPARMOR_PATH := $(LIBAPPARMOR_SRC)/src/.libs/
|
||||
ifeq ($(realpath $(LIBAPPARMOR_PATH)/libapparmor.a),)
|
||||
ERROR_MESSAGE = $(error ${nl}\
|
||||
************************************************************************${nl}\
|
||||
$(LIBAPPARMOR_PATH)/libapparmor.a is missing; either build against${nl}\
|
||||
the in-tree libapparmor by building it first and then trying again${nl}\
|
||||
(see the top-level README for help) or build against the system${nl}\
|
||||
libapparmor by adding USE_SYSTEM=1 to your make command.${nl}\
|
||||
************************************************************************${nl})
|
||||
endif
|
||||
LIBAPPARMOR_INCLUDE = -I$(LIBAPPARMOR_INCLUDE_PATH)
|
||||
AA_LINK_FLAGS = -L$(LIBAPPARMOR_PATH)
|
||||
AA_LDLIBS = -lapparmor
|
||||
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
|
||||
ifeq ($(COMMONDIR_EXISTS), true)
|
||||
common/Make.rules: $(COMMONDIR)/Make.rules
|
||||
ln -sf $(COMMONDIR) .
|
||||
endif
|
||||
EXTRA_CFLAGS=$(CFLAGS) $(CPPFLAGS) -fPIC -shared -Wall $(LIBAPPARMOR_INCLUDE)
|
||||
LINK_FLAGS=-Xlinker -x $(AA_LINK_FLAGS) $(LDFLAGS)
|
||||
LIBS=-lpam $(AA_LDLIBS)
|
||||
|
||||
EXTRA_CFLAGS=$(CFLAGS) -fPIC -shared -Wall
|
||||
LINK_FLAGS=-Xlinker -x
|
||||
LIBS=-lpam -lapparmor
|
||||
OBJECTS=${NAME}.o get_options.o
|
||||
|
||||
.PHONY: libapparmor_check
|
||||
.SILENT: libapparmor_check
|
||||
libapparmor_check: ; $(ERROR_MESSAGE)
|
||||
|
||||
all: libapparmor_check $(NAME).so docs
|
||||
|
||||
.PHONY: docs
|
||||
# docs: we should have some
|
||||
docs:
|
||||
all: $(NAME).so
|
||||
|
||||
$(NAME).so: ${OBJECTS}
|
||||
$(CC) $(EXTRA_CFLAGS) $(LINK_FLAGS) -o $@ ${OBJECTS} $(LIBS)
|
||||
@@ -77,7 +42,7 @@ $(NAME).so: ${OBJECTS}
|
||||
|
||||
# need some better way of determining this
|
||||
DESTDIR=/
|
||||
SECDIR ?= ${DESTDIR}/lib/security
|
||||
SECDIR=${DESTDIR}/lib/security
|
||||
|
||||
.PHONY: install
|
||||
install: $(NAME).so
|
||||
@@ -85,5 +50,7 @@ install: $(NAME).so
|
||||
install -m 555 $(NAME).so $(SECDIR)/
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
clean: ${MAKE_RULES}
|
||||
rm -f core core.* *.so *.o *.s *.a *~
|
||||
rm -f ${NAME}-*.tar.gz Make.rules
|
||||
|
||||
|
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Written by Steve Beattie <sbeattie@suse.de> 2006/10/25
|
||||
*
|
||||
* Modeled after the option parsing code in pam_unix2 by:
|
||||
|
@@ -1,14 +1,10 @@
|
||||
/* pam_apparmor module */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006
|
||||
* NOVELL (All rights reserved)
|
||||
*
|
||||
* Copyright (c) 2010
|
||||
* Canonical, Ltd. (All rights reserved)
|
||||
* $Id$
|
||||
*
|
||||
* Written by Jesse Michael <jmichael@suse.de> 2006/08/24
|
||||
* and Steve Beattie <sbeattie@ubuntu.com> 2006/10/25
|
||||
* and Steve Beattie <sbeattie@suse.de> 2006/10/25
|
||||
*
|
||||
* Based off of pam_motd by:
|
||||
* Ben Collins <bcollins@debian.org> 2005/10/04
|
||||
@@ -111,7 +107,6 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
sizeof(magic_token));
|
||||
if (retval < 0) {
|
||||
pam_syslog(pamh, LOG_ERR, "Can't read from /dev/urandom\n");
|
||||
close(fd);
|
||||
return PAM_PERM_DENIED;
|
||||
}
|
||||
} while ((magic_token == 0) || (retval != sizeof(magic_token)));
|
||||
@@ -170,8 +165,8 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
|
||||
* stop attempting to use change_hat */
|
||||
goto nodefault;
|
||||
break;
|
||||
case EPERM: /* Disable when ECHILD patch gets accepted */
|
||||
case EACCES:
|
||||
case ENOENT:
|
||||
/* failed to change into attempted hat, so we'll
|
||||
* jump back out and try the next one */
|
||||
break;
|
||||
|
@@ -1,6 +1,8 @@
|
||||
/* pam_apparmor module */
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Written by Jesse Michael <jmichael@suse.de> 2006/08/24
|
||||
* and Steve Beattie <sbeattie@suse.de> 2006/10/25
|
||||
*
|
||||
|
83
changehat/pam_apparmor/pam_apparmor.spec.in
Normal file
83
changehat/pam_apparmor/pam_apparmor.spec.in
Normal file
@@ -0,0 +1,83 @@
|
||||
#
|
||||
# spec file for package pam_apparmor (Version 2)
|
||||
#
|
||||
# Copyright (c) 2005 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
# This file and all modifications and additions to the pristine
|
||||
# package are under the same license as the package itself.
|
||||
#
|
||||
# Please submit bugfixes or comments via http://www.suse.de/feedback/
|
||||
#
|
||||
|
||||
# norootforbuild
|
||||
|
||||
Name: pam_apparmor
|
||||
License: GPL
|
||||
Group: Productivity/Security
|
||||
Autoreqprov: on
|
||||
Version: @@immunix_version@@
|
||||
Release: @@repo_version@@
|
||||
Summary: Pam module to add AppArmor change_hat functionality
|
||||
URL: http://forge.novell.com/modules/xfmod/project/?apparmor
|
||||
Source: pam_apparmor-%{version}-@@repo_version@@.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
BuildRequires: pam-devel
|
||||
Requires: pam
|
||||
Prereq: pam
|
||||
|
||||
%if %{?suse_version:1}0
|
||||
%if 0%{?suse_version} < 1030
|
||||
BuildRequires: libapparmor
|
||||
%else
|
||||
BuildRequires: libapparmor-devel
|
||||
%endif
|
||||
%else
|
||||
BuildRequires: libapparmor-devel
|
||||
%endif
|
||||
|
||||
%description
|
||||
The pam_apparmor module provides the means for any pam applications that
|
||||
call pam_open_session() to automatically perform an AppArmor change_hat
|
||||
operation in order to switch to a user-specific security policy.
|
||||
|
||||
|
||||
Authors:
|
||||
--------
|
||||
Jesse Michael jmichael@suse.de
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
make CFLAGS="${RPM_OPT_FLAGS}"
|
||||
|
||||
%install
|
||||
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
|
||||
make install DESTDIR=${RPM_BUILD_ROOT} SECDIR=${RPM_BUILD_ROOT}/%{_lib}/security
|
||||
|
||||
%clean
|
||||
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
|
||||
|
||||
%files
|
||||
%defattr(444,root,root,755)
|
||||
%doc README COPYING
|
||||
%attr(555,root,root) /%{_lib}/security/pam_apparmor.so
|
||||
|
||||
%changelog -n pam_apparmor
|
||||
* Tue Oct 31 2006 Jesse Michael <jmichael@suse.de>
|
||||
- Add debug option
|
||||
* Tue Oct 31 2006 Steve Beattie <sbeattie@suse.de>
|
||||
- Add configuration options to order attempted hat changes
|
||||
* Wed Oct 25 2006 Steve Beattie <sbeattie@suse.de>
|
||||
- remove auto-editing of pam's common-session
|
||||
- honor RPM's CFLAGS when building
|
||||
- add license (same as Linux PAM package).
|
||||
* Thu Sep 14 2006 Jesse Michael <jmichael@suse.de>
|
||||
- header comment was incorrect
|
||||
- use pam_get_user() instead of pam_get_item()
|
||||
- fix read from urandom if 0
|
||||
* Fri Jan 13 2006 Steve Beattie <sbeattie@suse.de>
|
||||
- Add svn repo number to tarball
|
||||
* Fri Jan 13 2006 Jesse Michael <jmichael@suse.de>
|
||||
- Make magic tokens harder to guess by pulling them from /dev/urandom
|
||||
* Wed Dec 21 2005 - jmichael@suse.de
|
||||
- initial
|
@@ -1,3 +1,4 @@
|
||||
# $Id: Makefile 10 2006-04-12 20:31:08Z steve-beattie $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 1999, 2004, 2005, 2006 NOVELL (All rights reserved)
|
||||
#
|
||||
@@ -17,7 +18,13 @@ NAME = tomcat_apparmor
|
||||
all:
|
||||
COMMONDIR=../../../common/
|
||||
|
||||
include $(COMMONDIR)/Make.rules
|
||||
include common/Make.rules
|
||||
|
||||
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
|
||||
ifeq ($(COMMONDIR_EXISTS), true)
|
||||
common/Make.rules: $(COMMONDIR)/Make.rules
|
||||
ln -sf $(COMMONDIR) .
|
||||
endif
|
||||
|
||||
LIB = lib
|
||||
CATALINA_HOME = /usr/share/tomcat5
|
||||
@@ -28,6 +35,7 @@ all:
|
||||
|
||||
clean:
|
||||
ant clean
|
||||
rm -f tomcat_apparmor.spec ${NAME}-*.tar.gz Make.rules
|
||||
|
||||
install:
|
||||
ant -Dversion=$(VERSION) -Drelease=$(MAN_RELEASE) -Dcatalina_home=${CATALINA_HOME} -Dinstall_lib=${LIB} install_jar install_jni
|
||||
install: $(SPECFILE)
|
||||
ant -Dversion=$(VERSION) -Drelease=$(RELEASE) -Dcatalina_home=${CATALINA_HOME} -Dinstall_lib=${LIB} install_jar install_jni
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "jni.h"
|
||||
#include <errno.h>
|
||||
#include <sys/apparmor.h>
|
||||
#include "sys/apparmor.h"
|
||||
#include "com_novell_apparmor_JNIChangeHat.h"
|
||||
|
||||
/* c intermediate lib call for Java -> JNI -> c library execution of the change_hat call */
|
||||
|
86
changehat/tomcat_apparmor/tomcat_5_0/tomcat_apparmor.spec.in
Normal file
86
changehat/tomcat_apparmor/tomcat_5_0/tomcat_apparmor.spec.in
Normal file
@@ -0,0 +1,86 @@
|
||||
# $Id:$
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2006 NOVELL (All rights reserved)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
# norootforbuild
|
||||
|
||||
# Check first to see if distro is already defined.
|
||||
|
||||
%if ! %{?distro:1}0
|
||||
%define distro suse
|
||||
%endif
|
||||
|
||||
%if %{distro} == "suse"
|
||||
%define CATALINA_HOME /usr/share/tomcat5
|
||||
%endif
|
||||
%define APPARMOR_DOC_DIR /usr/share/doc/packages/apparmor-docs/
|
||||
%define JNI_SO libJNIChangeHat.so
|
||||
%define JAR_FILE changeHatValve.jar
|
||||
|
||||
|
||||
Summary: Tomcat 5 plugin for AppArmor change_hat
|
||||
Name: tomcat_apparmor
|
||||
Version: @@immunix_version@@
|
||||
Release: @@repo_version@@
|
||||
Group: System/Libraries
|
||||
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
|
||||
License: LGPL
|
||||
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
|
||||
Url: http://developer.novell.com/wiki/index.php/Novell_AppArmor
|
||||
Prereq: tomcat5, servletapi5, libapparmor
|
||||
BuildRequires: tomcat5, servletapi5 ant, java, libapparmor, java2-devel-packages, apparmor-docs
|
||||
Provides: tomcat_apparmor
|
||||
|
||||
%description
|
||||
tomcat_apparmor - is a plugin for Apache Tomcat version 5.x that provides
|
||||
support for AppArmor change_hat for creating AppArmor containers that are
|
||||
bound to discrete elements of processing within the Tomcat servlet
|
||||
container. The AppArmor containers, or "hats", can be created for invidual
|
||||
URL processing or per servlet.
|
||||
|
||||
%prep
|
||||
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
|
||||
|
||||
ant -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dtarget=1.4 jar jni_so
|
||||
|
||||
%install
|
||||
ant -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dversion=%{version} -Drelease=%{release} -Dcatalina_home=%{CATALINA_HOME} -Dinstall_root=${RPM_BUILD_ROOT} -Dinstall_lib=%{_lib} install_jar install_jni
|
||||
|
||||
mkdir -p ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
|
||||
install ${RPM_BUILD_DIR}/%{name}-%{version}/README.tomcat_apparmor ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
|
||||
|
||||
%clean
|
||||
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%{CATALINA_HOME}/server/lib/%{JAR_FILE}
|
||||
/%{_lib}/lib*
|
||||
/%{_libdir}/lib*
|
||||
%{APPARMOR_DOC_DIR}/README.tomcat_apparmor
|
||||
|
||||
%post
|
||||
ldconfig
|
||||
|
||||
%postun
|
||||
ldconfig
|
||||
|
||||
%changelog
|
||||
* Mon Oct 9 2006 - dreynolds@suse.de
|
||||
- Initial package creation.
|
@@ -1,3 +1,4 @@
|
||||
# $Id: Makefile 10 2006-04-12 20:31:08Z steve-beattie $
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 1999, 2004, 2005, 2006 NOVELL (All rights reserved)
|
||||
#
|
||||
@@ -17,7 +18,13 @@ NAME = tomcat_apparmor
|
||||
all:
|
||||
COMMONDIR=../../../common/
|
||||
|
||||
include $(COMMONDIR)/Make.rules
|
||||
include common/Make.rules
|
||||
|
||||
COMMONDIR_EXISTS=$(strip $(shell [ -d ${COMMONDIR} ] && echo true))
|
||||
ifeq ($(COMMONDIR_EXISTS), true)
|
||||
common/Make.rules: $(COMMONDIR)/Make.rules
|
||||
ln -sf $(COMMONDIR) .
|
||||
endif
|
||||
|
||||
LIB = lib
|
||||
CATALINA_HOME = /usr/share/tomcat55
|
||||
@@ -28,6 +35,7 @@ all:
|
||||
|
||||
clean:
|
||||
ant clean
|
||||
rm -f tomcat_apparmor.spec ${NAME}-*.tar.gz Make.rules
|
||||
|
||||
install:
|
||||
ant -Dversion=$(VERSION) -Drelease=$(MAN_RELEASE) -Dcatalina_home=${CATALINA_HOME} -Dinstall_lib=${LIB} install_jar install_jni
|
||||
install: $(SPECFILE)
|
||||
ant -Dversion=$(VERSION) -Drelease=$(RELEASE) -Dcatalina_home=${CATALINA_HOME} -Dinstall_lib=${LIB} install_jar install_jni
|
||||
|
@@ -4,8 +4,8 @@
|
||||
<property name="jni_src" location="src/jni_src"/>
|
||||
<property name="build" location="build"/>
|
||||
<property name="install_root" location="/"/>
|
||||
<property name="catalina_home" location="/usr/share/tomcat6"/>
|
||||
<property name="lib" location="/usr/share/tomcat6/bin"/>
|
||||
<property name="catalina_home" location="/usr/share/tomcat5"/>
|
||||
<property name="lib" location="lib"/>
|
||||
<property name="install_lib" value="/lib"/>
|
||||
<property name="dist" location="dist"/>
|
||||
<property name="jarfile" location="${dist}/${ant.project.name}.jar"/>
|
||||
@@ -18,11 +18,10 @@
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
|
||||
<fileset id="tomcat.jars" dir="${catalina_home}/lib">
|
||||
<fileset id="tomcat.jars" dir="${catalina_home}/server/lib">
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
|
||||
<fileset id="servlet.jars" dir="${catalina_home}/lib">
|
||||
<fileset id="servlet.jars" dir="${catalina_home}/common/lib">
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
|
||||
@@ -81,9 +80,9 @@
|
||||
</target>
|
||||
|
||||
<target name="install_jar" depends="jni_so" description="Install jar file">
|
||||
<mkdir dir="${install_root}/${catalina_home}/lib/"/>
|
||||
<copy file="${jarfile}" tofile="${install_root}/${catalina_home}/lib/${ant.project.name}.jar"/>
|
||||
<chmod perm="644" file="${install_root}/${catalina_home}/lib/${ant.project.name}.jar"/>
|
||||
<mkdir dir="${install_root}/${catalina_home}/server/lib/"/>
|
||||
<copy file="${jarfile}" tofile="${install_root}/${catalina_home}/server/lib/${ant.project.name}.jar"/>
|
||||
<chmod perm="644" file="${install_root}/${catalina_home}/server/lib/${ant.project.name}.jar"/>
|
||||
</target>
|
||||
|
||||
<target name="clean" description="Remove build and dist directories">
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#include "jni.h"
|
||||
#include <errno.h>
|
||||
#include <sys/apparmor.h>
|
||||
#include "sys/apparmor.h"
|
||||
#include "com_novell_apparmor_JNIChangeHat.h"
|
||||
|
||||
/* c intermediate lib call for Java -> JNI -> c library execution of the change_hat call */
|
||||
|
@@ -4,7 +4,7 @@ LIB = lib/
|
||||
LIBDIR = /usr/${LIB}
|
||||
INCLUDE = ${LIBDIR}/jvm/java/include
|
||||
CFLAGS = -g -O2 -Wall -Wstrict-prototypes -Wl,-soname,$@.${SO_VERS} -pipe -fpic -D_REENTRANT
|
||||
INCLUDES = -I$(INCLUDE) -I$(INCLUDE)/linux -I$(TOP)/../../../libraries/libapparmor/src/
|
||||
INCLUDES = -I$(INCLUDE) -I$(INCLUDE)/linux
|
||||
CLASSFILE = ${CLASSPATH}/com/novell/apparmor/${JAVA_CLASSNAME}.class
|
||||
DESTDIR = ${TOP}/dist
|
||||
SO_VERS = 1
|
||||
@@ -20,7 +20,7 @@ ${JAVA_CLASSNAME}.java com_novell_apparmor_${JAVA_CLASSNAME}.h: ${CLASSFILE}
|
||||
javah -jni -classpath ${CLASSPATH} com.novell.apparmor.${JAVA_CLASSNAME}
|
||||
|
||||
${TARGET}.so: ${JAVA_CLASSNAME}.c ${JAVA_CLASSNAME}.java com_novell_apparmor_${JAVA_CLASSNAME}.h
|
||||
gcc ${INCLUDES} ${CFLAGS} -shared -o ${TARGET}.so ${JAVA_CLASSNAME}.c -L$(TOP)/../../../libraries/libapparmor/src/.libs -lapparmor
|
||||
gcc ${INCLUDES} ${CFLAGS} -shared -o ${TARGET}.so ${JAVA_CLASSNAME}.c -lapparmor
|
||||
|
||||
install: ${TARGET}.so
|
||||
install -d $(DESTDIR)/${LIB} $(DESTDIR)${LIBDIR}
|
||||
|
87
changehat/tomcat_apparmor/tomcat_5_5/tomcat_apparmor.spec.in
Normal file
87
changehat/tomcat_apparmor/tomcat_5_5/tomcat_apparmor.spec.in
Normal file
@@ -0,0 +1,87 @@
|
||||
# $Id:$
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2006 NOVELL (All rights reserved)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
# norootforbuild
|
||||
|
||||
# Check first to see if distro is already defined.
|
||||
|
||||
%if ! %{?distro:1}0
|
||||
%define distro suse
|
||||
%endif
|
||||
|
||||
%if %{distro} == "suse"
|
||||
%define CATALINA_HOME /usr/share/tomcat55
|
||||
%endif
|
||||
%define APPARMOR_DOC_DIR /usr/share/doc/packages/apparmor-docs/
|
||||
%define JNI_SO libJNIChangeHat.so
|
||||
%define JAR_FILE changeHatValve.jar
|
||||
|
||||
|
||||
Summary: Tomcat 5 plugin for AppArmor change_hat
|
||||
Name: tomcat_apparmor
|
||||
Version: @@immunix_version@@
|
||||
Release: @@repo_version@@
|
||||
Group: System/Libraries
|
||||
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
|
||||
License: LGPL
|
||||
BuildRoot: %{?_tmppath:}%{!?_tmppath:/var/tmp}/%{name}-%{version}-build
|
||||
Url: http://developer.novell.com/wiki/index.php/Novell_AppArmor
|
||||
Prereq: tomcat55, servletapi5
|
||||
BuildRequires: tomcat55, servletapi5, ant, java, libapparmor-devel, java2-devel-packages, apparmor-docs
|
||||
|
||||
%description
|
||||
tomcat_apparmor - is a plugin for Apache Tomcat version 5.x that provides
|
||||
support for AppArmor change_hat for creating AppArmor containers that are
|
||||
bound to discrete elements of processing within the Tomcat servlet
|
||||
container. The AppArmor containers, or "hats", can be created for invidual
|
||||
URL processing or per servlet.
|
||||
|
||||
%prep
|
||||
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
[ "${RPM_BUILD_ROOT}" != "/" ] && rm -rf ${RPM_BUILD_ROOT}
|
||||
|
||||
ant -Dinstall_lib=%{_lib} -Dcatalina_home=%{CATALINA_HOME} -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dtarget=1.4 jar jni_so
|
||||
|
||||
%install
|
||||
ant -Ddist=${RPM_BUILD_DIR}/%{name}-%{version} -Dversion=%{version} -Drelease=%{release} -Dcatalina_home=%{CATALINA_HOME} -Dinstall_root=${RPM_BUILD_ROOT} -Dinstall_lib=%{_lib} install_jar install_jni
|
||||
|
||||
mkdir -p ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
|
||||
install ${RPM_BUILD_DIR}/%{name}-%{version}/README.tomcat_apparmor ${RPM_BUILD_ROOT}%{APPARMOR_DOC_DIR}
|
||||
|
||||
%clean
|
||||
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%{CATALINA_HOME}/server/lib/%{JAR_FILE}
|
||||
/%{_lib}/lib*
|
||||
/%{_libdir}/lib*
|
||||
doc %attr(0644,root,root) %{APPARMOR_DOC_DIR}/README.tomcat_apparmor
|
||||
|
||||
%post
|
||||
ldconfig
|
||||
|
||||
%postun
|
||||
ldconfig
|
||||
|
||||
%changelog
|
||||
* Mon Jul 20 2007 - sbeattie@suse.de
|
||||
- Convert builddep on libapparmor to libapparmor-devel
|
||||
* Mon Oct 9 2006 - dreynolds@suse.de
|
||||
- Initial package creation.
|
@@ -1,19 +1,12 @@
|
||||
# $Id$
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 1999-2008 NOVELL (All rights reserved)
|
||||
# Copyright 2009-2015 Canonical Ltd.
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
#
|
||||
# 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.
|
||||
# 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.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# The including makefile needs to define LANG, which lists the lang
|
||||
@@ -21,14 +14,13 @@
|
||||
# exist
|
||||
LOCALEDIR=/usr/share/locale
|
||||
|
||||
XGETTEXT_ARGS=--copyright-holder="Canonical Ltd" --msgid-bugs-address=apparmor@lists.ubuntu.com -d ${NAME}
|
||||
XGETTEXT_ARGS=--copyright-holder="NOVELL, Inc." --msgid-bugs-address=apparmor-general@forge.novell.com -d ${NAME}
|
||||
|
||||
# When making the .pot file, it's expected that the parent Makefile will
|
||||
# pass in the list of sources in the SOURCES variable
|
||||
PARENT_SOURCES=$(foreach source, ${SOURCES}, ../${source})
|
||||
|
||||
# Can override by passing LANGS=whatever here
|
||||
LANGS?=$(patsubst %.po, %, $(wildcard *.po))
|
||||
LANGS=$(patsubst %.po, %, $(wildcard *.po))
|
||||
TARGET_MOS=$(foreach lang, $(filter-out $(DISABLED_LANGS),$(LANGS)), ${lang}.mo)
|
||||
|
||||
.PHONY: all
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# $Id$
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
# Copyright (C) 2010-2015 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
|
||||
@@ -15,100 +15,164 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ------------------------------------------------------------------
|
||||
# Make.rules - common make targets and variables for building AppArmor
|
||||
# Make.rules - common make targets and variables for building the SHASS
|
||||
# product.
|
||||
#
|
||||
# NOTES:
|
||||
# Before including this file in your Makefile, you should
|
||||
# - define COMMONDIR (the location of the common/ directory)
|
||||
# - define the default rule (usually 'all:'). (Note: you can redefine
|
||||
# it later in your Makefile)
|
||||
|
||||
.PHONY: common_Make.rules_is_a_bad_target
|
||||
common_Make.rules_is_a_bad_target:
|
||||
@echo "*** default target in common/Make.rules hit - either you did something strange, or something is broken... ***"
|
||||
exit 1
|
||||
# - must define the package NAME before including this file.
|
||||
# - After checking in to cvs, you'll need to delele the hardlinked
|
||||
# Make.rules files that already exist in the individual application
|
||||
# directories
|
||||
|
||||
DISTRIBUTION=AppArmor
|
||||
VERSION=$(shell cat $(COMMONDIR)/Version)
|
||||
VERSION=2.3
|
||||
|
||||
# Convenience functions
|
||||
pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))
|
||||
map = $(foreach a,$(2),$(call $(1),$(a)))
|
||||
# OVERRIDABLE variables
|
||||
# Set these variables before including Make.rules to change its behavior
|
||||
# SPECFILE - for packages that have a non-standard specfile name
|
||||
# EXTERNAL_PACKAGE - for packages that have upstream versions that
|
||||
# we're locally modifying (e.g. imnxcerttool/gnutls).
|
||||
#
|
||||
# use 'make BUILDIR=/some/where/else/' to override the /usr/src/redhat
|
||||
# location -- it *should* pick out the right thing to do based on the
|
||||
# .rpmmacros file, but you can still use BUILDDIR to override that.
|
||||
TESTBUILDDIR=$(shell [ -f ${HOME}/.rpmmacros ] && awk '/^%_topdir/ {print $$2}' ${HOME}/.rpmmacros)
|
||||
ifndef BUILDDIR
|
||||
BUILDDIR=$(shell if [ -d "${TESTBUILDDIR}" ] ; then \
|
||||
echo ${TESTBUILDDIR} | sed "s^/$$^^" ; \
|
||||
elif [ -d "/usr/src/redhat" ] ; then \
|
||||
echo "/usr/src/redhat" ; \
|
||||
elif [ -d "/usr/src/packages" ] ; then \
|
||||
echo "/usr/src/packages" ; \
|
||||
else \
|
||||
echo "/tmp/${NAME}" ; \
|
||||
fi ;)
|
||||
endif
|
||||
RPMHOSTVENDOR=$(shell rpm --eval "%{_host_vendor}")
|
||||
ifndef DISTRO
|
||||
DISTRO=$(shell if [ -f /etc/slackware-version ] ; then \
|
||||
echo slackware ; \
|
||||
elif [ -f /etc/debian_version ] ; then \
|
||||
echo debian ;\
|
||||
elif [ ${RPMHOSTVENDOR} = "suse" ] ; then \
|
||||
echo suse ;\
|
||||
elif [ ${RPMHOSTVENDOR} = "redhat" ] ; then \
|
||||
echo rhel4 ;\
|
||||
else \
|
||||
echo unknown ;\
|
||||
fi)
|
||||
endif
|
||||
RPMARG=--define "_topdir $(BUILDDIR:/=)" \
|
||||
--define "vendor NOVELL, Inc." \
|
||||
--define "distribution ${DISTRIBUTION}" \
|
||||
--define "debug_package %{nil}" \
|
||||
--define "immunix_version ${VERSION}" \
|
||||
$(shell [ -d ${BUILDDIR}/BUILDROOT ] && echo --define \"buildroot $(BUILDDIR:/=)/BUILDROOT\") \
|
||||
$(shell [ -n "${DISTRO}" ] && echo --define \"distro ${DISTRO}\")
|
||||
|
||||
AWK:=$(shell which awk)
|
||||
ifndef AWK
|
||||
$(error awk utility required for build but not available)
|
||||
#REPO_VERSION=$(shell if [ -x /usr/bin/svn ] ; then \
|
||||
# if ! /usr/bin/svn info -r HEAD . 2> /dev/null | grep "^Last Changed Rev:" | sed "s/^Last Changed Rev: //" ; then \
|
||||
# /usr/bin/svn info . 2> /dev/null | grep "^Last Changed Rev:" | sed "s/^Last Changed Rev: //" ; \
|
||||
# fi ; \
|
||||
# fi)
|
||||
REPO_VERSION=$(shell if [ -x /usr/bin/svn ] ; then \
|
||||
/usr/bin/svn info . 2> /dev/null | grep "^Last Changed Rev:" | sed "s/^Last Changed Rev: //" ; \
|
||||
fi)
|
||||
REPO_URL=$(shell if [ -x /usr/bin/svn ] ; then \
|
||||
/usr/bin/svn info . 2> /dev/null | grep "^URL:" | sed "s/^URL: //" ; \
|
||||
fi)
|
||||
COMMON_REPO_URL=$(shell if [ -x /usr/bin/svn ] ; then \
|
||||
/usr/bin/svn info $(COMMONDIR) 2> /dev/null | grep "^URL:" | sed "s/^URL: //" ; \
|
||||
fi)
|
||||
|
||||
ifdef EXTERNAL_PACKAGE
|
||||
RPMARG+=--define "_sourcedir $(shell pwd)"
|
||||
endif
|
||||
|
||||
define nl
|
||||
ifndef SPECFILE
|
||||
SPECFILE = $(NAME).spec
|
||||
endif
|
||||
RELEASE = $(shell rpm -q --specfile --define "_sourcedir ." ${RPMARG} --qf "%{RELEASE}" ${SPECFILE})
|
||||
RELEASE_DIR = $(NAME)-$(VERSION)
|
||||
TARBALL = $(NAME)-$(VERSION)-${REPO_VERSION}.tar.gz
|
||||
TAR = /bin/tar czvp -h --exclude .svn --exclude CVS --exclude .cvsignore --exclude ${TARBALL} --exclude ${RELEASE_DIR}/${RELEASE_DIR} $(shell test -f ${NAME}.exclude && echo "-X ${NAME}.exclude")
|
||||
LDCONFIG = /sbin/ldconfig
|
||||
|
||||
CVSPKG_VERSION=$(shell rpm -q --specfile --define "_sourcedir ." ${RPMARG} ${SPECFILE} | head -1 | tr "." "_")
|
||||
|
||||
endef
|
||||
RPMSUBDIRS=SOURCES SPECS BUILD BUILDROOT SRPMS RPMS/i386 RPMS/i586 \
|
||||
RPMS/i686 RPMS/athlon RPMS/noarch RPMS/x86_64
|
||||
BUILDRPMSUBDIRS=$(foreach subdir, $(RPMSUBDIRS), $(BUILDDIR:/=)/$(subdir))
|
||||
|
||||
REPO_VERSION_CMD=[ -x /usr/bin/bzr ] && /usr/bin/bzr version-info --custom --template="{revno}" . 2> /dev/null || awk '{ print $2 }' common/.stamp_rev
|
||||
.PHONY: cvs_tag
|
||||
cvs_tag:
|
||||
cvs tag IMMUNIX-${CVSPKG_VERSION}
|
||||
|
||||
ifndef PYTHON_VERSIONS
|
||||
PYTHON_VERSIONS = $(call map, pathsearch, python2 python3)
|
||||
.PHONY: checkin
|
||||
checkin:
|
||||
if cvs -q up -d | grep -q "^\?" ; then echo "Hey! You have" \
|
||||
"files in the directory you have not added into cvs."; exit 1; \
|
||||
fi
|
||||
cvs ci
|
||||
make cvs_tag
|
||||
|
||||
ifdef EXTERNAL_PACKAGE
|
||||
.PHONY: rpm
|
||||
rpm: clean $(BUILDRPMSUBDIRS)
|
||||
rpmbuild -ba ${RPMARG} ${SPECFILE}
|
||||
|
||||
else
|
||||
.PHONY: rpm
|
||||
rpm: clean $(TARBALL) $(BUILDRPMSUBDIRS)
|
||||
cp $(TARBALL) $(BUILDDIR)/SOURCES/
|
||||
cp ${SPECFILE} $(BUILDDIR)/SPECS/
|
||||
rpmbuild -ba ${RPMARG} ${SPECFILE}
|
||||
|
||||
.PHONY: ${SPECFILE}
|
||||
${SPECFILE}: ${SPECFILE}.in
|
||||
sed -e "s/@@immunix_version@@/${VERSION}/g" \
|
||||
-e "s/@@repo_version@@/${REPO_VERSION}/g" $< > $@
|
||||
|
||||
${TARBALL}: clean ${SPECFILE}
|
||||
-rm -rf $(RELEASE_DIR)
|
||||
mkdir $(RELEASE_DIR)
|
||||
$(TAR) . | tar xz -C $(RELEASE_DIR)
|
||||
$(TAR) -f $@ $(RELEASE_DIR)
|
||||
rm -rf $(RELEASE_DIR)
|
||||
|
||||
ifndef OVERRIDE_TARBALL
|
||||
.PHONY: tarball
|
||||
tarball: clean $(TARBALL)
|
||||
endif
|
||||
|
||||
ifndef PYTHON
|
||||
PYTHON = $(firstword ${PYTHON_VERSIONS})
|
||||
endif
|
||||
.PHONY: dist
|
||||
dist: clean $(SPECFILE)
|
||||
-rm -rf $(RELEASE_DIR)
|
||||
svn export -r $(REPO_VERSION) $(REPO_URL) $(RELEASE_DIR)
|
||||
svn export $(COMMON_REPO_URL) $(RELEASE_DIR)/common
|
||||
make -C $(RELEASE_DIR) $(SPECFILE) REPO_VERSION=${REPO_VERSION} COMMONDIR_EXISTS=false
|
||||
$(TAR) -f $(TARBALL) $(RELEASE_DIR)
|
||||
rm -rf $(RELEASE_DIR)
|
||||
|
||||
#Helper function to be used with $(call pyalldo, run_test_with_all.py)
|
||||
pyalldo=set -e; $(foreach py, $(PYTHON_VERSIONS), $(py) $(1);)
|
||||
endif
|
||||
|
||||
.PHONY: version
|
||||
.SILENT: version
|
||||
version:
|
||||
echo $(VERSION)
|
||||
rpm -q --define "_sourcedir ." ${RPMARG} --specfile ${SPECFILE}
|
||||
|
||||
.PHONY: repo_version
|
||||
.SILENT: repo_version
|
||||
repo_version:
|
||||
echo $(shell $(value REPO_VERSION_CMD))
|
||||
.PHONY: build_dir
|
||||
build_dir: $(BUILDRPMSUBDIRS)
|
||||
|
||||
.PHONY: pod_clean
|
||||
ifndef VERBOSE
|
||||
.SILENT: pod_clean
|
||||
endif
|
||||
pod_clean:
|
||||
$(BUILDRPMSUBDIRS):
|
||||
mkdir -p $(BUILDRPMSUBDIRS)
|
||||
|
||||
.PHONY: _clean
|
||||
.SILENT: _clean
|
||||
_clean:
|
||||
-rm -f ${NAME}-${VERSION}-*.tar.gz
|
||||
-rm -f ${MANPAGES} *.[0-9].gz ${HTMLMANPAGES} pod2htm*.tmp
|
||||
|
||||
# =====================
|
||||
# generate list of capabilities based on
|
||||
# /usr/include/linux/capabilities.h for use in multiple locations in
|
||||
# the source tree
|
||||
# =====================
|
||||
|
||||
# emits defined capabilities in a simple list, e.g. "CAP_NAME CAP_NAME2"
|
||||
CAPABILITIES=$(shell echo "\#include <linux/capability.h>" | cpp -dM | LC_ALL=C sed -n -e '/CAP_EMPTY_SET/d' -e 's/^\#define[ \t]\+CAP_\([A-Z0-9_]\+\)[ \t]\+\([0-9xa-f]\+\)\(.*\)$$/CAP_\1/p' | LC_ALL=C sort)
|
||||
|
||||
.PHONY: list_capabilities
|
||||
list_capabilities: /usr/include/linux/capability.h
|
||||
@echo "$(CAPABILITIES)"
|
||||
|
||||
# =====================
|
||||
# generate list of network protocols based on
|
||||
# sys/socket.h for use in multiple locations in
|
||||
# the source tree
|
||||
# =====================
|
||||
|
||||
# These are the families that it doesn't make sense for apparmor
|
||||
# to mediate. We use PF_ here since that is what is required in
|
||||
# bits/socket.h, but we will rewrite these as AF_.
|
||||
|
||||
FILTER_FAMILIES=PF_UNIX
|
||||
|
||||
__FILTER=$(shell echo $(strip $(FILTER_FAMILIES)) | sed -e 's/ /\\\|/g')
|
||||
|
||||
# emits the AF names in a "AF_NAME NUMBER," pattern
|
||||
AF_NAMES=$(shell echo "\#include <sys/socket.h>" | cpp -dM | LC_ALL=C sed -n -e '/$(__FILTER)/d' -e 's/PF_LOCAL/PF_UNIX/' -e 's/^\#define[ \t]\+PF_\([A-Z0-9_]\+\)[ \t]\+\([0-9]\+\).*$$/AF_\1 \2,/p' | sort -n -k2)
|
||||
|
||||
.PHONY: list_af_names
|
||||
list_af_names:
|
||||
@echo "$(AF_NAMES)"
|
||||
|
||||
# =====================
|
||||
# manpages
|
||||
# =====================
|
||||
@@ -127,12 +191,32 @@ install_manpages: $(MANPAGES)
|
||||
$(foreach dir, ${MANDIRS}, \
|
||||
install -d ${DESTDIR}/${MANDIR}/man${dir} ; \
|
||||
install -m 644 $(filter %.${dir}, ${MANPAGES}) ${DESTDIR}/${MANDIR}/man${dir}; \
|
||||
)
|
||||
$(foreach aa_page, $(filter %.${dir}, ${AA_MANPAGES}), \
|
||||
ln -sf $(aa_page) ${DESTDIR}/${MANDIR}/man${dir}/${aa_page:%=aa-%};))
|
||||
|
||||
MAN_RELEASE="AppArmor ${VERSION}"
|
||||
%.1: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=1 > $@
|
||||
|
||||
%.1 %.2 %.3 %.4 %.5 %.6 %.7 %.8: %.pod
|
||||
$(POD2MAN) $< --release=$(MAN_RELEASE) --center=AppArmor --stderr --section=$(subst .,,$(suffix $@)) > $@
|
||||
%.2: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=2 > $@
|
||||
|
||||
%.3: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=3 > $@
|
||||
|
||||
%.4: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=4 > $@
|
||||
|
||||
%.5: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=5 > $@
|
||||
|
||||
%.6: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=6 > $@
|
||||
|
||||
%.7: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=7 > $@
|
||||
|
||||
%.8: %.pod
|
||||
$(POD2MAN) $< --release=NOVELL/SUSE --center=AppArmor --section=8 > $@
|
||||
|
||||
%.1.html: %.pod
|
||||
$(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@
|
||||
@@ -158,6 +242,43 @@ MAN_RELEASE="AppArmor ${VERSION}"
|
||||
%.8.html: %.pod
|
||||
$(POD2HTML) --header --css apparmor.css --infile=$< --outfile=$@
|
||||
|
||||
# =====================
|
||||
# Slackware poo
|
||||
# =====================
|
||||
.PHONY: slack
|
||||
slack:
|
||||
rm -rf ${BUILDDIR}
|
||||
mkdir -p ${BUILDDIR}/install
|
||||
make install DESTDIR=${BUILDDIR} DISTRO=slackware
|
||||
# comment line is there so grep always has something to match
|
||||
( echo "# install script pulled from ${SPECFILE}" ; rpm -q --specfile --define "_sourcedir ." ${RPMARG} --qf "%{POSTIN}\n" ${SPECFILE}) | grep -v "^(none)$$" >> ${BUILDDIR}/install/doinst.sh
|
||||
( cd ${BUILDDIR} && makepkg -l y -c y -p ${PWD}/${NAME}-${VERSION}-${RELEASE}.tgz )
|
||||
|
||||
# =====================
|
||||
# Debian poo
|
||||
# =====================
|
||||
.PHONY: deb
|
||||
deb: ${TARBALL}
|
||||
rm -rf ${BUILDDIR}
|
||||
mkdir -p ${BUILDDIR}
|
||||
tar -xvzf ${TARBALL} -C ${BUILDDIR}
|
||||
( cd ${BUILDDIR}/${RELEASE_DIR} && sh -c "DEBFULLNAME='NOVELL, Inc' dh_make -e apparmor-general@forge.novell.com --library -f ~/svn/immunix/immunix/libimmunix/libimmunix-2.0.tar.gz << EOM \
|
||||
\
|
||||
EOM" )
|
||||
make ${NAME}-deb -C ${BUILDDIR}/${RELEASE_DIR}
|
||||
# ( cd ${BUILDDIR}/${RELEASE_DIR} && dpkg-buildpackage -b -sd -rfakeroot)
|
||||
|
||||
DEBIAN_DISTRO=stable
|
||||
|
||||
DEB_CHANGELOG_OUTPUT="${NAME} (${VERSION}-${RELEASE}) ${DEBIAN_DISTRO}; urgency=low\n\
|
||||
\n * Automatically generated by the AppArmor Build System.\n\
|
||||
\n -- AppArmor Development Team <apparmor-general@forge.novell.com> $(shell date -R)"
|
||||
|
||||
|
||||
.PHONY: debian/changelog
|
||||
debian/changelog:
|
||||
echo -e ${DEB_CHANGELOG_OUTPUT} > $@
|
||||
|
||||
A2PS_ARGS=-Ec -g --line-numbers=1
|
||||
ENSCRIPT_ARGS=-C -2jGr -f Courier6 -E
|
||||
%.c.ps: %.c
|
||||
@@ -166,7 +287,3 @@ ENSCRIPT_ARGS=-C -2jGr -f Courier6 -E
|
||||
|
||||
%.pm.ps: %.pm
|
||||
enscript ${ENSCRIPT_ARGS} -o $@ $<
|
||||
|
||||
.PHONY: check_pod_files
|
||||
check_pod_files:
|
||||
LANG=C podchecker -warning -warning *.pod
|
||||
|
@@ -1 +0,0 @@
|
||||
2.11.95
|
@@ -1,62 +0,0 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 1999, 2004-2009 NOVELL (All rights reserved)
|
||||
# Copyright (c) 2010-2011, 2014 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.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Novell, Inc.
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# NOTE: this Makefile has been adjusted from the original to assist in
|
||||
# the installation of the Immunix perl modules, if they're still needed
|
||||
# by users. Because the utilities conflict with their replacments, make
|
||||
# install *will* *not* install them.
|
||||
|
||||
NAME = apparmor-utils
|
||||
all:
|
||||
COMMONDIR=../../common/
|
||||
|
||||
include $(COMMONDIR)/Make.rules
|
||||
|
||||
MODDIR = Immunix
|
||||
PERLTOOLS = aa-genprof aa-logprof aa-autodep aa-audit aa-complain aa-enforce \
|
||||
aa-unconfined aa-disable
|
||||
MODULES = ${MODDIR}/AppArmor.pm ${MODDIR}/Repository.pm \
|
||||
${MODDIR}/Config.pm ${MODDIR}/Severity.pm
|
||||
|
||||
all:
|
||||
|
||||
# need some better way of determining this
|
||||
DESTDIR=/
|
||||
BINDIR=${DESTDIR}/usr/sbin
|
||||
CONFDIR=${DESTDIR}/etc/apparmor
|
||||
VENDOR_PERL=$(shell perl -e 'use Config; print $$Config{"vendorlib"};')
|
||||
PERLDIR=${DESTDIR}${VENDOR_PERL}/${MODDIR}
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
install -d ${PERLDIR}
|
||||
install -m 644 ${MODULES} ${PERLDIR}
|
||||
|
||||
.PHONY: clean
|
||||
ifndef VERBOSE
|
||||
.SILENT: clean
|
||||
endif
|
||||
clean: pod_clean
|
||||
rm -f core core.* *.o *.s *.a *~
|
||||
rm -rf staging/ build/
|
||||
|
||||
.PHONY: check
|
||||
.SILENT: check
|
||||
check:
|
||||
for i in ${MODULES} ${PERLTOOLS} ; do \
|
||||
perl -c $$i || exit 1; \
|
||||
done
|
@@ -1,152 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2005-2010 Novell, Inc. All Rights Reserved.
|
||||
# Copyright (c) 2011 Canonical, Inc. All Rights Reserved.
|
||||
#
|
||||
# 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 as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, contact Canonical, Inc.
|
||||
#
|
||||
# To contact Canonical about this file by physical or electronic mail,
|
||||
# you may find current contact information at www.canonical.com.
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
use strict;
|
||||
use FindBin;
|
||||
use Getopt::Long;
|
||||
|
||||
use Immunix::AppArmor;
|
||||
|
||||
use Data::Dumper;
|
||||
|
||||
use Locale::gettext;
|
||||
use POSIX;
|
||||
use File::Basename;
|
||||
|
||||
# initialize the local poo
|
||||
setlocale(LC_MESSAGES, "");
|
||||
textdomain("apparmor-utils");
|
||||
|
||||
$UI_Mode = "text";
|
||||
|
||||
# options variables
|
||||
my $help = '';
|
||||
|
||||
GetOptions(
|
||||
'dir|d=s' => \$profiledir,
|
||||
'help|h' => \$help,
|
||||
);
|
||||
|
||||
# tell 'em how to use it...
|
||||
&usage && exit if $help;
|
||||
|
||||
# let's convert it to full path...
|
||||
$profiledir = get_full_path($profiledir);
|
||||
|
||||
unless (-d $profiledir) {
|
||||
UI_Important("Can't find AppArmor profiles in $profiledir.");
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $disabledir = "$profiledir/disable";
|
||||
unless (-d $disabledir) {
|
||||
UI_Important("Can't find AppArmor disable directory '$disabledir'.");
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# what are we profiling?
|
||||
my @profiling = @ARGV;
|
||||
|
||||
unless (@profiling) {
|
||||
@profiling = (UI_GetString(gettext("Please enter the program whose profile should be disabled: "), ""));
|
||||
}
|
||||
|
||||
for my $profiling (@profiling) {
|
||||
|
||||
next unless $profiling;
|
||||
|
||||
my $fqdbin;
|
||||
if (-e $profiling) {
|
||||
$fqdbin = get_full_path($profiling);
|
||||
chomp($fqdbin);
|
||||
} else {
|
||||
if ($profiling !~ /\//) {
|
||||
opendir(DIR,$profiledir);
|
||||
my @tmp_fqdbin = grep ( /$profiling/, readdir(DIR));
|
||||
closedir(DIR);
|
||||
if (scalar @tmp_fqdbin eq 1) {
|
||||
$fqdbin = "$profiledir/$tmp_fqdbin[0]";
|
||||
} else {
|
||||
my $which = which($profiling);
|
||||
if ($which) {
|
||||
$fqdbin = get_full_path($which);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (-e $fqdbin) {
|
||||
|
||||
my $filename;
|
||||
if ($fqdbin =~ /^$profiledir\//) {
|
||||
$filename = $fqdbin;
|
||||
} else {
|
||||
$filename = getprofilefilename($fqdbin);
|
||||
}
|
||||
|
||||
# argh, skip directories
|
||||
next unless -f $filename;
|
||||
|
||||
# skip package manager backup files
|
||||
next if isSkippableFile($filename);
|
||||
|
||||
my ($bname, $dname, $suffix) = File::Basename::fileparse($filename);
|
||||
if ($bname eq "") {
|
||||
UI_Info(sprintf(gettext('Could not find basename for %s.'), $filename));
|
||||
exit 1;
|
||||
}
|
||||
|
||||
printf(gettext('Disabling %s.'), $fqdbin);
|
||||
print "\n";
|
||||
|
||||
my $link = "$disabledir/$bname";
|
||||
if (! -e $link) {
|
||||
if (symlink($filename, $link) != 1) {
|
||||
UI_Info(sprintf(gettext('Could not create %s symlink.'), $link));
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
my $cmd_info = qx(cat $filename | $parser -I$profiledir -R 2>&1 1>/dev/null);
|
||||
if ($? != 0) {
|
||||
UI_Info($cmd_info);
|
||||
exit $?;
|
||||
}
|
||||
|
||||
# if check_for_subdomain();
|
||||
} else {
|
||||
if ($profiling =~ /^[^\/]+$/) {
|
||||
UI_Info(sprintf(gettext('Can\'t find %s in the system path list. If the name of the application is correct, please run \'which %s\' as a user with the correct PATH environment set up in order to find the fully-qualified path.'), $profiling, $profiling));
|
||||
exit 1;
|
||||
} else {
|
||||
UI_Info(sprintf(gettext('%s does not exist, please double-check the path.'), $profiling));
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
sub usage {
|
||||
UI_Info(sprintf(gettext("usage: \%s [ -d /path/to/profiles ] [ program to have profile disabled ]"), $0));
|
||||
exit 0;
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,36 +0,0 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (c) 2016 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.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# ----------------------------------------------------------------------
|
||||
NAME = documentation
|
||||
all:
|
||||
COMMONDIR=../common/
|
||||
|
||||
include $(COMMONDIR)/Make.rules
|
||||
|
||||
all: docs
|
||||
|
||||
SOURCES:= $(wildcard *.odt)
|
||||
DOCS:=$(SOURCES:.odt=.pdf)
|
||||
|
||||
.PHONY: docs
|
||||
docs: $(DOCS)
|
||||
|
||||
%.pdf: %.odt
|
||||
unoconv -v -f pdf --output "$@" "$<"
|
||||
|
||||
.PHONY: clean
|
||||
ifndef VERBOSE
|
||||
.SILENT: clean
|
||||
endif
|
||||
clean:
|
||||
rm -f *.pdf
|
||||
|
Binary file not shown.
144
kernel-patches/2.6.24/__d_path-keep-connected.diff
Normal file
144
kernel-patches/2.6.24/__d_path-keep-connected.diff
Normal file
@@ -0,0 +1,144 @@
|
||||
From: John Johansen <jjohansen@suse.de>
|
||||
Subject: Fix __d_path to allow for old and new behavior bnc#380763
|
||||
|
||||
Fix __d_path so that it can be told whether or not to connect
|
||||
disconnect path to the root. This is easier and more efficient
|
||||
than trying to reconnect these paths for d_path and get_cwd
|
||||
after the fact.
|
||||
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/dcache.c | 57 ++++++++++++++++++-------------------------------
|
||||
fs/namespace.c | 2 -
|
||||
include/linux/dcache.h | 2 -
|
||||
3 files changed, 24 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -1772,6 +1772,7 @@ shouldnt_be_hashed:
|
||||
* @buffer: buffer to return value in
|
||||
* @buflen: buffer length
|
||||
* @fail_deleted: what to return for deleted files
|
||||
+ * @disconnect: don't return a path starting with / when disconnected
|
||||
*
|
||||
* Convert a dentry into an ASCII path name. If the entry has been deleted,
|
||||
* then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise,
|
||||
@@ -1784,9 +1785,10 @@ shouldnt_be_hashed:
|
||||
*/
|
||||
char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
struct dentry *root, struct vfsmount *rootmnt,
|
||||
- char *buffer, int buflen, int fail_deleted)
|
||||
+ char *buffer, int buflen, int fail_deleted, int disconnect)
|
||||
{
|
||||
- int namelen, is_slash, vfsmount_locked = 0;
|
||||
+ int namelen, vfsmount_locked = 0;
|
||||
+ const unsigned char *name;
|
||||
|
||||
if (buflen < 2)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
@@ -1847,27 +1849,26 @@ global_root:
|
||||
* unconnected dentry, or the file is on a pseudo filesystem.
|
||||
*/
|
||||
namelen = dentry->d_name.len;
|
||||
- is_slash = (namelen == 1 && *dentry->d_name.name == '/');
|
||||
- if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) {
|
||||
- /*
|
||||
- * Make sure we won't return a pathname starting with '/'.
|
||||
- *
|
||||
- * Historically, we also glue together the root dentry and
|
||||
- * remaining name for pseudo filesystems like pipefs, which
|
||||
- * have the MS_NOUSER flag set. This results in pathnames
|
||||
- * like "pipe:[439336]".
|
||||
- */
|
||||
- if (*buffer == '/') {
|
||||
- buffer++;
|
||||
- buflen++;
|
||||
- }
|
||||
- if (is_slash)
|
||||
- goto out;
|
||||
+ name = dentry->d_name.name;
|
||||
+
|
||||
+ /*
|
||||
+ * If this is a root dentry, then overwrite the slash. This
|
||||
+ * will also DTRT with pseudo filesystems which have root
|
||||
+ * dentries named "foo:".
|
||||
+ */
|
||||
+ if (IS_ROOT(dentry)) {
|
||||
+ buffer++;
|
||||
+ buflen++;
|
||||
+ }
|
||||
+ if (disconnect && *name == '/') {
|
||||
+ /* Make sure we won't return a pathname starting with '/' */
|
||||
+ name++;
|
||||
+ namelen--;
|
||||
}
|
||||
if (buflen < namelen)
|
||||
goto Elong;
|
||||
buffer -= namelen;
|
||||
- memcpy(buffer, dentry->d_name.name, namelen);
|
||||
+ memcpy(buffer, name, namelen);
|
||||
goto out;
|
||||
|
||||
Elong:
|
||||
@@ -1875,18 +1876,6 @@ Elong:
|
||||
goto out;
|
||||
}
|
||||
|
||||
-static char *__connect_d_path(char *path, char *buffer)
|
||||
-{
|
||||
- if (!IS_ERR(path) && *path != '/') {
|
||||
- /* Pretend that disconnected paths are hanging off the root. */
|
||||
- if (path == buffer)
|
||||
- path = ERR_PTR(-ENAMETOOLONG);
|
||||
- else
|
||||
- *--path = '/';
|
||||
- }
|
||||
- return path;
|
||||
-}
|
||||
-
|
||||
/* write full pathname into buffer and return start of pathname */
|
||||
char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf,
|
||||
int buflen)
|
||||
@@ -1909,8 +1898,7 @@ char *d_path(struct dentry *dentry, stru
|
||||
rootmnt = mntget(current->fs->rootmnt);
|
||||
root = dget(current->fs->root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
- res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0);
|
||||
- res = __connect_d_path(res, buf);
|
||||
+ res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0, 0);
|
||||
dput(root);
|
||||
mntput(rootmnt);
|
||||
return res;
|
||||
@@ -1972,8 +1960,7 @@ asmlinkage long sys_getcwd(char __user *
|
||||
root = dget(current->fs->root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
|
||||
- cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1);
|
||||
- cwd = __connect_d_path(cwd, page);
|
||||
+ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1, 0);
|
||||
error = PTR_ERR(cwd);
|
||||
if (IS_ERR(cwd))
|
||||
goto out;
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -1901,7 +1901,7 @@ char *d_namespace_path(struct dentry *de
|
||||
mntput(rootmnt);
|
||||
if (nsrootmnt)
|
||||
root = dget(nsrootmnt->mnt_root);
|
||||
- res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1);
|
||||
+ res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1, 1);
|
||||
dput(root);
|
||||
mntput(nsrootmnt);
|
||||
/* Prevent empty path for lazily unmounted filesystems. */
|
||||
--- a/include/linux/dcache.h
|
||||
+++ b/include/linux/dcache.h
|
||||
@@ -301,7 +301,7 @@ extern int d_validate(struct dentry *, s
|
||||
extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
|
||||
|
||||
extern char *__d_path(struct dentry *, struct vfsmount *, struct dentry *,
|
||||
- struct vfsmount *, char *, int, int);
|
||||
+ struct vfsmount *, char *, int, int, int);
|
||||
extern char * d_path(struct dentry *, struct vfsmount *, char *, int);
|
||||
|
||||
/* Allocation counts.. */
|
72
kernel-patches/2.6.24/apparmor-audit.diff
Normal file
72
kernel-patches/2.6.24/apparmor-audit.diff
Normal file
@@ -0,0 +1,72 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Export audit subsystem for use by modules
|
||||
|
||||
Update kenel audit range comments to show AppArmor's registered range of
|
||||
1500-1599. This range used to be reserved for LSPP but LSPP uses the
|
||||
SE Linux range and the range was given to AppArmor.
|
||||
Adds necessary export symbols for audit subsystem routines.
|
||||
Changes audit_log_vformat to be externally visible (analagous to vprintf)
|
||||
Patch is not in mainline -- pending AppArmor code submission to lkml
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
include/linux/audit.h | 12 +++++++++++-
|
||||
kernel/audit.c | 6 ++++--
|
||||
2 files changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/include/linux/audit.h
|
||||
+++ b/include/linux/audit.h
|
||||
@@ -33,7 +33,7 @@
|
||||
* 1200 - 1299 messages internal to the audit daemon
|
||||
* 1300 - 1399 audit event messages
|
||||
* 1400 - 1499 SE Linux use
|
||||
- * 1500 - 1599 kernel LSPP events
|
||||
+ * 1500 - 1599 AppArmor use
|
||||
* 1600 - 1699 kernel crypto events
|
||||
* 1700 - 1799 kernel anomaly records
|
||||
* 1800 - 1999 future kernel use (maybe integrity labels and related events)
|
||||
@@ -116,6 +116,13 @@
|
||||
#define AUDIT_MAC_IPSEC_DELSPD 1414 /* Not used */
|
||||
#define AUDIT_MAC_IPSEC_EVENT 1415 /* Audit an IPSec event */
|
||||
|
||||
+#define AUDIT_APPARMOR_AUDIT 1501 /* AppArmor audited grants */
|
||||
+#define AUDIT_APPARMOR_ALLOWED 1502 /* Allowed Access for learning */
|
||||
+#define AUDIT_APPARMOR_DENIED 1503
|
||||
+#define AUDIT_APPARMOR_HINT 1504 /* Process Tracking information */
|
||||
+#define AUDIT_APPARMOR_STATUS 1505 /* Changes in config */
|
||||
+#define AUDIT_APPARMOR_ERROR 1506 /* Internal AppArmor Errors */
|
||||
+
|
||||
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
|
||||
#define AUDIT_LAST_KERN_ANOM_MSG 1799
|
||||
#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
|
||||
@@ -513,6 +520,9 @@ extern void audit_log(struct audit_
|
||||
__attribute__((format(printf,4,5)));
|
||||
|
||||
extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
|
||||
+extern void audit_log_vformat(struct audit_buffer *ab,
|
||||
+ const char *fmt, va_list args)
|
||||
+ __attribute__((format(printf,2,0)));
|
||||
extern void audit_log_format(struct audit_buffer *ab,
|
||||
const char *fmt, ...)
|
||||
__attribute__((format(printf,2,3)));
|
||||
--- a/kernel/audit.c
|
||||
+++ b/kernel/audit.c
|
||||
@@ -1215,8 +1215,7 @@ static inline int audit_expand(struct au
|
||||
* will be called a second time. Currently, we assume that a printk
|
||||
* can't format message larger than 1024 bytes, so we don't either.
|
||||
*/
|
||||
-static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
|
||||
- va_list args)
|
||||
+void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args)
|
||||
{
|
||||
int len, avail;
|
||||
struct sk_buff *skb;
|
||||
@@ -1471,3 +1470,6 @@ EXPORT_SYMBOL(audit_log_start);
|
||||
EXPORT_SYMBOL(audit_log_end);
|
||||
EXPORT_SYMBOL(audit_log_format);
|
||||
EXPORT_SYMBOL(audit_log);
|
||||
+EXPORT_SYMBOL_GPL(audit_log_vformat);
|
||||
+EXPORT_SYMBOL_GPL(audit_log_untrustedstring);
|
||||
+EXPORT_SYMBOL_GPL(audit_log_d_path);
|
30
kernel-patches/2.6.24/apparmor-intree.diff
Normal file
30
kernel-patches/2.6.24/apparmor-intree.diff
Normal file
@@ -0,0 +1,30 @@
|
||||
From: John Johansen <jjohansen@suse.de>
|
||||
Subject: Add AppArmor LSM to security/Makefile
|
||||
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
|
||||
---
|
||||
security/Kconfig | 1 +
|
||||
security/Makefile | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
--- a/security/Kconfig
|
||||
+++ b/security/Kconfig
|
||||
@@ -104,6 +104,7 @@ config SECURITY_ROOTPLUG
|
||||
If you are unsure how to answer this question, answer N.
|
||||
|
||||
source security/selinux/Kconfig
|
||||
+source security/apparmor/Kconfig
|
||||
|
||||
endmenu
|
||||
|
||||
--- a/security/Makefile
|
||||
+++ b/security/Makefile
|
||||
@@ -14,5 +14,6 @@ endif
|
||||
obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o
|
||||
# Must precede capability.o in order to stack properly.
|
||||
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
|
||||
+obj-$(CONFIG_SECURITY_APPARMOR) += commoncap.o apparmor/
|
||||
obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
|
||||
obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
|
904
kernel-patches/2.6.24/apparmor-lsm.diff
Normal file
904
kernel-patches/2.6.24/apparmor-lsm.diff
Normal file
@@ -0,0 +1,904 @@
|
||||
From: John Johansen <jjohansen@suse.de>
|
||||
Subject: AppArmor: Module and LSM hooks
|
||||
|
||||
Module parameters, LSM hooks, initialization and teardown.
|
||||
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
|
||||
---
|
||||
security/apparmor/lsm.c | 889 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 889 insertions(+)
|
||||
|
||||
--- /dev/null
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -0,0 +1,889 @@
|
||||
+/*
|
||||
+ * Copyright (C) 1998-2007 Novell/SUSE
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation, version 2 of the
|
||||
+ * License.
|
||||
+ *
|
||||
+ * AppArmor LSM interface
|
||||
+ */
|
||||
+
|
||||
+#include <linux/security.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/mman.h>
|
||||
+#include <linux/mount.h>
|
||||
+#include <linux/namei.h>
|
||||
+#include <linux/ctype.h>
|
||||
+#include <linux/sysctl.h>
|
||||
+#include <linux/audit.h>
|
||||
+
|
||||
+#include "apparmor.h"
|
||||
+#include "inline.h"
|
||||
+
|
||||
+/* Flag indicating whether initialization completed */
|
||||
+int apparmor_initialized = 0;
|
||||
+
|
||||
+static int param_set_aabool(const char *val, struct kernel_param *kp);
|
||||
+static int param_get_aabool(char *buffer, struct kernel_param *kp);
|
||||
+#define param_check_aabool(name, p) __param_check(name, p, int)
|
||||
+
|
||||
+static int param_set_aauint(const char *val, struct kernel_param *kp);
|
||||
+static int param_get_aauint(char *buffer, struct kernel_param *kp);
|
||||
+#define param_check_aauint(name, p) __param_check(name, p, int)
|
||||
+
|
||||
+/* Flag values, also controllable via /sys/module/apparmor/parameters
|
||||
+ * We define special types as we want to do additional mediation.
|
||||
+ *
|
||||
+ * Complain mode -- in complain mode access failures result in auditing only
|
||||
+ * and task is allowed access. audit events are processed by userspace to
|
||||
+ * generate policy. Default is 'enforce' (0).
|
||||
+ * Value is also togglable per profile and referenced when global value is
|
||||
+ * enforce.
|
||||
+ */
|
||||
+int apparmor_complain = 0;
|
||||
+module_param_named(complain, apparmor_complain, aabool, S_IRUSR | S_IWUSR);
|
||||
+MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode");
|
||||
+
|
||||
+/* Debug mode */
|
||||
+int apparmor_debug = 0;
|
||||
+module_param_named(debug, apparmor_debug, aabool, S_IRUSR | S_IWUSR);
|
||||
+MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode");
|
||||
+
|
||||
+/* Audit mode */
|
||||
+int apparmor_audit = 0;
|
||||
+module_param_named(audit, apparmor_audit, aabool, S_IRUSR | S_IWUSR);
|
||||
+MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode");
|
||||
+
|
||||
+/* Syscall logging mode */
|
||||
+int apparmor_logsyscall = 0;
|
||||
+module_param_named(logsyscall, apparmor_logsyscall, aabool, S_IRUSR | S_IWUSR);
|
||||
+MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode");
|
||||
+
|
||||
+/* Maximum pathname length before accesses will start getting rejected */
|
||||
+unsigned int apparmor_path_max = 2 * PATH_MAX;
|
||||
+module_param_named(path_max, apparmor_path_max, aauint, S_IRUSR | S_IWUSR);
|
||||
+MODULE_PARM_DESC(apparmor_path_max, "Maximum pathname length allowed");
|
||||
+
|
||||
+/* Boot time disable flag */
|
||||
+#ifdef CONFIG_SECURITY_APPARMOR_DISABLE
|
||||
+#define AA_ENABLED_PERMS 0600
|
||||
+#else
|
||||
+#define AA_ENABLED_PERMS 0400
|
||||
+#endif
|
||||
+static int param_set_aa_enabled(const char *val, struct kernel_param *kp);
|
||||
+unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
|
||||
+module_param_call(enabled, param_set_aa_enabled, param_get_aauint,
|
||||
+ &apparmor_enabled, AA_ENABLED_PERMS);
|
||||
+MODULE_PARM_DESC(apparmor_enabled, "Enable/Disable Apparmor on boot");
|
||||
+
|
||||
+static int __init apparmor_enabled_setup(char *str)
|
||||
+{
|
||||
+ apparmor_enabled = simple_strtol(str, NULL, 0);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("apparmor=", apparmor_enabled_setup);
|
||||
+
|
||||
+static int param_set_aabool(const char *val, struct kernel_param *kp)
|
||||
+{
|
||||
+ if (aa_task_context(current))
|
||||
+ return -EPERM;
|
||||
+ return param_set_bool(val, kp);
|
||||
+}
|
||||
+
|
||||
+static int param_get_aabool(char *buffer, struct kernel_param *kp)
|
||||
+{
|
||||
+ if (aa_task_context(current))
|
||||
+ return -EPERM;
|
||||
+ return param_get_bool(buffer, kp);
|
||||
+}
|
||||
+
|
||||
+static int param_set_aauint(const char *val, struct kernel_param *kp)
|
||||
+{
|
||||
+ if (aa_task_context(current))
|
||||
+ return -EPERM;
|
||||
+ return param_set_uint(val, kp);
|
||||
+}
|
||||
+
|
||||
+static int param_get_aauint(char *buffer, struct kernel_param *kp)
|
||||
+{
|
||||
+ if (aa_task_context(current))
|
||||
+ return -EPERM;
|
||||
+ return param_get_uint(buffer, kp);
|
||||
+}
|
||||
+
|
||||
+/* allow run time disabling of apparmor */
|
||||
+static int param_set_aa_enabled(const char *val, struct kernel_param *kp)
|
||||
+{
|
||||
+ char *endp;
|
||||
+ unsigned long l;
|
||||
+
|
||||
+ if (!apparmor_initialized) {
|
||||
+ apparmor_enabled = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (aa_task_context(current))
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ if (!apparmor_enabled)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!val)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ l = simple_strtoul(val, &endp, 0);
|
||||
+ if (endp == val || l != 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ apparmor_enabled = 0;
|
||||
+ apparmor_disable();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aa_reject_syscall(struct task_struct *task, gfp_t flags,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct aa_profile *profile = aa_get_profile(task);
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (profile) {
|
||||
+ error = aa_audit_syscallreject(profile, flags, name);
|
||||
+ aa_put_profile(profile);
|
||||
+ }
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_ptrace(struct task_struct *parent,
|
||||
+ struct task_struct *child)
|
||||
+{
|
||||
+ struct aa_task_context *cxt;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * parent can ptrace child when
|
||||
+ * - parent is unconfined
|
||||
+ * - parent & child are in the same namespace &&
|
||||
+ * - parent is in complain mode
|
||||
+ * - parent and child are confined by the same profile
|
||||
+ * - parent profile has CAP_SYS_PTRACE
|
||||
+ */
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+ cxt = aa_task_context(parent);
|
||||
+ if (cxt) {
|
||||
+ if (parent->nsproxy != child->nsproxy) {
|
||||
+ struct aa_audit sa;
|
||||
+ memset(&sa, 0, sizeof(sa));
|
||||
+ sa.operation = "ptrace";
|
||||
+ sa.gfp_mask = GFP_ATOMIC;
|
||||
+ sa.parent = parent->pid;
|
||||
+ sa.task = child->pid;
|
||||
+ sa.info = "different namespaces";
|
||||
+ aa_audit_reject(cxt->profile, &sa);
|
||||
+ error = -EPERM;
|
||||
+ } else {
|
||||
+ struct aa_task_context *child_cxt =
|
||||
+ aa_task_context(child);
|
||||
+
|
||||
+ error = aa_may_ptrace(cxt, child_cxt ?
|
||||
+ child_cxt->profile : NULL);
|
||||
+ if (PROFILE_COMPLAIN(cxt->profile)) {
|
||||
+ struct aa_audit sa;
|
||||
+ memset(&sa, 0, sizeof(sa));
|
||||
+ sa.operation = "ptrace";
|
||||
+ sa.gfp_mask = GFP_ATOMIC;
|
||||
+ sa.parent = parent->pid;
|
||||
+ sa.task = child->pid;
|
||||
+ aa_audit_hint(cxt->profile, &sa);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_capable(struct task_struct *task, int cap)
|
||||
+{
|
||||
+ int error;
|
||||
+ struct aa_task_context *cxt;
|
||||
+
|
||||
+ /* cap_capable returns 0 on success, else -EPERM */
|
||||
+ error = cap_capable(task, cap);
|
||||
+
|
||||
+ rcu_read_lock();
|
||||
+ cxt = aa_task_context(task);
|
||||
+ if (cxt && (!error || cap_raised(cxt->profile->set_caps, cap)))
|
||||
+ error = aa_capability(cxt, cap);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_sysctl(struct ctl_table *table, int op)
|
||||
+{
|
||||
+ struct aa_profile *profile = aa_get_profile(current);
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (profile) {
|
||||
+ char *buffer, *name;
|
||||
+ int mask;
|
||||
+
|
||||
+ mask = 0;
|
||||
+ if (op & 4)
|
||||
+ mask |= MAY_READ;
|
||||
+ if (op & 2)
|
||||
+ mask |= MAY_WRITE;
|
||||
+
|
||||
+ error = -ENOMEM;
|
||||
+ buffer = (char*)__get_free_page(GFP_KERNEL);
|
||||
+ if (!buffer)
|
||||
+ goto out;
|
||||
+ name = sysctl_pathname(table, buffer, PAGE_SIZE);
|
||||
+ if (name && name - buffer >= 5) {
|
||||
+ name -= 5;
|
||||
+ memcpy(name, "/proc", 5);
|
||||
+ error = aa_perm_path(profile, "sysctl", name, mask, 0);
|
||||
+ }
|
||||
+ free_page((unsigned long)buffer);
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ aa_put_profile(profile);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_bprm_set_security(struct linux_binprm *bprm)
|
||||
+{
|
||||
+ /* handle capability bits with setuid, etc */
|
||||
+ cap_bprm_set_security(bprm);
|
||||
+ /* already set based on script name */
|
||||
+ if (bprm->sh_bang)
|
||||
+ return 0;
|
||||
+ return aa_register(bprm);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_bprm_secureexec(struct linux_binprm *bprm)
|
||||
+{
|
||||
+ int ret = cap_bprm_secureexec(bprm);
|
||||
+
|
||||
+ if (!ret && (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) {
|
||||
+ AA_DEBUG("%s: secureexec required for %s\n",
|
||||
+ __FUNCTION__, bprm->filename);
|
||||
+ ret = 1;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type,
|
||||
+ unsigned long flags, void *data)
|
||||
+{
|
||||
+ return aa_reject_syscall(current, GFP_KERNEL, "mount");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_umount(struct vfsmount *mnt, int flags)
|
||||
+{
|
||||
+ return aa_reject_syscall(current, GFP_KERNEL, "umount");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mask)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (!mnt || !mediated_filesystem(dir))
|
||||
+ goto out;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+
|
||||
+ if (profile)
|
||||
+ error = aa_perm_dir(profile, "inode_mkdir", dentry, mnt,
|
||||
+ MAY_WRITE);
|
||||
+
|
||||
+ aa_put_profile(profile);
|
||||
+
|
||||
+out:
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_rmdir(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (!mnt || !mediated_filesystem(dir))
|
||||
+ goto out;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+
|
||||
+ if (profile)
|
||||
+ error = aa_perm_dir(profile, "inode_rmdir", dentry, mnt,
|
||||
+ MAY_WRITE);
|
||||
+
|
||||
+ aa_put_profile(profile);
|
||||
+
|
||||
+out:
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int aa_permission(const char *operation, struct inode *inode,
|
||||
+ struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ int mask, int check)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (mnt && mediated_filesystem(inode)) {
|
||||
+ struct aa_profile *profile;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+ if (profile)
|
||||
+ error = aa_perm(profile, operation, dentry, mnt, mask,
|
||||
+ check);
|
||||
+ aa_put_profile(profile);
|
||||
+ }
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static inline int aa_mask_permissions(int mask)
|
||||
+{
|
||||
+ if (mask & MAY_APPEND)
|
||||
+ mask &= (MAY_READ | MAY_APPEND | MAY_EXEC);
|
||||
+ else
|
||||
+ mask &= (MAY_READ | MAY_WRITE | MAY_EXEC);
|
||||
+ return mask;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_create(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mask)
|
||||
+{
|
||||
+ return aa_permission("inode_create", dir, dentry, mnt, MAY_APPEND, 0);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_link(struct dentry *old_dentry,
|
||||
+ struct vfsmount *old_mnt, struct inode *dir,
|
||||
+ struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+ struct aa_profile *profile;
|
||||
+
|
||||
+ if (!old_mnt || !new_mnt || !mediated_filesystem(dir))
|
||||
+ goto out;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+
|
||||
+ if (profile)
|
||||
+ error = aa_link(profile, new_dentry, new_mnt,
|
||||
+ old_dentry, old_mnt);
|
||||
+
|
||||
+ aa_put_profile(profile);
|
||||
+
|
||||
+out:
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_unlink(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
+{
|
||||
+ int check = 0;
|
||||
+
|
||||
+ if (S_ISDIR(dentry->d_inode->i_mode))
|
||||
+ check |= AA_CHECK_DIR;
|
||||
+ return aa_permission("inode_unlink", dir, dentry, mnt, MAY_WRITE,
|
||||
+ check);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_symlink(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, const char *old_name)
|
||||
+{
|
||||
+ return aa_permission("inode_symlink", dir, dentry, mnt, MAY_WRITE, 0);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_mknod(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode, dev_t dev)
|
||||
+{
|
||||
+ return aa_permission("inode_mknod", dir, dentry, mnt, MAY_WRITE, 0);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_rename(struct inode *old_dir,
|
||||
+ struct dentry *old_dentry,
|
||||
+ struct vfsmount *old_mnt,
|
||||
+ struct inode *new_dir,
|
||||
+ struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if ((!old_mnt && !new_mnt) || !mediated_filesystem(old_dir))
|
||||
+ goto out;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+
|
||||
+ if (profile) {
|
||||
+ struct inode *inode = old_dentry->d_inode;
|
||||
+ int check = 0;
|
||||
+
|
||||
+ if (inode && S_ISDIR(inode->i_mode))
|
||||
+ check |= AA_CHECK_DIR;
|
||||
+ if (old_mnt)
|
||||
+ error = aa_perm(profile, "inode_rename", old_dentry,
|
||||
+ old_mnt, MAY_READ | MAY_WRITE, check);
|
||||
+
|
||||
+ if (!error && new_mnt) {
|
||||
+ error = aa_perm(profile, "inode_rename", new_dentry,
|
||||
+ new_mnt, MAY_WRITE, check);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ aa_put_profile(profile);
|
||||
+
|
||||
+out:
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_permission(struct inode *inode, int mask,
|
||||
+ struct nameidata *nd)
|
||||
+{
|
||||
+ int check = 0;
|
||||
+
|
||||
+ if (!nd || nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE))
|
||||
+ return 0;
|
||||
+ mask = aa_mask_permissions(mask);
|
||||
+ if (S_ISDIR(inode->i_mode)) {
|
||||
+ check |= AA_CHECK_DIR;
|
||||
+ /* allow traverse accesses to directories */
|
||||
+ mask &= ~MAY_EXEC;
|
||||
+ }
|
||||
+ return aa_permission("inode_permission", inode, nd->dentry, nd->mnt,
|
||||
+ mask, check);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct iattr *iattr)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (!mnt)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (mediated_filesystem(dentry->d_inode)) {
|
||||
+ struct aa_profile *profile;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+ /*
|
||||
+ * Mediate any attempt to change attributes of a file
|
||||
+ * (chmod, chown, chgrp, etc)
|
||||
+ */
|
||||
+ if (profile)
|
||||
+ error = aa_attr(profile, dentry, mnt, iattr);
|
||||
+
|
||||
+ aa_put_profile(profile);
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int aa_xattr_permission(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ const char *operation, int mask,
|
||||
+ struct file *file)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (mnt && mediated_filesystem(dentry->d_inode)) {
|
||||
+ struct aa_profile *profile = aa_get_profile(current);
|
||||
+ int check = file ? AA_CHECK_FD : 0;
|
||||
+
|
||||
+ if (profile)
|
||||
+ error = aa_perm_xattr(profile, operation, dentry, mnt,
|
||||
+ mask, check);
|
||||
+ aa_put_profile(profile);
|
||||
+ }
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name, void *value, size_t size,
|
||||
+ int flags, struct file *file)
|
||||
+{
|
||||
+ return aa_xattr_permission(dentry, mnt, "xattr set", MAY_WRITE, file);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name, struct file *file)
|
||||
+{
|
||||
+ return aa_xattr_permission(dentry, mnt, "xattr get", MAY_READ, file);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct file *file)
|
||||
+{
|
||||
+ return aa_xattr_permission(dentry, mnt, "xattr list", MAY_READ, file);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_inode_removexattr(struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, char *name,
|
||||
+ struct file *file)
|
||||
+{
|
||||
+ return aa_xattr_permission(dentry, mnt, "xattr remove", MAY_WRITE,
|
||||
+ file);
|
||||
+}
|
||||
+
|
||||
+static int aa_file_permission(const char *op, struct file *file, int mask)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ struct aa_profile *file_profile = (struct aa_profile*)file->f_security;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (!file_profile)
|
||||
+ goto out;
|
||||
+
|
||||
+ /*
|
||||
+ * If this file was opened under a different profile, we
|
||||
+ * revalidate the access against the current profile.
|
||||
+ */
|
||||
+ profile = aa_get_profile(current);
|
||||
+ if (profile && (file_profile != profile || mask & AA_MAY_LOCK)) {
|
||||
+ struct dentry *dentry = file->f_dentry;
|
||||
+ struct vfsmount *mnt = file->f_vfsmnt;
|
||||
+ struct inode *inode = dentry->d_inode;
|
||||
+ int check = AA_CHECK_FD;
|
||||
+
|
||||
+ /*
|
||||
+ * FIXME: We should remember which profiles we revalidated
|
||||
+ * against.
|
||||
+ */
|
||||
+ if (S_ISDIR(inode->i_mode))
|
||||
+ check |= AA_CHECK_DIR;
|
||||
+ error = aa_permission(op, inode, dentry, mnt, mask, check);
|
||||
+ }
|
||||
+ aa_put_profile(profile);
|
||||
+
|
||||
+out:
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_file_permission(struct file *file, int mask)
|
||||
+{
|
||||
+ return aa_file_permission("file_permission", file,
|
||||
+ aa_mask_permissions(mask));
|
||||
+}
|
||||
+
|
||||
+static inline int apparmor_file_lock (struct file *file, unsigned int cmd)
|
||||
+{
|
||||
+ int mask = AA_MAY_LOCK;
|
||||
+ if (cmd == F_WRLCK)
|
||||
+ mask |= MAY_WRITE;
|
||||
+ return aa_file_permission("file_lock", file, mask);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_file_alloc_security(struct file *file)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+ if (profile)
|
||||
+ file->f_security = profile;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void apparmor_file_free_security(struct file *file)
|
||||
+{
|
||||
+ struct aa_profile *file_profile = (struct aa_profile*)file->f_security;
|
||||
+
|
||||
+ aa_put_profile(file_profile);
|
||||
+}
|
||||
+
|
||||
+static inline int aa_mmap(struct file *file, const char *operation,
|
||||
+ unsigned long prot, unsigned long flags)
|
||||
+{
|
||||
+ struct dentry *dentry;
|
||||
+ int mask = 0;
|
||||
+
|
||||
+ if (!file || !file->f_security)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (prot & PROT_READ)
|
||||
+ mask |= MAY_READ;
|
||||
+ /* Private mappings don't require write perms since they don't
|
||||
+ * write back to the files */
|
||||
+ if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE))
|
||||
+ mask |= MAY_WRITE;
|
||||
+ if (prot & PROT_EXEC)
|
||||
+ mask |= AA_EXEC_MMAP;
|
||||
+
|
||||
+ dentry = file->f_dentry;
|
||||
+ return aa_permission(operation, dentry->d_inode, dentry,
|
||||
+ file->f_vfsmnt, mask, AA_CHECK_FD);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
|
||||
+ unsigned long prot, unsigned long flags,
|
||||
+ unsigned long addr, unsigned long addr_only)
|
||||
+{
|
||||
+ if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) {
|
||||
+ struct aa_profile *profile = aa_get_profile(current);
|
||||
+ if (profile)
|
||||
+ /* future control check here */
|
||||
+ return -EACCES;
|
||||
+ else
|
||||
+ return -EACCES;
|
||||
+ aa_put_profile(profile);
|
||||
+ }
|
||||
+
|
||||
+ return aa_mmap(file, "file_mmap", prot, flags);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_file_mprotect(struct vm_area_struct *vma,
|
||||
+ unsigned long reqprot, unsigned long prot)
|
||||
+{
|
||||
+ return aa_mmap(vma->vm_file, "file_mprotect", prot,
|
||||
+ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_task_alloc_security(struct task_struct *task)
|
||||
+{
|
||||
+ return aa_clone(task);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Called from IRQ context from RCU callback.
|
||||
+ */
|
||||
+static void apparmor_task_free_security(struct task_struct *task)
|
||||
+{
|
||||
+ aa_release(task);
|
||||
+}
|
||||
+
|
||||
+static int apparmor_getprocattr(struct task_struct *task, char *name,
|
||||
+ char **value)
|
||||
+{
|
||||
+ unsigned len;
|
||||
+ int error;
|
||||
+ struct aa_profile *profile;
|
||||
+
|
||||
+ /* AppArmor only supports the "current" process attribute */
|
||||
+ if (strcmp(name, "current") != 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* must be task querying itself or admin */
|
||||
+ if (current != task && !capable(CAP_SYS_ADMIN))
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ profile = aa_get_profile(task);
|
||||
+ error = aa_getprocattr(profile, value, &len);
|
||||
+ aa_put_profile(profile);
|
||||
+ if (!error)
|
||||
+ error = len;
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_setprocattr(struct task_struct *task, char *name,
|
||||
+ void *value, size_t size)
|
||||
+{
|
||||
+ char *command, *args;
|
||||
+ int error;
|
||||
+
|
||||
+ if (strcmp(name, "current") != 0 || size == 0 || size >= PAGE_SIZE)
|
||||
+ return -EINVAL;
|
||||
+ args = value;
|
||||
+ args[size] = '\0';
|
||||
+ args = strstrip(args);
|
||||
+ command = strsep(&args, " ");
|
||||
+ if (!args)
|
||||
+ return -EINVAL;
|
||||
+ while (isspace(*args))
|
||||
+ args++;
|
||||
+ if (!*args)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (strcmp(command, "changehat") == 0) {
|
||||
+ if (current != task)
|
||||
+ return -EACCES;
|
||||
+ error = aa_setprocattr_changehat(args);
|
||||
+ } else if (strcmp(command, "changeprofile") == 0) {
|
||||
+ if (current != task)
|
||||
+ return -EACCES;
|
||||
+ error = aa_setprocattr_changeprofile(args);
|
||||
+ } else if (strcmp(command, "setprofile") == 0) {
|
||||
+ struct aa_profile *profile;
|
||||
+
|
||||
+ /* Only an unconfined process with admin capabilities
|
||||
+ * may change the profile of another task.
|
||||
+ */
|
||||
+
|
||||
+ if (!capable(CAP_SYS_ADMIN))
|
||||
+ return -EACCES;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+ if (profile) {
|
||||
+ struct aa_audit sa;
|
||||
+ memset(&sa, 0, sizeof(sa));
|
||||
+ sa.operation = "profile_set";
|
||||
+ sa.gfp_mask = GFP_KERNEL;
|
||||
+ sa.task = task->pid;
|
||||
+ sa.info = "from confined process";
|
||||
+ aa_audit_reject(profile, &sa);
|
||||
+ aa_put_profile(profile);
|
||||
+ return -EACCES;
|
||||
+ }
|
||||
+ error = aa_setprocattr_setprofile(task, args);
|
||||
+ } else {
|
||||
+ struct aa_audit sa;
|
||||
+ memset(&sa, 0, sizeof(sa));
|
||||
+ sa.operation = "setprocattr";
|
||||
+ sa.gfp_mask = GFP_KERNEL;
|
||||
+ sa.info = "invalid command";
|
||||
+ sa.name = command;
|
||||
+ sa.task = task->pid;
|
||||
+ aa_audit_reject(NULL, &sa);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!error)
|
||||
+ error = size;
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+struct security_operations apparmor_ops = {
|
||||
+ .ptrace = apparmor_ptrace,
|
||||
+ .capget = cap_capget,
|
||||
+ .capset_check = cap_capset_check,
|
||||
+ .capset_set = cap_capset_set,
|
||||
+ .sysctl = apparmor_sysctl,
|
||||
+ .capable = apparmor_capable,
|
||||
+ .syslog = cap_syslog,
|
||||
+
|
||||
+ .netlink_send = cap_netlink_send,
|
||||
+ .netlink_recv = cap_netlink_recv,
|
||||
+
|
||||
+ .bprm_apply_creds = cap_bprm_apply_creds,
|
||||
+ .bprm_set_security = apparmor_bprm_set_security,
|
||||
+ .bprm_secureexec = apparmor_bprm_secureexec,
|
||||
+
|
||||
+ .sb_mount = apparmor_sb_mount,
|
||||
+ .sb_umount = apparmor_umount,
|
||||
+
|
||||
+ .inode_mkdir = apparmor_inode_mkdir,
|
||||
+ .inode_rmdir = apparmor_inode_rmdir,
|
||||
+ .inode_create = apparmor_inode_create,
|
||||
+ .inode_link = apparmor_inode_link,
|
||||
+ .inode_unlink = apparmor_inode_unlink,
|
||||
+ .inode_symlink = apparmor_inode_symlink,
|
||||
+ .inode_mknod = apparmor_inode_mknod,
|
||||
+ .inode_rename = apparmor_inode_rename,
|
||||
+ .inode_permission = apparmor_inode_permission,
|
||||
+ .inode_setattr = apparmor_inode_setattr,
|
||||
+ .inode_setxattr = apparmor_inode_setxattr,
|
||||
+ .inode_getxattr = apparmor_inode_getxattr,
|
||||
+ .inode_listxattr = apparmor_inode_listxattr,
|
||||
+ .inode_removexattr = apparmor_inode_removexattr,
|
||||
+ .file_permission = apparmor_file_permission,
|
||||
+ .file_alloc_security = apparmor_file_alloc_security,
|
||||
+ .file_free_security = apparmor_file_free_security,
|
||||
+ .file_mmap = apparmor_file_mmap,
|
||||
+ .file_mprotect = apparmor_file_mprotect,
|
||||
+ .file_lock = apparmor_file_lock,
|
||||
+
|
||||
+ .task_alloc_security = apparmor_task_alloc_security,
|
||||
+ .task_free_security = apparmor_task_free_security,
|
||||
+ .task_post_setuid = cap_task_post_setuid,
|
||||
+ .task_reparent_to_init = cap_task_reparent_to_init,
|
||||
+
|
||||
+ .getprocattr = apparmor_getprocattr,
|
||||
+ .setprocattr = apparmor_setprocattr,
|
||||
+};
|
||||
+
|
||||
+void info_message(const char *str)
|
||||
+{
|
||||
+ struct aa_audit sa;
|
||||
+ memset(&sa, 0, sizeof(sa));
|
||||
+ sa.gfp_mask = GFP_KERNEL;
|
||||
+ sa.info = str;
|
||||
+ printk(KERN_INFO "AppArmor: %s\n", str);
|
||||
+ if (audit_enabled)
|
||||
+ aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS);
|
||||
+}
|
||||
+
|
||||
+static int __init apparmor_init(void)
|
||||
+{
|
||||
+ int error;
|
||||
+
|
||||
+ if (!apparmor_enabled) {
|
||||
+ info_message("AppArmor disabled by boottime parameter\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ((error = create_apparmorfs())) {
|
||||
+ AA_ERROR("Unable to activate AppArmor filesystem\n");
|
||||
+ goto createfs_out;
|
||||
+ }
|
||||
+
|
||||
+ if ((error = alloc_default_namespace())){
|
||||
+ AA_ERROR("Unable to allocate default profile namespace\n");
|
||||
+ goto alloc_out;
|
||||
+ }
|
||||
+
|
||||
+ if ((error = register_security(&apparmor_ops))) {
|
||||
+ AA_ERROR("Unable to register AppArmor\n");
|
||||
+ goto register_security_out;
|
||||
+ }
|
||||
+
|
||||
+ /* Report that AppArmor successfully initialized */
|
||||
+ apparmor_initialized = 1;
|
||||
+ if (apparmor_complain)
|
||||
+ info_message("AppArmor initialized: complainmode enabled");
|
||||
+ else
|
||||
+ info_message("AppArmor initialized");
|
||||
+
|
||||
+ return error;
|
||||
+
|
||||
+register_security_out:
|
||||
+ free_default_namespace();
|
||||
+
|
||||
+alloc_out:
|
||||
+ destroy_apparmorfs();
|
||||
+
|
||||
+createfs_out:
|
||||
+ return error;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+security_initcall(apparmor_init);
|
||||
+
|
||||
+void apparmor_disable(void)
|
||||
+{
|
||||
+ /* Remove and release all the profiles on the profile list. */
|
||||
+ mutex_lock(&aa_interface_lock);
|
||||
+ aa_profile_ns_list_release();
|
||||
+
|
||||
+ /* FIXME: cleanup profiles references on files */
|
||||
+ free_default_namespace();
|
||||
+
|
||||
+ /*
|
||||
+ * Delay for an rcu cycle to make sure that all active task
|
||||
+ * context readers have finished, and all profiles have been
|
||||
+ * freed by their rcu callbacks.
|
||||
+ */
|
||||
+ synchronize_rcu();
|
||||
+
|
||||
+ destroy_apparmorfs();
|
||||
+ mutex_unlock(&aa_interface_lock);
|
||||
+
|
||||
+ apparmor_initialized = 0;
|
||||
+
|
||||
+ info_message("AppArmor protection removed");
|
||||
+}
|
||||
+
|
||||
+MODULE_DESCRIPTION("AppArmor process confinement");
|
||||
+MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org");
|
||||
+MODULE_LICENSE("GPL");
|
1494
kernel-patches/2.6.24/apparmor-main.diff
Normal file
1494
kernel-patches/2.6.24/apparmor-main.diff
Normal file
File diff suppressed because it is too large
Load Diff
1418
kernel-patches/2.6.24/apparmor-misc.diff
Normal file
1418
kernel-patches/2.6.24/apparmor-misc.diff
Normal file
File diff suppressed because it is too large
Load Diff
1350
kernel-patches/2.6.24/apparmor-module_interface.diff
Normal file
1350
kernel-patches/2.6.24/apparmor-module_interface.diff
Normal file
File diff suppressed because it is too large
Load Diff
408
kernel-patches/2.6.24/apparmor-network.diff
Normal file
408
kernel-patches/2.6.24/apparmor-network.diff
Normal file
@@ -0,0 +1,408 @@
|
||||
From: John Johansen <jjohansen@suse.de>
|
||||
Subject: AppArmor: Simplified network controls for AppArmor
|
||||
|
||||
Simple network control determining which network families a confined
|
||||
application has access to.
|
||||
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
security/apparmor/Makefile | 7 +
|
||||
security/apparmor/apparmor.h | 9 ++
|
||||
security/apparmor/lsm.c | 129 ++++++++++++++++++++++++++++++++++-
|
||||
security/apparmor/main.c | 107 ++++++++++++++++++++++++++++-
|
||||
security/apparmor/module_interface.c | 26 ++++++-
|
||||
5 files changed, 271 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/security/apparmor/Makefile
|
||||
+++ b/security/apparmor/Makefile
|
||||
@@ -8,6 +8,11 @@ apparmor-y := main.o list.o procattr.o l
|
||||
quiet_cmd_make-caps = GEN $@
|
||||
cmd_make-caps = sed -n -e "/CAP_FS_MASK/d" -e "s/^\#define[ \\t]\\+CAP_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z > $@
|
||||
|
||||
-$(obj)/main.o : $(obj)/capability_names.h
|
||||
+quiet_cmd_make-af = GEN $@
|
||||
+cmd_make-af = sed -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "s/^\#define[ \\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z > $@
|
||||
+
|
||||
+$(obj)/main.o : $(obj)/capability_names.h $(obj)/af_names.h
|
||||
$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
|
||||
$(call cmd,make-caps)
|
||||
+$(obj)/af_names.h : $(srctree)/include/linux/socket.h
|
||||
+ $(call cmd,make-af)
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <linux/fs.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/rcupdate.h>
|
||||
+#include <linux/socket.h>
|
||||
+#include <net/sock.h>
|
||||
|
||||
/*
|
||||
* We use MAY_READ, MAY_WRITE, MAY_EXEC, MAY_APPEND and the following flags
|
||||
@@ -208,6 +210,9 @@ struct aa_profile {
|
||||
struct list_head task_contexts;
|
||||
spinlock_t lock;
|
||||
unsigned long int_flags;
|
||||
+ u16 network_families[AF_MAX];
|
||||
+ u16 audit_network[AF_MAX];
|
||||
+ u16 quiet_network[AF_MAX];
|
||||
};
|
||||
|
||||
extern struct list_head profile_ns_list;
|
||||
@@ -254,6 +259,7 @@ struct aa_audit {
|
||||
int request_mask, denied_mask, audit_mask;
|
||||
struct iattr *iattr;
|
||||
pid_t task, parent;
|
||||
+ int family, type, protocol;
|
||||
int error_code;
|
||||
};
|
||||
|
||||
@@ -315,6 +321,9 @@ extern void aa_change_task_context(struc
|
||||
struct aa_profile *previous_profile);
|
||||
extern int aa_may_ptrace(struct aa_task_context *cxt,
|
||||
struct aa_profile *tracee);
|
||||
+extern int aa_net_perm(struct aa_profile *profile, char *operation,
|
||||
+ int family, int type, int protocol);
|
||||
+extern int aa_revalidate_sk(struct sock *sk, char *operation);
|
||||
|
||||
/* lsm.c */
|
||||
extern int apparmor_initialized;
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/audit.h>
|
||||
+#include <net/sock.h>
|
||||
|
||||
#include "apparmor.h"
|
||||
#include "inline.h"
|
||||
@@ -663,6 +664,117 @@ static void apparmor_task_free_security(
|
||||
aa_release(task);
|
||||
}
|
||||
|
||||
+static int apparmor_socket_create(int family, int type, int protocol, int kern)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (kern)
|
||||
+ return 0;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+ if (profile)
|
||||
+ error = aa_net_perm(profile, "socket_create", family,
|
||||
+ type, protocol);
|
||||
+ aa_put_profile(profile);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_post_create(struct socket *sock, int family,
|
||||
+ int type, int protocol, int kern)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ if (kern)
|
||||
+ return 0;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_post_create");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_bind(struct socket *sock,
|
||||
+ struct sockaddr *address, int addrlen)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_bind");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_connect(struct socket *sock,
|
||||
+ struct sockaddr *address, int addrlen)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_connect");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_listen(struct socket *sock, int backlog)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_listen");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_accept");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_sendmsg(struct socket *sock,
|
||||
+ struct msghdr *msg, int size)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_sendmsg");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_recvmsg(struct socket *sock,
|
||||
+ struct msghdr *msg, int size, int flags)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_recvmsg");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getsockname(struct socket *sock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_getsockname");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getpeername(struct socket *sock)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_getpeername");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_getsockopt(struct socket *sock, int level,
|
||||
+ int optname)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_getsockopt");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_setsockopt(struct socket *sock, int level,
|
||||
+ int optname)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_setsockopt");
|
||||
+}
|
||||
+
|
||||
+static int apparmor_socket_shutdown(struct socket *sock, int how)
|
||||
+{
|
||||
+ struct sock *sk = sock->sk;
|
||||
+
|
||||
+ return aa_revalidate_sk(sk, "socket_shutdown");
|
||||
+}
|
||||
+
|
||||
static int apparmor_getprocattr(struct task_struct *task, char *name,
|
||||
char **value)
|
||||
{
|
||||
@@ -763,9 +875,6 @@ struct security_operations apparmor_ops
|
||||
.capable = apparmor_capable,
|
||||
.syslog = cap_syslog,
|
||||
|
||||
- .netlink_send = cap_netlink_send,
|
||||
- .netlink_recv = cap_netlink_recv,
|
||||
-
|
||||
.bprm_apply_creds = cap_bprm_apply_creds,
|
||||
.bprm_set_security = apparmor_bprm_set_security,
|
||||
.bprm_secureexec = apparmor_bprm_secureexec,
|
||||
@@ -801,6 +910,20 @@ struct security_operations apparmor_ops
|
||||
|
||||
.getprocattr = apparmor_getprocattr,
|
||||
.setprocattr = apparmor_setprocattr,
|
||||
+
|
||||
+ .socket_create = apparmor_socket_create,
|
||||
+ .socket_post_create = apparmor_socket_post_create,
|
||||
+ .socket_bind = apparmor_socket_bind,
|
||||
+ .socket_connect = apparmor_socket_connect,
|
||||
+ .socket_listen = apparmor_socket_listen,
|
||||
+ .socket_accept = apparmor_socket_accept,
|
||||
+ .socket_sendmsg = apparmor_socket_sendmsg,
|
||||
+ .socket_recvmsg = apparmor_socket_recvmsg,
|
||||
+ .socket_getsockname = apparmor_socket_getsockname,
|
||||
+ .socket_getpeername = apparmor_socket_getpeername,
|
||||
+ .socket_getsockopt = apparmor_socket_getsockopt,
|
||||
+ .socket_setsockopt = apparmor_socket_setsockopt,
|
||||
+ .socket_shutdown = apparmor_socket_shutdown,
|
||||
};
|
||||
|
||||
void info_message(const char *str)
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <linux/audit.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/ptrace.h>
|
||||
+#include <linux/socket.h>
|
||||
+#include <linux/net.h>
|
||||
+#include <net/sock.h>
|
||||
|
||||
#include "apparmor.h"
|
||||
|
||||
@@ -116,6 +119,24 @@ static void aa_audit_file_mask(struct au
|
||||
audit_log_format(ab, " %s=\"%s::%s\"", name, user, other);
|
||||
}
|
||||
|
||||
+static const char *address_families[] = {
|
||||
+#include "af_names.h"
|
||||
+};
|
||||
+
|
||||
+static const char *sock_types[] = {
|
||||
+ "unknown(0)",
|
||||
+ "stream",
|
||||
+ "dgram",
|
||||
+ "raw",
|
||||
+ "rdm",
|
||||
+ "seqpacket",
|
||||
+ "dccp",
|
||||
+ "unknown(7)",
|
||||
+ "unknown(8)",
|
||||
+ "unknown(9)",
|
||||
+ "packet",
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* aa_audit - Log an audit event to the audit subsystem
|
||||
* @profile: profile to check against
|
||||
@@ -187,7 +208,25 @@ static int aa_audit_base(struct aa_profi
|
||||
audit_log_untrustedstring(ab, sa->name2);
|
||||
}
|
||||
|
||||
- audit_log_format(ab, " pid=%d", current->pid);
|
||||
+ if (sa->family || sa->type) {
|
||||
+ if (address_families[sa->family])
|
||||
+ audit_log_format(ab, " family=\"%s\"",
|
||||
+ address_families[sa->family]);
|
||||
+ else
|
||||
+ audit_log_format(ab, " family=\"unknown(%d)\"",
|
||||
+ sa->family);
|
||||
+
|
||||
+ if (sock_types[sa->type])
|
||||
+ audit_log_format(ab, " sock_type=\"%s\"",
|
||||
+ sock_types[sa->type]);
|
||||
+ else
|
||||
+ audit_log_format(ab, " sock_type=\"unknown(%d)\"",
|
||||
+ sa->type);
|
||||
+
|
||||
+ audit_log_format(ab, " protocol=%d", sa->protocol);
|
||||
+ }
|
||||
+
|
||||
+ audit_log_format(ab, " pid=%d", current->pid);
|
||||
|
||||
if (profile) {
|
||||
audit_log_format(ab, " profile=");
|
||||
@@ -768,6 +807,72 @@ int aa_link(struct aa_profile *profile,
|
||||
return error;
|
||||
}
|
||||
|
||||
+int aa_net_perm(struct aa_profile *profile, char *operation,
|
||||
+ int family, int type, int protocol)
|
||||
+{
|
||||
+ struct aa_audit sa;
|
||||
+ int error = 0;
|
||||
+ u16 family_mask, audit_mask, quiet_mask;
|
||||
+
|
||||
+ if ((family < 0) || (family >= AF_MAX))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if ((type < 0) || (type >= SOCK_MAX))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* unix domain and netlink sockets are handled by ipc */
|
||||
+ if (family == AF_UNIX || family == AF_NETLINK)
|
||||
+ return 0;
|
||||
+
|
||||
+ family_mask = profile->network_families[family];
|
||||
+ audit_mask = profile->audit_network[family];
|
||||
+ quiet_mask = profile->quiet_network[family];
|
||||
+
|
||||
+ error = (family_mask & (1 << type)) ? 0 : -EACCES;
|
||||
+
|
||||
+ memset(&sa, 0, sizeof(sa));
|
||||
+ sa.operation = operation;
|
||||
+ sa.gfp_mask = GFP_KERNEL;
|
||||
+ sa.family = family;
|
||||
+ sa.type = type;
|
||||
+ sa.protocol = protocol;
|
||||
+ sa.error_code = error;
|
||||
+
|
||||
+ if (likely(!error)) {
|
||||
+ if (!PROFILE_AUDIT(profile) && !(family_mask & audit_mask))
|
||||
+ return 0;
|
||||
+ } else if (!((1 << type) & ~quiet_mask)) {
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ error = aa_audit(profile, &sa);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+int aa_revalidate_sk(struct sock *sk, char *operation)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ /* this is some debugging code to flush out the network hooks that
|
||||
+ that are called in interrupt context */
|
||||
+ if (in_interrupt()) {
|
||||
+ printk("AppArmor Debug: Hook being called from interrupt context\n");
|
||||
+ dump_stack();
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+ if (profile)
|
||||
+ error = aa_net_perm(profile, operation,
|
||||
+ sk->sk_family, sk->sk_type,
|
||||
+ sk->sk_protocol);
|
||||
+ aa_put_profile(profile);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
/*******************************
|
||||
* Global task related functions
|
||||
*******************************/
|
||||
--- a/security/apparmor/module_interface.c
|
||||
+++ b/security/apparmor/module_interface.c
|
||||
@@ -320,8 +320,8 @@ static struct aa_profile *aa_unpack_prof
|
||||
struct aa_audit *sa)
|
||||
{
|
||||
struct aa_profile *profile = NULL;
|
||||
-
|
||||
- int error = -EPROTO;
|
||||
+ size_t size = 0;
|
||||
+ int i, error = -EPROTO;
|
||||
|
||||
profile = alloc_aa_profile();
|
||||
if (!profile)
|
||||
@@ -354,6 +354,28 @@ static struct aa_profile *aa_unpack_prof
|
||||
if (!aa_is_u32(e, &(profile->set_caps), NULL))
|
||||
goto fail;
|
||||
|
||||
+ size = aa_is_array(e, "net_allowed_af");
|
||||
+ if (size) {
|
||||
+ if (size > AF_MAX)
|
||||
+ goto fail;
|
||||
+
|
||||
+ for (i = 0; i < size; i++) {
|
||||
+ if (!aa_is_u16(e, &profile->network_families[i], NULL))
|
||||
+ goto fail;
|
||||
+ if (!aa_is_u16(e, &profile->audit_network[i], NULL))
|
||||
+ goto fail;
|
||||
+ if (!aa_is_u16(e, &profile->quiet_network[i], NULL))
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
|
||||
+ goto fail;
|
||||
+ /* allow unix domain and netlink sockets they are handled
|
||||
+ * by IPC
|
||||
+ */
|
||||
+ }
|
||||
+ profile->network_families[AF_UNIX] = 0xffff;
|
||||
+ profile->network_families[AF_NETLINK] = 0xffff;
|
||||
+
|
||||
/* get file rules */
|
||||
profile->file_rules = aa_unpack_dfa(e);
|
||||
if (IS_ERR(profile->file_rules)) {
|
461
kernel-patches/2.6.24/apparmor-rlimits.diff
Normal file
461
kernel-patches/2.6.24/apparmor-rlimits.diff
Normal file
@@ -0,0 +1,461 @@
|
||||
From: John Johansen <jjohansen@suse.de>
|
||||
Subject: AppArmor: per profile controls for system rlimits
|
||||
|
||||
Provide contol of rlimits on a per profile basis. Each profile provides
|
||||
a per limit contol and corresponding hard limit value, such that when a
|
||||
profile becomes attached to a task it sets the tasks limits to be <= to
|
||||
the profiles specified limits. Note: the profile limit value will not
|
||||
raise a tasks limit if it is already less than the profile mandates.
|
||||
|
||||
In addition to setting a tasks limits, the ability to set limits on
|
||||
a confined task are controlled. AppArmor only controls the raising
|
||||
of a tasks limits Tasks with CAP_SYS_RESOURCE can have their hard limits
|
||||
raised up to the value specified by the profile. AppArmor does not
|
||||
prevent a task for lowering its hard limits, nor does it provide
|
||||
additional control on soft limits.
|
||||
|
||||
AppArmor only controls the limits specified in a profile so that
|
||||
any limit not specified is free to be modified subject to standard
|
||||
linux limitations.
|
||||
|
||||
---
|
||||
security/apparmor/apparmor.h | 23 ++++++
|
||||
security/apparmor/apparmorfs.c | 2
|
||||
security/apparmor/lsm.c | 16 ++++
|
||||
security/apparmor/main.c | 132 +++++++++++++++++++++++++++++++----
|
||||
security/apparmor/module_interface.c | 56 ++++++++++++++
|
||||
5 files changed, 215 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/fs.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/rcupdate.h>
|
||||
+#include <linux/resource.h>
|
||||
#include <linux/socket.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
@@ -136,6 +137,18 @@ extern unsigned int apparmor_path_max;
|
||||
|
||||
#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args)
|
||||
|
||||
+/* struct aa_rlimit - rlimits settings for the profile
|
||||
+ * @mask: which hard limits to set
|
||||
+ * @limits: rlimit values that override task limits
|
||||
+ *
|
||||
+ * AppArmor rlimits are used to set confined task rlimits. Only the
|
||||
+ * limits specified in @mask will be controlled by apparmor.
|
||||
+ */
|
||||
+struct aa_rlimit {
|
||||
+ unsigned int mask;
|
||||
+ struct rlimit limits[RLIM_NLIMITS];
|
||||
+};
|
||||
+
|
||||
struct aa_profile;
|
||||
|
||||
/* struct aa_namespace - namespace for a set of profiles
|
||||
@@ -170,6 +183,8 @@ struct aa_namespace {
|
||||
* @audit_caps: caps that are to be audited
|
||||
* @quiet_caps: caps that should not be audited
|
||||
* @capabilities: capabilities granted by the process
|
||||
+ * @rlimits: rlimits for the profile
|
||||
+ * @task_count: how many tasks the profile is attached to
|
||||
* @count: reference count of the profile
|
||||
* @task_contexts: list of tasks confined by profile
|
||||
* @lock: lock for the task_contexts list
|
||||
@@ -206,6 +221,9 @@ struct aa_profile {
|
||||
kernel_cap_t audit_caps;
|
||||
kernel_cap_t quiet_caps;
|
||||
|
||||
+ struct aa_rlimit rlimits;
|
||||
+ unsigned int task_count;
|
||||
+
|
||||
struct kref count;
|
||||
struct list_head task_contexts;
|
||||
spinlock_t lock;
|
||||
@@ -257,6 +275,7 @@ struct aa_audit {
|
||||
const char *name2;
|
||||
const char *name3;
|
||||
int request_mask, denied_mask, audit_mask;
|
||||
+ int rlimit;
|
||||
struct iattr *iattr;
|
||||
pid_t task, parent;
|
||||
int family, type, protocol;
|
||||
@@ -324,6 +343,10 @@ extern int aa_may_ptrace(struct aa_task_
|
||||
extern int aa_net_perm(struct aa_profile *profile, char *operation,
|
||||
int family, int type, int protocol);
|
||||
extern int aa_revalidate_sk(struct sock *sk, char *operation);
|
||||
+extern int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
|
||||
+ struct rlimit *new_rlim);
|
||||
+extern void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile);
|
||||
+
|
||||
|
||||
/* lsm.c */
|
||||
extern int apparmor_initialized;
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -105,7 +105,7 @@ static ssize_t aa_features_read(struct f
|
||||
{
|
||||
const char *features = "file=3.0 capability=2.0 network=1.0 "
|
||||
"change_hat=1.4 change_profile=1.0 "
|
||||
- "aanamespaces=1.0";
|
||||
+ "aanamespaces=1.0 rlimit=1.0";
|
||||
|
||||
return simple_read_from_buffer(buf, size, ppos, features,
|
||||
strlen(features));
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -866,6 +866,21 @@ static int apparmor_setprocattr(struct t
|
||||
return error;
|
||||
}
|
||||
|
||||
+static int apparmor_task_setrlimit(unsigned int resource,
|
||||
+ struct rlimit *new_rlim)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+ if (profile) {
|
||||
+ error = aa_task_setrlimit(profile, resource, new_rlim);
|
||||
+ }
|
||||
+ aa_put_profile(profile);
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
struct security_operations apparmor_ops = {
|
||||
.ptrace = apparmor_ptrace,
|
||||
.capget = cap_capget,
|
||||
@@ -907,6 +922,7 @@ struct security_operations apparmor_ops
|
||||
.task_free_security = apparmor_task_free_security,
|
||||
.task_post_setuid = cap_task_post_setuid,
|
||||
.task_reparent_to_init = cap_task_reparent_to_init,
|
||||
+ .task_setrlimit = apparmor_task_setrlimit,
|
||||
|
||||
.getprocattr = apparmor_getprocattr,
|
||||
.setprocattr = apparmor_setprocattr,
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -177,6 +177,9 @@ static int aa_audit_base(struct aa_profi
|
||||
if (sa->request_mask)
|
||||
audit_log_format(ab, " fsuid=%d", current->fsuid);
|
||||
|
||||
+ if (sa->rlimit)
|
||||
+ audit_log_format(ab, " rlimit=%d", sa->rlimit - 1);
|
||||
+
|
||||
if (sa->iattr) {
|
||||
struct iattr *iattr = sa->iattr;
|
||||
|
||||
@@ -872,6 +875,79 @@ int aa_revalidate_sk(struct sock *sk, ch
|
||||
|
||||
return error;
|
||||
}
|
||||
+/**
|
||||
+ * aa_task_setrlimit - test permission to set an rlimit
|
||||
+ * @profile - profile confining the task
|
||||
+ * @resource - the resource being set
|
||||
+ * @new_rlim - the new resource limit
|
||||
+ *
|
||||
+ * Control raising the processes hard limit.
|
||||
+ */
|
||||
+int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
|
||||
+ struct rlimit *new_rlim)
|
||||
+{
|
||||
+ struct aa_audit sa;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ memset(&sa, 0, sizeof(sa));
|
||||
+ sa.operation = "setrlimit";
|
||||
+ sa.gfp_mask = GFP_KERNEL;
|
||||
+ sa.rlimit = resource + 1;
|
||||
+
|
||||
+ if (profile->rlimits.mask & (1 << resource) &&
|
||||
+ new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) {
|
||||
+ sa.error_code = -EACCES;
|
||||
+
|
||||
+ error = aa_audit(profile, &sa);
|
||||
+ }
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int aa_rlimit_nproc(struct aa_profile *profile) {
|
||||
+ if (profile && (profile->rlimits.mask & (1 << RLIMIT_NPROC)) &&
|
||||
+ profile->task_count >= profile->rlimits.limits[RLIMIT_NPROC].rlim_max)
|
||||
+ return -EAGAIN;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile)
|
||||
+{
|
||||
+ int i, mask;
|
||||
+
|
||||
+ if (!profile)
|
||||
+ return;
|
||||
+
|
||||
+ if (!profile->rlimits.mask)
|
||||
+ return;
|
||||
+
|
||||
+ task_lock(task->group_leader);
|
||||
+ mask = 1;
|
||||
+ for (i = 0; i < RLIM_NLIMITS; i++, mask <<= 1) {
|
||||
+ struct rlimit new_rlim, *old_rlim;
|
||||
+
|
||||
+ /* check to see if NPROC which is per profile and handled
|
||||
+ * in clone/exec or whether this is a limit to be set
|
||||
+ * can't set cpu limit either right now
|
||||
+ */
|
||||
+ if (i == RLIMIT_NPROC || i == RLIMIT_CPU)
|
||||
+ continue;
|
||||
+
|
||||
+ old_rlim = task->signal->rlim + i;
|
||||
+ new_rlim = *old_rlim;
|
||||
+
|
||||
+ if (mask & profile->rlimits.mask &&
|
||||
+ profile->rlimits.limits[i].rlim_max < new_rlim.rlim_max) {
|
||||
+ new_rlim.rlim_max = profile->rlimits.limits[i].rlim_max;
|
||||
+ /* soft limit should not exceed hard limit */
|
||||
+ if (new_rlim.rlim_cur > new_rlim.rlim_max)
|
||||
+ new_rlim.rlim_cur = new_rlim.rlim_max;
|
||||
+ }
|
||||
+
|
||||
+ *old_rlim = new_rlim;
|
||||
+ }
|
||||
+ task_unlock(task->group_leader);
|
||||
+}
|
||||
|
||||
/*******************************
|
||||
* Global task related functions
|
||||
@@ -885,6 +961,7 @@ int aa_revalidate_sk(struct sock *sk, ch
|
||||
*/
|
||||
int aa_clone(struct task_struct *child)
|
||||
{
|
||||
+ struct aa_audit sa;
|
||||
struct aa_task_context *cxt, *child_cxt;
|
||||
struct aa_profile *profile;
|
||||
|
||||
@@ -894,6 +971,11 @@ int aa_clone(struct task_struct *child)
|
||||
if (!child_cxt)
|
||||
return -ENOMEM;
|
||||
|
||||
+ memset(&sa, 0, sizeof(sa));
|
||||
+ sa.operation = "clone";
|
||||
+ sa.task = child->pid;
|
||||
+ sa.gfp_mask = GFP_KERNEL;
|
||||
+
|
||||
repeat:
|
||||
profile = aa_get_profile(current);
|
||||
if (profile) {
|
||||
@@ -910,18 +992,22 @@ repeat:
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
+ if (aa_rlimit_nproc(profile)) {
|
||||
+ sa.info = "rlimit nproc limit exceeded";
|
||||
+ unlock_profile(profile);
|
||||
+ aa_audit_reject(profile, &sa);
|
||||
+ aa_put_profile(profile);
|
||||
+ return -EAGAIN;
|
||||
+ }
|
||||
+
|
||||
/* No need to grab the child's task lock here. */
|
||||
aa_change_task_context(child, child_cxt, profile,
|
||||
cxt->cookie, cxt->previous_profile);
|
||||
+
|
||||
unlock_profile(profile);
|
||||
|
||||
if (APPARMOR_COMPLAIN(child_cxt) &&
|
||||
profile == profile->ns->null_complain_profile) {
|
||||
- struct aa_audit sa;
|
||||
- memset(&sa, 0, sizeof(sa));
|
||||
- sa.operation = "clone";
|
||||
- sa.gfp_mask = GFP_KERNEL;
|
||||
- sa.task = child->pid;
|
||||
aa_audit_hint(profile, &sa);
|
||||
}
|
||||
aa_put_profile(profile);
|
||||
@@ -1156,6 +1242,10 @@ repeat:
|
||||
sa.task = current->parent->pid;
|
||||
aa_audit_reject(profile, &sa);
|
||||
}
|
||||
+ if (PTR_ERR(old_profile) == -EAGAIN) {
|
||||
+ sa.info = "rlimit nproc limit exceeded";
|
||||
+ aa_audit_reject(profile, &sa);
|
||||
+ }
|
||||
new_profile = old_profile;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -1296,6 +1386,12 @@ static int do_change_profile(struct aa_p
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if ((error = aa_rlimit_nproc(new_profile))) {
|
||||
+ sa->info = "rlimit nproc limit exceeded";
|
||||
+ aa_audit_reject(cxt->profile, sa);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (new_profile == ns->null_complain_profile)
|
||||
aa_audit_hint(cxt->profile, sa);
|
||||
|
||||
@@ -1482,17 +1578,18 @@ struct aa_profile *__aa_replace_profile(
|
||||
|
||||
cxt = lock_task_and_profiles(task, profile);
|
||||
if (unlikely(profile && profile->isstale)) {
|
||||
- task_unlock(task);
|
||||
- unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
|
||||
- aa_free_task_context(new_cxt);
|
||||
- return ERR_PTR(-ESTALE);
|
||||
+ old_profile = ERR_PTR(-ESTALE);
|
||||
+ goto error;
|
||||
}
|
||||
|
||||
if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) {
|
||||
- task_unlock(task);
|
||||
- unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
|
||||
- aa_free_task_context(new_cxt);
|
||||
- return ERR_PTR(-EPERM);
|
||||
+ old_profile = ERR_PTR(-EPERM);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (aa_rlimit_nproc(profile)) {
|
||||
+ old_profile = ERR_PTR(-EAGAIN);
|
||||
+ goto error;
|
||||
}
|
||||
|
||||
if (cxt)
|
||||
@@ -1500,8 +1597,15 @@ struct aa_profile *__aa_replace_profile(
|
||||
aa_change_task_context(task, new_cxt, profile, 0, NULL);
|
||||
|
||||
task_unlock(task);
|
||||
+ aa_set_rlimits(task, profile);
|
||||
unlock_both_profiles(profile, old_profile);
|
||||
return old_profile;
|
||||
+
|
||||
+error:
|
||||
+ task_unlock(task);
|
||||
+ unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
|
||||
+ aa_free_task_context(new_cxt);
|
||||
+ return old_profile;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1566,6 +1670,7 @@ void aa_change_task_context(struct task_
|
||||
|
||||
if (old_cxt) {
|
||||
list_del_init(&old_cxt->list);
|
||||
+ old_cxt->profile->task_count--;
|
||||
call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback);
|
||||
}
|
||||
if (new_cxt) {
|
||||
@@ -1577,6 +1682,7 @@ void aa_change_task_context(struct task_
|
||||
new_cxt->cookie = cookie;
|
||||
new_cxt->task = task;
|
||||
new_cxt->profile = aa_dup_profile(profile);
|
||||
+ profile->task_count++;
|
||||
new_cxt->previous_profile = aa_dup_profile(previous_profile);
|
||||
list_move(&new_cxt->list, &profile->task_contexts);
|
||||
}
|
||||
--- a/security/apparmor/module_interface.c
|
||||
+++ b/security/apparmor/module_interface.c
|
||||
@@ -177,6 +177,22 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int aa_is_u64(struct aa_ext *e, u64 *data, const char *name)
|
||||
+{
|
||||
+ void *pos = e->pos;
|
||||
+ if (aa_is_nameX(e, AA_U64, name)) {
|
||||
+ if (!aa_inbounds(e, sizeof(u64)))
|
||||
+ goto fail;
|
||||
+ if (data)
|
||||
+ *data = le64_to_cpu(get_unaligned((u64 *)e->pos));
|
||||
+ e->pos += sizeof(u64);
|
||||
+ return 1;
|
||||
+ }
|
||||
+fail:
|
||||
+ e->pos = pos;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static size_t aa_is_array(struct aa_ext *e, const char *name)
|
||||
{
|
||||
void *pos = e->pos;
|
||||
@@ -311,6 +327,39 @@ fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int aa_unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
|
||||
+{
|
||||
+ void *pos = e->pos;
|
||||
+
|
||||
+ /* rlimits are optional */
|
||||
+ if (aa_is_nameX(e, AA_STRUCT, "rlimits")) {
|
||||
+ int i, size;
|
||||
+ u32 tmp = 0;
|
||||
+ if (!aa_is_u32(e, &tmp, NULL))
|
||||
+ goto fail;
|
||||
+ profile->rlimits.mask = tmp;
|
||||
+
|
||||
+ size = aa_is_array(e, NULL);
|
||||
+ if (size != RLIM_NLIMITS)
|
||||
+ goto fail;
|
||||
+ for (i = 0; i < size; i++) {
|
||||
+ u64 tmp = 0;
|
||||
+ if (!aa_is_u64(e, &tmp, NULL))
|
||||
+ goto fail;
|
||||
+ profile->rlimits.limits[i].rlim_max = tmp;
|
||||
+ }
|
||||
+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
|
||||
+ goto fail;
|
||||
+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ return 1;
|
||||
+
|
||||
+fail:
|
||||
+ e->pos = pos;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* aa_unpack_profile - unpack a serialized profile
|
||||
* @e: serialized data extent information
|
||||
@@ -354,6 +403,9 @@ static struct aa_profile *aa_unpack_prof
|
||||
if (!aa_is_u32(e, &(profile->set_caps), NULL))
|
||||
goto fail;
|
||||
|
||||
+ if (!aa_unpack_rlimits(e, profile))
|
||||
+ goto fail;
|
||||
+
|
||||
size = aa_is_array(e, "net_allowed_af");
|
||||
if (size) {
|
||||
if (size > AF_MAX)
|
||||
@@ -613,6 +665,8 @@ ssize_t aa_replace_profile(void *udata,
|
||||
sa.operation = "profile_load";
|
||||
goto out;
|
||||
}
|
||||
+ /* do not fail replacement based off of profile's NPROC rlimit */
|
||||
+
|
||||
/*
|
||||
* Replacement needs to allocate a new aa_task_context for each
|
||||
* task confined by old_profile. To do this the profile locks
|
||||
@@ -633,6 +687,7 @@ ssize_t aa_replace_profile(void *udata,
|
||||
task_lock(task);
|
||||
task_replace(task, new_cxt, new_profile);
|
||||
task_unlock(task);
|
||||
+ aa_set_rlimits(task, new_profile);
|
||||
new_cxt = NULL;
|
||||
}
|
||||
unlock_both_profiles(old_profile, new_profile);
|
||||
@@ -655,6 +710,7 @@ out:
|
||||
*
|
||||
* remove a profile from the profile list and all aa_task_context references
|
||||
* to said profile.
|
||||
+ * NOTE: removing confinement does not restore rlimits to preconfinemnet values
|
||||
*/
|
||||
ssize_t aa_remove_profile(char *name, size_t size)
|
||||
{
|
18
kernel-patches/2.6.24/audit-log-type-in-syslog.diff
Normal file
18
kernel-patches/2.6.24/audit-log-type-in-syslog.diff
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
security/apparmor/main.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -159,8 +159,10 @@ static int aa_audit_base(struct aa_profi
|
||||
return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
+ audit_log_format(ab, " type=%d", type);
|
||||
+
|
||||
if (sa->operation)
|
||||
- audit_log_format(ab, "operation=\"%s\"", sa->operation);
|
||||
+ audit_log_format(ab, " operation=\"%s\"", sa->operation);
|
||||
|
||||
if (sa->info) {
|
||||
audit_log_format(ab, " info=\"%s\"", sa->info);
|
86
kernel-patches/2.6.24/d_namespace_path.diff
Normal file
86
kernel-patches/2.6.24/d_namespace_path.diff
Normal file
@@ -0,0 +1,86 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Add d_namespace_path() to compute namespace relative pathnames
|
||||
|
||||
In AppArmor, we are interested in pathnames relative to the namespace root.
|
||||
This is the same as d_path() except for the root where the search ends. Add
|
||||
a function for computing the namespace-relative path.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/dcache.c | 6 +++---
|
||||
fs/namespace.c | 27 +++++++++++++++++++++++++++
|
||||
include/linux/dcache.h | 2 ++
|
||||
include/linux/mount.h | 2 ++
|
||||
4 files changed, 34 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -1782,9 +1782,9 @@ shouldnt_be_hashed:
|
||||
*
|
||||
* Returns the buffer or an error code.
|
||||
*/
|
||||
-static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
- struct dentry *root, struct vfsmount *rootmnt,
|
||||
- char *buffer, int buflen, int fail_deleted)
|
||||
+char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
+ struct dentry *root, struct vfsmount *rootmnt,
|
||||
+ char *buffer, int buflen, int fail_deleted)
|
||||
{
|
||||
int namelen, is_slash, vfsmount_locked = 0;
|
||||
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -1883,3 +1883,30 @@ void __put_mnt_ns(struct mnt_namespace *
|
||||
release_mounts(&umount_list);
|
||||
kfree(ns);
|
||||
}
|
||||
+
|
||||
+char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
+ char *buf, int buflen)
|
||||
+{
|
||||
+ struct vfsmount *rootmnt, *nsrootmnt = NULL;
|
||||
+ struct dentry *root = NULL;
|
||||
+ char *res;
|
||||
+
|
||||
+ read_lock(¤t->fs->lock);
|
||||
+ rootmnt = mntget(current->fs->rootmnt);
|
||||
+ read_unlock(¤t->fs->lock);
|
||||
+ spin_lock(&vfsmount_lock);
|
||||
+ if (rootmnt->mnt_ns)
|
||||
+ nsrootmnt = mntget(rootmnt->mnt_ns->root);
|
||||
+ spin_unlock(&vfsmount_lock);
|
||||
+ mntput(rootmnt);
|
||||
+ if (nsrootmnt)
|
||||
+ root = dget(nsrootmnt->mnt_root);
|
||||
+ res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1);
|
||||
+ dput(root);
|
||||
+ mntput(nsrootmnt);
|
||||
+ /* Prevent empty path for lazily unmounted filesystems. */
|
||||
+ if (!IS_ERR(res) && *res == '\0')
|
||||
+ *--res = '.';
|
||||
+ return res;
|
||||
+}
|
||||
+EXPORT_SYMBOL(d_namespace_path);
|
||||
--- a/include/linux/dcache.h
|
||||
+++ b/include/linux/dcache.h
|
||||
@@ -300,6 +300,8 @@ extern int d_validate(struct dentry *, s
|
||||
*/
|
||||
extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
|
||||
|
||||
+extern char *__d_path(struct dentry *, struct vfsmount *, struct dentry *,
|
||||
+ struct vfsmount *, char *, int, int);
|
||||
extern char * d_path(struct dentry *, struct vfsmount *, char *, int);
|
||||
|
||||
/* Allocation counts.. */
|
||||
--- a/include/linux/mount.h
|
||||
+++ b/include/linux/mount.h
|
||||
@@ -103,5 +103,7 @@ extern void shrink_submounts(struct vfsm
|
||||
extern spinlock_t vfsmount_lock;
|
||||
extern dev_t name_to_dev_t(char *name);
|
||||
|
||||
+extern char *d_namespace_path(struct dentry *, struct vfsmount *, char *, int);
|
||||
+
|
||||
#endif
|
||||
#endif /* _LINUX_MOUNT_H */
|
47
kernel-patches/2.6.24/do_path_lookup-nameidata.diff
Normal file
47
kernel-patches/2.6.24/do_path_lookup-nameidata.diff
Normal file
@@ -0,0 +1,47 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Switch to vfs_permission() in do_path_lookup()
|
||||
|
||||
Switch from file_permission() to vfs_permission() in do_path_lookup():
|
||||
this avoids calling permission() with a NULL nameidata here.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 13 ++++++-------
|
||||
1 file changed, 6 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -1147,25 +1147,24 @@ static int fastcall do_path_lookup(int d
|
||||
nd->dentry = dget(fs->pwd);
|
||||
read_unlock(&fs->lock);
|
||||
} else {
|
||||
- struct dentry *dentry;
|
||||
-
|
||||
file = fget_light(dfd, &fput_needed);
|
||||
retval = -EBADF;
|
||||
if (!file)
|
||||
goto out_fail;
|
||||
|
||||
- dentry = file->f_path.dentry;
|
||||
+ nd->dentry = file->f_path.dentry;
|
||||
+ nd->mnt = file->f_path.mnt;
|
||||
|
||||
retval = -ENOTDIR;
|
||||
- if (!S_ISDIR(dentry->d_inode->i_mode))
|
||||
+ if (!S_ISDIR(nd->dentry->d_inode->i_mode))
|
||||
goto fput_fail;
|
||||
|
||||
- retval = file_permission(file, MAY_EXEC);
|
||||
+ retval = vfs_permission(nd, MAY_EXEC);
|
||||
if (retval)
|
||||
goto fput_fail;
|
||||
|
||||
- nd->mnt = mntget(file->f_path.mnt);
|
||||
- nd->dentry = dget(dentry);
|
||||
+ mntget(nd->mnt);
|
||||
+ dget(nd->dentry);
|
||||
|
||||
fput_light(file, fput_needed);
|
||||
}
|
83
kernel-patches/2.6.24/file-handle-ops.diff
Normal file
83
kernel-patches/2.6.24/file-handle-ops.diff
Normal file
@@ -0,0 +1,83 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Enable LSM hooks to distinguish operations on file descriptors from operations on pathnames
|
||||
|
||||
Struct iattr already contains ia_file since commit cc4e69de from
|
||||
Miklos (which is related to commit befc649c). Use this to pass
|
||||
struct file down the setattr hooks. This allows LSMs to distinguish
|
||||
operations on file descriptors from operations on paths.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
Cc: Miklos Szeredi <mszeredi@suse.cz>
|
||||
|
||||
---
|
||||
fs/nfsd/vfs.c | 12 +++++++-----
|
||||
fs/open.c | 4 +++-
|
||||
2 files changed, 10 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -413,7 +413,7 @@ static ssize_t nfsd_getxattr(struct dent
|
||||
{
|
||||
ssize_t buflen;
|
||||
|
||||
- buflen = vfs_getxattr(dentry, mnt, key, NULL, 0);
|
||||
+ buflen = vfs_getxattr(dentry, mnt, key, NULL, 0, NULL);
|
||||
if (buflen <= 0)
|
||||
return buflen;
|
||||
|
||||
@@ -421,7 +421,7 @@ static ssize_t nfsd_getxattr(struct dent
|
||||
if (!*buf)
|
||||
return -ENOMEM;
|
||||
|
||||
- return vfs_getxattr(dentry, mnt, key, *buf, buflen);
|
||||
+ return vfs_getxattr(dentry, mnt, key, *buf, buflen, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -447,7 +447,7 @@ set_nfsv4_acl_one(struct dentry *dentry,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- error = vfs_setxattr(dentry, mnt, key, buf, len, 0);
|
||||
+ error = vfs_setxattr(dentry, mnt, key, buf, len, 0, NULL);
|
||||
out:
|
||||
kfree(buf);
|
||||
return error;
|
||||
@@ -2051,12 +2051,14 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
|
||||
|
||||
mnt = fhp->fh_export->ex_mnt;
|
||||
if (size)
|
||||
- error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size,0);
|
||||
+ error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size, 0,
|
||||
+ NULL);
|
||||
else {
|
||||
if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
|
||||
error = 0;
|
||||
else {
|
||||
- error = vfs_removexattr(fhp->fh_dentry, mnt, name);
|
||||
+ error = vfs_removexattr(fhp->fh_dentry, mnt, name,
|
||||
+ NULL);
|
||||
if (error == -ENODATA)
|
||||
error = 0;
|
||||
}
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -581,7 +581,7 @@ asmlinkage long sys_fchmod(unsigned int
|
||||
if (mode == (mode_t) -1)
|
||||
mode = inode->i_mode;
|
||||
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
||||
- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||
+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME | ATTR_FILE;
|
||||
err = fnotify_change(dentry, file->f_path.mnt, &newattrs, file);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
@@ -661,6 +661,8 @@ static int chown_common(struct dentry *
|
||||
if (!S_ISDIR(inode->i_mode))
|
||||
newattrs.ia_valid |=
|
||||
ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
|
||||
+ if (file)
|
||||
+ newattrs.ia_valid |= ATTR_FILE;
|
||||
mutex_lock(&inode->i_mutex);
|
||||
error = fnotify_change(dentry, mnt, &newattrs, file);
|
||||
mutex_unlock(&inode->i_mutex);
|
31
kernel-patches/2.6.24/file_permission-nameidata.diff
Normal file
31
kernel-patches/2.6.24/file_permission-nameidata.diff
Normal file
@@ -0,0 +1,31 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Fix file_permission()
|
||||
|
||||
We cannot easily switch from file_permission() to vfs_permission()
|
||||
everywhere, so fix file_permission() to not use a NULL nameidata
|
||||
for the remaining users.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -313,7 +313,13 @@ int vfs_permission(struct nameidata *nd,
|
||||
*/
|
||||
int file_permission(struct file *file, int mask)
|
||||
{
|
||||
- return permission(file->f_path.dentry->d_inode, mask, NULL);
|
||||
+ struct nameidata nd;
|
||||
+
|
||||
+ nd.dentry = file->f_path.dentry;
|
||||
+ nd.mnt = file->f_path.mnt;
|
||||
+ nd.flags = LOOKUP_ACCESS;
|
||||
+
|
||||
+ return permission(nd.dentry->d_inode, mask, &nd);
|
||||
}
|
||||
|
||||
/*
|
44
kernel-patches/2.6.24/fix-vfs_rmdir.diff
Normal file
44
kernel-patches/2.6.24/fix-vfs_rmdir.diff
Normal file
@@ -0,0 +1,44 @@
|
||||
From: John Johansen <jjohansen@suse.de>
|
||||
Subject: Call lsm hook before unhashing dentry in vfs_rmdir()
|
||||
|
||||
If we unhash the dentry before calling the security_inode_rmdir hook,
|
||||
we cannot compute the file's pathname in the hook anymore. AppArmor
|
||||
needs to know the filename in order to decide whether a file may be
|
||||
deleted, though.
|
||||
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 13 +++++++------
|
||||
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2097,6 +2097,10 @@ int vfs_rmdir(struct inode *dir, struct
|
||||
if (!dir->i_op || !dir->i_op->rmdir)
|
||||
return -EPERM;
|
||||
|
||||
+ error = security_inode_rmdir(dir, dentry, mnt);
|
||||
+ if (error)
|
||||
+ return error;
|
||||
+
|
||||
DQUOT_INIT(dir);
|
||||
|
||||
mutex_lock(&dentry->d_inode->i_mutex);
|
||||
@@ -2104,12 +2108,9 @@ int vfs_rmdir(struct inode *dir, struct
|
||||
if (d_mountpoint(dentry))
|
||||
error = -EBUSY;
|
||||
else {
|
||||
- error = security_inode_rmdir(dir, dentry, mnt);
|
||||
- if (!error) {
|
||||
- error = dir->i_op->rmdir(dir, dentry);
|
||||
- if (!error)
|
||||
- dentry->d_inode->i_flags |= S_DEAD;
|
||||
- }
|
||||
+ error = dir->i_op->rmdir(dir, dentry);
|
||||
+ if (!error)
|
||||
+ dentry->d_inode->i_flags |= S_DEAD;
|
||||
}
|
||||
mutex_unlock(&dentry->d_inode->i_mutex);
|
||||
if (!error) {
|
27
kernel-patches/2.6.24/fsetattr-reintro-ATTR_FILE.diff
Normal file
27
kernel-patches/2.6.24/fsetattr-reintro-ATTR_FILE.diff
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
fs/open.c | 3 +++
|
||||
include/linux/fs.h | 1 +
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -207,6 +207,9 @@ int do_truncate(struct dentry *dentry, s
|
||||
newattrs.ia_size = length;
|
||||
newattrs.ia_valid = ATTR_SIZE | time_attrs;
|
||||
|
||||
+ if (filp)
|
||||
+ newattrs.ia_valid |= ATTR_FILE;
|
||||
+
|
||||
/* Remove suid/sgid on truncate too */
|
||||
newattrs.ia_valid |= should_remove_suid(dentry);
|
||||
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -329,6 +329,7 @@ typedef void (dio_iodone_t)(struct kiocb
|
||||
#define ATTR_ATTR_FLAG 1024
|
||||
#define ATTR_KILL_SUID 2048
|
||||
#define ATTR_KILL_SGID 4096
|
||||
+#define ATTR_FILE 8192
|
||||
#define ATTR_KILL_PRIV 16384
|
||||
#define ATTR_OPEN 32768 /* Truncating from open(O_TRUNC) */
|
||||
|
392
kernel-patches/2.6.24/fsetattr.diff
Normal file
392
kernel-patches/2.6.24/fsetattr.diff
Normal file
@@ -0,0 +1,392 @@
|
||||
Subject: VFS: new fsetattr() file operation
|
||||
|
||||
From: Miklos Szeredi <mszeredi@suse.cz>
|
||||
|
||||
Add a new file operation: f_op->fsetattr(), that is invoked by
|
||||
ftruncate, fchmod, fchown and utimensat. Fall back to i_op->setattr()
|
||||
if it is not defined.
|
||||
|
||||
For the reasons why we need this, see patch adding fgetattr().
|
||||
|
||||
ftruncate() already passed the open file to the filesystem via the
|
||||
ia_file member of struct iattr. However it is cleaner to have a
|
||||
separate file operation for this, so remove ia_file, ATTR_FILE and
|
||||
convert existing users: fuse and AFS.
|
||||
|
||||
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> ---
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de> ---
|
||||
|
||||
---
|
||||
fs/afs/dir.c | 1 +
|
||||
fs/afs/file.c | 1 +
|
||||
fs/afs/inode.c | 19 +++++++++++++++----
|
||||
fs/afs/internal.h | 1 +
|
||||
fs/attr.c | 18 ++++++++++++++----
|
||||
fs/fuse/dir.c | 20 +++++++++-----------
|
||||
fs/fuse/file.c | 7 +++++++
|
||||
fs/fuse/fuse_i.h | 4 ++++
|
||||
fs/open.c | 20 ++++++++------------
|
||||
fs/utimes.c | 2 +-
|
||||
include/linux/fs.h | 10 ++--------
|
||||
11 files changed, 63 insertions(+), 40 deletions(-)
|
||||
|
||||
--- a/fs/afs/dir.c
|
||||
+++ b/fs/afs/dir.c
|
||||
@@ -45,6 +45,7 @@ const struct file_operations afs_dir_fil
|
||||
.release = afs_release,
|
||||
.readdir = afs_readdir,
|
||||
.lock = afs_lock,
|
||||
+ .fsetattr = afs_fsetattr,
|
||||
};
|
||||
|
||||
const struct inode_operations afs_dir_inode_operations = {
|
||||
--- a/fs/afs/file.c
|
||||
+++ b/fs/afs/file.c
|
||||
@@ -36,6 +36,7 @@ const struct file_operations afs_file_op
|
||||
.fsync = afs_fsync,
|
||||
.lock = afs_lock,
|
||||
.flock = afs_flock,
|
||||
+ .fsetattr = afs_fsetattr,
|
||||
};
|
||||
|
||||
const struct inode_operations afs_file_inode_operations = {
|
||||
--- a/fs/afs/inode.c
|
||||
+++ b/fs/afs/inode.c
|
||||
@@ -360,7 +360,8 @@ void afs_clear_inode(struct inode *inode
|
||||
/*
|
||||
* set the attributes of an inode
|
||||
*/
|
||||
-int afs_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
+static int afs_do_setattr(struct dentry *dentry, struct iattr *attr,
|
||||
+ struct file *file)
|
||||
{
|
||||
struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
|
||||
struct key *key;
|
||||
@@ -382,8 +383,8 @@ int afs_setattr(struct dentry *dentry, s
|
||||
afs_writeback_all(vnode);
|
||||
}
|
||||
|
||||
- if (attr->ia_valid & ATTR_FILE) {
|
||||
- key = attr->ia_file->private_data;
|
||||
+ if (file) {
|
||||
+ key = file->private_data;
|
||||
} else {
|
||||
key = afs_request_key(vnode->volume->cell);
|
||||
if (IS_ERR(key)) {
|
||||
@@ -393,10 +394,20 @@ int afs_setattr(struct dentry *dentry, s
|
||||
}
|
||||
|
||||
ret = afs_vnode_setattr(vnode, key, attr);
|
||||
- if (!(attr->ia_valid & ATTR_FILE))
|
||||
+ if (!file)
|
||||
key_put(key);
|
||||
|
||||
error:
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+int afs_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
+{
|
||||
+ return afs_do_setattr(dentry, attr, NULL);
|
||||
+}
|
||||
+
|
||||
+int afs_fsetattr(struct file *file, struct iattr *attr)
|
||||
+{
|
||||
+ return afs_do_setattr(file->f_path.dentry, attr, file);
|
||||
+}
|
||||
--- a/fs/afs/internal.h
|
||||
+++ b/fs/afs/internal.h
|
||||
@@ -550,6 +550,7 @@ extern void afs_zap_data(struct afs_vnod
|
||||
extern int afs_validate(struct afs_vnode *, struct key *);
|
||||
extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
|
||||
extern int afs_setattr(struct dentry *, struct iattr *);
|
||||
+extern int afs_fsetattr(struct file *, struct iattr *);
|
||||
extern void afs_clear_inode(struct inode *);
|
||||
|
||||
/*
|
||||
--- a/fs/attr.c
|
||||
+++ b/fs/attr.c
|
||||
@@ -100,8 +100,8 @@ int inode_setattr(struct inode * inode,
|
||||
}
|
||||
EXPORT_SYMBOL(inode_setattr);
|
||||
|
||||
-int notify_change(struct dentry *dentry, struct vfsmount *mnt,
|
||||
- struct iattr *attr)
|
||||
+int fnotify_change(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct iattr *attr, struct file *file)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
mode_t mode = inode->i_mode;
|
||||
@@ -160,8 +160,12 @@ int notify_change(struct dentry *dentry,
|
||||
|
||||
if (inode->i_op && inode->i_op->setattr) {
|
||||
error = security_inode_setattr(dentry, mnt, attr);
|
||||
- if (!error)
|
||||
- error = inode->i_op->setattr(dentry, attr);
|
||||
+ if (!error) {
|
||||
+ if (file && file->f_op && file->f_op->fsetattr)
|
||||
+ error = file->f_op->fsetattr(file, attr);
|
||||
+ else
|
||||
+ error = inode->i_op->setattr(dentry, attr);
|
||||
+ }
|
||||
} else {
|
||||
error = inode_change_ok(inode, attr);
|
||||
if (!error)
|
||||
@@ -184,4 +188,10 @@ int notify_change(struct dentry *dentry,
|
||||
return error;
|
||||
}
|
||||
|
||||
+int notify_change(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct iattr *attr)
|
||||
+{
|
||||
+ return fnotify_change(dentry, mnt, attr, NULL);
|
||||
+}
|
||||
+
|
||||
EXPORT_SYMBOL(notify_change);
|
||||
--- a/fs/fuse/dir.c
|
||||
+++ b/fs/fuse/dir.c
|
||||
@@ -1063,21 +1063,22 @@ static int fuse_dir_fsync(struct file *f
|
||||
return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
|
||||
}
|
||||
|
||||
-static bool update_mtime(unsigned ivalid)
|
||||
+static bool update_mtime(unsigned ivalid, bool have_file)
|
||||
{
|
||||
/* Always update if mtime is explicitly set */
|
||||
if (ivalid & ATTR_MTIME_SET)
|
||||
return true;
|
||||
|
||||
/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
|
||||
- if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
|
||||
+ if ((ivalid & ATTR_SIZE) && ((ivalid & ATTR_OPEN) || have_file))
|
||||
return false;
|
||||
|
||||
/* In all other cases update */
|
||||
return true;
|
||||
}
|
||||
|
||||
-static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
|
||||
+static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
|
||||
+ bool have_file)
|
||||
{
|
||||
unsigned ivalid = iattr->ia_valid;
|
||||
|
||||
@@ -1096,7 +1097,7 @@ static void iattr_to_fattr(struct iattr
|
||||
if (!(ivalid & ATTR_ATIME_SET))
|
||||
arg->valid |= FATTR_ATIME_NOW;
|
||||
}
|
||||
- if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
|
||||
+ if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, have_file)) {
|
||||
arg->valid |= FATTR_MTIME;
|
||||
arg->mtime = iattr->ia_mtime.tv_sec;
|
||||
arg->mtimensec = iattr->ia_mtime.tv_nsec;
|
||||
@@ -1113,8 +1114,8 @@ static void iattr_to_fattr(struct iattr
|
||||
* vmtruncate() doesn't allow for this case, so do the rlimit checking
|
||||
* and the actual truncation by hand.
|
||||
*/
|
||||
-static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
|
||||
- struct file *file)
|
||||
+int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
|
||||
+ struct file *file)
|
||||
{
|
||||
struct inode *inode = entry->d_inode;
|
||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||
@@ -1152,7 +1153,7 @@ static int fuse_do_setattr(struct dentry
|
||||
|
||||
memset(&inarg, 0, sizeof(inarg));
|
||||
memset(&outarg, 0, sizeof(outarg));
|
||||
- iattr_to_fattr(attr, &inarg);
|
||||
+ iattr_to_fattr(attr, &inarg, file != NULL);
|
||||
if (file) {
|
||||
struct fuse_file *ff = file->private_data;
|
||||
inarg.valid |= FATTR_FH;
|
||||
@@ -1194,10 +1195,7 @@ static int fuse_do_setattr(struct dentry
|
||||
|
||||
static int fuse_setattr(struct dentry *entry, struct iattr *attr)
|
||||
{
|
||||
- if (attr->ia_valid & ATTR_FILE)
|
||||
- return fuse_do_setattr(entry, attr, attr->ia_file);
|
||||
- else
|
||||
- return fuse_do_setattr(entry, attr, NULL);
|
||||
+ return fuse_do_setattr(entry, attr, NULL);
|
||||
}
|
||||
|
||||
static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
|
||||
--- a/fs/fuse/file.c
|
||||
+++ b/fs/fuse/file.c
|
||||
@@ -907,6 +907,11 @@ static sector_t fuse_bmap(struct address
|
||||
return err ? 0 : outarg.block;
|
||||
}
|
||||
|
||||
+static int fuse_fsetattr(struct file *file, struct iattr *attr)
|
||||
+{
|
||||
+ return fuse_do_setattr(file->f_path.dentry, attr, file);
|
||||
+}
|
||||
+
|
||||
static const struct file_operations fuse_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = do_sync_read,
|
||||
@@ -920,6 +925,7 @@ static const struct file_operations fuse
|
||||
.fsync = fuse_fsync,
|
||||
.lock = fuse_file_lock,
|
||||
.flock = fuse_file_flock,
|
||||
+ .fsetattr = fuse_fsetattr,
|
||||
.splice_read = generic_file_splice_read,
|
||||
};
|
||||
|
||||
@@ -933,6 +939,7 @@ static const struct file_operations fuse
|
||||
.fsync = fuse_fsync,
|
||||
.lock = fuse_file_lock,
|
||||
.flock = fuse_file_flock,
|
||||
+ .fsetattr = fuse_fsetattr,
|
||||
/* no mmap and splice_read */
|
||||
};
|
||||
|
||||
--- a/fs/fuse/fuse_i.h
|
||||
+++ b/fs/fuse/fuse_i.h
|
||||
@@ -505,6 +505,10 @@ void fuse_change_attributes(struct inode
|
||||
*/
|
||||
int fuse_dev_init(void);
|
||||
|
||||
+
|
||||
+int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
|
||||
+ struct file *file);
|
||||
+
|
||||
/**
|
||||
* Cleanup the client device
|
||||
*/
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -206,16 +206,12 @@ int do_truncate(struct dentry *dentry, s
|
||||
|
||||
newattrs.ia_size = length;
|
||||
newattrs.ia_valid = ATTR_SIZE | time_attrs;
|
||||
- if (filp) {
|
||||
- newattrs.ia_file = filp;
|
||||
- newattrs.ia_valid |= ATTR_FILE;
|
||||
- }
|
||||
|
||||
/* Remove suid/sgid on truncate too */
|
||||
newattrs.ia_valid |= should_remove_suid(dentry);
|
||||
|
||||
mutex_lock(&dentry->d_inode->i_mutex);
|
||||
- err = notify_change(dentry, mnt, &newattrs);
|
||||
+ err = fnotify_change(dentry, mnt, &newattrs, filp);
|
||||
mutex_unlock(&dentry->d_inode->i_mutex);
|
||||
return err;
|
||||
}
|
||||
@@ -583,7 +579,7 @@ asmlinkage long sys_fchmod(unsigned int
|
||||
mode = inode->i_mode;
|
||||
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
||||
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||
- err = notify_change(dentry, file->f_path.mnt, &newattrs);
|
||||
+ err = fnotify_change(dentry, file->f_path.mnt, &newattrs, file);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
out_putf:
|
||||
@@ -633,7 +629,7 @@ asmlinkage long sys_chmod(const char __u
|
||||
}
|
||||
|
||||
static int chown_common(struct dentry * dentry, struct vfsmount *mnt,
|
||||
- uid_t user, gid_t group)
|
||||
+ uid_t user, gid_t group, struct file *file)
|
||||
{
|
||||
struct inode * inode;
|
||||
int error;
|
||||
@@ -663,7 +659,7 @@ static int chown_common(struct dentry *
|
||||
newattrs.ia_valid |=
|
||||
ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
|
||||
mutex_lock(&inode->i_mutex);
|
||||
- error = notify_change(dentry, mnt, &newattrs);
|
||||
+ error = fnotify_change(dentry, mnt, &newattrs, file);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
out:
|
||||
return error;
|
||||
@@ -677,7 +673,7 @@ asmlinkage long sys_chown(const char __u
|
||||
error = user_path_walk(filename, &nd);
|
||||
if (error)
|
||||
goto out;
|
||||
- error = chown_common(nd.dentry, nd.mnt, user, group);
|
||||
+ error = chown_common(nd.dentry, nd.mnt, user, group, NULL);
|
||||
path_release(&nd);
|
||||
out:
|
||||
return error;
|
||||
@@ -697,7 +693,7 @@ asmlinkage long sys_fchownat(int dfd, co
|
||||
error = __user_walk_fd(dfd, filename, follow, &nd);
|
||||
if (error)
|
||||
goto out;
|
||||
- error = chown_common(nd.dentry, nd.mnt, user, group);
|
||||
+ error = chown_common(nd.dentry, nd.mnt, user, group, NULL);
|
||||
path_release(&nd);
|
||||
out:
|
||||
return error;
|
||||
@@ -711,7 +707,7 @@ asmlinkage long sys_lchown(const char __
|
||||
error = user_path_walk_link(filename, &nd);
|
||||
if (error)
|
||||
goto out;
|
||||
- error = chown_common(nd.dentry, nd.mnt, user, group);
|
||||
+ error = chown_common(nd.dentry, nd.mnt, user, group, NULL);
|
||||
path_release(&nd);
|
||||
out:
|
||||
return error;
|
||||
@@ -730,7 +726,7 @@ asmlinkage long sys_fchown(unsigned int
|
||||
|
||||
dentry = file->f_path.dentry;
|
||||
audit_inode(NULL, dentry);
|
||||
- error = chown_common(dentry, file->f_path.mnt, user, group);
|
||||
+ error = chown_common(dentry, file->f_path.mnt, user, group, file);
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
--- a/fs/utimes.c
|
||||
+++ b/fs/utimes.c
|
||||
@@ -132,7 +132,7 @@ long do_utimes(int dfd, char __user *fil
|
||||
}
|
||||
}
|
||||
mutex_lock(&inode->i_mutex);
|
||||
- error = notify_change(path.dentry, path.mnt, &newattrs);
|
||||
+ error = fnotify_change(path.dentry, path.mnt, &newattrs, f);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
dput_and_out:
|
||||
if (f)
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -329,7 +329,6 @@ typedef void (dio_iodone_t)(struct kiocb
|
||||
#define ATTR_ATTR_FLAG 1024
|
||||
#define ATTR_KILL_SUID 2048
|
||||
#define ATTR_KILL_SGID 4096
|
||||
-#define ATTR_FILE 8192
|
||||
#define ATTR_KILL_PRIV 16384
|
||||
#define ATTR_OPEN 32768 /* Truncating from open(O_TRUNC) */
|
||||
|
||||
@@ -351,13 +350,6 @@ struct iattr {
|
||||
struct timespec ia_atime;
|
||||
struct timespec ia_mtime;
|
||||
struct timespec ia_ctime;
|
||||
-
|
||||
- /*
|
||||
- * Not an attribute, but an auxilary info for filesystems wanting to
|
||||
- * implement an ftruncate() like method. NOTE: filesystem should
|
||||
- * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL).
|
||||
- */
|
||||
- struct file *ia_file;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1188,6 +1180,7 @@ struct file_operations {
|
||||
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
|
||||
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
|
||||
int (*setlease)(struct file *, long, struct file_lock **);
|
||||
+ int (*fsetattr)(struct file *, struct iattr *);
|
||||
};
|
||||
|
||||
struct inode_operations {
|
||||
@@ -1694,6 +1687,7 @@ extern int do_remount_sb(struct super_bl
|
||||
extern sector_t bmap(struct inode *, sector_t);
|
||||
#endif
|
||||
extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *);
|
||||
+extern int fnotify_change(struct dentry *, struct vfsmount *, struct iattr *, struct file *);
|
||||
extern int permission(struct inode *, int, struct nameidata *);
|
||||
extern int generic_permission(struct inode *, int,
|
||||
int (*check_acl)(struct inode *, int));
|
60
kernel-patches/2.6.24/mount-consistent-__d_path.diff
Normal file
60
kernel-patches/2.6.24/mount-consistent-__d_path.diff
Normal file
@@ -0,0 +1,60 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Make d_path() consistent across mount operations
|
||||
|
||||
The path that __d_path() computes can become slightly inconsistent when it
|
||||
races with mount operations: it grabs the vfsmount_lock when traversing mount
|
||||
points but immediately drops it again, only to re-grab it when it reaches the
|
||||
next mount point. The result is that the filename computed is not always
|
||||
consisent, and the file may never have had that name. (This is unlikely, but
|
||||
still possible.)
|
||||
|
||||
Fix this by grabbing the vfsmount_lock when the first mount point is reached,
|
||||
and holding onto it until the d_cache lookup is completed.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/dcache.c | 14 ++++++++------
|
||||
1 file changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -1786,7 +1786,7 @@ static char *__d_path(struct dentry *den
|
||||
struct dentry *root, struct vfsmount *rootmnt,
|
||||
char *buffer, int buflen, int fail_deleted)
|
||||
{
|
||||
- int namelen, is_slash;
|
||||
+ int namelen, is_slash, vfsmount_locked = 0;
|
||||
|
||||
if (buflen < 2)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
@@ -1809,14 +1809,14 @@ static char *__d_path(struct dentry *den
|
||||
struct dentry * parent;
|
||||
|
||||
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
|
||||
- spin_lock(&vfsmount_lock);
|
||||
- if (vfsmnt->mnt_parent == vfsmnt) {
|
||||
- spin_unlock(&vfsmount_lock);
|
||||
- goto global_root;
|
||||
+ if (!vfsmount_locked) {
|
||||
+ spin_lock(&vfsmount_lock);
|
||||
+ vfsmount_locked = 1;
|
||||
}
|
||||
+ if (vfsmnt->mnt_parent == vfsmnt)
|
||||
+ goto global_root;
|
||||
dentry = vfsmnt->mnt_mountpoint;
|
||||
vfsmnt = vfsmnt->mnt_parent;
|
||||
- spin_unlock(&vfsmount_lock);
|
||||
continue;
|
||||
}
|
||||
parent = dentry->d_parent;
|
||||
@@ -1835,6 +1835,8 @@ static char *__d_path(struct dentry *den
|
||||
*--buffer = '/';
|
||||
|
||||
out:
|
||||
+ if (vfsmount_locked)
|
||||
+ spin_unlock(&vfsmount_lock);
|
||||
spin_unlock(&dcache_lock);
|
||||
return buffer;
|
||||
|
24
kernel-patches/2.6.24/parent-permission.diff
Normal file
24
kernel-patches/2.6.24/parent-permission.diff
Normal file
@@ -0,0 +1,24 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Allow permission functions to tell between parent and leaf checks
|
||||
|
||||
Set the LOOKUP_CONTINUE flag when checking parent permissions. This allows
|
||||
permission functions to tell between parent and leaf checks.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -1508,6 +1508,8 @@ static inline int may_create(struct inod
|
||||
return -EEXIST;
|
||||
if (IS_DEADDIR(dir))
|
||||
return -ENOENT;
|
||||
+ if (nd)
|
||||
+ nd->flags |= LOOKUP_CONTINUE;
|
||||
return permission(dir,MAY_WRITE | MAY_EXEC, nd);
|
||||
}
|
||||
|
144
kernel-patches/2.6.24/remove_suid.diff
Normal file
144
kernel-patches/2.6.24/remove_suid.diff
Normal file
@@ -0,0 +1,144 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Pass struct path down to remove_suid and children
|
||||
|
||||
Required by a later patch that adds a struct vfsmount parameter to
|
||||
notify_change().
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
|
||||
fs/ntfs/file.c | 2 +-
|
||||
fs/splice.c | 4 ++--
|
||||
fs/xfs/linux-2.6/xfs_lrw.c | 2 +-
|
||||
include/linux/fs.h | 4 ++--
|
||||
mm/filemap.c | 16 ++++++++--------
|
||||
mm/filemap_xip.c | 2 +-
|
||||
mm/shmem.c | 2 +-
|
||||
7 files changed, 16 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/fs/ntfs/file.c
|
||||
+++ b/fs/ntfs/file.c
|
||||
@@ -2120,7 +2120,7 @@ static ssize_t ntfs_file_aio_write_noloc
|
||||
goto out;
|
||||
if (!count)
|
||||
goto out;
|
||||
- err = remove_suid(file->f_path.dentry);
|
||||
+ err = remove_suid(&file->f_path);
|
||||
if (err)
|
||||
goto out;
|
||||
file_update_time(file);
|
||||
--- a/fs/splice.c
|
||||
+++ b/fs/splice.c
|
||||
@@ -775,7 +775,7 @@ generic_file_splice_write_nolock(struct
|
||||
ssize_t ret;
|
||||
int err;
|
||||
|
||||
- err = remove_suid(out->f_path.dentry);
|
||||
+ err = remove_suid(&out->f_path);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
|
||||
@@ -835,7 +835,7 @@ generic_file_splice_write(struct pipe_in
|
||||
if (killpriv)
|
||||
err = security_inode_killpriv(out->f_path.dentry);
|
||||
if (!err && killsuid)
|
||||
- err = __remove_suid(out->f_path.dentry, killsuid);
|
||||
+ err = __remove_suid(&out->f_path, killsuid);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
if (err)
|
||||
return err;
|
||||
--- a/fs/xfs/linux-2.6/xfs_lrw.c
|
||||
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
|
||||
@@ -727,7 +727,7 @@ start:
|
||||
!capable(CAP_FSETID)) {
|
||||
error = xfs_write_clear_setuid(xip);
|
||||
if (likely(!error))
|
||||
- error = -remove_suid(file->f_path.dentry);
|
||||
+ error = -remove_suid(&file->f_path);
|
||||
if (unlikely(error)) {
|
||||
goto out_unlock_internal;
|
||||
}
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -1766,9 +1766,9 @@ extern void __iget(struct inode * inode)
|
||||
extern void clear_inode(struct inode *);
|
||||
extern void destroy_inode(struct inode *);
|
||||
extern struct inode *new_inode(struct super_block *);
|
||||
-extern int __remove_suid(struct dentry *, int);
|
||||
+extern int __remove_suid(struct path *, int);
|
||||
extern int should_remove_suid(struct dentry *);
|
||||
-extern int remove_suid(struct dentry *);
|
||||
+extern int remove_suid(struct path *);
|
||||
|
||||
extern void __insert_inode_hash(struct inode *, unsigned long hashval);
|
||||
extern void remove_inode_hash(struct inode *);
|
||||
--- a/mm/filemap.c
|
||||
+++ b/mm/filemap.c
|
||||
@@ -1610,26 +1610,26 @@ int should_remove_suid(struct dentry *de
|
||||
}
|
||||
EXPORT_SYMBOL(should_remove_suid);
|
||||
|
||||
-int __remove_suid(struct dentry *dentry, int kill)
|
||||
+int __remove_suid(struct path *path, int kill)
|
||||
{
|
||||
struct iattr newattrs;
|
||||
|
||||
newattrs.ia_valid = ATTR_FORCE | kill;
|
||||
- return notify_change(dentry, &newattrs);
|
||||
+ return notify_change(path->dentry, &newattrs);
|
||||
}
|
||||
|
||||
-int remove_suid(struct dentry *dentry)
|
||||
+int remove_suid(struct path *path)
|
||||
{
|
||||
- int killsuid = should_remove_suid(dentry);
|
||||
- int killpriv = security_inode_need_killpriv(dentry);
|
||||
+ int killsuid = should_remove_suid(path->dentry);
|
||||
+ int killpriv = security_inode_need_killpriv(path->dentry);
|
||||
int error = 0;
|
||||
|
||||
if (killpriv < 0)
|
||||
return killpriv;
|
||||
if (killpriv)
|
||||
- error = security_inode_killpriv(dentry);
|
||||
+ error = security_inode_killpriv(path->dentry);
|
||||
if (!error && killsuid)
|
||||
- error = __remove_suid(dentry, killsuid);
|
||||
+ error = __remove_suid(path, killsuid);
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -2342,7 +2342,7 @@ __generic_file_aio_write_nolock(struct k
|
||||
if (count == 0)
|
||||
goto out;
|
||||
|
||||
- err = remove_suid(file->f_path.dentry);
|
||||
+ err = remove_suid(&file->f_path);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
--- a/mm/filemap_xip.c
|
||||
+++ b/mm/filemap_xip.c
|
||||
@@ -378,7 +378,7 @@ xip_file_write(struct file *filp, const
|
||||
if (count == 0)
|
||||
goto out_backing;
|
||||
|
||||
- ret = remove_suid(filp->f_path.dentry);
|
||||
+ ret = remove_suid(&filp->f_path);
|
||||
if (ret)
|
||||
goto out_backing;
|
||||
|
||||
--- a/mm/shmem.c
|
||||
+++ b/mm/shmem.c
|
||||
@@ -1525,7 +1525,7 @@ shmem_file_write(struct file *file, cons
|
||||
if (err || !count)
|
||||
goto out;
|
||||
|
||||
- err = remove_suid(file->f_path.dentry);
|
||||
+ err = remove_suid(&file->f_path);
|
||||
if (err)
|
||||
goto out;
|
||||
|
107
kernel-patches/2.6.24/security-create.diff
Normal file
107
kernel-patches/2.6.24/security-create.diff
Normal file
@@ -0,0 +1,107 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_create LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 2 +-
|
||||
include/linux/security.h | 9 ++++++---
|
||||
security/dummy.c | 2 +-
|
||||
security/security.c | 5 +++--
|
||||
security/selinux/hooks.c | 3 ++-
|
||||
5 files changed, 13 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/fs/namei.c 2007-11-02 17:44:43.000000000 -0400
|
||||
+++ b/fs/namei.c 2007-11-02 17:49:23.000000000 -0400
|
||||
@@ -1583,7 +1583,7 @@ int vfs_create(struct inode *dir, struct
|
||||
return -EACCES; /* shouldn't it be ENOSYS? */
|
||||
mode &= S_IALLUGO;
|
||||
mode |= S_IFREG;
|
||||
- error = security_inode_create(dir, dentry, mode);
|
||||
+ error = security_inode_create(dir, dentry, nd ? nd->mnt : NULL, mode);
|
||||
if (error)
|
||||
return error;
|
||||
DQUOT_INIT(dir);
|
||||
--- a/include/linux/security.h 2007-11-02 17:44:43.000000000 -0400
|
||||
+++ b/include/linux/security.h 2007-11-02 17:49:39.000000000 -0400
|
||||
@@ -297,6 +297,7 @@ struct request_sock;
|
||||
* Check permission to create a regular file.
|
||||
* @dir contains inode structure of the parent of the new file.
|
||||
* @dentry contains the dentry structure for the file to be created.
|
||||
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
|
||||
* @mode contains the file mode of the file to be created.
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_link:
|
||||
@@ -1247,8 +1248,8 @@ struct security_operations {
|
||||
void (*inode_free_security) (struct inode *inode);
|
||||
int (*inode_init_security) (struct inode *inode, struct inode *dir,
|
||||
char **name, void **value, size_t *len);
|
||||
- int (*inode_create) (struct inode *dir,
|
||||
- struct dentry *dentry, int mode);
|
||||
+ int (*inode_create) (struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode);
|
||||
int (*inode_link) (struct dentry *old_dentry,
|
||||
struct inode *dir, struct dentry *new_dentry);
|
||||
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
|
||||
@@ -1503,7 +1504,8 @@ int security_inode_alloc(struct inode *i
|
||||
void security_inode_free(struct inode *inode);
|
||||
int security_inode_init_security(struct inode *inode, struct inode *dir,
|
||||
char **name, void **value, size_t *len);
|
||||
-int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
|
||||
+int security_inode_create(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode);
|
||||
int security_inode_link(struct dentry *old_dentry, struct inode *dir,
|
||||
struct dentry *new_dentry);
|
||||
int security_inode_unlink(struct inode *dir, struct dentry *dentry);
|
||||
@@ -1813,6 +1815,7 @@ static inline int security_inode_init_se
|
||||
|
||||
static inline int security_inode_create (struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
+ struct vfsmount *mnt,
|
||||
int mode)
|
||||
{
|
||||
return 0;
|
||||
--- a/security/dummy.c 2007-11-02 17:44:43.000000000 -0400
|
||||
+++ b/security/dummy.c 2007-11-02 17:49:23.000000000 -0400
|
||||
@@ -262,7 +262,7 @@ static int dummy_inode_init_security (st
|
||||
}
|
||||
|
||||
static int dummy_inode_create (struct inode *inode, struct dentry *dentry,
|
||||
- int mask)
|
||||
+ struct vfsmount *mnt, int mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c 2007-11-02 17:46:44.000000000 -0400
|
||||
+++ b/security/security.c 2007-11-02 17:49:23.000000000 -0400
|
||||
@@ -329,11 +329,12 @@ int security_inode_init_security(struct
|
||||
}
|
||||
EXPORT_SYMBOL(security_inode_init_security);
|
||||
|
||||
-int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
|
||||
+int security_inode_create(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dir)))
|
||||
return 0;
|
||||
- return security_ops->inode_create(dir, dentry, mode);
|
||||
+ return security_ops->inode_create(dir, dentry, mnt, mode);
|
||||
}
|
||||
|
||||
int security_inode_link(struct dentry *old_dentry, struct inode *dir,
|
||||
--- a/security/selinux/hooks.c 2007-11-02 17:44:43.000000000 -0400
|
||||
+++ b/security/selinux/hooks.c 2007-11-02 17:49:23.000000000 -0400
|
||||
@@ -2184,7 +2184,8 @@ static int selinux_inode_init_security(s
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
|
||||
+static int selinux_inode_create(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mask)
|
||||
{
|
||||
return may_create(dir, dentry, SECCLASS_FILE);
|
||||
}
|
110
kernel-patches/2.6.24/security-getxattr.diff
Normal file
110
kernel-patches/2.6.24/security-getxattr.diff
Normal file
@@ -0,0 +1,110 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_getxattr LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/xattr.c | 2 +-
|
||||
include/linux/security.h | 11 +++++++----
|
||||
security/dummy.c | 3 ++-
|
||||
security/security.c | 5 +++--
|
||||
security/selinux/hooks.c | 3 ++-
|
||||
5 files changed, 15 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/fs/xattr.c
|
||||
+++ b/fs/xattr.c
|
||||
@@ -115,7 +115,7 @@ vfs_getxattr(struct dentry *dentry, stru
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
- error = security_inode_getxattr(dentry, name);
|
||||
+ error = security_inode_getxattr(dentry, mnt, name);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -405,7 +405,7 @@ struct request_sock;
|
||||
* @value identified by @name for @dentry and @mnt.
|
||||
* @inode_getxattr:
|
||||
* Check permission before obtaining the extended attributes
|
||||
- * identified by @name for @dentry.
|
||||
+ * identified by @name for @dentry and @mnt.
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_listxattr:
|
||||
* Check permission before obtaining the list of extended attribute
|
||||
@@ -1291,7 +1291,8 @@ struct security_operations {
|
||||
struct vfsmount *mnt,
|
||||
char *name, void *value,
|
||||
size_t size, int flags);
|
||||
- int (*inode_getxattr) (struct dentry *dentry, char *name);
|
||||
+ int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name);
|
||||
int (*inode_listxattr) (struct dentry *dentry);
|
||||
int (*inode_removexattr) (struct dentry *dentry, char *name);
|
||||
int (*inode_need_killpriv) (struct dentry *dentry);
|
||||
@@ -1554,7 +1555,8 @@ int security_inode_setxattr(struct dentr
|
||||
void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
char *name, void *value, size_t size,
|
||||
int flags);
|
||||
-int security_inode_getxattr(struct dentry *dentry, char *name);
|
||||
+int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name);
|
||||
int security_inode_listxattr(struct dentry *dentry);
|
||||
int security_inode_removexattr(struct dentry *dentry, char *name);
|
||||
int security_inode_need_killpriv(struct dentry *dentry);
|
||||
@@ -1954,7 +1956,8 @@ static inline void security_inode_post_s
|
||||
int flags)
|
||||
{ }
|
||||
|
||||
-static inline int security_inode_getxattr (struct dentry *dentry, char *name)
|
||||
+static inline int security_inode_getxattr (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -365,7 +365,8 @@ static void dummy_inode_post_setxattr (s
|
||||
{
|
||||
}
|
||||
|
||||
-static int dummy_inode_getxattr (struct dentry *dentry, char *name)
|
||||
+static int dummy_inode_getxattr (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -458,11 +458,12 @@ void security_inode_post_setxattr(struct
|
||||
security_ops->inode_post_setxattr(dentry, mnt, name, value, size, flags);
|
||||
}
|
||||
|
||||
-int security_inode_getxattr(struct dentry *dentry, char *name)
|
||||
+int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_getxattr(dentry, name);
|
||||
+ return security_ops->inode_getxattr(dentry, mnt, name);
|
||||
}
|
||||
|
||||
int security_inode_listxattr(struct dentry *dentry)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2409,7 +2409,8 @@ static void selinux_inode_post_setxattr(
|
||||
return;
|
||||
}
|
||||
|
||||
-static int selinux_inode_getxattr (struct dentry *dentry, char *name)
|
||||
+static int selinux_inode_getxattr (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name)
|
||||
{
|
||||
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
|
||||
}
|
134
kernel-patches/2.6.24/security-link.diff
Normal file
134
kernel-patches/2.6.24/security-link.diff
Normal file
@@ -0,0 +1,134 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass the struct vfsmounts to the inode_link LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 3 ++-
|
||||
include/linux/security.h | 16 +++++++++++-----
|
||||
security/dummy.c | 6 ++++--
|
||||
security/security.c | 8 +++++---
|
||||
security/selinux/hooks.c | 9 +++++++--
|
||||
5 files changed, 29 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2356,7 +2356,8 @@ int vfs_link(struct dentry *old_dentry,
|
||||
if (S_ISDIR(old_dentry->d_inode->i_mode))
|
||||
return -EPERM;
|
||||
|
||||
- error = security_inode_link(old_dentry, dir, new_dentry);
|
||||
+ error = security_inode_link(old_dentry, old_mnt, dir, new_dentry,
|
||||
+ new_mnt);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -303,8 +303,10 @@ struct request_sock;
|
||||
* @inode_link:
|
||||
* Check permission before creating a new hard link to a file.
|
||||
* @old_dentry contains the dentry structure for an existing link to the file.
|
||||
+ * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL).
|
||||
* @dir contains the inode structure of the parent directory of the new link.
|
||||
* @new_dentry contains the dentry structure for the new link.
|
||||
+ * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL).
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_unlink:
|
||||
* Check the permission to remove a hard link to a file.
|
||||
@@ -1255,8 +1257,9 @@ struct security_operations {
|
||||
char **name, void **value, size_t *len);
|
||||
int (*inode_create) (struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode);
|
||||
- int (*inode_link) (struct dentry *old_dentry,
|
||||
- struct inode *dir, struct dentry *new_dentry);
|
||||
+ int (*inode_link) (struct dentry *old_dentry, struct vfsmount *old_mnt,
|
||||
+ struct inode *dir, struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt);
|
||||
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
|
||||
int (*inode_symlink) (struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, const char *old_name);
|
||||
@@ -1513,8 +1516,9 @@ int security_inode_init_security(struct
|
||||
char **name, void **value, size_t *len);
|
||||
int security_inode_create(struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode);
|
||||
-int security_inode_link(struct dentry *old_dentry, struct inode *dir,
|
||||
- struct dentry *new_dentry);
|
||||
+int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
|
||||
+ struct inode *dir, struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt);
|
||||
int security_inode_unlink(struct inode *dir, struct dentry *dentry);
|
||||
int security_inode_symlink(struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, const char *old_name);
|
||||
@@ -1832,8 +1836,10 @@ static inline int security_inode_create
|
||||
}
|
||||
|
||||
static inline int security_inode_link (struct dentry *old_dentry,
|
||||
+ struct vfsmount *old_mnt,
|
||||
struct inode *dir,
|
||||
- struct dentry *new_dentry)
|
||||
+ struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -267,8 +267,10 @@ static int dummy_inode_create (struct in
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int dummy_inode_link (struct dentry *old_dentry, struct inode *inode,
|
||||
- struct dentry *new_dentry)
|
||||
+static int dummy_inode_link (struct dentry *old_dentry,
|
||||
+ struct vfsmount *old_mnt, struct inode *inode,
|
||||
+ struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -336,12 +336,14 @@ int security_inode_create(struct inode *
|
||||
return security_ops->inode_create(dir, dentry, mnt, mode);
|
||||
}
|
||||
|
||||
-int security_inode_link(struct dentry *old_dentry, struct inode *dir,
|
||||
- struct dentry *new_dentry)
|
||||
+int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
|
||||
+ struct inode *dir, struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(old_dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_link(old_dentry, dir, new_dentry);
|
||||
+ return security_ops->inode_link(old_dentry, old_mnt, dir,
|
||||
+ new_dentry, new_mnt);
|
||||
}
|
||||
|
||||
int security_inode_unlink(struct inode *dir, struct dentry *dentry)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2190,11 +2190,16 @@ static int selinux_inode_create(struct i
|
||||
return may_create(dir, dentry, SECCLASS_FILE);
|
||||
}
|
||||
|
||||
-static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
|
||||
+static int selinux_inode_link(struct dentry *old_dentry,
|
||||
+ struct vfsmount *old_mnt,
|
||||
+ struct inode *dir,
|
||||
+ struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt)
|
||||
{
|
||||
int rc;
|
||||
|
||||
- rc = secondary_ops->inode_link(old_dentry,dir,new_dentry);
|
||||
+ rc = secondary_ops->inode_link(old_dentry, old_mnt, dir, new_dentry,
|
||||
+ new_mnt);
|
||||
if (rc)
|
||||
return rc;
|
||||
return may_link(dir, old_dentry, MAY_LINK);
|
105
kernel-patches/2.6.24/security-listxattr.diff
Normal file
105
kernel-patches/2.6.24/security-listxattr.diff
Normal file
@@ -0,0 +1,105 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_listxattr LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/xattr.c | 2 +-
|
||||
include/linux/security.h | 9 +++++----
|
||||
security/dummy.c | 2 +-
|
||||
security/security.c | 4 ++--
|
||||
security/selinux/hooks.c | 2 +-
|
||||
5 files changed, 10 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/fs/xattr.c
|
||||
+++ b/fs/xattr.c
|
||||
@@ -148,7 +148,7 @@ vfs_listxattr(struct dentry *dentry, str
|
||||
struct inode *inode = dentry->d_inode;
|
||||
ssize_t error;
|
||||
|
||||
- error = security_inode_listxattr(dentry);
|
||||
+ error = security_inode_listxattr(dentry, mnt);
|
||||
if (error)
|
||||
return error;
|
||||
error = -EOPNOTSUPP;
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -409,7 +409,7 @@ struct request_sock;
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_listxattr:
|
||||
* Check permission before obtaining the list of extended attribute
|
||||
- * names for @dentry.
|
||||
+ * names for @dentry and @mnt.
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_removexattr:
|
||||
* Check permission before removing the extended attribute
|
||||
@@ -1293,7 +1293,7 @@ struct security_operations {
|
||||
size_t size, int flags);
|
||||
int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
char *name);
|
||||
- int (*inode_listxattr) (struct dentry *dentry);
|
||||
+ int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt);
|
||||
int (*inode_removexattr) (struct dentry *dentry, char *name);
|
||||
int (*inode_need_killpriv) (struct dentry *dentry);
|
||||
int (*inode_killpriv) (struct dentry *dentry);
|
||||
@@ -1557,7 +1557,7 @@ void security_inode_post_setxattr(struct
|
||||
int flags);
|
||||
int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
char *name);
|
||||
-int security_inode_listxattr(struct dentry *dentry);
|
||||
+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt);
|
||||
int security_inode_removexattr(struct dentry *dentry, char *name);
|
||||
int security_inode_need_killpriv(struct dentry *dentry);
|
||||
int security_inode_killpriv(struct dentry *dentry);
|
||||
@@ -1962,7 +1962,8 @@ static inline int security_inode_getxatt
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline int security_inode_listxattr (struct dentry *dentry)
|
||||
+static inline int security_inode_listxattr (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -371,7 +371,7 @@ static int dummy_inode_getxattr (struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int dummy_inode_listxattr (struct dentry *dentry)
|
||||
+static int dummy_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -466,11 +466,11 @@ int security_inode_getxattr(struct dentr
|
||||
return security_ops->inode_getxattr(dentry, mnt, name);
|
||||
}
|
||||
|
||||
-int security_inode_listxattr(struct dentry *dentry)
|
||||
+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_listxattr(dentry);
|
||||
+ return security_ops->inode_listxattr(dentry, mnt);
|
||||
}
|
||||
|
||||
int security_inode_removexattr(struct dentry *dentry, char *name)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2415,7 +2415,7 @@ static int selinux_inode_getxattr (struc
|
||||
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
|
||||
}
|
||||
|
||||
-static int selinux_inode_listxattr (struct dentry *dentry)
|
||||
+static int selinux_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
|
||||
}
|
106
kernel-patches/2.6.24/security-mkdir.diff
Normal file
106
kernel-patches/2.6.24/security-mkdir.diff
Normal file
@@ -0,0 +1,106 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_mkdir LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 2 +-
|
||||
include/linux/security.h | 8 ++++++--
|
||||
security/dummy.c | 2 +-
|
||||
security/security.c | 5 +++--
|
||||
security/selinux/hooks.c | 3 ++-
|
||||
5 files changed, 13 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2009,7 +2009,7 @@ int vfs_mkdir(struct inode *dir, struct
|
||||
return -EPERM;
|
||||
|
||||
mode &= (S_IRWXUGO|S_ISVTX);
|
||||
- error = security_inode_mkdir(dir, dentry, mode);
|
||||
+ error = security_inode_mkdir(dir, dentry, mnt, mode);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -322,6 +322,7 @@ struct request_sock;
|
||||
* associated with inode strcture @dir.
|
||||
* @dir containst the inode structure of parent of the directory to be created.
|
||||
* @dentry contains the dentry structure of new directory.
|
||||
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
|
||||
* @mode contains the mode of new directory.
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_rmdir:
|
||||
@@ -1256,7 +1257,8 @@ struct security_operations {
|
||||
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
|
||||
int (*inode_symlink) (struct inode *dir,
|
||||
struct dentry *dentry, const char *old_name);
|
||||
- int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode);
|
||||
+ int (*inode_mkdir) (struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode);
|
||||
int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
|
||||
int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
|
||||
int mode, dev_t dev);
|
||||
@@ -1513,7 +1515,8 @@ int security_inode_link(struct dentry *o
|
||||
int security_inode_unlink(struct inode *dir, struct dentry *dentry);
|
||||
int security_inode_symlink(struct inode *dir, struct dentry *dentry,
|
||||
const char *old_name);
|
||||
-int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode);
|
||||
+int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode);
|
||||
int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
|
||||
int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
|
||||
int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
@@ -1846,6 +1849,7 @@ static inline int security_inode_symlink
|
||||
|
||||
static inline int security_inode_mkdir (struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
+ struct vfsmount *mnt,
|
||||
int mode)
|
||||
{
|
||||
return 0;
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -285,7 +285,7 @@ static int dummy_inode_symlink (struct i
|
||||
}
|
||||
|
||||
static int dummy_inode_mkdir (struct inode *inode, struct dentry *dentry,
|
||||
- int mask)
|
||||
+ struct vfsmount *mnt, int mask)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -359,11 +359,12 @@ int security_inode_symlink(struct inode
|
||||
return security_ops->inode_symlink(dir, dentry, old_name);
|
||||
}
|
||||
|
||||
-int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
+int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dir)))
|
||||
return 0;
|
||||
- return security_ops->inode_mkdir(dir, dentry, mode);
|
||||
+ return security_ops->inode_mkdir(dir, dentry, mnt, mode);
|
||||
}
|
||||
|
||||
int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2215,7 +2215,8 @@ static int selinux_inode_symlink(struct
|
||||
return may_create(dir, dentry, SECCLASS_LNK_FILE);
|
||||
}
|
||||
|
||||
-static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)
|
||||
+static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mask)
|
||||
{
|
||||
return may_create(dir, dentry, SECCLASS_DIR);
|
||||
}
|
110
kernel-patches/2.6.24/security-mknod.diff
Normal file
110
kernel-patches/2.6.24/security-mknod.diff
Normal file
@@ -0,0 +1,110 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_mknod LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 2 +-
|
||||
include/linux/security.h | 7 +++++--
|
||||
security/dummy.c | 2 +-
|
||||
security/security.c | 5 +++--
|
||||
security/selinux/hooks.c | 5 +++--
|
||||
5 files changed, 13 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -1932,7 +1932,7 @@ int vfs_mknod(struct inode *dir, struct
|
||||
if (!dir->i_op || !dir->i_op->mknod)
|
||||
return -EPERM;
|
||||
|
||||
- error = security_inode_mknod(dir, dentry, mode, dev);
|
||||
+ error = security_inode_mknod(dir, dentry, mnt, mode, dev);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -337,6 +337,7 @@ struct request_sock;
|
||||
* and not this hook.
|
||||
* @dir contains the inode structure of parent of the new file.
|
||||
* @dentry contains the dentry structure of the new file.
|
||||
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
|
||||
* @mode contains the mode of the new file.
|
||||
* @dev contains the device number.
|
||||
* Return 0 if permission is granted.
|
||||
@@ -1261,7 +1262,7 @@ struct security_operations {
|
||||
struct vfsmount *mnt, int mode);
|
||||
int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
|
||||
int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
|
||||
- int mode, dev_t dev);
|
||||
+ struct vfsmount *mnt, int mode, dev_t dev);
|
||||
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct inode *new_dir, struct dentry *new_dentry);
|
||||
int (*inode_readlink) (struct dentry *dentry);
|
||||
@@ -1518,7 +1519,8 @@ int security_inode_symlink(struct inode
|
||||
int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode);
|
||||
int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
|
||||
-int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
|
||||
+int security_inode_mknod(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode, dev_t dev);
|
||||
int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct inode *new_dir, struct dentry *new_dentry);
|
||||
int security_inode_readlink(struct dentry *dentry);
|
||||
@@ -1863,6 +1865,7 @@ static inline int security_inode_rmdir (
|
||||
|
||||
static inline int security_inode_mknod (struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
+ struct vfsmount *mnt,
|
||||
int mode, dev_t dev)
|
||||
{
|
||||
return 0;
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -296,7 +296,7 @@ static int dummy_inode_rmdir (struct ino
|
||||
}
|
||||
|
||||
static int dummy_inode_mknod (struct inode *inode, struct dentry *dentry,
|
||||
- int mode, dev_t dev)
|
||||
+ struct vfsmount *mnt, int mode, dev_t dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -374,11 +374,12 @@ int security_inode_rmdir(struct inode *d
|
||||
return security_ops->inode_rmdir(dir, dentry);
|
||||
}
|
||||
|
||||
-int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
|
||||
+int security_inode_mknod(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode, dev_t dev)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dir)))
|
||||
return 0;
|
||||
- return security_ops->inode_mknod(dir, dentry, mode, dev);
|
||||
+ return security_ops->inode_mknod(dir, dentry, mnt, mode, dev);
|
||||
}
|
||||
|
||||
int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2226,11 +2226,12 @@ static int selinux_inode_rmdir(struct in
|
||||
return may_link(dir, dentry, MAY_RMDIR);
|
||||
}
|
||||
|
||||
-static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
|
||||
+static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, int mode, dev_t dev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
- rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);
|
||||
+ rc = secondary_ops->inode_mknod(dir, dentry, mnt, mode, dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
104
kernel-patches/2.6.24/security-readlink.diff
Normal file
104
kernel-patches/2.6.24/security-readlink.diff
Normal file
@@ -0,0 +1,104 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_readlink LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/stat.c | 2 +-
|
||||
include/linux/security.h | 8 +++++---
|
||||
security/dummy.c | 2 +-
|
||||
security/security.c | 4 ++--
|
||||
security/selinux/hooks.c | 2 +-
|
||||
5 files changed, 10 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/fs/stat.c
|
||||
+++ b/fs/stat.c
|
||||
@@ -306,7 +306,7 @@ asmlinkage long sys_readlinkat(int dfd,
|
||||
|
||||
error = -EINVAL;
|
||||
if (inode->i_op && inode->i_op->readlink) {
|
||||
- error = security_inode_readlink(nd.dentry);
|
||||
+ error = security_inode_readlink(nd.dentry, nd.mnt);
|
||||
if (!error) {
|
||||
touch_atime(nd.mnt, nd.dentry);
|
||||
error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -352,6 +352,7 @@ struct request_sock;
|
||||
* @inode_readlink:
|
||||
* Check the permission to read the symbolic link.
|
||||
* @dentry contains the dentry structure for the file link.
|
||||
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_follow_link:
|
||||
* Check permission to follow a symbolic link when looking up a pathname.
|
||||
@@ -1266,7 +1267,7 @@ struct security_operations {
|
||||
struct vfsmount *mnt, int mode, dev_t dev);
|
||||
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct inode *new_dir, struct dentry *new_dentry);
|
||||
- int (*inode_readlink) (struct dentry *dentry);
|
||||
+ int (*inode_readlink) (struct dentry *dentry, struct vfsmount *mnt);
|
||||
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
|
||||
int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
|
||||
int (*inode_setattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
@@ -1524,7 +1525,7 @@ int security_inode_mknod(struct inode *d
|
||||
struct vfsmount *mnt, int mode, dev_t dev);
|
||||
int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
struct inode *new_dir, struct dentry *new_dentry);
|
||||
-int security_inode_readlink(struct dentry *dentry);
|
||||
+int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt);
|
||||
int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
|
||||
int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd);
|
||||
int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
@@ -1881,7 +1882,8 @@ static inline int security_inode_rename
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline int security_inode_readlink (struct dentry *dentry)
|
||||
+static inline int security_inode_readlink(struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -309,7 +309,7 @@ static int dummy_inode_rename (struct in
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int dummy_inode_readlink (struct dentry *dentry)
|
||||
+static int dummy_inode_readlink (struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -392,11 +392,11 @@ int security_inode_rename(struct inode *
|
||||
new_dir, new_dentry);
|
||||
}
|
||||
|
||||
-int security_inode_readlink(struct dentry *dentry)
|
||||
+int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_readlink(dentry);
|
||||
+ return security_ops->inode_readlink(dentry, mnt);
|
||||
}
|
||||
|
||||
int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2245,7 +2245,7 @@ static int selinux_inode_rename(struct i
|
||||
return may_rename(old_inode, old_dentry, new_inode, new_dentry);
|
||||
}
|
||||
|
||||
-static int selinux_inode_readlink(struct dentry *dentry)
|
||||
+static int selinux_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
return dentry_has_perm(current, NULL, dentry, FILE__READ);
|
||||
}
|
126
kernel-patches/2.6.24/security-removexattr.diff
Normal file
126
kernel-patches/2.6.24/security-removexattr.diff
Normal file
@@ -0,0 +1,126 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_removexattr LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/xattr.c | 2 +-
|
||||
include/linux/security.h | 13 ++++++++-----
|
||||
security/commoncap.c | 3 ++-
|
||||
security/dummy.c | 3 ++-
|
||||
security/security.c | 5 +++--
|
||||
security/selinux/hooks.c | 3 ++-
|
||||
6 files changed, 18 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/fs/xattr.c
|
||||
+++ b/fs/xattr.c
|
||||
@@ -176,7 +176,7 @@ vfs_removexattr(struct dentry *dentry, s
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
- error = security_inode_removexattr(dentry, name);
|
||||
+ error = security_inode_removexattr(dentry, mnt, name);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -57,7 +57,7 @@ extern int cap_bprm_set_security (struct
|
||||
extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe);
|
||||
extern int cap_bprm_secureexec(struct linux_binprm *bprm);
|
||||
extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, void *value, size_t size, int flags);
|
||||
-extern int cap_inode_removexattr(struct dentry *dentry, char *name);
|
||||
+extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name);
|
||||
extern int cap_inode_need_killpriv(struct dentry *dentry);
|
||||
extern int cap_inode_killpriv(struct dentry *dentry);
|
||||
extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
|
||||
@@ -1294,7 +1294,8 @@ struct security_operations {
|
||||
int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
char *name);
|
||||
int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt);
|
||||
- int (*inode_removexattr) (struct dentry *dentry, char *name);
|
||||
+ int (*inode_removexattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name);
|
||||
int (*inode_need_killpriv) (struct dentry *dentry);
|
||||
int (*inode_killpriv) (struct dentry *dentry);
|
||||
int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
|
||||
@@ -1558,7 +1559,8 @@ void security_inode_post_setxattr(struct
|
||||
int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
char *name);
|
||||
int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt);
|
||||
-int security_inode_removexattr(struct dentry *dentry, char *name);
|
||||
+int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name);
|
||||
int security_inode_need_killpriv(struct dentry *dentry);
|
||||
int security_inode_killpriv(struct dentry *dentry);
|
||||
int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
|
||||
@@ -1968,9 +1970,10 @@ static inline int security_inode_listxat
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline int security_inode_removexattr (struct dentry *dentry, char *name)
|
||||
+static inline int security_inode_removexattr (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, char *name)
|
||||
{
|
||||
- return cap_inode_removexattr(dentry, name);
|
||||
+ return cap_inode_removexattr(dentry, mnt, name);
|
||||
}
|
||||
|
||||
static inline int security_inode_need_killpriv(struct dentry *dentry)
|
||||
--- a/security/commoncap.c
|
||||
+++ b/security/commoncap.c
|
||||
@@ -382,7 +382,8 @@ int cap_inode_setxattr(struct dentry *de
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int cap_inode_removexattr(struct dentry *dentry, char *name)
|
||||
+int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name)
|
||||
{
|
||||
if (!strcmp(name, XATTR_NAME_CAPS)) {
|
||||
if (!capable(CAP_SETFCAP))
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -376,7 +376,8 @@ static int dummy_inode_listxattr (struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int dummy_inode_removexattr (struct dentry *dentry, char *name)
|
||||
+static int dummy_inode_removexattr (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name)
|
||||
{
|
||||
if (!strncmp(name, XATTR_SECURITY_PREFIX,
|
||||
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -473,11 +473,12 @@ int security_inode_listxattr(struct dent
|
||||
return security_ops->inode_listxattr(dentry, mnt);
|
||||
}
|
||||
|
||||
-int security_inode_removexattr(struct dentry *dentry, char *name)
|
||||
+int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_removexattr(dentry, name);
|
||||
+ return security_ops->inode_removexattr(dentry, mnt, name);
|
||||
}
|
||||
|
||||
int security_inode_need_killpriv(struct dentry *dentry)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2420,7 +2420,8 @@ static int selinux_inode_listxattr (stru
|
||||
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
|
||||
}
|
||||
|
||||
-static int selinux_inode_removexattr (struct dentry *dentry, char *name)
|
||||
+static int selinux_inode_removexattr (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, char *name)
|
||||
{
|
||||
if (strcmp(name, XATTR_NAME_SELINUX))
|
||||
return selinux_inode_setotherxattr(dentry, name);
|
136
kernel-patches/2.6.24/security-rename.diff
Normal file
136
kernel-patches/2.6.24/security-rename.diff
Normal file
@@ -0,0 +1,136 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_rename LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 6 ++++--
|
||||
include/linux/security.h | 13 ++++++++++---
|
||||
security/dummy.c | 4 +++-
|
||||
security/security.c | 7 ++++---
|
||||
security/selinux/hooks.c | 8 ++++++--
|
||||
5 files changed, 27 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2480,7 +2480,8 @@ static int vfs_rename_dir(struct inode *
|
||||
return error;
|
||||
}
|
||||
|
||||
- error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
|
||||
+ error = security_inode_rename(old_dir, old_dentry, old_mnt,
|
||||
+ new_dir, new_dentry, new_mnt);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -2514,7 +2515,8 @@ static int vfs_rename_other(struct inode
|
||||
struct inode *target;
|
||||
int error;
|
||||
|
||||
- error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
|
||||
+ error = security_inode_rename(old_dir, old_dentry, old_mnt,
|
||||
+ new_dir, new_dentry, new_mnt);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -350,8 +350,10 @@ struct request_sock;
|
||||
* Check for permission to rename a file or directory.
|
||||
* @old_dir contains the inode structure for parent of the old link.
|
||||
* @old_dentry contains the dentry structure of the old link.
|
||||
+ * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL).
|
||||
* @new_dir contains the inode structure for parent of the new link.
|
||||
* @new_dentry contains the dentry structure of the new link.
|
||||
+ * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL).
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_readlink:
|
||||
* Check the permission to read the symbolic link.
|
||||
@@ -1273,7 +1275,9 @@ struct security_operations {
|
||||
int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode, dev_t dev);
|
||||
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
|
||||
- struct inode *new_dir, struct dentry *new_dentry);
|
||||
+ struct vfsmount *old_mnt,
|
||||
+ struct inode *new_dir, struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt);
|
||||
int (*inode_readlink) (struct dentry *dentry, struct vfsmount *mnt);
|
||||
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
|
||||
int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
|
||||
@@ -1534,7 +1538,8 @@ int security_inode_rmdir(struct inode *d
|
||||
int security_inode_mknod(struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode, dev_t dev);
|
||||
int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
- struct inode *new_dir, struct dentry *new_dentry);
|
||||
+ struct vfsmount *old_mnt, struct inode *new_dir,
|
||||
+ struct dentry *new_dentry, struct vfsmount *new_mnt);
|
||||
int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt);
|
||||
int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
|
||||
int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd);
|
||||
@@ -1890,8 +1895,10 @@ static inline int security_inode_mknod (
|
||||
|
||||
static inline int security_inode_rename (struct inode *old_dir,
|
||||
struct dentry *old_dentry,
|
||||
+ struct vfsmount *old_mnt,
|
||||
struct inode *new_dir,
|
||||
- struct dentry *new_dentry)
|
||||
+ struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -307,8 +307,10 @@ static int dummy_inode_mknod (struct ino
|
||||
|
||||
static int dummy_inode_rename (struct inode *old_inode,
|
||||
struct dentry *old_dentry,
|
||||
+ struct vfsmount *old_mnt,
|
||||
struct inode *new_inode,
|
||||
- struct dentry *new_dentry)
|
||||
+ struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -387,13 +387,14 @@ int security_inode_mknod(struct inode *d
|
||||
}
|
||||
|
||||
int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
- struct inode *new_dir, struct dentry *new_dentry)
|
||||
+ struct vfsmount *old_mnt, struct inode *new_dir,
|
||||
+ struct dentry *new_dentry, struct vfsmount *new_mnt)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(old_dentry->d_inode) ||
|
||||
(new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode))))
|
||||
return 0;
|
||||
- return security_ops->inode_rename(old_dir, old_dentry,
|
||||
- new_dir, new_dentry);
|
||||
+ return security_ops->inode_rename(old_dir, old_dentry, old_mnt,
|
||||
+ new_dir, new_dentry, new_mnt);
|
||||
}
|
||||
|
||||
int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2246,8 +2246,12 @@ static int selinux_inode_mknod(struct in
|
||||
return may_create(dir, dentry, inode_mode_to_security_class(mode));
|
||||
}
|
||||
|
||||
-static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
|
||||
- struct inode *new_inode, struct dentry *new_dentry)
|
||||
+static int selinux_inode_rename(struct inode *old_inode,
|
||||
+ struct dentry *old_dentry,
|
||||
+ struct vfsmount *old_mnt,
|
||||
+ struct inode *new_inode,
|
||||
+ struct dentry *new_dentry,
|
||||
+ struct vfsmount *new_mnt)
|
||||
{
|
||||
return may_rename(old_inode, old_dentry, new_inode, new_dentry);
|
||||
}
|
109
kernel-patches/2.6.24/security-rmdir.diff
Normal file
109
kernel-patches/2.6.24/security-rmdir.diff
Normal file
@@ -0,0 +1,109 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_rmdir LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 2 +-
|
||||
include/linux/security.h | 10 +++++++---
|
||||
security/dummy.c | 3 ++-
|
||||
security/security.c | 5 +++--
|
||||
security/selinux/hooks.c | 3 ++-
|
||||
5 files changed, 15 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2104,7 +2104,7 @@ int vfs_rmdir(struct inode *dir, struct
|
||||
if (d_mountpoint(dentry))
|
||||
error = -EBUSY;
|
||||
else {
|
||||
- error = security_inode_rmdir(dir, dentry);
|
||||
+ error = security_inode_rmdir(dir, dentry, mnt);
|
||||
if (!error) {
|
||||
error = dir->i_op->rmdir(dir, dentry);
|
||||
if (!error)
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -332,6 +332,7 @@ struct request_sock;
|
||||
* Check the permission to remove a directory.
|
||||
* @dir contains the inode structure of parent of the directory to be removed.
|
||||
* @dentry contains the dentry structure of directory to be removed.
|
||||
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_mknod:
|
||||
* Check permissions when creating a special file (or a socket or a fifo
|
||||
@@ -1265,7 +1266,8 @@ struct security_operations {
|
||||
struct vfsmount *mnt, const char *old_name);
|
||||
int (*inode_mkdir) (struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode);
|
||||
- int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
|
||||
+ int (*inode_rmdir) (struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt);
|
||||
int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode, dev_t dev);
|
||||
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
|
||||
@@ -1524,7 +1526,8 @@ int security_inode_symlink(struct inode
|
||||
struct vfsmount *mnt, const char *old_name);
|
||||
int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode);
|
||||
-int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
|
||||
+int security_inode_rmdir(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt);
|
||||
int security_inode_mknod(struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode, dev_t dev);
|
||||
int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
@@ -1867,7 +1870,8 @@ static inline int security_inode_mkdir (
|
||||
}
|
||||
|
||||
static inline int security_inode_rmdir (struct inode *dir,
|
||||
- struct dentry *dentry)
|
||||
+ struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -292,7 +292,8 @@ static int dummy_inode_mkdir (struct ino
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int dummy_inode_rmdir (struct inode *inode, struct dentry *dentry)
|
||||
+static int dummy_inode_rmdir (struct inode *inode, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -369,11 +369,12 @@ int security_inode_mkdir(struct inode *d
|
||||
return security_ops->inode_mkdir(dir, dentry, mnt, mode);
|
||||
}
|
||||
|
||||
-int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
+int security_inode_rmdir(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_rmdir(dir, dentry);
|
||||
+ return security_ops->inode_rmdir(dir, dentry, mnt);
|
||||
}
|
||||
|
||||
int security_inode_mknod(struct inode *dir, struct dentry *dentry,
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2227,7 +2227,8 @@ static int selinux_inode_mkdir(struct in
|
||||
return may_create(dir, dentry, SECCLASS_DIR);
|
||||
}
|
||||
|
||||
-static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
+static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
return may_link(dir, dentry, MAY_RMDIR);
|
||||
}
|
119
kernel-patches/2.6.24/security-setattr.diff
Normal file
119
kernel-patches/2.6.24/security-setattr.diff
Normal file
@@ -0,0 +1,119 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_setattr LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/attr.c | 4 ++--
|
||||
include/linux/security.h | 8 ++++++--
|
||||
security/dummy.c | 3 ++-
|
||||
security/security.c | 5 +++--
|
||||
security/selinux/hooks.c | 5 +++--
|
||||
5 files changed, 16 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/fs/attr.c
|
||||
+++ b/fs/attr.c
|
||||
@@ -159,13 +159,13 @@ int notify_change(struct dentry *dentry,
|
||||
down_write(&dentry->d_inode->i_alloc_sem);
|
||||
|
||||
if (inode->i_op && inode->i_op->setattr) {
|
||||
- error = security_inode_setattr(dentry, attr);
|
||||
+ error = security_inode_setattr(dentry, mnt, attr);
|
||||
if (!error)
|
||||
error = inode->i_op->setattr(dentry, attr);
|
||||
} else {
|
||||
error = inode_change_ok(inode, attr);
|
||||
if (!error)
|
||||
- error = security_inode_setattr(dentry, attr);
|
||||
+ error = security_inode_setattr(dentry, mnt, attr);
|
||||
if (!error) {
|
||||
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
|
||||
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -372,6 +372,7 @@ struct request_sock;
|
||||
* file attributes change (such as when a file is truncated, chown/chmod
|
||||
* operations, transferring disk quotas, etc).
|
||||
* @dentry contains the dentry structure for the file.
|
||||
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
|
||||
* @attr is the iattr structure containing the new file attributes.
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_getattr:
|
||||
@@ -1264,7 +1265,8 @@ struct security_operations {
|
||||
int (*inode_readlink) (struct dentry *dentry);
|
||||
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
|
||||
int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
|
||||
- int (*inode_setattr) (struct dentry *dentry, struct iattr *attr);
|
||||
+ int (*inode_setattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct iattr *attr);
|
||||
int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
|
||||
void (*inode_delete) (struct inode *inode);
|
||||
int (*inode_setxattr) (struct dentry *dentry, char *name, void *value,
|
||||
@@ -1519,7 +1521,8 @@ int security_inode_rename(struct inode *
|
||||
int security_inode_readlink(struct dentry *dentry);
|
||||
int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
|
||||
int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd);
|
||||
-int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
|
||||
+int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct iattr *attr);
|
||||
int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
|
||||
void security_inode_delete(struct inode *inode);
|
||||
int security_inode_setxattr(struct dentry *dentry, char *name,
|
||||
@@ -1887,6 +1890,7 @@ static inline int security_inode_permiss
|
||||
}
|
||||
|
||||
static inline int security_inode_setattr (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt,
|
||||
struct iattr *attr)
|
||||
{
|
||||
return 0;
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -325,7 +325,8 @@ static int dummy_inode_permission (struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int dummy_inode_setattr (struct dentry *dentry, struct iattr *iattr)
|
||||
+static int dummy_inode_setattr (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct iattr *iattr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -411,11 +411,12 @@ int security_inode_permission(struct ino
|
||||
return security_ops->inode_permission(inode, mask, nd);
|
||||
}
|
||||
|
||||
-int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
+int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct iattr *attr)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_setattr(dentry, attr);
|
||||
+ return security_ops->inode_setattr(dentry, mnt, attr);
|
||||
}
|
||||
|
||||
int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2275,11 +2275,12 @@ static int selinux_inode_permission(stru
|
||||
file_mask_to_av(inode->i_mode, mask), NULL);
|
||||
}
|
||||
|
||||
-static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
|
||||
+static int selinux_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct iattr *iattr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
- rc = secondary_ops->inode_setattr(dentry, iattr);
|
||||
+ rc = secondary_ops->inode_setattr(dentry, mnt, iattr);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
210
kernel-patches/2.6.24/security-setxattr.diff
Normal file
210
kernel-patches/2.6.24/security-setxattr.diff
Normal file
@@ -0,0 +1,210 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_setxattr LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/xattr.c | 4 ++--
|
||||
include/linux/security.h | 35 +++++++++++++++++++++--------------
|
||||
security/commoncap.c | 4 ++--
|
||||
security/dummy.c | 9 ++++++---
|
||||
security/security.c | 14 ++++++++------
|
||||
security/selinux/hooks.c | 8 ++++++--
|
||||
6 files changed, 45 insertions(+), 29 deletions(-)
|
||||
|
||||
--- a/fs/xattr.c
|
||||
+++ b/fs/xattr.c
|
||||
@@ -79,7 +79,7 @@ vfs_setxattr(struct dentry *dentry, stru
|
||||
return error;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
- error = security_inode_setxattr(dentry, name, value, size, flags);
|
||||
+ error = security_inode_setxattr(dentry, mnt, name, value, size, flags);
|
||||
if (error)
|
||||
goto out;
|
||||
error = -EOPNOTSUPP;
|
||||
@@ -87,7 +87,7 @@ vfs_setxattr(struct dentry *dentry, stru
|
||||
error = inode->i_op->setxattr(dentry, name, value, size, flags);
|
||||
if (!error) {
|
||||
fsnotify_xattr(dentry);
|
||||
- security_inode_post_setxattr(dentry, name, value,
|
||||
+ security_inode_post_setxattr(dentry, mnt, name, value,
|
||||
size, flags);
|
||||
}
|
||||
} else if (!strncmp(name, XATTR_SECURITY_PREFIX,
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -56,7 +56,7 @@ extern void cap_capset_set (struct task_
|
||||
extern int cap_bprm_set_security (struct linux_binprm *bprm);
|
||||
extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe);
|
||||
extern int cap_bprm_secureexec(struct linux_binprm *bprm);
|
||||
-extern int cap_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags);
|
||||
+extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, void *value, size_t size, int flags);
|
||||
extern int cap_inode_removexattr(struct dentry *dentry, char *name);
|
||||
extern int cap_inode_need_killpriv(struct dentry *dentry);
|
||||
extern int cap_inode_killpriv(struct dentry *dentry);
|
||||
@@ -398,11 +398,11 @@ struct request_sock;
|
||||
* inode.
|
||||
* @inode_setxattr:
|
||||
* Check permission before setting the extended attributes
|
||||
- * @value identified by @name for @dentry.
|
||||
+ * @value identified by @name for @dentry and @mnt.
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_post_setxattr:
|
||||
* Update inode security field after successful setxattr operation.
|
||||
- * @value identified by @name for @dentry.
|
||||
+ * @value identified by @name for @dentry and @mnt.
|
||||
* @inode_getxattr:
|
||||
* Check permission before obtaining the extended attributes
|
||||
* identified by @name for @dentry.
|
||||
@@ -1285,9 +1285,11 @@ struct security_operations {
|
||||
struct iattr *attr);
|
||||
int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
|
||||
void (*inode_delete) (struct inode *inode);
|
||||
- int (*inode_setxattr) (struct dentry *dentry, char *name, void *value,
|
||||
- size_t size, int flags);
|
||||
- void (*inode_post_setxattr) (struct dentry *dentry, char *name, void *value,
|
||||
+ int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name, void *value, size_t size, int flags);
|
||||
+ void (*inode_post_setxattr) (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt,
|
||||
+ char *name, void *value,
|
||||
size_t size, int flags);
|
||||
int (*inode_getxattr) (struct dentry *dentry, char *name);
|
||||
int (*inode_listxattr) (struct dentry *dentry);
|
||||
@@ -1547,10 +1549,11 @@ int security_inode_setattr(struct dentry
|
||||
struct iattr *attr);
|
||||
int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
|
||||
void security_inode_delete(struct inode *inode);
|
||||
-int security_inode_setxattr(struct dentry *dentry, char *name,
|
||||
- void *value, size_t size, int flags);
|
||||
-void security_inode_post_setxattr(struct dentry *dentry, char *name,
|
||||
- void *value, size_t size, int flags);
|
||||
+int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name, void *value, size_t size, int flags);
|
||||
+void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name, void *value, size_t size,
|
||||
+ int flags);
|
||||
int security_inode_getxattr(struct dentry *dentry, char *name);
|
||||
int security_inode_listxattr(struct dentry *dentry);
|
||||
int security_inode_removexattr(struct dentry *dentry, char *name);
|
||||
@@ -1937,14 +1940,18 @@ static inline int security_inode_getattr
|
||||
static inline void security_inode_delete (struct inode *inode)
|
||||
{ }
|
||||
|
||||
-static inline int security_inode_setxattr (struct dentry *dentry, char *name,
|
||||
+static inline int security_inode_setxattr (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, char *name,
|
||||
void *value, size_t size, int flags)
|
||||
{
|
||||
- return cap_inode_setxattr(dentry, name, value, size, flags);
|
||||
+ return cap_inode_setxattr(dentry, mnt, name, value, size, flags);
|
||||
}
|
||||
|
||||
-static inline void security_inode_post_setxattr (struct dentry *dentry, char *name,
|
||||
- void *value, size_t size, int flags)
|
||||
+static inline void security_inode_post_setxattr (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt,
|
||||
+ char *name,
|
||||
+ void *value, size_t size,
|
||||
+ int flags)
|
||||
{ }
|
||||
|
||||
static inline int security_inode_getxattr (struct dentry *dentry, char *name)
|
||||
--- a/security/commoncap.c
|
||||
+++ b/security/commoncap.c
|
||||
@@ -368,8 +368,8 @@ int cap_bprm_secureexec (struct linux_bi
|
||||
current->egid != current->gid);
|
||||
}
|
||||
|
||||
-int cap_inode_setxattr(struct dentry *dentry, char *name, void *value,
|
||||
- size_t size, int flags)
|
||||
+int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name,
|
||||
+ void *value, size_t size, int flags)
|
||||
{
|
||||
if (!strcmp(name, XATTR_NAME_CAPS)) {
|
||||
if (!capable(CAP_SETFCAP))
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -347,8 +347,9 @@ static void dummy_inode_delete (struct i
|
||||
return;
|
||||
}
|
||||
|
||||
-static int dummy_inode_setxattr (struct dentry *dentry, char *name, void *value,
|
||||
- size_t size, int flags)
|
||||
+static int dummy_inode_setxattr (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name, void *value, size_t size,
|
||||
+ int flags)
|
||||
{
|
||||
if (!strncmp(name, XATTR_SECURITY_PREFIX,
|
||||
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
|
||||
@@ -357,7 +358,9 @@ static int dummy_inode_setxattr (struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void dummy_inode_post_setxattr (struct dentry *dentry, char *name, void *value,
|
||||
+static void dummy_inode_post_setxattr (struct dentry *dentry,
|
||||
+ struct vfsmount *mnt,
|
||||
+ char *name, void *value,
|
||||
size_t size, int flags)
|
||||
{
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -440,20 +440,22 @@ void security_inode_delete(struct inode
|
||||
security_ops->inode_delete(inode);
|
||||
}
|
||||
|
||||
-int security_inode_setxattr(struct dentry *dentry, char *name,
|
||||
- void *value, size_t size, int flags)
|
||||
+int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name, void *value, size_t size, int flags)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_setxattr(dentry, name, value, size, flags);
|
||||
+ return security_ops->inode_setxattr(dentry, mnt, name, value, size,
|
||||
+ flags);
|
||||
}
|
||||
|
||||
-void security_inode_post_setxattr(struct dentry *dentry, char *name,
|
||||
- void *value, size_t size, int flags)
|
||||
+void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name, void *value, size_t size,
|
||||
+ int flags)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return;
|
||||
- security_ops->inode_post_setxattr(dentry, name, value, size, flags);
|
||||
+ security_ops->inode_post_setxattr(dentry, mnt, name, value, size, flags);
|
||||
}
|
||||
|
||||
int security_inode_getxattr(struct dentry *dentry, char *name)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2332,7 +2332,9 @@ static int selinux_inode_setotherxattr(s
|
||||
return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
|
||||
}
|
||||
|
||||
-static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags)
|
||||
+static int selinux_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *name, void *value, size_t size,
|
||||
+ int flags)
|
||||
{
|
||||
struct task_security_struct *tsec = current->security;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
@@ -2381,7 +2383,9 @@ static int selinux_inode_setxattr(struct
|
||||
&ad);
|
||||
}
|
||||
|
||||
-static void selinux_inode_post_setxattr(struct dentry *dentry, char *name,
|
||||
+static void selinux_inode_post_setxattr(struct dentry *dentry,
|
||||
+ struct vfsmount *mnt,
|
||||
+ char *name,
|
||||
void *value, size_t size, int flags)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
105
kernel-patches/2.6.24/security-symlink.diff
Normal file
105
kernel-patches/2.6.24/security-symlink.diff
Normal file
@@ -0,0 +1,105 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_symlink LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 2 +-
|
||||
include/linux/security.h | 8 +++++---
|
||||
security/dummy.c | 2 +-
|
||||
security/security.c | 4 ++--
|
||||
security/selinux/hooks.c | 3 ++-
|
||||
5 files changed, 11 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2277,7 +2277,7 @@ int vfs_symlink(struct inode *dir, struc
|
||||
if (!dir->i_op || !dir->i_op->symlink)
|
||||
return -EPERM;
|
||||
|
||||
- error = security_inode_symlink(dir, dentry, oldname);
|
||||
+ error = security_inode_symlink(dir, dentry, mnt, oldname);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -315,6 +315,7 @@ struct request_sock;
|
||||
* Check the permission to create a symbolic link to a file.
|
||||
* @dir contains the inode structure of parent directory of the symbolic link.
|
||||
* @dentry contains the dentry structure of the symbolic link.
|
||||
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
|
||||
* @old_name contains the pathname of file.
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_mkdir:
|
||||
@@ -1256,8 +1257,8 @@ struct security_operations {
|
||||
int (*inode_link) (struct dentry *old_dentry,
|
||||
struct inode *dir, struct dentry *new_dentry);
|
||||
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
|
||||
- int (*inode_symlink) (struct inode *dir,
|
||||
- struct dentry *dentry, const char *old_name);
|
||||
+ int (*inode_symlink) (struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, const char *old_name);
|
||||
int (*inode_mkdir) (struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode);
|
||||
int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
|
||||
@@ -1515,7 +1516,7 @@ int security_inode_link(struct dentry *o
|
||||
struct dentry *new_dentry);
|
||||
int security_inode_unlink(struct inode *dir, struct dentry *dentry);
|
||||
int security_inode_symlink(struct inode *dir, struct dentry *dentry,
|
||||
- const char *old_name);
|
||||
+ struct vfsmount *mnt, const char *old_name);
|
||||
int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, int mode);
|
||||
int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
|
||||
@@ -1844,6 +1845,7 @@ static inline int security_inode_unlink
|
||||
|
||||
static inline int security_inode_symlink (struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
+ struct vfsmount *mnt,
|
||||
const char *old_name)
|
||||
{
|
||||
return 0;
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -279,7 +279,7 @@ static int dummy_inode_unlink (struct in
|
||||
}
|
||||
|
||||
static int dummy_inode_symlink (struct inode *inode, struct dentry *dentry,
|
||||
- const char *name)
|
||||
+ struct vfsmount *mnt, const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -352,11 +352,11 @@ int security_inode_unlink(struct inode *
|
||||
}
|
||||
|
||||
int security_inode_symlink(struct inode *dir, struct dentry *dentry,
|
||||
- const char *old_name)
|
||||
+ struct vfsmount *mnt, const char *old_name)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dir)))
|
||||
return 0;
|
||||
- return security_ops->inode_symlink(dir, dentry, old_name);
|
||||
+ return security_ops->inode_symlink(dir, dentry, mnt, old_name);
|
||||
}
|
||||
|
||||
int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2210,7 +2210,8 @@ static int selinux_inode_unlink(struct i
|
||||
return may_link(dir, dentry, MAY_UNLINK);
|
||||
}
|
||||
|
||||
-static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
|
||||
+static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, const char *name)
|
||||
{
|
||||
return may_create(dir, dentry, SECCLASS_LNK_FILE);
|
||||
}
|
114
kernel-patches/2.6.24/security-unlink.diff
Normal file
114
kernel-patches/2.6.24/security-unlink.diff
Normal file
@@ -0,0 +1,114 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Pass struct vfsmount to the inode_unlink LSM hook
|
||||
|
||||
This is needed for computing pathnames in the AppArmor LSM.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/namei.c | 2 +-
|
||||
include/linux/security.h | 10 +++++++---
|
||||
security/dummy.c | 3 ++-
|
||||
security/security.c | 5 +++--
|
||||
security/selinux/hooks.c | 5 +++--
|
||||
5 files changed, 16 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2184,7 +2184,7 @@ int vfs_unlink(struct inode *dir, struct
|
||||
if (d_mountpoint(dentry))
|
||||
error = -EBUSY;
|
||||
else {
|
||||
- error = security_inode_unlink(dir, dentry);
|
||||
+ error = security_inode_unlink(dir, dentry, mnt);
|
||||
if (!error)
|
||||
error = dir->i_op->unlink(dir, dentry);
|
||||
}
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -312,6 +312,7 @@ struct request_sock;
|
||||
* Check the permission to remove a hard link to a file.
|
||||
* @dir contains the inode structure of parent directory of the file.
|
||||
* @dentry contains the dentry structure for file to be unlinked.
|
||||
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
|
||||
* Return 0 if permission is granted.
|
||||
* @inode_symlink:
|
||||
* Check the permission to create a symbolic link to a file.
|
||||
@@ -1261,7 +1262,8 @@ struct security_operations {
|
||||
int (*inode_link) (struct dentry *old_dentry, struct vfsmount *old_mnt,
|
||||
struct inode *dir, struct dentry *new_dentry,
|
||||
struct vfsmount *new_mnt);
|
||||
- int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
|
||||
+ int (*inode_unlink) (struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt);
|
||||
int (*inode_symlink) (struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, const char *old_name);
|
||||
int (*inode_mkdir) (struct inode *dir, struct dentry *dentry,
|
||||
@@ -1521,7 +1523,8 @@ int security_inode_create(struct inode *
|
||||
int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
|
||||
struct inode *dir, struct dentry *new_dentry,
|
||||
struct vfsmount *new_mnt);
|
||||
-int security_inode_unlink(struct inode *dir, struct dentry *dentry);
|
||||
+int security_inode_unlink(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt);
|
||||
int security_inode_symlink(struct inode *dir, struct dentry *dentry,
|
||||
struct vfsmount *mnt, const char *old_name);
|
||||
int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
@@ -1848,7 +1851,8 @@ static inline int security_inode_link (s
|
||||
}
|
||||
|
||||
static inline int security_inode_unlink (struct inode *dir,
|
||||
- struct dentry *dentry)
|
||||
+ struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -275,7 +275,8 @@ static int dummy_inode_link (struct dent
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry)
|
||||
+static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -346,11 +346,12 @@ int security_inode_link(struct dentry *o
|
||||
new_dentry, new_mnt);
|
||||
}
|
||||
|
||||
-int security_inode_unlink(struct inode *dir, struct dentry *dentry)
|
||||
+int security_inode_unlink(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_unlink(dir, dentry);
|
||||
+ return security_ops->inode_unlink(dir, dentry, mnt);
|
||||
}
|
||||
|
||||
int security_inode_symlink(struct inode *dir, struct dentry *dentry,
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2205,11 +2205,12 @@ static int selinux_inode_link(struct den
|
||||
return may_link(dir, old_dentry, MAY_LINK);
|
||||
}
|
||||
|
||||
-static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
|
||||
+static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt)
|
||||
{
|
||||
int rc;
|
||||
|
||||
- rc = secondary_ops->inode_unlink(dir, dentry);
|
||||
+ rc = secondary_ops->inode_unlink(dir, dentry, mnt);
|
||||
if (rc)
|
||||
return rc;
|
||||
return may_link(dir, dentry, MAY_UNLINK);
|
540
kernel-patches/2.6.24/security-xattr-file.diff
Normal file
540
kernel-patches/2.6.24/security-xattr-file.diff
Normal file
@@ -0,0 +1,540 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Pass struct file down the inode_*xattr security LSM hooks
|
||||
|
||||
This allows LSMs to also distinguish between file descriptor and path
|
||||
access for the xattr operations. (The other relevant operations are
|
||||
covered by the setattr hook.)
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/xattr.c | 58 ++++++++++++++++++++++++-----------------------
|
||||
include/linux/security.h | 40 +++++++++++++++++++-------------
|
||||
include/linux/xattr.h | 8 +++---
|
||||
security/commoncap.c | 4 +--
|
||||
security/dummy.c | 10 ++++----
|
||||
security/security.c | 21 +++++++++--------
|
||||
security/selinux/hooks.c | 10 ++++----
|
||||
7 files changed, 84 insertions(+), 67 deletions(-)
|
||||
|
||||
--- a/fs/xattr.c
|
||||
+++ b/fs/xattr.c
|
||||
@@ -69,7 +69,7 @@ xattr_permission(struct inode *inode, co
|
||||
|
||||
int
|
||||
vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name,
|
||||
- void *value, size_t size, int flags)
|
||||
+ void *value, size_t size, int flags, struct file *file)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
@@ -79,7 +79,7 @@ vfs_setxattr(struct dentry *dentry, stru
|
||||
return error;
|
||||
|
||||
mutex_lock(&inode->i_mutex);
|
||||
- error = security_inode_setxattr(dentry, mnt, name, value, size, flags);
|
||||
+ error = security_inode_setxattr(dentry, mnt, name, value, size, flags, file);
|
||||
if (error)
|
||||
goto out;
|
||||
error = -EOPNOTSUPP;
|
||||
@@ -106,7 +106,7 @@ EXPORT_SYMBOL_GPL(vfs_setxattr);
|
||||
|
||||
ssize_t
|
||||
vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, char *name,
|
||||
- void *value, size_t size)
|
||||
+ void *value, size_t size, struct file *file)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
@@ -115,7 +115,7 @@ vfs_getxattr(struct dentry *dentry, stru
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
- error = security_inode_getxattr(dentry, mnt, name);
|
||||
+ error = security_inode_getxattr(dentry, mnt, name, file);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -143,12 +143,12 @@ EXPORT_SYMBOL_GPL(vfs_getxattr);
|
||||
|
||||
ssize_t
|
||||
vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, char *list,
|
||||
- size_t size)
|
||||
+ size_t size, struct file *file)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
ssize_t error;
|
||||
|
||||
- error = security_inode_listxattr(dentry, mnt);
|
||||
+ error = security_inode_listxattr(dentry, mnt, file);
|
||||
if (error)
|
||||
return error;
|
||||
error = -EOPNOTSUPP;
|
||||
@@ -164,7 +164,8 @@ vfs_listxattr(struct dentry *dentry, str
|
||||
EXPORT_SYMBOL_GPL(vfs_listxattr);
|
||||
|
||||
int
|
||||
-vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name)
|
||||
+vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name,
|
||||
+ struct file *file)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
@@ -176,7 +177,7 @@ vfs_removexattr(struct dentry *dentry, s
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
- error = security_inode_removexattr(dentry, mnt, name);
|
||||
+ error = security_inode_removexattr(dentry, mnt, name, file);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -196,7 +197,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
|
||||
*/
|
||||
static long
|
||||
setxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name,
|
||||
- void __user *value, size_t size, int flags)
|
||||
+ void __user *value, size_t size, int flags, struct file *file)
|
||||
{
|
||||
int error;
|
||||
void *kvalue = NULL;
|
||||
@@ -223,7 +224,7 @@ setxattr(struct dentry *dentry, struct v
|
||||
}
|
||||
}
|
||||
|
||||
- error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags);
|
||||
+ error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags, file);
|
||||
kfree(kvalue);
|
||||
return error;
|
||||
}
|
||||
@@ -238,7 +239,7 @@ sys_setxattr(char __user *path, char __u
|
||||
error = user_path_walk(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = setxattr(nd.dentry, nd.mnt, name, value, size, flags);
|
||||
+ error = setxattr(nd.dentry, nd.mnt, name, value, size, flags, NULL);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -253,7 +254,7 @@ sys_lsetxattr(char __user *path, char __
|
||||
error = user_path_walk_link(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = setxattr(nd.dentry, nd.mnt, name, value, size, flags);
|
||||
+ error = setxattr(nd.dentry, nd.mnt, name, value, size, flags, NULL);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -271,7 +272,7 @@ sys_fsetxattr(int fd, char __user *name,
|
||||
return error;
|
||||
dentry = f->f_path.dentry;
|
||||
audit_inode(NULL, dentry);
|
||||
- error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags);
|
||||
+ error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags, f);
|
||||
fput(f);
|
||||
return error;
|
||||
}
|
||||
@@ -281,7 +282,7 @@ sys_fsetxattr(int fd, char __user *name,
|
||||
*/
|
||||
static ssize_t
|
||||
getxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name,
|
||||
- void __user *value, size_t size)
|
||||
+ void __user *value, size_t size, struct file *file)
|
||||
{
|
||||
ssize_t error;
|
||||
void *kvalue = NULL;
|
||||
@@ -301,7 +302,7 @@ getxattr(struct dentry *dentry, struct v
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- error = vfs_getxattr(dentry, mnt, kname, kvalue, size);
|
||||
+ error = vfs_getxattr(dentry, mnt, kname, kvalue, size, file);
|
||||
if (error > 0) {
|
||||
if (size && copy_to_user(value, kvalue, error))
|
||||
error = -EFAULT;
|
||||
@@ -324,7 +325,7 @@ sys_getxattr(char __user *path, char __u
|
||||
error = user_path_walk(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = getxattr(nd.dentry, nd.mnt, name, value, size);
|
||||
+ error = getxattr(nd.dentry, nd.mnt, name, value, size, NULL);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -339,7 +340,7 @@ sys_lgetxattr(char __user *path, char __
|
||||
error = user_path_walk_link(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = getxattr(nd.dentry, nd.mnt, name, value, size);
|
||||
+ error = getxattr(nd.dentry, nd.mnt, name, value, size, NULL);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -354,7 +355,7 @@ sys_fgetxattr(int fd, char __user *name,
|
||||
if (!f)
|
||||
return error;
|
||||
audit_inode(NULL, f->f_path.dentry);
|
||||
- error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size);
|
||||
+ error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size, f);
|
||||
fput(f);
|
||||
return error;
|
||||
}
|
||||
@@ -364,7 +365,7 @@ sys_fgetxattr(int fd, char __user *name,
|
||||
*/
|
||||
static ssize_t
|
||||
listxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *list,
|
||||
- size_t size)
|
||||
+ size_t size, struct file *file)
|
||||
{
|
||||
ssize_t error;
|
||||
char *klist = NULL;
|
||||
@@ -377,7 +378,7 @@ listxattr(struct dentry *dentry, struct
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- error = vfs_listxattr(dentry, mnt, klist, size);
|
||||
+ error = vfs_listxattr(dentry, mnt, klist, size, file);
|
||||
if (error > 0) {
|
||||
if (size && copy_to_user(list, klist, error))
|
||||
error = -EFAULT;
|
||||
@@ -399,7 +400,7 @@ sys_listxattr(char __user *path, char __
|
||||
error = user_path_walk(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = listxattr(nd.dentry, nd.mnt, list, size);
|
||||
+ error = listxattr(nd.dentry, nd.mnt, list, size, NULL);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -413,7 +414,7 @@ sys_llistxattr(char __user *path, char _
|
||||
error = user_path_walk_link(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = listxattr(nd.dentry, nd.mnt, list, size);
|
||||
+ error = listxattr(nd.dentry, nd.mnt, list, size, NULL);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -428,7 +429,7 @@ sys_flistxattr(int fd, char __user *list
|
||||
if (!f)
|
||||
return error;
|
||||
audit_inode(NULL, f->f_path.dentry);
|
||||
- error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size);
|
||||
+ error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size, f);
|
||||
fput(f);
|
||||
return error;
|
||||
}
|
||||
@@ -437,7 +438,8 @@ sys_flistxattr(int fd, char __user *list
|
||||
* Extended attribute REMOVE operations
|
||||
*/
|
||||
static long
|
||||
-removexattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name)
|
||||
+removexattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name,
|
||||
+ struct file *file)
|
||||
{
|
||||
int error;
|
||||
char kname[XATTR_NAME_MAX + 1];
|
||||
@@ -448,7 +450,7 @@ removexattr(struct dentry *dentry, struc
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
- return vfs_removexattr(dentry, mnt, kname);
|
||||
+ return vfs_removexattr(dentry, mnt, kname, file);
|
||||
}
|
||||
|
||||
asmlinkage long
|
||||
@@ -460,7 +462,7 @@ sys_removexattr(char __user *path, char
|
||||
error = user_path_walk(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = removexattr(nd.dentry, nd.mnt, name);
|
||||
+ error = removexattr(nd.dentry, nd.mnt, name, NULL);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -474,7 +476,7 @@ sys_lremovexattr(char __user *path, char
|
||||
error = user_path_walk_link(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = removexattr(nd.dentry, nd.mnt, name);
|
||||
+ error = removexattr(nd.dentry, nd.mnt, name, NULL);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -491,7 +493,7 @@ sys_fremovexattr(int fd, char __user *na
|
||||
return error;
|
||||
dentry = f->f_path.dentry;
|
||||
audit_inode(NULL, dentry);
|
||||
- error = removexattr(dentry, f->f_path.mnt, name);
|
||||
+ error = removexattr(dentry, f->f_path.mnt, name, f);
|
||||
fput(f);
|
||||
return error;
|
||||
}
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -56,8 +56,8 @@ extern void cap_capset_set (struct task_
|
||||
extern int cap_bprm_set_security (struct linux_binprm *bprm);
|
||||
extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe);
|
||||
extern int cap_bprm_secureexec(struct linux_binprm *bprm);
|
||||
-extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, void *value, size_t size, int flags);
|
||||
-extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name);
|
||||
+extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name, void *value, size_t size, int flags, struct file *file);
|
||||
+extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name, struct file *file);
|
||||
extern int cap_inode_need_killpriv(struct dentry *dentry);
|
||||
extern int cap_inode_killpriv(struct dentry *dentry);
|
||||
extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
|
||||
@@ -1286,16 +1286,18 @@ struct security_operations {
|
||||
int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
|
||||
void (*inode_delete) (struct inode *inode);
|
||||
int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name, void *value, size_t size, int flags);
|
||||
+ char *name, void *value, size_t size, int flags,
|
||||
+ struct file *file);
|
||||
void (*inode_post_setxattr) (struct dentry *dentry,
|
||||
struct vfsmount *mnt,
|
||||
char *name, void *value,
|
||||
size_t size, int flags);
|
||||
int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name);
|
||||
- int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt);
|
||||
+ char *name, struct file *file);
|
||||
+ int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct file *file);
|
||||
int (*inode_removexattr) (struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name);
|
||||
+ char *name, struct file *file);
|
||||
int (*inode_need_killpriv) (struct dentry *dentry);
|
||||
int (*inode_killpriv) (struct dentry *dentry);
|
||||
int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
|
||||
@@ -1552,15 +1554,17 @@ int security_inode_setattr(struct dentry
|
||||
int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
|
||||
void security_inode_delete(struct inode *inode);
|
||||
int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name, void *value, size_t size, int flags);
|
||||
+ char *name, void *value, size_t size, int flags,
|
||||
+ struct file *file);
|
||||
void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
char *name, void *value, size_t size,
|
||||
int flags);
|
||||
int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name);
|
||||
-int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt);
|
||||
+ char *name, struct file *file);
|
||||
+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct file *file);
|
||||
int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name);
|
||||
+ char *name, struct file *file);
|
||||
int security_inode_need_killpriv(struct dentry *dentry);
|
||||
int security_inode_killpriv(struct dentry *dentry);
|
||||
int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
|
||||
@@ -1946,9 +1950,10 @@ static inline void security_inode_delete
|
||||
|
||||
static inline int security_inode_setxattr (struct dentry *dentry,
|
||||
struct vfsmount *mnt, char *name,
|
||||
- void *value, size_t size, int flags)
|
||||
+ void *value, size_t size, int flags,
|
||||
+ struct file *file)
|
||||
{
|
||||
- return cap_inode_setxattr(dentry, mnt, name, value, size, flags);
|
||||
+ return cap_inode_setxattr(dentry, mnt, name, value, size, flags, file);
|
||||
}
|
||||
|
||||
static inline void security_inode_post_setxattr (struct dentry *dentry,
|
||||
@@ -1959,21 +1964,24 @@ static inline void security_inode_post_s
|
||||
{ }
|
||||
|
||||
static inline int security_inode_getxattr (struct dentry *dentry,
|
||||
- struct vfsmount *mnt, char *name)
|
||||
+ struct vfsmount *mnt, char *name,
|
||||
+ struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int security_inode_listxattr (struct dentry *dentry,
|
||||
- struct vfsmount *mnt)
|
||||
+ struct vfsmount *mnt,
|
||||
+ struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int security_inode_removexattr (struct dentry *dentry,
|
||||
- struct vfsmount *mnt, char *name)
|
||||
+ struct vfsmount *mnt, char *name,
|
||||
+ struct file *file)
|
||||
{
|
||||
- return cap_inode_removexattr(dentry, mnt, name);
|
||||
+ return cap_inode_removexattr(dentry, mnt, name, file);
|
||||
}
|
||||
|
||||
static inline int security_inode_need_killpriv(struct dentry *dentry)
|
||||
--- a/include/linux/xattr.h
|
||||
+++ b/include/linux/xattr.h
|
||||
@@ -47,12 +47,12 @@ struct xattr_handler {
|
||||
};
|
||||
|
||||
ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, char *, void *,
|
||||
- size_t);
|
||||
+ size_t, struct file *);
|
||||
ssize_t vfs_listxattr(struct dentry *d, struct vfsmount *, char *list,
|
||||
- size_t size);
|
||||
+ size_t size, struct file *);
|
||||
int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t,
|
||||
- int);
|
||||
-int vfs_removexattr(struct dentry *, struct vfsmount *, char *);
|
||||
+ int, struct file *);
|
||||
+int vfs_removexattr(struct dentry *, struct vfsmount *, char *, struct file *);
|
||||
|
||||
ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
|
||||
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
|
||||
--- a/security/commoncap.c
|
||||
+++ b/security/commoncap.c
|
||||
@@ -369,7 +369,7 @@ int cap_bprm_secureexec (struct linux_bi
|
||||
}
|
||||
|
||||
int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name,
|
||||
- void *value, size_t size, int flags)
|
||||
+ void *value, size_t size, int flags, struct file *file)
|
||||
{
|
||||
if (!strcmp(name, XATTR_NAME_CAPS)) {
|
||||
if (!capable(CAP_SETFCAP))
|
||||
@@ -383,7 +383,7 @@ int cap_inode_setxattr(struct dentry *de
|
||||
}
|
||||
|
||||
int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name)
|
||||
+ char *name, struct file *file)
|
||||
{
|
||||
if (!strcmp(name, XATTR_NAME_CAPS)) {
|
||||
if (!capable(CAP_SETFCAP))
|
||||
--- a/security/dummy.c
|
||||
+++ b/security/dummy.c
|
||||
@@ -349,7 +349,7 @@ static void dummy_inode_delete (struct i
|
||||
|
||||
static int dummy_inode_setxattr (struct dentry *dentry, struct vfsmount *mnt,
|
||||
char *name, void *value, size_t size,
|
||||
- int flags)
|
||||
+ int flags, struct file *file)
|
||||
{
|
||||
if (!strncmp(name, XATTR_SECURITY_PREFIX,
|
||||
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
|
||||
@@ -366,18 +366,20 @@ static void dummy_inode_post_setxattr (s
|
||||
}
|
||||
|
||||
static int dummy_inode_getxattr (struct dentry *dentry,
|
||||
- struct vfsmount *mnt, char *name)
|
||||
+ struct vfsmount *mnt, char *name,
|
||||
+ struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int dummy_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt)
|
||||
+static int dummy_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dummy_inode_removexattr (struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name)
|
||||
+ char *name, struct file *file)
|
||||
{
|
||||
if (!strncmp(name, XATTR_SECURITY_PREFIX,
|
||||
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -441,12 +441,13 @@ void security_inode_delete(struct inode
|
||||
}
|
||||
|
||||
int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name, void *value, size_t size, int flags)
|
||||
+ char *name, void *value, size_t size, int flags,
|
||||
+ struct file *file)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
return security_ops->inode_setxattr(dentry, mnt, name, value, size,
|
||||
- flags);
|
||||
+ flags, file);
|
||||
}
|
||||
|
||||
void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
@@ -455,30 +456,32 @@ void security_inode_post_setxattr(struct
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return;
|
||||
- security_ops->inode_post_setxattr(dentry, mnt, name, value, size, flags);
|
||||
+ security_ops->inode_post_setxattr(dentry, mnt, name, value, size,
|
||||
+ flags);
|
||||
}
|
||||
|
||||
int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name)
|
||||
+ char *name, struct file *file)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_getxattr(dentry, mnt, name);
|
||||
+ return security_ops->inode_getxattr(dentry, mnt, name, file);
|
||||
}
|
||||
|
||||
-int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt)
|
||||
+int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct file *file)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_listxattr(dentry, mnt);
|
||||
+ return security_ops->inode_listxattr(dentry, mnt, file);
|
||||
}
|
||||
|
||||
int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name)
|
||||
+ char *name, struct file *file)
|
||||
{
|
||||
if (unlikely(IS_PRIVATE(dentry->d_inode)))
|
||||
return 0;
|
||||
- return security_ops->inode_removexattr(dentry, mnt, name);
|
||||
+ return security_ops->inode_removexattr(dentry, mnt, name, file);
|
||||
}
|
||||
|
||||
int security_inode_need_killpriv(struct dentry *dentry)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -2334,7 +2334,7 @@ static int selinux_inode_setotherxattr(s
|
||||
|
||||
static int selinux_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
char *name, void *value, size_t size,
|
||||
- int flags)
|
||||
+ int flags, struct file *file)
|
||||
{
|
||||
struct task_security_struct *tsec = current->security;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
@@ -2410,18 +2410,20 @@ static void selinux_inode_post_setxattr(
|
||||
}
|
||||
|
||||
static int selinux_inode_getxattr (struct dentry *dentry, struct vfsmount *mnt,
|
||||
- char *name)
|
||||
+ char *name, struct file *file)
|
||||
{
|
||||
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
|
||||
}
|
||||
|
||||
-static int selinux_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt)
|
||||
+static int selinux_inode_listxattr (struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct file *file)
|
||||
{
|
||||
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
|
||||
}
|
||||
|
||||
static int selinux_inode_removexattr (struct dentry *dentry,
|
||||
- struct vfsmount *mnt, char *name)
|
||||
+ struct vfsmount *mnt, char *name,
|
||||
+ struct file *file)
|
||||
{
|
||||
if (strcmp(name, XATTR_NAME_SELINUX))
|
||||
return selinux_inode_setotherxattr(dentry, name);
|
55
kernel-patches/2.6.24/series
Normal file
55
kernel-patches/2.6.24/series
Normal file
@@ -0,0 +1,55 @@
|
||||
security-create.diff
|
||||
remove_suid.diff
|
||||
vfs-notify_change.diff
|
||||
security-setattr.diff
|
||||
vfs-mkdir.diff
|
||||
security-mkdir.diff
|
||||
vfs-mknod.diff
|
||||
security-mknod.diff
|
||||
vfs-symlink.diff
|
||||
security-symlink.diff
|
||||
security-readlink.diff
|
||||
vfs-link.diff
|
||||
security-link.diff
|
||||
vfs-rmdir.diff
|
||||
security-rmdir.diff
|
||||
fix-vfs_rmdir.diff
|
||||
vfs-unlink.diff
|
||||
security-unlink.diff
|
||||
vfs-rename.diff
|
||||
security-rename.diff
|
||||
vfs-setxattr.diff
|
||||
security-setxattr.diff
|
||||
vfs-getxattr.diff
|
||||
security-getxattr.diff
|
||||
vfs-listxattr.diff
|
||||
security-listxattr.diff
|
||||
vfs-removexattr.diff
|
||||
security-removexattr.diff
|
||||
unambiguous-__d_path.diff
|
||||
mount-consistent-__d_path.diff
|
||||
d_namespace_path.diff
|
||||
__d_path-keep-connected.diff
|
||||
fsetattr.diff
|
||||
fsetattr-reintro-ATTR_FILE.diff
|
||||
file-handle-ops.diff
|
||||
security-xattr-file.diff
|
||||
sysctl-pathname.diff
|
||||
parent-permission.diff
|
||||
do_path_lookup-nameidata.diff
|
||||
sys_fchdir-nameidata.diff
|
||||
file_permission-nameidata.diff
|
||||
apparmor-audit.diff
|
||||
apparmor-main.diff
|
||||
apparmor-lsm.diff
|
||||
apparmor-module_interface.diff
|
||||
apparmor-misc.diff
|
||||
apparmor-intree.diff
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
apparmor-network.diff
|
||||
apparmor-rlimits.diff
|
||||
audit-log-type-in-syslog.diff
|
51
kernel-patches/2.6.24/sys_fchdir-nameidata.diff
Normal file
51
kernel-patches/2.6.24/sys_fchdir-nameidata.diff
Normal file
@@ -0,0 +1,51 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Switch to vfs_permission() in sys_fchdir()
|
||||
|
||||
Switch from file_permission() to vfs_permission() in sys_fchdir(): this
|
||||
avoids calling permission() with a NULL nameidata here.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/open.c | 16 +++++++---------
|
||||
1 file changed, 7 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -501,10 +501,8 @@ out:
|
||||
|
||||
asmlinkage long sys_fchdir(unsigned int fd)
|
||||
{
|
||||
+ struct nameidata nd;
|
||||
struct file *file;
|
||||
- struct dentry *dentry;
|
||||
- struct inode *inode;
|
||||
- struct vfsmount *mnt;
|
||||
int error;
|
||||
|
||||
error = -EBADF;
|
||||
@@ -512,17 +510,17 @@ asmlinkage long sys_fchdir(unsigned int
|
||||
if (!file)
|
||||
goto out;
|
||||
|
||||
- dentry = file->f_path.dentry;
|
||||
- mnt = file->f_path.mnt;
|
||||
- inode = dentry->d_inode;
|
||||
+ nd.dentry = file->f_path.dentry;
|
||||
+ nd.mnt = file->f_path.mnt;
|
||||
+ nd.flags = 0;
|
||||
|
||||
error = -ENOTDIR;
|
||||
- if (!S_ISDIR(inode->i_mode))
|
||||
+ if (!S_ISDIR(nd.dentry->d_inode->i_mode))
|
||||
goto out_putf;
|
||||
|
||||
- error = file_permission(file, MAY_EXEC);
|
||||
+ error = vfs_permission(&nd, MAY_EXEC);
|
||||
if (!error)
|
||||
- set_fs_pwd(current->fs, mnt, dentry);
|
||||
+ set_fs_pwd(current->fs, nd.mnt, nd.dentry);
|
||||
out_putf:
|
||||
fput(file);
|
||||
out:
|
111
kernel-patches/2.6.24/sysctl-pathname.diff
Normal file
111
kernel-patches/2.6.24/sysctl-pathname.diff
Normal file
@@ -0,0 +1,111 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Factor out sysctl pathname code
|
||||
|
||||
Convert the selinux sysctl pathname computation code into a standalone
|
||||
function.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
Reviewed-by: James Morris <jmorris@namei.org>
|
||||
|
||||
---
|
||||
include/linux/sysctl.h | 2 ++
|
||||
kernel/sysctl.c | 27 +++++++++++++++++++++++++++
|
||||
security/selinux/hooks.c | 35 +++++------------------------------
|
||||
3 files changed, 34 insertions(+), 30 deletions(-)
|
||||
|
||||
--- a/include/linux/sysctl.h
|
||||
+++ b/include/linux/sysctl.h
|
||||
@@ -983,6 +983,8 @@ extern int proc_doulongvec_minmax(struct
|
||||
extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int,
|
||||
struct file *, void __user *, size_t *, loff_t *);
|
||||
|
||||
+extern char *sysctl_pathname(ctl_table *, char *, int);
|
||||
+
|
||||
extern int do_sysctl (int __user *name, int nlen,
|
||||
void __user *oldval, size_t __user *oldlenp,
|
||||
void __user *newval, size_t newlen);
|
||||
--- a/kernel/sysctl.c
|
||||
+++ b/kernel/sysctl.c
|
||||
@@ -1327,6 +1327,33 @@ struct ctl_table_header *sysctl_head_nex
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+char *sysctl_pathname(ctl_table *table, char *buffer, int buflen)
|
||||
+{
|
||||
+ if (buflen < 1)
|
||||
+ return NULL;
|
||||
+ buffer += --buflen;
|
||||
+ *buffer = '\0';
|
||||
+
|
||||
+ while (table) {
|
||||
+ int namelen = strlen(table->procname);
|
||||
+
|
||||
+ if (buflen < namelen + 1)
|
||||
+ return NULL;
|
||||
+ buflen -= namelen + 1;
|
||||
+ buffer -= namelen;
|
||||
+ memcpy(buffer, table->procname, namelen);
|
||||
+ *--buffer = '/';
|
||||
+ table = table->parent;
|
||||
+ }
|
||||
+ if (buflen < 4)
|
||||
+ return NULL;
|
||||
+ buffer -= 4;
|
||||
+ memcpy(buffer, "/sys", 4);
|
||||
+
|
||||
+ return buffer;
|
||||
+}
|
||||
+EXPORT_SYMBOL(sysctl_pathname);
|
||||
+
|
||||
#ifdef CONFIG_SYSCTL_SYSCALL
|
||||
int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
|
||||
void __user *newval, size_t newlen)
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -1431,40 +1431,15 @@ static int selinux_capable(struct task_s
|
||||
|
||||
static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
|
||||
{
|
||||
- int buflen, rc;
|
||||
- char *buffer, *path, *end;
|
||||
+ char *buffer, *path;
|
||||
+ int rc = -ENOMEM;
|
||||
|
||||
- rc = -ENOMEM;
|
||||
buffer = (char*)__get_free_page(GFP_KERNEL);
|
||||
if (!buffer)
|
||||
goto out;
|
||||
-
|
||||
- buflen = PAGE_SIZE;
|
||||
- end = buffer+buflen;
|
||||
- *--end = '\0';
|
||||
- buflen--;
|
||||
- path = end-1;
|
||||
- *path = '/';
|
||||
- while (table) {
|
||||
- const char *name = table->procname;
|
||||
- size_t namelen = strlen(name);
|
||||
- buflen -= namelen + 1;
|
||||
- if (buflen < 0)
|
||||
- goto out_free;
|
||||
- end -= namelen;
|
||||
- memcpy(end, name, namelen);
|
||||
- *--end = '/';
|
||||
- path = end;
|
||||
- table = table->parent;
|
||||
- }
|
||||
- buflen -= 4;
|
||||
- if (buflen < 0)
|
||||
- goto out_free;
|
||||
- end -= 4;
|
||||
- memcpy(end, "/sys", 4);
|
||||
- path = end;
|
||||
- rc = security_genfs_sid("proc", path, tclass, sid);
|
||||
-out_free:
|
||||
+ path = sysctl_pathname(table, buffer, PAGE_SIZE);
|
||||
+ if (path)
|
||||
+ rc = security_genfs_sid("proc", path, tclass, sid);
|
||||
free_page((unsigned long)buffer);
|
||||
out:
|
||||
return rc;
|
268
kernel-patches/2.6.24/unambiguous-__d_path.diff
Normal file
268
kernel-patches/2.6.24/unambiguous-__d_path.diff
Normal file
@@ -0,0 +1,268 @@
|
||||
From: Andreas Gruenbacher <agruen@suse.de>
|
||||
Subject: Fix __d_path() for lazy unmounts and make it unambiguous
|
||||
|
||||
First, when __d_path() hits a lazily unmounted mount point, it tries to prepend
|
||||
the name of the lazily unmounted dentry to the path name. It gets this wrong,
|
||||
and also overwrites the slash that separates the name from the following
|
||||
pathname component. This patch fixes that; if a process was in directory
|
||||
/foo/bar and /foo got lazily unmounted, the old result was ``foobar'' (note the
|
||||
missing slash), while the new result with this patch is ``foo/bar''.
|
||||
|
||||
Second, it isn't always possible to tell from the __d_path() result whether the
|
||||
specified root and rootmnt (i.e., the chroot) was reached. We need an
|
||||
unambiguous result for AppArmor at least though, so we make sure that paths
|
||||
will only start with a slash if the path leads all the way up to the root.
|
||||
|
||||
We also add a @fail_deleted argument, which allows to get rid of some of the
|
||||
mess in sys_getcwd().
|
||||
|
||||
This patch leaves getcwd() and d_path() as they were before for everything
|
||||
except for bind-mounted directories; for them, it reports ``/foo/bar'' instead
|
||||
of ``foobar'' in the example described above.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
|
||||
|
||||
---
|
||||
fs/dcache.c | 169 ++++++++++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 98 insertions(+), 71 deletions(-)
|
||||
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -1764,52 +1764,51 @@ shouldnt_be_hashed:
|
||||
}
|
||||
|
||||
/**
|
||||
- * d_path - return the path of a dentry
|
||||
+ * __d_path - return the path of a dentry
|
||||
* @dentry: dentry to report
|
||||
* @vfsmnt: vfsmnt to which the dentry belongs
|
||||
* @root: root dentry
|
||||
* @rootmnt: vfsmnt to which the root dentry belongs
|
||||
* @buffer: buffer to return value in
|
||||
* @buflen: buffer length
|
||||
+ * @fail_deleted: what to return for deleted files
|
||||
*
|
||||
- * Convert a dentry into an ASCII path name. If the entry has been deleted
|
||||
+ * Convert a dentry into an ASCII path name. If the entry has been deleted,
|
||||
+ * then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise,
|
||||
* the string " (deleted)" is appended. Note that this is ambiguous.
|
||||
*
|
||||
- * Returns the buffer or an error code if the path was too long.
|
||||
+ * If @dentry is not connected to @root, the path returned will be relative
|
||||
+ * (i.e., it will not start with a slash).
|
||||
*
|
||||
- * "buflen" should be positive. Caller holds the dcache_lock.
|
||||
+ * Returns the buffer or an error code.
|
||||
*/
|
||||
-static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
- struct dentry *root, struct vfsmount *rootmnt,
|
||||
- char *buffer, int buflen)
|
||||
-{
|
||||
- char * end = buffer+buflen;
|
||||
- char * retval;
|
||||
- int namelen;
|
||||
+static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
+ struct dentry *root, struct vfsmount *rootmnt,
|
||||
+ char *buffer, int buflen, int fail_deleted)
|
||||
+{
|
||||
+ int namelen, is_slash;
|
||||
+
|
||||
+ if (buflen < 2)
|
||||
+ return ERR_PTR(-ENAMETOOLONG);
|
||||
+ buffer += --buflen;
|
||||
+ *buffer = '\0';
|
||||
|
||||
- *--end = '\0';
|
||||
- buflen--;
|
||||
+ spin_lock(&dcache_lock);
|
||||
if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
|
||||
- buflen -= 10;
|
||||
- end -= 10;
|
||||
- if (buflen < 0)
|
||||
+ if (fail_deleted) {
|
||||
+ buffer = ERR_PTR(-ENOENT);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (buflen < 10)
|
||||
goto Elong;
|
||||
- memcpy(end, " (deleted)", 10);
|
||||
+ buflen -= 10;
|
||||
+ buffer -= 10;
|
||||
+ memcpy(buffer, " (deleted)", 10);
|
||||
}
|
||||
-
|
||||
- if (buflen < 1)
|
||||
- goto Elong;
|
||||
- /* Get '/' right */
|
||||
- retval = end-1;
|
||||
- *retval = '/';
|
||||
-
|
||||
- for (;;) {
|
||||
+ while (dentry != root || vfsmnt != rootmnt) {
|
||||
struct dentry * parent;
|
||||
|
||||
- if (dentry == root && vfsmnt == rootmnt)
|
||||
- break;
|
||||
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
|
||||
- /* Global root? */
|
||||
spin_lock(&vfsmount_lock);
|
||||
if (vfsmnt->mnt_parent == vfsmnt) {
|
||||
spin_unlock(&vfsmount_lock);
|
||||
@@ -1823,33 +1822,72 @@ static char * __d_path( struct dentry *d
|
||||
parent = dentry->d_parent;
|
||||
prefetch(parent);
|
||||
namelen = dentry->d_name.len;
|
||||
- buflen -= namelen + 1;
|
||||
- if (buflen < 0)
|
||||
+ if (buflen < namelen + 1)
|
||||
goto Elong;
|
||||
- end -= namelen;
|
||||
- memcpy(end, dentry->d_name.name, namelen);
|
||||
- *--end = '/';
|
||||
- retval = end;
|
||||
+ buflen -= namelen + 1;
|
||||
+ buffer -= namelen;
|
||||
+ memcpy(buffer, dentry->d_name.name, namelen);
|
||||
+ *--buffer = '/';
|
||||
dentry = parent;
|
||||
}
|
||||
+ /* Get '/' right. */
|
||||
+ if (*buffer != '/')
|
||||
+ *--buffer = '/';
|
||||
|
||||
- return retval;
|
||||
+out:
|
||||
+ spin_unlock(&dcache_lock);
|
||||
+ return buffer;
|
||||
|
||||
global_root:
|
||||
+ /*
|
||||
+ * We went past the (vfsmount, dentry) we were looking for and have
|
||||
+ * either hit a root dentry, a lazily unmounted dentry, an
|
||||
+ * unconnected dentry, or the file is on a pseudo filesystem.
|
||||
+ */
|
||||
namelen = dentry->d_name.len;
|
||||
- buflen -= namelen;
|
||||
- if (buflen < 0)
|
||||
+ is_slash = (namelen == 1 && *dentry->d_name.name == '/');
|
||||
+ if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) {
|
||||
+ /*
|
||||
+ * Make sure we won't return a pathname starting with '/'.
|
||||
+ *
|
||||
+ * Historically, we also glue together the root dentry and
|
||||
+ * remaining name for pseudo filesystems like pipefs, which
|
||||
+ * have the MS_NOUSER flag set. This results in pathnames
|
||||
+ * like "pipe:[439336]".
|
||||
+ */
|
||||
+ if (*buffer == '/') {
|
||||
+ buffer++;
|
||||
+ buflen++;
|
||||
+ }
|
||||
+ if (is_slash)
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (buflen < namelen)
|
||||
goto Elong;
|
||||
- retval -= namelen-1; /* hit the slash */
|
||||
- memcpy(retval, dentry->d_name.name, namelen);
|
||||
- return retval;
|
||||
+ buffer -= namelen;
|
||||
+ memcpy(buffer, dentry->d_name.name, namelen);
|
||||
+ goto out;
|
||||
+
|
||||
Elong:
|
||||
- return ERR_PTR(-ENAMETOOLONG);
|
||||
+ buffer = ERR_PTR(-ENAMETOOLONG);
|
||||
+ goto out;
|
||||
+}
|
||||
+
|
||||
+static char *__connect_d_path(char *path, char *buffer)
|
||||
+{
|
||||
+ if (!IS_ERR(path) && *path != '/') {
|
||||
+ /* Pretend that disconnected paths are hanging off the root. */
|
||||
+ if (path == buffer)
|
||||
+ path = ERR_PTR(-ENAMETOOLONG);
|
||||
+ else
|
||||
+ *--path = '/';
|
||||
+ }
|
||||
+ return path;
|
||||
}
|
||||
|
||||
/* write full pathname into buffer and return start of pathname */
|
||||
-char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
- char *buf, int buflen)
|
||||
+char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf,
|
||||
+ int buflen)
|
||||
{
|
||||
char *res;
|
||||
struct vfsmount *rootmnt;
|
||||
@@ -1869,9 +1907,8 @@ char * d_path(struct dentry *dentry, str
|
||||
rootmnt = mntget(current->fs->rootmnt);
|
||||
root = dget(current->fs->root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
- spin_lock(&dcache_lock);
|
||||
- res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
|
||||
- spin_unlock(&dcache_lock);
|
||||
+ res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0);
|
||||
+ res = __connect_d_path(res, buf);
|
||||
dput(root);
|
||||
mntput(rootmnt);
|
||||
return res;
|
||||
@@ -1918,10 +1955,10 @@ char *dynamic_dname(struct dentry *dentr
|
||||
*/
|
||||
asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
|
||||
{
|
||||
- int error;
|
||||
+ int error, len;
|
||||
struct vfsmount *pwdmnt, *rootmnt;
|
||||
struct dentry *pwd, *root;
|
||||
- char *page = (char *) __get_free_page(GFP_USER);
|
||||
+ char *page = (char *) __get_free_page(GFP_USER), *cwd;
|
||||
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
@@ -1933,29 +1970,19 @@ asmlinkage long sys_getcwd(char __user *
|
||||
root = dget(current->fs->root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
|
||||
- error = -ENOENT;
|
||||
- /* Has the current directory has been unlinked? */
|
||||
- spin_lock(&dcache_lock);
|
||||
- if (pwd->d_parent == pwd || !d_unhashed(pwd)) {
|
||||
- unsigned long len;
|
||||
- char * cwd;
|
||||
-
|
||||
- cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
|
||||
- spin_unlock(&dcache_lock);
|
||||
-
|
||||
- error = PTR_ERR(cwd);
|
||||
- if (IS_ERR(cwd))
|
||||
- goto out;
|
||||
-
|
||||
- error = -ERANGE;
|
||||
- len = PAGE_SIZE + page - cwd;
|
||||
- if (len <= size) {
|
||||
- error = len;
|
||||
- if (copy_to_user(buf, cwd, len))
|
||||
- error = -EFAULT;
|
||||
- }
|
||||
- } else
|
||||
- spin_unlock(&dcache_lock);
|
||||
+ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1);
|
||||
+ cwd = __connect_d_path(cwd, page);
|
||||
+ error = PTR_ERR(cwd);
|
||||
+ if (IS_ERR(cwd))
|
||||
+ goto out;
|
||||
+
|
||||
+ error = -ERANGE;
|
||||
+ len = PAGE_SIZE + page - cwd;
|
||||
+ if (len <= size) {
|
||||
+ error = len;
|
||||
+ if (copy_to_user(buf, cwd, len))
|
||||
+ error = -EFAULT;
|
||||
+ }
|
||||
|
||||
out:
|
||||
dput(pwd);
|
190
kernel-patches/2.6.24/vfs-getxattr.diff
Normal file
190
kernel-patches/2.6.24/vfs-getxattr.diff
Normal file
@@ -0,0 +1,190 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add a struct vfsmount parameter to vfs_getxattr()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/nfsd/nfs4xdr.c | 2 +-
|
||||
fs/nfsd/vfs.c | 21 ++++++++++++---------
|
||||
fs/xattr.c | 14 ++++++++------
|
||||
include/linux/nfsd/nfsd.h | 3 ++-
|
||||
include/linux/xattr.h | 3 ++-
|
||||
5 files changed, 25 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/fs/nfsd/nfs4xdr.c
|
||||
+++ b/fs/nfsd/nfs4xdr.c
|
||||
@@ -1496,7 +1496,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
|
||||
}
|
||||
if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
|
||||
| FATTR4_WORD0_SUPPORTED_ATTRS)) {
|
||||
- err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
|
||||
+ err = nfsd4_get_nfs4_acl(rqstp, dentry, exp->ex_mnt, &acl);
|
||||
aclsupport = (err == 0);
|
||||
if (bmval0 & FATTR4_WORD0_ACL) {
|
||||
if (err == -EOPNOTSUPP)
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -408,11 +408,12 @@ out_nfserr:
|
||||
#if defined(CONFIG_NFSD_V2_ACL) || \
|
||||
defined(CONFIG_NFSD_V3_ACL) || \
|
||||
defined(CONFIG_NFSD_V4)
|
||||
-static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
|
||||
+static ssize_t nfsd_getxattr(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char *key, void **buf)
|
||||
{
|
||||
ssize_t buflen;
|
||||
|
||||
- buflen = vfs_getxattr(dentry, key, NULL, 0);
|
||||
+ buflen = vfs_getxattr(dentry, mnt, key, NULL, 0);
|
||||
if (buflen <= 0)
|
||||
return buflen;
|
||||
|
||||
@@ -420,7 +421,7 @@ static ssize_t nfsd_getxattr(struct dent
|
||||
if (!*buf)
|
||||
return -ENOMEM;
|
||||
|
||||
- return vfs_getxattr(dentry, key, *buf, buflen);
|
||||
+ return vfs_getxattr(dentry, mnt, key, *buf, buflen);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -501,13 +502,13 @@ out_nfserr:
|
||||
}
|
||||
|
||||
static struct posix_acl *
|
||||
-_get_posix_acl(struct dentry *dentry, char *key)
|
||||
+_get_posix_acl(struct dentry *dentry, struct vfsmount *mnt, char *key)
|
||||
{
|
||||
void *buf = NULL;
|
||||
struct posix_acl *pacl = NULL;
|
||||
int buflen;
|
||||
|
||||
- buflen = nfsd_getxattr(dentry, key, &buf);
|
||||
+ buflen = nfsd_getxattr(dentry, mnt, key, &buf);
|
||||
if (!buflen)
|
||||
buflen = -ENODATA;
|
||||
if (buflen <= 0)
|
||||
@@ -519,14 +520,15 @@ _get_posix_acl(struct dentry *dentry, ch
|
||||
}
|
||||
|
||||
int
|
||||
-nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_acl **acl)
|
||||
+nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
|
||||
+ struct vfsmount *mnt, struct nfs4_acl **acl)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error = 0;
|
||||
struct posix_acl *pacl = NULL, *dpacl = NULL;
|
||||
unsigned int flags = 0;
|
||||
|
||||
- pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS);
|
||||
+ pacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_ACCESS);
|
||||
if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA)
|
||||
pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
|
||||
if (IS_ERR(pacl)) {
|
||||
@@ -536,7 +538,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqst
|
||||
}
|
||||
|
||||
if (S_ISDIR(inode->i_mode)) {
|
||||
- dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT);
|
||||
+ dpacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_DEFAULT);
|
||||
if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA)
|
||||
dpacl = NULL;
|
||||
else if (IS_ERR(dpacl)) {
|
||||
@@ -2001,7 +2003,8 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
- size = nfsd_getxattr(fhp->fh_dentry, name, &value);
|
||||
+ size = nfsd_getxattr(fhp->fh_dentry, fhp->fh_export->ex_mnt, name,
|
||||
+ &value);
|
||||
if (size < 0)
|
||||
return ERR_PTR(size);
|
||||
|
||||
--- a/fs/xattr.c
|
||||
+++ b/fs/xattr.c
|
||||
@@ -105,7 +105,8 @@ out:
|
||||
EXPORT_SYMBOL_GPL(vfs_setxattr);
|
||||
|
||||
ssize_t
|
||||
-vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
|
||||
+vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, char *name,
|
||||
+ void *value, size_t size)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
@@ -277,7 +278,8 @@ sys_fsetxattr(int fd, char __user *name,
|
||||
* Extended attribute GET operations
|
||||
*/
|
||||
static ssize_t
|
||||
-getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
|
||||
+getxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name,
|
||||
+ void __user *value, size_t size)
|
||||
{
|
||||
ssize_t error;
|
||||
void *kvalue = NULL;
|
||||
@@ -297,7 +299,7 @@ getxattr(struct dentry *d, char __user *
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- error = vfs_getxattr(d, kname, kvalue, size);
|
||||
+ error = vfs_getxattr(dentry, mnt, kname, kvalue, size);
|
||||
if (error > 0) {
|
||||
if (size && copy_to_user(value, kvalue, error))
|
||||
error = -EFAULT;
|
||||
@@ -320,7 +322,7 @@ sys_getxattr(char __user *path, char __u
|
||||
error = user_path_walk(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = getxattr(nd.dentry, name, value, size);
|
||||
+ error = getxattr(nd.dentry, nd.mnt, name, value, size);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -335,7 +337,7 @@ sys_lgetxattr(char __user *path, char __
|
||||
error = user_path_walk_link(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = getxattr(nd.dentry, name, value, size);
|
||||
+ error = getxattr(nd.dentry, nd.mnt, name, value, size);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -350,7 +352,7 @@ sys_fgetxattr(int fd, char __user *name,
|
||||
if (!f)
|
||||
return error;
|
||||
audit_inode(NULL, f->f_path.dentry);
|
||||
- error = getxattr(f->f_path.dentry, name, value, size);
|
||||
+ error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size);
|
||||
fput(f);
|
||||
return error;
|
||||
}
|
||||
--- a/include/linux/nfsd/nfsd.h
|
||||
+++ b/include/linux/nfsd/nfsd.h
|
||||
@@ -79,7 +79,8 @@ __be32 nfsd_setattr(struct svc_rqst *,
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
__be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
|
||||
struct nfs4_acl *);
|
||||
-int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **);
|
||||
+int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *,
|
||||
+ struct vfsmount *mnt, struct nfs4_acl **);
|
||||
#endif /* CONFIG_NFSD_V4 */
|
||||
__be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
|
||||
char *name, int len, struct iattr *attrs,
|
||||
--- a/include/linux/xattr.h
|
||||
+++ b/include/linux/xattr.h
|
||||
@@ -46,7 +46,8 @@ struct xattr_handler {
|
||||
size_t size, int flags);
|
||||
};
|
||||
|
||||
-ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
|
||||
+ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, char *, void *,
|
||||
+ size_t);
|
||||
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
|
||||
int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t,
|
||||
int);
|
90
kernel-patches/2.6.24/vfs-link.diff
Normal file
90
kernel-patches/2.6.24/vfs-link.diff
Normal file
@@ -0,0 +1,90 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add struct vfsmount parameters to vfs_link()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/ecryptfs/inode.c | 9 +++++++--
|
||||
fs/namei.c | 5 +++--
|
||||
fs/nfsd/vfs.c | 3 ++-
|
||||
include/linux/fs.h | 2 +-
|
||||
4 files changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/fs/ecryptfs/inode.c
|
||||
+++ b/fs/ecryptfs/inode.c
|
||||
@@ -402,19 +402,24 @@ static int ecryptfs_link(struct dentry *
|
||||
struct dentry *new_dentry)
|
||||
{
|
||||
struct dentry *lower_old_dentry;
|
||||
+ struct vfsmount *lower_old_mnt;
|
||||
struct dentry *lower_new_dentry;
|
||||
+ struct vfsmount *lower_new_mnt;
|
||||
struct dentry *lower_dir_dentry;
|
||||
u64 file_size_save;
|
||||
int rc;
|
||||
|
||||
file_size_save = i_size_read(old_dentry->d_inode);
|
||||
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
|
||||
+ lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry);
|
||||
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
|
||||
+ lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
|
||||
dget(lower_old_dentry);
|
||||
dget(lower_new_dentry);
|
||||
lower_dir_dentry = lock_parent(lower_new_dentry);
|
||||
- rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
|
||||
- lower_new_dentry);
|
||||
+ rc = vfs_link(lower_old_dentry, lower_old_mnt,
|
||||
+ lower_dir_dentry->d_inode, lower_new_dentry,
|
||||
+ lower_new_mnt);
|
||||
if (rc || !lower_new_dentry->d_inode)
|
||||
goto out_lock;
|
||||
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2331,7 +2331,7 @@ asmlinkage long sys_symlink(const char _
|
||||
return sys_symlinkat(oldname, AT_FDCWD, newname);
|
||||
}
|
||||
|
||||
-int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
|
||||
+int vfs_link(struct dentry *old_dentry, struct vfsmount *old_mnt, struct inode *dir, struct dentry *new_dentry, struct vfsmount *new_mnt)
|
||||
{
|
||||
struct inode *inode = old_dentry->d_inode;
|
||||
int error;
|
||||
@@ -2409,7 +2409,8 @@ asmlinkage long sys_linkat(int olddfd, c
|
||||
error = PTR_ERR(new_dentry);
|
||||
if (IS_ERR(new_dentry))
|
||||
goto out_unlock;
|
||||
- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
|
||||
+ error = vfs_link(old_nd.dentry, old_nd.mnt, nd.dentry->d_inode,
|
||||
+ new_dentry, nd.mnt);
|
||||
dput(new_dentry);
|
||||
out_unlock:
|
||||
mutex_unlock(&nd.dentry->d_inode->i_mutex);
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -1589,7 +1589,8 @@ nfsd_link(struct svc_rqst *rqstp, struct
|
||||
dold = tfhp->fh_dentry;
|
||||
dest = dold->d_inode;
|
||||
|
||||
- host_err = vfs_link(dold, dirp, dnew);
|
||||
+ host_err = vfs_link(dold, tfhp->fh_export->ex_mnt, dirp,
|
||||
+ dnew, ffhp->fh_export->ex_mnt);
|
||||
if (!host_err) {
|
||||
if (EX_ISSYNC(ffhp->fh_export)) {
|
||||
err = nfserrno(nfsd_sync_dir(ddir));
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -1071,7 +1071,7 @@ extern int vfs_create(struct inode *, st
|
||||
extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int);
|
||||
extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t);
|
||||
extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int);
|
||||
-extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
|
||||
+extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
|
||||
extern int vfs_rmdir(struct inode *, struct dentry *);
|
||||
extern int vfs_unlink(struct inode *, struct dentry *);
|
||||
extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
|
102
kernel-patches/2.6.24/vfs-listxattr.diff
Normal file
102
kernel-patches/2.6.24/vfs-listxattr.diff
Normal file
@@ -0,0 +1,102 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add a struct vfsmount parameter to vfs_listxattr()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/xattr.c | 25 ++++++++++++++-----------
|
||||
include/linux/xattr.h | 3 ++-
|
||||
2 files changed, 16 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/fs/xattr.c
|
||||
+++ b/fs/xattr.c
|
||||
@@ -142,18 +142,20 @@ vfs_getxattr(struct dentry *dentry, stru
|
||||
EXPORT_SYMBOL_GPL(vfs_getxattr);
|
||||
|
||||
ssize_t
|
||||
-vfs_listxattr(struct dentry *d, char *list, size_t size)
|
||||
+vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, char *list,
|
||||
+ size_t size)
|
||||
{
|
||||
+ struct inode *inode = dentry->d_inode;
|
||||
ssize_t error;
|
||||
|
||||
- error = security_inode_listxattr(d);
|
||||
+ error = security_inode_listxattr(dentry);
|
||||
if (error)
|
||||
return error;
|
||||
error = -EOPNOTSUPP;
|
||||
- if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
|
||||
- error = d->d_inode->i_op->listxattr(d, list, size);
|
||||
- } else {
|
||||
- error = security_inode_listsecurity(d->d_inode, list, size);
|
||||
+ if (inode->i_op && inode->i_op->listxattr)
|
||||
+ error = inode->i_op->listxattr(dentry, list, size);
|
||||
+ else {
|
||||
+ error = security_inode_listsecurity(inode, list, size);
|
||||
if (size && error > size)
|
||||
error = -ERANGE;
|
||||
}
|
||||
@@ -361,7 +363,8 @@ sys_fgetxattr(int fd, char __user *name,
|
||||
* Extended attribute LIST operations
|
||||
*/
|
||||
static ssize_t
|
||||
-listxattr(struct dentry *d, char __user *list, size_t size)
|
||||
+listxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *list,
|
||||
+ size_t size)
|
||||
{
|
||||
ssize_t error;
|
||||
char *klist = NULL;
|
||||
@@ -374,7 +377,7 @@ listxattr(struct dentry *d, char __user
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- error = vfs_listxattr(d, klist, size);
|
||||
+ error = vfs_listxattr(dentry, mnt, klist, size);
|
||||
if (error > 0) {
|
||||
if (size && copy_to_user(list, klist, error))
|
||||
error = -EFAULT;
|
||||
@@ -396,7 +399,7 @@ sys_listxattr(char __user *path, char __
|
||||
error = user_path_walk(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = listxattr(nd.dentry, list, size);
|
||||
+ error = listxattr(nd.dentry, nd.mnt, list, size);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -410,7 +413,7 @@ sys_llistxattr(char __user *path, char _
|
||||
error = user_path_walk_link(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = listxattr(nd.dentry, list, size);
|
||||
+ error = listxattr(nd.dentry, nd.mnt, list, size);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -425,7 +428,7 @@ sys_flistxattr(int fd, char __user *list
|
||||
if (!f)
|
||||
return error;
|
||||
audit_inode(NULL, f->f_path.dentry);
|
||||
- error = listxattr(f->f_path.dentry, list, size);
|
||||
+ error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size);
|
||||
fput(f);
|
||||
return error;
|
||||
}
|
||||
--- a/include/linux/xattr.h
|
||||
+++ b/include/linux/xattr.h
|
||||
@@ -48,7 +48,8 @@ struct xattr_handler {
|
||||
|
||||
ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, char *, void *,
|
||||
size_t);
|
||||
-ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
|
||||
+ssize_t vfs_listxattr(struct dentry *d, struct vfsmount *, char *list,
|
||||
+ size_t size);
|
||||
int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t,
|
||||
int);
|
||||
int vfs_removexattr(struct dentry *, char *);
|
137
kernel-patches/2.6.24/vfs-mkdir.diff
Normal file
137
kernel-patches/2.6.24/vfs-mkdir.diff
Normal file
@@ -0,0 +1,137 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add struct vfsmount parameter to vfs_mkdir()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/ecryptfs/inode.c | 5 ++++-
|
||||
fs/namei.c | 5 +++--
|
||||
fs/nfsd/nfs4recover.c | 3 ++-
|
||||
fs/nfsd/vfs.c | 8 +++++---
|
||||
include/linux/fs.h | 2 +-
|
||||
kernel/cgroup.c | 2 +-
|
||||
6 files changed, 16 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/fs/ecryptfs/inode.c
|
||||
+++ b/fs/ecryptfs/inode.c
|
||||
@@ -488,11 +488,14 @@ static int ecryptfs_mkdir(struct inode *
|
||||
{
|
||||
int rc;
|
||||
struct dentry *lower_dentry;
|
||||
+ struct vfsmount *lower_mnt;
|
||||
struct dentry *lower_dir_dentry;
|
||||
|
||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
|
||||
lower_dir_dentry = lock_parent(lower_dentry);
|
||||
- rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
|
||||
+ rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt,
|
||||
+ mode);
|
||||
if (rc || !lower_dentry->d_inode)
|
||||
goto out;
|
||||
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -1998,7 +1998,8 @@ asmlinkage long sys_mknod(const char __u
|
||||
return sys_mknodat(AT_FDCWD, filename, mode, dev);
|
||||
}
|
||||
|
||||
-int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
+int vfs_mkdir(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ int mode)
|
||||
{
|
||||
int error = may_create(dir, dentry, NULL);
|
||||
|
||||
@@ -2042,7 +2043,7 @@ asmlinkage long sys_mkdirat(int dfd, con
|
||||
|
||||
if (!IS_POSIXACL(nd.dentry->d_inode))
|
||||
mode &= ~current->fs->umask;
|
||||
- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
|
||||
+ error = vfs_mkdir(nd.dentry->d_inode, dentry, nd.mnt, mode);
|
||||
dput(dentry);
|
||||
out_unlock:
|
||||
mutex_unlock(&nd.dentry->d_inode->i_mutex);
|
||||
--- a/fs/nfsd/nfs4recover.c
|
||||
+++ b/fs/nfsd/nfs4recover.c
|
||||
@@ -154,7 +154,8 @@ nfsd4_create_clid_dir(struct nfs4_client
|
||||
dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
|
||||
goto out_put;
|
||||
}
|
||||
- status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
|
||||
+ status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, rec_dir.mnt,
|
||||
+ S_IRWXU);
|
||||
out_put:
|
||||
dput(dentry);
|
||||
out_unlock:
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -1165,6 +1165,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
|
||||
int type, dev_t rdev, struct svc_fh *resfhp)
|
||||
{
|
||||
struct dentry *dentry, *dchild = NULL;
|
||||
+ struct svc_export *exp;
|
||||
struct inode *dirp;
|
||||
__be32 err;
|
||||
int host_err;
|
||||
@@ -1181,6 +1182,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
|
||||
goto out;
|
||||
|
||||
dentry = fhp->fh_dentry;
|
||||
+ exp = fhp->fh_export;
|
||||
dirp = dentry->d_inode;
|
||||
|
||||
err = nfserr_notdir;
|
||||
@@ -1197,7 +1199,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
|
||||
host_err = PTR_ERR(dchild);
|
||||
if (IS_ERR(dchild))
|
||||
goto out_nfserr;
|
||||
- err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
|
||||
+ err = fh_compose(resfhp, exp, dchild, fhp);
|
||||
if (err)
|
||||
goto out;
|
||||
} else {
|
||||
@@ -1236,7 +1238,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
|
||||
host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
|
||||
break;
|
||||
case S_IFDIR:
|
||||
- host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
|
||||
+ host_err = vfs_mkdir(dirp, dchild, exp->ex_mnt, iap->ia_mode);
|
||||
break;
|
||||
case S_IFCHR:
|
||||
case S_IFBLK:
|
||||
@@ -1251,7 +1253,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
|
||||
if (host_err < 0)
|
||||
goto out_nfserr;
|
||||
|
||||
- if (EX_ISSYNC(fhp->fh_export)) {
|
||||
+ if (EX_ISSYNC(exp)) {
|
||||
err = nfserrno(nfsd_sync_dir(dentry));
|
||||
write_inode_now(dchild->d_inode, 1);
|
||||
}
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -1068,7 +1068,7 @@ extern void unlock_super(struct super_bl
|
||||
*/
|
||||
extern int vfs_permission(struct nameidata *, int);
|
||||
extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
|
||||
-extern int vfs_mkdir(struct inode *, struct dentry *, int);
|
||||
+extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int);
|
||||
extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
|
||||
extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
|
||||
extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
|
||||
--- a/kernel/cgroup.c
|
||||
+++ b/kernel/cgroup.c
|
||||
@@ -2611,7 +2611,7 @@ int cgroup_clone(struct task_struct *tsk
|
||||
}
|
||||
|
||||
/* Create the cgroup directory, which also creates the cgroup */
|
||||
- ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755);
|
||||
+ ret = vfs_mkdir(inode, dentry, NULL, S_IFDIR | 0755);
|
||||
child = __d_cgrp(dentry);
|
||||
dput(dentry);
|
||||
if (ret) {
|
98
kernel-patches/2.6.24/vfs-mknod.diff
Normal file
98
kernel-patches/2.6.24/vfs-mknod.diff
Normal file
@@ -0,0 +1,98 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add a struct vfsmount parameter to vfs_mknod()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/ecryptfs/inode.c | 5 ++++-
|
||||
fs/namei.c | 10 ++++++----
|
||||
fs/nfsd/vfs.c | 3 ++-
|
||||
include/linux/fs.h | 2 +-
|
||||
net/unix/af_unix.c | 2 +-
|
||||
5 files changed, 14 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/fs/ecryptfs/inode.c
|
||||
+++ b/fs/ecryptfs/inode.c
|
||||
@@ -551,11 +551,14 @@ ecryptfs_mknod(struct inode *dir, struct
|
||||
{
|
||||
int rc;
|
||||
struct dentry *lower_dentry;
|
||||
+ struct vfsmount *lower_mnt;
|
||||
struct dentry *lower_dir_dentry;
|
||||
|
||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
|
||||
lower_dir_dentry = lock_parent(lower_dentry);
|
||||
- rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
|
||||
+ rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, mode,
|
||||
+ dev);
|
||||
if (rc || !lower_dentry->d_inode)
|
||||
goto out;
|
||||
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -1918,7 +1918,8 @@ fail:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lookup_create);
|
||||
|
||||
-int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
|
||||
+int vfs_mknod(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ int mode, dev_t dev)
|
||||
{
|
||||
int error = may_create(dir, dentry, NULL);
|
||||
|
||||
@@ -1970,11 +1971,12 @@ asmlinkage long sys_mknodat(int dfd, con
|
||||
error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
|
||||
break;
|
||||
case S_IFCHR: case S_IFBLK:
|
||||
- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
|
||||
- new_decode_dev(dev));
|
||||
+ error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt,
|
||||
+ mode, new_decode_dev(dev));
|
||||
break;
|
||||
case S_IFIFO: case S_IFSOCK:
|
||||
- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
|
||||
+ error = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt,
|
||||
+ mode, 0);
|
||||
break;
|
||||
case S_IFDIR:
|
||||
error = -EPERM;
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -1244,7 +1244,8 @@ nfsd_create(struct svc_rqst *rqstp, stru
|
||||
case S_IFBLK:
|
||||
case S_IFIFO:
|
||||
case S_IFSOCK:
|
||||
- host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
|
||||
+ host_err = vfs_mknod(dirp, dchild, exp->ex_mnt, iap->ia_mode,
|
||||
+ rdev);
|
||||
break;
|
||||
default:
|
||||
printk("nfsd: bad file type %o in nfsd_create\n", type);
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -1069,7 +1069,7 @@ extern void unlock_super(struct super_bl
|
||||
extern int vfs_permission(struct nameidata *, int);
|
||||
extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
|
||||
extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int);
|
||||
-extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
|
||||
+extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t);
|
||||
extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
|
||||
extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
|
||||
extern int vfs_rmdir(struct inode *, struct dentry *);
|
||||
--- a/net/unix/af_unix.c
|
||||
+++ b/net/unix/af_unix.c
|
||||
@@ -839,7 +839,7 @@ static int unix_bind(struct socket *sock
|
||||
*/
|
||||
mode = S_IFSOCK |
|
||||
(SOCK_INODE(sock)->i_mode & ~current->fs->umask);
|
||||
- err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
|
||||
+ err = vfs_mknod(nd.dentry->d_inode, dentry, nd.mnt, mode, 0);
|
||||
if (err)
|
||||
goto out_mknod_dput;
|
||||
mutex_unlock(&nd.dentry->d_inode->i_mutex);
|
387
kernel-patches/2.6.24/vfs-notify_change.diff
Normal file
387
kernel-patches/2.6.24/vfs-notify_change.diff
Normal file
@@ -0,0 +1,387 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add a vfsmount parameter to notify_change()
|
||||
|
||||
The vfsmount parameter must be set appropriately for files visibile
|
||||
outside the kernel. Files that are only used in a filesystem (e.g.,
|
||||
reiserfs xattr files) will have a NULL vfsmount.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/attr.c | 3 ++-
|
||||
fs/ecryptfs/inode.c | 4 +++-
|
||||
fs/exec.c | 3 ++-
|
||||
fs/fat/file.c | 2 +-
|
||||
fs/hpfs/namei.c | 2 +-
|
||||
fs/namei.c | 2 +-
|
||||
fs/nfsd/vfs.c | 8 ++++----
|
||||
fs/open.c | 28 +++++++++++++++-------------
|
||||
fs/reiserfs/xattr.c | 6 +++---
|
||||
fs/sysfs/file.c | 2 +-
|
||||
fs/utimes.c | 11 ++++++-----
|
||||
include/linux/fs.h | 6 +++---
|
||||
mm/filemap.c | 2 +-
|
||||
mm/tiny-shmem.c | 2 +-
|
||||
14 files changed, 44 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/fs/attr.c
|
||||
+++ b/fs/attr.c
|
||||
@@ -100,7 +100,8 @@ int inode_setattr(struct inode * inode,
|
||||
}
|
||||
EXPORT_SYMBOL(inode_setattr);
|
||||
|
||||
-int notify_change(struct dentry * dentry, struct iattr * attr)
|
||||
+int notify_change(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct iattr *attr)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
mode_t mode = inode->i_mode;
|
||||
--- a/fs/ecryptfs/inode.c
|
||||
+++ b/fs/ecryptfs/inode.c
|
||||
@@ -862,6 +862,7 @@ static int ecryptfs_setattr(struct dentr
|
||||
{
|
||||
int rc = 0;
|
||||
struct dentry *lower_dentry;
|
||||
+ struct vfsmount *lower_mnt;
|
||||
struct inode *inode;
|
||||
struct inode *lower_inode;
|
||||
struct ecryptfs_crypt_stat *crypt_stat;
|
||||
@@ -872,6 +873,7 @@ static int ecryptfs_setattr(struct dentr
|
||||
inode = dentry->d_inode;
|
||||
lower_inode = ecryptfs_inode_to_lower(inode);
|
||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
|
||||
mutex_lock(&crypt_stat->cs_mutex);
|
||||
if (S_ISDIR(dentry->d_inode->i_mode))
|
||||
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
|
||||
@@ -922,7 +924,7 @@ static int ecryptfs_setattr(struct dentr
|
||||
if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
|
||||
ia->ia_valid &= ~ATTR_MODE;
|
||||
|
||||
- rc = notify_change(lower_dentry, ia);
|
||||
+ rc = notify_change(lower_dentry, lower_mnt, ia);
|
||||
out:
|
||||
fsstack_copy_attr_all(inode, lower_inode, NULL);
|
||||
return rc;
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1784,7 +1784,8 @@ int do_coredump(long signr, int exit_cod
|
||||
goto close_fail;
|
||||
if (!file->f_op->write)
|
||||
goto close_fail;
|
||||
- if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0)
|
||||
+ if (!ispipe &&
|
||||
+ do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0)
|
||||
goto close_fail;
|
||||
|
||||
retval = binfmt->core_dump(signr, regs, file, core_limit);
|
||||
--- a/fs/fat/file.c
|
||||
+++ b/fs/fat/file.c
|
||||
@@ -92,7 +92,7 @@ int fat_generic_ioctl(struct inode *inod
|
||||
}
|
||||
|
||||
/* This MUST be done before doing anything irreversible... */
|
||||
- err = notify_change(filp->f_path.dentry, &ia);
|
||||
+ err = notify_change(filp->f_path.dentry, filp->f_path.mnt, &ia);
|
||||
if (err)
|
||||
goto up;
|
||||
|
||||
--- a/fs/hpfs/namei.c
|
||||
+++ b/fs/hpfs/namei.c
|
||||
@@ -426,7 +426,7 @@ again:
|
||||
/*printk("HPFS: truncating file before delete.\n");*/
|
||||
newattrs.ia_size = 0;
|
||||
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
|
||||
- err = notify_change(dentry, &newattrs);
|
||||
+ err = notify_change(dentry, NULL, &newattrs);
|
||||
put_write_access(inode);
|
||||
if (!err)
|
||||
goto again;
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -1660,7 +1660,7 @@ int may_open(struct nameidata *nd, int a
|
||||
if (!error) {
|
||||
DQUOT_INIT(inode);
|
||||
|
||||
- error = do_truncate(dentry, 0,
|
||||
+ error = do_truncate(dentry, nd->mnt, 0,
|
||||
ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
|
||||
NULL);
|
||||
}
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -388,7 +388,7 @@ nfsd_setattr(struct svc_rqst *rqstp, str
|
||||
err = nfserr_notsync;
|
||||
if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
|
||||
fh_lock(fhp);
|
||||
- host_err = notify_change(dentry, iap);
|
||||
+ host_err = notify_change(dentry, fhp->fh_export->ex_mnt, iap);
|
||||
err = nfserrno(host_err);
|
||||
fh_unlock(fhp);
|
||||
}
|
||||
@@ -943,13 +943,13 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
-static void kill_suid(struct dentry *dentry)
|
||||
+static void kill_suid(struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
struct iattr ia;
|
||||
ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
|
||||
|
||||
mutex_lock(&dentry->d_inode->i_mutex);
|
||||
- notify_change(dentry, &ia);
|
||||
+ notify_change(dentry, mnt, &ia);
|
||||
mutex_unlock(&dentry->d_inode->i_mutex);
|
||||
}
|
||||
|
||||
@@ -1008,7 +1008,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
|
||||
|
||||
/* clear setuid/setgid flag after write */
|
||||
if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
|
||||
- kill_suid(dentry);
|
||||
+ kill_suid(dentry, exp->ex_mnt);
|
||||
|
||||
if (host_err >= 0 && stable) {
|
||||
static ino_t last_ino;
|
||||
--- a/fs/open.c
|
||||
+++ b/fs/open.c
|
||||
@@ -194,8 +194,8 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
-int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
||||
- struct file *filp)
|
||||
+int do_truncate(struct dentry *dentry, struct vfsmount *mnt, loff_t length,
|
||||
+ unsigned int time_attrs, struct file *filp)
|
||||
{
|
||||
int err;
|
||||
struct iattr newattrs;
|
||||
@@ -215,7 +215,7 @@ int do_truncate(struct dentry *dentry, l
|
||||
newattrs.ia_valid |= should_remove_suid(dentry);
|
||||
|
||||
mutex_lock(&dentry->d_inode->i_mutex);
|
||||
- err = notify_change(dentry, &newattrs);
|
||||
+ err = notify_change(dentry, mnt, &newattrs);
|
||||
mutex_unlock(&dentry->d_inode->i_mutex);
|
||||
return err;
|
||||
}
|
||||
@@ -271,7 +271,7 @@ static long do_sys_truncate(const char _
|
||||
error = locks_verify_truncate(inode, NULL, length);
|
||||
if (!error) {
|
||||
DQUOT_INIT(inode);
|
||||
- error = do_truncate(nd.dentry, length, 0, NULL);
|
||||
+ error = do_truncate(nd.dentry, nd.mnt, length, 0, NULL);
|
||||
}
|
||||
|
||||
put_write_and_out:
|
||||
@@ -324,7 +324,8 @@ static long do_sys_ftruncate(unsigned in
|
||||
|
||||
error = locks_verify_truncate(inode, file, length);
|
||||
if (!error)
|
||||
- error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
|
||||
+ error = do_truncate(dentry, file->f_path.mnt, length,
|
||||
+ ATTR_MTIME|ATTR_CTIME, file);
|
||||
out_putf:
|
||||
fput(file);
|
||||
out:
|
||||
@@ -582,7 +583,7 @@ asmlinkage long sys_fchmod(unsigned int
|
||||
mode = inode->i_mode;
|
||||
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
||||
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||
- err = notify_change(dentry, &newattrs);
|
||||
+ err = notify_change(dentry, file->f_path.mnt, &newattrs);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
out_putf:
|
||||
@@ -617,7 +618,7 @@ asmlinkage long sys_fchmodat(int dfd, co
|
||||
mode = inode->i_mode;
|
||||
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
||||
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||
- error = notify_change(nd.dentry, &newattrs);
|
||||
+ error = notify_change(nd.dentry, nd.mnt, &newattrs);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
dput_and_out:
|
||||
@@ -631,7 +632,8 @@ asmlinkage long sys_chmod(const char __u
|
||||
return sys_fchmodat(AT_FDCWD, filename, mode);
|
||||
}
|
||||
|
||||
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
|
||||
+static int chown_common(struct dentry * dentry, struct vfsmount *mnt,
|
||||
+ uid_t user, gid_t group)
|
||||
{
|
||||
struct inode * inode;
|
||||
int error;
|
||||
@@ -661,7 +663,7 @@ static int chown_common(struct dentry *
|
||||
newattrs.ia_valid |=
|
||||
ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
|
||||
mutex_lock(&inode->i_mutex);
|
||||
- error = notify_change(dentry, &newattrs);
|
||||
+ error = notify_change(dentry, mnt, &newattrs);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
out:
|
||||
return error;
|
||||
@@ -675,7 +677,7 @@ asmlinkage long sys_chown(const char __u
|
||||
error = user_path_walk(filename, &nd);
|
||||
if (error)
|
||||
goto out;
|
||||
- error = chown_common(nd.dentry, user, group);
|
||||
+ error = chown_common(nd.dentry, nd.mnt, user, group);
|
||||
path_release(&nd);
|
||||
out:
|
||||
return error;
|
||||
@@ -695,7 +697,7 @@ asmlinkage long sys_fchownat(int dfd, co
|
||||
error = __user_walk_fd(dfd, filename, follow, &nd);
|
||||
if (error)
|
||||
goto out;
|
||||
- error = chown_common(nd.dentry, user, group);
|
||||
+ error = chown_common(nd.dentry, nd.mnt, user, group);
|
||||
path_release(&nd);
|
||||
out:
|
||||
return error;
|
||||
@@ -709,7 +711,7 @@ asmlinkage long sys_lchown(const char __
|
||||
error = user_path_walk_link(filename, &nd);
|
||||
if (error)
|
||||
goto out;
|
||||
- error = chown_common(nd.dentry, user, group);
|
||||
+ error = chown_common(nd.dentry, nd.mnt, user, group);
|
||||
path_release(&nd);
|
||||
out:
|
||||
return error;
|
||||
@@ -728,7 +730,7 @@ asmlinkage long sys_fchown(unsigned int
|
||||
|
||||
dentry = file->f_path.dentry;
|
||||
audit_inode(NULL, dentry);
|
||||
- error = chown_common(dentry, user, group);
|
||||
+ error = chown_common(dentry, file->f_path.mnt, user, group);
|
||||
fput(file);
|
||||
out:
|
||||
return error;
|
||||
--- a/fs/reiserfs/xattr.c
|
||||
+++ b/fs/reiserfs/xattr.c
|
||||
@@ -485,7 +485,7 @@ reiserfs_xattr_set(struct inode *inode,
|
||||
newattrs.ia_size = buffer_size;
|
||||
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
|
||||
mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR);
|
||||
- err = notify_change(fp->f_path.dentry, &newattrs);
|
||||
+ err = notify_change(fp->f_path.dentry, NULL, &newattrs);
|
||||
if (err)
|
||||
goto out_filp;
|
||||
|
||||
@@ -825,7 +825,7 @@ reiserfs_chown_xattrs_filler(void *buf,
|
||||
}
|
||||
|
||||
if (!S_ISDIR(xafile->d_inode->i_mode))
|
||||
- err = notify_change(xafile, attrs);
|
||||
+ err = notify_change(xafile, NULL, attrs);
|
||||
dput(xafile);
|
||||
|
||||
return err;
|
||||
@@ -877,7 +877,7 @@ int reiserfs_chown_xattrs(struct inode *
|
||||
goto out_dir;
|
||||
}
|
||||
|
||||
- err = notify_change(dir, attrs);
|
||||
+ err = notify_change(dir, NULL, attrs);
|
||||
unlock_kernel();
|
||||
|
||||
out_dir:
|
||||
--- a/fs/sysfs/file.c
|
||||
+++ b/fs/sysfs/file.c
|
||||
@@ -610,7 +610,7 @@ int sysfs_chmod_file(struct kobject *kob
|
||||
|
||||
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
|
||||
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
|
||||
- rc = notify_change(victim, &newattrs);
|
||||
+ rc = notify_change(victim, NULL, &newattrs);
|
||||
|
||||
if (rc == 0) {
|
||||
mutex_lock(&sysfs_mutex);
|
||||
--- a/fs/utimes.c
|
||||
+++ b/fs/utimes.c
|
||||
@@ -54,7 +54,7 @@ long do_utimes(int dfd, char __user *fil
|
||||
{
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
- struct dentry *dentry;
|
||||
+ struct path path;
|
||||
struct inode *inode;
|
||||
struct iattr newattrs;
|
||||
struct file *f = NULL;
|
||||
@@ -77,16 +77,17 @@ long do_utimes(int dfd, char __user *fil
|
||||
f = fget(dfd);
|
||||
if (!f)
|
||||
goto out;
|
||||
- dentry = f->f_path.dentry;
|
||||
+ path = f->f_path;
|
||||
} else {
|
||||
error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
- dentry = nd.dentry;
|
||||
+ path.dentry = nd.dentry;
|
||||
+ path.mnt = nd.mnt;
|
||||
}
|
||||
|
||||
- inode = dentry->d_inode;
|
||||
+ inode = path.dentry->d_inode;
|
||||
|
||||
error = -EROFS;
|
||||
if (IS_RDONLY(inode))
|
||||
@@ -131,7 +132,7 @@ long do_utimes(int dfd, char __user *fil
|
||||
}
|
||||
}
|
||||
mutex_lock(&inode->i_mutex);
|
||||
- error = notify_change(dentry, &newattrs);
|
||||
+ error = notify_change(path.dentry, path.mnt, &newattrs);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
dput_and_out:
|
||||
if (f)
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -1536,8 +1536,8 @@ static inline int break_lease(struct ino
|
||||
|
||||
/* fs/open.c */
|
||||
|
||||
-extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
|
||||
- struct file *filp);
|
||||
+extern int do_truncate(struct dentry *, struct vfsmount *, loff_t start,
|
||||
+ unsigned int time_attrs, struct file *filp);
|
||||
extern long do_sys_open(int dfd, const char __user *filename, int flags,
|
||||
int mode);
|
||||
extern struct file *filp_open(const char *, int, int);
|
||||
@@ -1693,7 +1693,7 @@ extern int do_remount_sb(struct super_bl
|
||||
#ifdef CONFIG_BLOCK
|
||||
extern sector_t bmap(struct inode *, sector_t);
|
||||
#endif
|
||||
-extern int notify_change(struct dentry *, struct iattr *);
|
||||
+extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *);
|
||||
extern int permission(struct inode *, int, struct nameidata *);
|
||||
extern int generic_permission(struct inode *, int,
|
||||
int (*check_acl)(struct inode *, int));
|
||||
--- a/mm/filemap.c
|
||||
+++ b/mm/filemap.c
|
||||
@@ -1615,7 +1615,7 @@ int __remove_suid(struct path *path, int
|
||||
struct iattr newattrs;
|
||||
|
||||
newattrs.ia_valid = ATTR_FORCE | kill;
|
||||
- return notify_change(path->dentry, &newattrs);
|
||||
+ return notify_change(path->dentry, path->mnt, &newattrs);
|
||||
}
|
||||
|
||||
int remove_suid(struct path *path)
|
||||
--- a/mm/tiny-shmem.c
|
||||
+++ b/mm/tiny-shmem.c
|
||||
@@ -81,7 +81,7 @@ struct file *shmem_file_setup(char *name
|
||||
inode->i_nlink = 0; /* It is unlinked */
|
||||
|
||||
/* notify everyone as to the change of file size */
|
||||
- error = do_truncate(dentry, size, 0, file);
|
||||
+ error = do_truncate(dentry, file->f_path.mnt, size, 0, file);
|
||||
if (error < 0)
|
||||
goto close_file;
|
||||
|
111
kernel-patches/2.6.24/vfs-removexattr.diff
Normal file
111
kernel-patches/2.6.24/vfs-removexattr.diff
Normal file
@@ -0,0 +1,111 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add a struct vfsmount parameter to vfs_removexattr()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/nfsd/vfs.c | 7 ++++---
|
||||
fs/xattr.c | 12 ++++++------
|
||||
include/linux/xattr.h | 2 +-
|
||||
3 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -2016,6 +2016,7 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i
|
||||
int
|
||||
nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
|
||||
{
|
||||
+ struct vfsmount *mnt;
|
||||
struct inode *inode = fhp->fh_dentry->d_inode;
|
||||
char *name;
|
||||
void *value = NULL;
|
||||
@@ -2048,14 +2049,14 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
|
||||
} else
|
||||
size = 0;
|
||||
|
||||
+ mnt = fhp->fh_export->ex_mnt;
|
||||
if (size)
|
||||
- error = vfs_setxattr(fhp->fh_dentry, fhp->fh_export->ex_mnt,
|
||||
- name, value, size,0);
|
||||
+ error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size,0);
|
||||
else {
|
||||
if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
|
||||
error = 0;
|
||||
else {
|
||||
- error = vfs_removexattr(fhp->fh_dentry, name);
|
||||
+ error = vfs_removexattr(fhp->fh_dentry, mnt, name);
|
||||
if (error == -ENODATA)
|
||||
error = 0;
|
||||
}
|
||||
--- a/fs/xattr.c
|
||||
+++ b/fs/xattr.c
|
||||
@@ -164,7 +164,7 @@ vfs_listxattr(struct dentry *dentry, str
|
||||
EXPORT_SYMBOL_GPL(vfs_listxattr);
|
||||
|
||||
int
|
||||
-vfs_removexattr(struct dentry *dentry, char *name)
|
||||
+vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, char *name)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
@@ -437,7 +437,7 @@ sys_flistxattr(int fd, char __user *list
|
||||
* Extended attribute REMOVE operations
|
||||
*/
|
||||
static long
|
||||
-removexattr(struct dentry *d, char __user *name)
|
||||
+removexattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name)
|
||||
{
|
||||
int error;
|
||||
char kname[XATTR_NAME_MAX + 1];
|
||||
@@ -448,7 +448,7 @@ removexattr(struct dentry *d, char __use
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
- return vfs_removexattr(d, kname);
|
||||
+ return vfs_removexattr(dentry, mnt, kname);
|
||||
}
|
||||
|
||||
asmlinkage long
|
||||
@@ -460,7 +460,7 @@ sys_removexattr(char __user *path, char
|
||||
error = user_path_walk(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = removexattr(nd.dentry, name);
|
||||
+ error = removexattr(nd.dentry, nd.mnt, name);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -474,7 +474,7 @@ sys_lremovexattr(char __user *path, char
|
||||
error = user_path_walk_link(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = removexattr(nd.dentry, name);
|
||||
+ error = removexattr(nd.dentry, nd.mnt, name);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -491,7 +491,7 @@ sys_fremovexattr(int fd, char __user *na
|
||||
return error;
|
||||
dentry = f->f_path.dentry;
|
||||
audit_inode(NULL, dentry);
|
||||
- error = removexattr(dentry, name);
|
||||
+ error = removexattr(dentry, f->f_path.mnt, name);
|
||||
fput(f);
|
||||
return error;
|
||||
}
|
||||
--- a/include/linux/xattr.h
|
||||
+++ b/include/linux/xattr.h
|
||||
@@ -52,7 +52,7 @@ ssize_t vfs_listxattr(struct dentry *d,
|
||||
size_t size);
|
||||
int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t,
|
||||
int);
|
||||
-int vfs_removexattr(struct dentry *, char *);
|
||||
+int vfs_removexattr(struct dentry *, struct vfsmount *, char *);
|
||||
|
||||
ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
|
||||
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
|
125
kernel-patches/2.6.24/vfs-rename.diff
Normal file
125
kernel-patches/2.6.24/vfs-rename.diff
Normal file
@@ -0,0 +1,125 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add struct vfsmount parameters to vfs_rename()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/ecryptfs/inode.c | 7 ++++++-
|
||||
fs/namei.c | 19 ++++++++++++-------
|
||||
fs/nfsd/vfs.c | 3 ++-
|
||||
include/linux/fs.h | 2 +-
|
||||
4 files changed, 21 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/fs/ecryptfs/inode.c
|
||||
+++ b/fs/ecryptfs/inode.c
|
||||
@@ -589,19 +589,24 @@ ecryptfs_rename(struct inode *old_dir, s
|
||||
{
|
||||
int rc;
|
||||
struct dentry *lower_old_dentry;
|
||||
+ struct vfsmount *lower_old_mnt;
|
||||
struct dentry *lower_new_dentry;
|
||||
+ struct vfsmount *lower_new_mnt;
|
||||
struct dentry *lower_old_dir_dentry;
|
||||
struct dentry *lower_new_dir_dentry;
|
||||
|
||||
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
|
||||
+ lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry);
|
||||
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
|
||||
+ lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
|
||||
dget(lower_old_dentry);
|
||||
dget(lower_new_dentry);
|
||||
lower_old_dir_dentry = dget_parent(lower_old_dentry);
|
||||
lower_new_dir_dentry = dget_parent(lower_new_dentry);
|
||||
lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
|
||||
rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
|
||||
- lower_new_dir_dentry->d_inode, lower_new_dentry);
|
||||
+ lower_old_mnt, lower_new_dir_dentry->d_inode,
|
||||
+ lower_new_dentry, lower_new_mnt);
|
||||
if (rc)
|
||||
goto out_lock;
|
||||
fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL);
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2464,7 +2464,8 @@ asmlinkage long sys_link(const char __us
|
||||
* locking].
|
||||
*/
|
||||
static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
|
||||
- struct inode *new_dir, struct dentry *new_dentry)
|
||||
+ struct vfsmount *old_mnt, struct inode *new_dir,
|
||||
+ struct dentry *new_dentry, struct vfsmount *new_mnt)
|
||||
{
|
||||
int error = 0;
|
||||
struct inode *target;
|
||||
@@ -2507,7 +2508,8 @@ static int vfs_rename_dir(struct inode *
|
||||
}
|
||||
|
||||
static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
|
||||
- struct inode *new_dir, struct dentry *new_dentry)
|
||||
+ struct vfsmount *old_mnt, struct inode *new_dir,
|
||||
+ struct dentry *new_dentry, struct vfsmount *new_mnt)
|
||||
{
|
||||
struct inode *target;
|
||||
int error;
|
||||
@@ -2535,7 +2537,8 @@ static int vfs_rename_other(struct inode
|
||||
}
|
||||
|
||||
int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
- struct inode *new_dir, struct dentry *new_dentry)
|
||||
+ struct vfsmount *old_mnt, struct inode *new_dir,
|
||||
+ struct dentry *new_dentry, struct vfsmount *new_mnt)
|
||||
{
|
||||
int error;
|
||||
int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
|
||||
@@ -2564,9 +2567,11 @@ int vfs_rename(struct inode *old_dir, st
|
||||
old_name = fsnotify_oldname_init(old_dentry->d_name.name);
|
||||
|
||||
if (is_dir)
|
||||
- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
|
||||
+ error = vfs_rename_dir(old_dir, old_dentry, old_mnt,
|
||||
+ new_dir, new_dentry, new_mnt);
|
||||
else
|
||||
- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
|
||||
+ error = vfs_rename_other(old_dir, old_dentry, old_mnt,
|
||||
+ new_dir, new_dentry, new_mnt);
|
||||
if (!error) {
|
||||
const char *new_name = old_dentry->d_name.name;
|
||||
fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
|
||||
@@ -2638,8 +2643,8 @@ static int do_rename(int olddfd, const c
|
||||
if (new_dentry == trap)
|
||||
goto exit5;
|
||||
|
||||
- error = vfs_rename(old_dir->d_inode, old_dentry,
|
||||
- new_dir->d_inode, new_dentry);
|
||||
+ error = vfs_rename(old_dir->d_inode, old_dentry, oldnd.mnt,
|
||||
+ new_dir->d_inode, new_dentry, newnd.mnt);
|
||||
exit5:
|
||||
dput(new_dentry);
|
||||
exit4:
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -1683,7 +1683,8 @@ nfsd_rename(struct svc_rqst *rqstp, stru
|
||||
host_err = -EPERM;
|
||||
} else
|
||||
#endif
|
||||
- host_err = vfs_rename(fdir, odentry, tdir, ndentry);
|
||||
+ host_err = vfs_rename(fdir, odentry, ffhp->fh_export->ex_mnt,
|
||||
+ tdir, ndentry, tfhp->fh_export->ex_mnt);
|
||||
if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
|
||||
host_err = nfsd_sync_dir(tdentry);
|
||||
if (!host_err)
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -1074,7 +1074,7 @@ extern int vfs_symlink(struct inode *, s
|
||||
extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
|
||||
extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *);
|
||||
extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *);
|
||||
-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
|
||||
+extern int vfs_rename(struct inode *, struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
|
||||
|
||||
/*
|
||||
* VFS dentry helper functions.
|
135
kernel-patches/2.6.24/vfs-rmdir.diff
Normal file
135
kernel-patches/2.6.24/vfs-rmdir.diff
Normal file
@@ -0,0 +1,135 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add a struct vfsmount parameter to vfs_rmdir()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/ecryptfs/inode.c | 4 +++-
|
||||
fs/namei.c | 4 ++--
|
||||
fs/nfsd/nfs4recover.c | 2 +-
|
||||
fs/nfsd/vfs.c | 8 +++++---
|
||||
fs/reiserfs/xattr.c | 2 +-
|
||||
include/linux/fs.h | 2 +-
|
||||
6 files changed, 13 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/fs/ecryptfs/inode.c
|
||||
+++ b/fs/ecryptfs/inode.c
|
||||
@@ -533,14 +533,16 @@ out:
|
||||
static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
{
|
||||
struct dentry *lower_dentry;
|
||||
+ struct vfsmount *lower_mnt;
|
||||
struct dentry *lower_dir_dentry;
|
||||
int rc;
|
||||
|
||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
|
||||
dget(dentry);
|
||||
lower_dir_dentry = lock_parent(lower_dentry);
|
||||
dget(lower_dentry);
|
||||
- rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
|
||||
+ rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt);
|
||||
dput(lower_dentry);
|
||||
if (!rc)
|
||||
d_delete(lower_dentry);
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2087,7 +2087,7 @@ void dentry_unhash(struct dentry *dentry
|
||||
spin_unlock(&dcache_lock);
|
||||
}
|
||||
|
||||
-int vfs_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
+int vfs_rmdir(struct inode *dir, struct dentry *dentry,struct vfsmount *mnt)
|
||||
{
|
||||
int error = may_delete(dir, dentry, 1);
|
||||
|
||||
@@ -2151,7 +2151,7 @@ static long do_rmdir(int dfd, const char
|
||||
error = PTR_ERR(dentry);
|
||||
if (IS_ERR(dentry))
|
||||
goto exit2;
|
||||
- error = vfs_rmdir(nd.dentry->d_inode, dentry);
|
||||
+ error = vfs_rmdir(nd.dentry->d_inode, dentry, nd.mnt);
|
||||
dput(dentry);
|
||||
exit2:
|
||||
mutex_unlock(&nd.dentry->d_inode->i_mutex);
|
||||
--- a/fs/nfsd/nfs4recover.c
|
||||
+++ b/fs/nfsd/nfs4recover.c
|
||||
@@ -274,7 +274,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
|
||||
* a kernel from the future.... */
|
||||
nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
|
||||
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
|
||||
- status = vfs_rmdir(dir->d_inode, dentry);
|
||||
+ status = vfs_rmdir(dir->d_inode, dentry, rec_dir.mnt);
|
||||
mutex_unlock(&dir->d_inode->i_mutex);
|
||||
return status;
|
||||
}
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -1719,6 +1719,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
|
||||
char *fname, int flen)
|
||||
{
|
||||
struct dentry *dentry, *rdentry;
|
||||
+ struct svc_export *exp;
|
||||
struct inode *dirp;
|
||||
__be32 err;
|
||||
int host_err;
|
||||
@@ -1733,6 +1734,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
|
||||
fh_lock_nested(fhp, I_MUTEX_PARENT);
|
||||
dentry = fhp->fh_dentry;
|
||||
dirp = dentry->d_inode;
|
||||
+ exp = fhp->fh_export;
|
||||
|
||||
rdentry = lookup_one_len(fname, dentry, flen);
|
||||
host_err = PTR_ERR(rdentry);
|
||||
@@ -1750,21 +1752,21 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
|
||||
|
||||
if (type != S_IFDIR) { /* It's UNLINK */
|
||||
#ifdef MSNFS
|
||||
- if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
|
||||
+ if ((exp->ex_flags & NFSEXP_MSNFS) &&
|
||||
(atomic_read(&rdentry->d_count) > 1)) {
|
||||
host_err = -EPERM;
|
||||
} else
|
||||
#endif
|
||||
host_err = vfs_unlink(dirp, rdentry);
|
||||
} else { /* It's RMDIR */
|
||||
- host_err = vfs_rmdir(dirp, rdentry);
|
||||
+ host_err = vfs_rmdir(dirp, rdentry, exp->ex_mnt);
|
||||
}
|
||||
|
||||
dput(rdentry);
|
||||
|
||||
if (host_err)
|
||||
goto out_nfserr;
|
||||
- if (EX_ISSYNC(fhp->fh_export))
|
||||
+ if (EX_ISSYNC(exp))
|
||||
host_err = nfsd_sync_dir(dentry);
|
||||
|
||||
out_nfserr:
|
||||
--- a/fs/reiserfs/xattr.c
|
||||
+++ b/fs/reiserfs/xattr.c
|
||||
@@ -781,7 +781,7 @@ int reiserfs_delete_xattrs(struct inode
|
||||
if (dir->d_inode->i_nlink <= 2) {
|
||||
root = get_xa_root(inode->i_sb, XATTR_REPLACE);
|
||||
reiserfs_write_lock_xattrs(inode->i_sb);
|
||||
- err = vfs_rmdir(root->d_inode, dir);
|
||||
+ err = vfs_rmdir(root->d_inode, dir, NULL);
|
||||
reiserfs_write_unlock_xattrs(inode->i_sb);
|
||||
dput(root);
|
||||
} else {
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -1072,7 +1072,7 @@ extern int vfs_mkdir(struct inode *, str
|
||||
extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t);
|
||||
extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int);
|
||||
extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
|
||||
-extern int vfs_rmdir(struct inode *, struct dentry *);
|
||||
+extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *);
|
||||
extern int vfs_unlink(struct inode *, struct dentry *);
|
||||
extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
|
||||
|
152
kernel-patches/2.6.24/vfs-setxattr.diff
Normal file
152
kernel-patches/2.6.24/vfs-setxattr.diff
Normal file
@@ -0,0 +1,152 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add a struct vfsmount parameter to vfs_setxattr()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/nfsd/vfs.c | 16 +++++++++++-----
|
||||
fs/xattr.c | 16 ++++++++--------
|
||||
include/linux/xattr.h | 3 ++-
|
||||
3 files changed, 21 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -426,7 +426,8 @@ static ssize_t nfsd_getxattr(struct dent
|
||||
|
||||
#if defined(CONFIG_NFSD_V4)
|
||||
static int
|
||||
-set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
|
||||
+set_nfsv4_acl_one(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ struct posix_acl *pacl, char *key)
|
||||
{
|
||||
int len;
|
||||
size_t buflen;
|
||||
@@ -445,7 +446,7 @@ set_nfsv4_acl_one(struct dentry *dentry,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- error = vfs_setxattr(dentry, key, buf, len, 0);
|
||||
+ error = vfs_setxattr(dentry, mnt, key, buf, len, 0);
|
||||
out:
|
||||
kfree(buf);
|
||||
return error;
|
||||
@@ -458,6 +459,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
|
||||
__be32 error;
|
||||
int host_error;
|
||||
struct dentry *dentry;
|
||||
+ struct vfsmount *mnt;
|
||||
struct inode *inode;
|
||||
struct posix_acl *pacl = NULL, *dpacl = NULL;
|
||||
unsigned int flags = 0;
|
||||
@@ -468,6 +470,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
|
||||
return error;
|
||||
|
||||
dentry = fhp->fh_dentry;
|
||||
+ mnt = fhp->fh_export->ex_mnt;
|
||||
inode = dentry->d_inode;
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
flags = NFS4_ACL_DIR;
|
||||
@@ -478,12 +481,14 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
|
||||
} else if (host_error < 0)
|
||||
goto out_nfserr;
|
||||
|
||||
- host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
|
||||
+ host_error = set_nfsv4_acl_one(dentry, mnt, pacl,
|
||||
+ POSIX_ACL_XATTR_ACCESS);
|
||||
if (host_error < 0)
|
||||
goto out_release;
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
- host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
|
||||
+ host_error = set_nfsv4_acl_one(dentry, mnt, dpacl,
|
||||
+ POSIX_ACL_XATTR_DEFAULT);
|
||||
|
||||
out_release:
|
||||
posix_acl_release(pacl);
|
||||
@@ -2041,7 +2046,8 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
|
||||
size = 0;
|
||||
|
||||
if (size)
|
||||
- error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0);
|
||||
+ error = vfs_setxattr(fhp->fh_dentry, fhp->fh_export->ex_mnt,
|
||||
+ name, value, size,0);
|
||||
else {
|
||||
if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
|
||||
error = 0;
|
||||
--- a/fs/xattr.c
|
||||
+++ b/fs/xattr.c
|
||||
@@ -68,8 +68,8 @@ xattr_permission(struct inode *inode, co
|
||||
}
|
||||
|
||||
int
|
||||
-vfs_setxattr(struct dentry *dentry, char *name, void *value,
|
||||
- size_t size, int flags)
|
||||
+vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, char *name,
|
||||
+ void *value, size_t size, int flags)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
int error;
|
||||
@@ -192,8 +192,8 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
|
||||
* Extended attribute SET operations
|
||||
*/
|
||||
static long
|
||||
-setxattr(struct dentry *d, char __user *name, void __user *value,
|
||||
- size_t size, int flags)
|
||||
+setxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *name,
|
||||
+ void __user *value, size_t size, int flags)
|
||||
{
|
||||
int error;
|
||||
void *kvalue = NULL;
|
||||
@@ -220,7 +220,7 @@ setxattr(struct dentry *d, char __user *
|
||||
}
|
||||
}
|
||||
|
||||
- error = vfs_setxattr(d, kname, kvalue, size, flags);
|
||||
+ error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags);
|
||||
kfree(kvalue);
|
||||
return error;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ sys_setxattr(char __user *path, char __u
|
||||
error = user_path_walk(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = setxattr(nd.dentry, name, value, size, flags);
|
||||
+ error = setxattr(nd.dentry, nd.mnt, name, value, size, flags);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -250,7 +250,7 @@ sys_lsetxattr(char __user *path, char __
|
||||
error = user_path_walk_link(path, &nd);
|
||||
if (error)
|
||||
return error;
|
||||
- error = setxattr(nd.dentry, name, value, size, flags);
|
||||
+ error = setxattr(nd.dentry, nd.mnt, name, value, size, flags);
|
||||
path_release(&nd);
|
||||
return error;
|
||||
}
|
||||
@@ -268,7 +268,7 @@ sys_fsetxattr(int fd, char __user *name,
|
||||
return error;
|
||||
dentry = f->f_path.dentry;
|
||||
audit_inode(NULL, dentry);
|
||||
- error = setxattr(dentry, name, value, size, flags);
|
||||
+ error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags);
|
||||
fput(f);
|
||||
return error;
|
||||
}
|
||||
--- a/include/linux/xattr.h
|
||||
+++ b/include/linux/xattr.h
|
||||
@@ -48,7 +48,8 @@ struct xattr_handler {
|
||||
|
||||
ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
|
||||
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
|
||||
-int vfs_setxattr(struct dentry *, char *, void *, size_t, int);
|
||||
+int vfs_setxattr(struct dentry *, struct vfsmount *, char *, void *, size_t,
|
||||
+ int);
|
||||
int vfs_removexattr(struct dentry *, char *);
|
||||
|
||||
ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
|
122
kernel-patches/2.6.24/vfs-symlink.diff
Normal file
122
kernel-patches/2.6.24/vfs-symlink.diff
Normal file
@@ -0,0 +1,122 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add a struct vfsmount parameter to vfs_symlink()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/ecryptfs/inode.c | 4 +++-
|
||||
fs/namei.c | 6 ++++--
|
||||
fs/nfsd/vfs.c | 12 ++++++++----
|
||||
include/linux/fs.h | 2 +-
|
||||
4 files changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/fs/ecryptfs/inode.c 2007-11-01 16:43:54.000000000 -0400
|
||||
+++ b/fs/ecryptfs/inode.c 2007-11-01 16:47:29.000000000 -0400
|
||||
@@ -461,6 +461,7 @@ static int ecryptfs_symlink(struct inode
|
||||
{
|
||||
int rc;
|
||||
struct dentry *lower_dentry;
|
||||
+ struct vfsmount *lower_mnt;
|
||||
struct dentry *lower_dir_dentry;
|
||||
umode_t mode;
|
||||
char *encoded_symname;
|
||||
@@ -469,6 +470,7 @@ static int ecryptfs_symlink(struct inode
|
||||
|
||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
dget(lower_dentry);
|
||||
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
|
||||
lower_dir_dentry = lock_parent(lower_dentry);
|
||||
mode = S_IALLUGO;
|
||||
encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname,
|
||||
@@ -478,7 +480,7 @@ static int ecryptfs_symlink(struct inode
|
||||
rc = encoded_symlen;
|
||||
goto out_lock;
|
||||
}
|
||||
- rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
|
||||
+ rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, lower_mnt,
|
||||
encoded_symname, mode);
|
||||
kfree(encoded_symname);
|
||||
if (rc || !lower_dentry->d_inode)
|
||||
--- a/fs/namei.c 2007-11-01 16:47:26.000000000 -0400
|
||||
+++ b/fs/namei.c 2007-11-01 16:47:29.000000000 -0400
|
||||
@@ -2266,7 +2266,8 @@ asmlinkage long sys_unlink(const char __
|
||||
return do_unlinkat(AT_FDCWD, pathname);
|
||||
}
|
||||
|
||||
-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
|
||||
+int vfs_symlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ const char *oldname, int mode)
|
||||
{
|
||||
int error = may_create(dir, dentry, NULL);
|
||||
|
||||
@@ -2312,7 +2313,8 @@ asmlinkage long sys_symlinkat(const char
|
||||
if (IS_ERR(dentry))
|
||||
goto out_unlock;
|
||||
|
||||
- error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
|
||||
+ error = vfs_symlink(nd.dentry->d_inode, dentry, nd.mnt, from,
|
||||
+ S_IALLUGO);
|
||||
dput(dentry);
|
||||
out_unlock:
|
||||
mutex_unlock(&nd.dentry->d_inode->i_mutex);
|
||||
--- a/fs/nfsd/vfs.c 2007-11-01 16:43:54.000000000 -0400
|
||||
+++ b/fs/nfsd/vfs.c 2007-11-01 16:47:29.000000000 -0400
|
||||
@@ -1489,6 +1489,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
|
||||
struct iattr *iap)
|
||||
{
|
||||
struct dentry *dentry, *dnew;
|
||||
+ struct svc_export *exp;
|
||||
__be32 err, cerr;
|
||||
int host_err;
|
||||
umode_t mode;
|
||||
@@ -1515,6 +1516,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
|
||||
if (iap && (iap->ia_valid & ATTR_MODE))
|
||||
mode = iap->ia_mode & S_IALLUGO;
|
||||
|
||||
+ exp = fhp->fh_export;
|
||||
if (unlikely(path[plen] != 0)) {
|
||||
char *path_alloced = kmalloc(plen+1, GFP_KERNEL);
|
||||
if (path_alloced == NULL)
|
||||
@@ -1522,20 +1524,22 @@ nfsd_symlink(struct svc_rqst *rqstp, str
|
||||
else {
|
||||
strncpy(path_alloced, path, plen);
|
||||
path_alloced[plen] = 0;
|
||||
- host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
|
||||
+ host_err = vfs_symlink(dentry->d_inode, dnew,
|
||||
+ exp->ex_mnt, path_alloced, mode);
|
||||
kfree(path_alloced);
|
||||
}
|
||||
} else
|
||||
- host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
|
||||
+ host_err = vfs_symlink(dentry->d_inode, dnew, exp->ex_mnt, path,
|
||||
+ mode);
|
||||
|
||||
if (!host_err) {
|
||||
- if (EX_ISSYNC(fhp->fh_export))
|
||||
+ if (EX_ISSYNC(exp))
|
||||
host_err = nfsd_sync_dir(dentry);
|
||||
}
|
||||
err = nfserrno(host_err);
|
||||
fh_unlock(fhp);
|
||||
|
||||
- cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp);
|
||||
+ cerr = fh_compose(resfhp, exp, dnew, fhp);
|
||||
dput(dnew);
|
||||
if (err==0) err = cerr;
|
||||
out:
|
||||
--- a/include/linux/fs.h 2007-11-01 16:43:54.000000000 -0400
|
||||
+++ b/include/linux/fs.h 2007-11-01 16:47:29.000000000 -0400
|
||||
@@ -1070,7 +1070,7 @@ extern int vfs_permission(struct nameida
|
||||
extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
|
||||
extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int);
|
||||
extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t);
|
||||
-extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
|
||||
+extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int);
|
||||
extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
|
||||
extern int vfs_rmdir(struct inode *, struct dentry *);
|
||||
extern int vfs_unlink(struct inode *, struct dentry *);
|
98
kernel-patches/2.6.24/vfs-unlink.diff
Normal file
98
kernel-patches/2.6.24/vfs-unlink.diff
Normal file
@@ -0,0 +1,98 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Add a struct vfsmount parameter to vfs_unlink()
|
||||
|
||||
The vfsmount will be passed down to the LSM hook so that LSMs can compute
|
||||
pathnames.
|
||||
|
||||
Signed-off-by: Tony Jones <tonyj@suse.de>
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/ecryptfs/inode.c | 3 ++-
|
||||
fs/namei.c | 4 ++--
|
||||
fs/nfsd/nfs4recover.c | 2 +-
|
||||
fs/nfsd/vfs.c | 2 +-
|
||||
include/linux/fs.h | 2 +-
|
||||
ipc/mqueue.c | 2 +-
|
||||
6 files changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/fs/ecryptfs/inode.c
|
||||
+++ b/fs/ecryptfs/inode.c
|
||||
@@ -444,10 +444,11 @@ static int ecryptfs_unlink(struct inode
|
||||
{
|
||||
int rc = 0;
|
||||
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
+ struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
|
||||
struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
|
||||
|
||||
lock_parent(lower_dentry);
|
||||
- rc = vfs_unlink(lower_dir_inode, lower_dentry);
|
||||
+ rc = vfs_unlink(lower_dir_inode, lower_dentry, lower_mnt);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
|
||||
goto out_unlock;
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2168,7 +2168,7 @@ asmlinkage long sys_rmdir(const char __u
|
||||
return do_rmdir(AT_FDCWD, pathname);
|
||||
}
|
||||
|
||||
-int vfs_unlink(struct inode *dir, struct dentry *dentry)
|
||||
+int vfs_unlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
int error = may_delete(dir, dentry, 0);
|
||||
|
||||
@@ -2232,7 +2232,7 @@ static long do_unlinkat(int dfd, const c
|
||||
inode = dentry->d_inode;
|
||||
if (inode)
|
||||
atomic_inc(&inode->i_count);
|
||||
- error = vfs_unlink(nd.dentry->d_inode, dentry);
|
||||
+ error = vfs_unlink(nd.dentry->d_inode, dentry, nd.mnt);
|
||||
exit2:
|
||||
dput(dentry);
|
||||
}
|
||||
--- a/fs/nfsd/nfs4recover.c
|
||||
+++ b/fs/nfsd/nfs4recover.c
|
||||
@@ -259,7 +259,7 @@ nfsd4_remove_clid_file(struct dentry *di
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
|
||||
- status = vfs_unlink(dir->d_inode, dentry);
|
||||
+ status = vfs_unlink(dir->d_inode, dentry, rec_dir.mnt);
|
||||
mutex_unlock(&dir->d_inode->i_mutex);
|
||||
return status;
|
||||
}
|
||||
--- a/fs/nfsd/vfs.c
|
||||
+++ b/fs/nfsd/vfs.c
|
||||
@@ -1757,7 +1757,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
|
||||
host_err = -EPERM;
|
||||
} else
|
||||
#endif
|
||||
- host_err = vfs_unlink(dirp, rdentry);
|
||||
+ host_err = vfs_unlink(dirp, rdentry, exp->ex_mnt);
|
||||
} else { /* It's RMDIR */
|
||||
host_err = vfs_rmdir(dirp, rdentry, exp->ex_mnt);
|
||||
}
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -1073,7 +1073,7 @@ extern int vfs_mknod(struct inode *, str
|
||||
extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *, int);
|
||||
extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *);
|
||||
extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *);
|
||||
-extern int vfs_unlink(struct inode *, struct dentry *);
|
||||
+extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *);
|
||||
extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
|
||||
|
||||
/*
|
||||
--- a/ipc/mqueue.c
|
||||
+++ b/ipc/mqueue.c
|
||||
@@ -744,7 +744,7 @@ asmlinkage long sys_mq_unlink(const char
|
||||
if (inode)
|
||||
atomic_inc(&inode->i_count);
|
||||
|
||||
- err = vfs_unlink(dentry->d_parent->d_inode, dentry);
|
||||
+ err = vfs_unlink(dentry->d_parent->d_inode, dentry, mqueue_mnt);
|
||||
out_err:
|
||||
dput(dentry);
|
||||
|
139
kernel-patches/2.6.25/__d_path-keep-connected.diff
Normal file
139
kernel-patches/2.6.25/__d_path-keep-connected.diff
Normal file
@@ -0,0 +1,139 @@
|
||||
From: John Johansen <jjohansen@suse.de>
|
||||
Subject: Fix __d_path to allow for old and new behavior bnc#380763
|
||||
|
||||
Fix __d_path so that it can be told whether or not to connect
|
||||
disconnect path to the root. This is easier and more efficient
|
||||
than trying to reconnect these paths for d_path and get_cwd
|
||||
after the fact.
|
||||
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
fs/dcache.c | 56 ++++++++++++++++++-------------------------------
|
||||
fs/namespace.c | 2 -
|
||||
include/linux/dcache.h | 2 -
|
||||
3 files changed, 23 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -1755,6 +1755,7 @@ shouldnt_be_hashed:
|
||||
* @buffer: buffer to return value in
|
||||
* @buflen: buffer length
|
||||
* @fail_deleted: what to return for deleted files
|
||||
+ * @disconnect: don't return a path starting with / when disconnected
|
||||
*
|
||||
* Convert a dentry into an ASCII path name. If the entry has been deleted,
|
||||
* then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise,
|
||||
@@ -1768,9 +1769,10 @@ shouldnt_be_hashed:
|
||||
*/
|
||||
char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
struct path *root, char *buffer, int buflen,
|
||||
- int fail_deleted)
|
||||
+ int fail_deleted, int disconnect)
|
||||
{
|
||||
- int namelen, is_slash, vfsmount_locked = 0;
|
||||
+ int namelen, vfsmount_locked = 0;
|
||||
+ const unsigned char *name;
|
||||
|
||||
if (buflen < 2)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
@@ -1832,22 +1834,21 @@ global_root:
|
||||
* unconnected dentry, or the file is on a pseudo filesystem.
|
||||
*/
|
||||
namelen = dentry->d_name.len;
|
||||
- is_slash = (namelen == 1 && *dentry->d_name.name == '/');
|
||||
- if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) {
|
||||
- /*
|
||||
- * Make sure we won't return a pathname starting with '/'.
|
||||
- *
|
||||
- * Historically, we also glue together the root dentry and
|
||||
- * remaining name for pseudo filesystems like pipefs, which
|
||||
- * have the MS_NOUSER flag set. This results in pathnames
|
||||
- * like "pipe:[439336]".
|
||||
- */
|
||||
- if (*buffer == '/') {
|
||||
- buffer++;
|
||||
- buflen++;
|
||||
- }
|
||||
- if (is_slash)
|
||||
- goto out;
|
||||
+ name = dentry->d_name.name;
|
||||
+
|
||||
+ /*
|
||||
+ * If this is a root dentry, then overwrite the slash. This
|
||||
+ * will also DTRT with pseudo filesystems which have root
|
||||
+ * dentries named "foo:".
|
||||
+ */
|
||||
+ if (IS_ROOT(dentry)) {
|
||||
+ buffer++;
|
||||
+ buflen++;
|
||||
+ }
|
||||
+ if (disconnect && *name == '/') {
|
||||
+ /* Make sure we won't return a pathname starting with '/' */
|
||||
+ name++;
|
||||
+ namelen--;
|
||||
}
|
||||
if (buflen < namelen)
|
||||
goto Elong;
|
||||
@@ -1860,19 +1861,6 @@ Elong:
|
||||
goto out;
|
||||
}
|
||||
|
||||
-static char *__connect_d_path(char *path, char *buffer, struct dentry *dentry)
|
||||
-{
|
||||
- if (!IS_ERR(path) && *path != '/' &&
|
||||
- !(dentry->d_sb->s_flags & MS_NOUSER)) {
|
||||
- /* Pretend that disconnected paths are hanging off the root. */
|
||||
- if (path == buffer)
|
||||
- path = ERR_PTR(-ENAMETOOLONG);
|
||||
- else
|
||||
- *--path = '/';
|
||||
- }
|
||||
- return path;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* d_path - return the path of a dentry
|
||||
* @path: path to report
|
||||
@@ -1905,8 +1893,7 @@ char *d_path(struct path *path, char *bu
|
||||
root = current->fs->root;
|
||||
path_get(¤t->fs->root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
- res = __d_path(path->dentry, path->mnt, &root, buf, buflen, 0);
|
||||
- res = __connect_d_path(res, buf, path->dentry);
|
||||
+ res = __d_path(path->dentry, path->mnt, &root, buf, buflen, 0, 0);
|
||||
path_put(&root);
|
||||
return res;
|
||||
}
|
||||
@@ -1966,8 +1953,7 @@ asmlinkage long sys_getcwd(char __user *
|
||||
path_get(¤t->fs->root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
|
||||
- cwd = __d_path(pwd.dentry, pwd.mnt, &root, page, PAGE_SIZE, 1);
|
||||
- cwd = __connect_d_path(cwd, page, pwd.dentry);
|
||||
+ cwd = __d_path(pwd.dentry, pwd.mnt, &root, page, PAGE_SIZE, 1, 0);
|
||||
error = PTR_ERR(cwd);
|
||||
if (IS_ERR(cwd))
|
||||
goto out;
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -1869,7 +1869,7 @@ char *d_namespace_path(struct dentry *de
|
||||
if (ns_root.mnt)
|
||||
ns_root.dentry = dget(ns_root.mnt->mnt_root);
|
||||
spin_unlock(&vfsmount_lock);
|
||||
- res = __d_path(dentry, vfsmnt, &ns_root, buf, buflen, 1);
|
||||
+ res = __d_path(dentry, vfsmnt, &ns_root, buf, buflen, 1, 1);
|
||||
path_put(&root);
|
||||
path_put(&ns_root);
|
||||
|
||||
--- a/include/linux/dcache.h
|
||||
+++ b/include/linux/dcache.h
|
||||
@@ -301,7 +301,7 @@ extern int d_validate(struct dentry *, s
|
||||
*/
|
||||
extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
|
||||
extern char *__d_path(struct dentry *, struct vfsmount *, struct path *,
|
||||
- char *, int, int);
|
||||
+ char *, int, int, int);
|
||||
extern char *d_path(struct path *, char *, int);
|
||||
|
||||
/* Allocation counts.. */
|
60
kernel-patches/2.6.25/apparmor-2.6.25.diff
Normal file
60
kernel-patches/2.6.25/apparmor-2.6.25.diff
Normal file
@@ -0,0 +1,60 @@
|
||||
From: John Johansen <jjohansen@suse.de>
|
||||
Subject: AppArmor: Patch AppArmor for 2.6.25 kernel
|
||||
|
||||
Add 64 bit capabilities support to AppArmor.
|
||||
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
security/apparmor/lsm.c | 3 ++-
|
||||
security/apparmor/module_interface.c | 22 ++++++++++++++++++----
|
||||
2 files changed, 20 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -462,7 +462,8 @@ static int apparmor_inode_permission(str
|
||||
/* allow traverse accesses to directories */
|
||||
mask &= ~MAY_EXEC;
|
||||
}
|
||||
- return aa_permission("inode_permission", inode, nd->dentry, nd->mnt,
|
||||
+ return aa_permission("inode_permission", inode, nd->path.dentry,
|
||||
+ nd->path.mnt,
|
||||
mask, check);
|
||||
}
|
||||
|
||||
--- a/security/apparmor/module_interface.c
|
||||
+++ b/security/apparmor/module_interface.c
|
||||
@@ -356,15 +356,29 @@ static struct aa_profile *aa_unpack_prof
|
||||
if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
|
||||
goto fail;
|
||||
|
||||
- if (!aa_is_u32(e, &(profile->capabilities), NULL))
|
||||
+ if (!aa_is_u32(e, &(profile->capabilities.cap[0]), NULL))
|
||||
goto fail;
|
||||
- if (!aa_is_u32(e, &(profile->audit_caps), NULL))
|
||||
+ if (!aa_is_u32(e, &(profile->audit_caps.cap[0]), NULL))
|
||||
goto fail;
|
||||
- if (!aa_is_u32(e, &(profile->quiet_caps), NULL))
|
||||
+ if (!aa_is_u32(e, &(profile->quiet_caps.cap[0]), NULL))
|
||||
goto fail;
|
||||
- if (!aa_is_u32(e, &(profile->set_caps), NULL))
|
||||
+ if (!aa_is_u32(e, &(profile->set_caps.cap[0]), NULL))
|
||||
goto fail;
|
||||
|
||||
+ if (aa_is_nameX(e, AA_STRUCT, "caps64")) {
|
||||
+ /* optional upper half of 64 bit caps */
|
||||
+ if (!aa_is_u32(e, &(profile->capabilities.cap[1]), NULL))
|
||||
+ goto fail;
|
||||
+ if (!aa_is_u32(e, &(profile->audit_caps.cap[1]), NULL))
|
||||
+ goto fail;
|
||||
+ if (!aa_is_u32(e, &(profile->quiet_caps.cap[1]), NULL))
|
||||
+ goto fail;
|
||||
+ if (!aa_is_u32(e, &(profile->set_caps.cap[1]), NULL))
|
||||
+ goto fail;
|
||||
+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if (!aa_unpack_rlimits(e, profile))
|
||||
goto fail;
|
||||
|
72
kernel-patches/2.6.25/apparmor-audit.diff
Normal file
72
kernel-patches/2.6.25/apparmor-audit.diff
Normal file
@@ -0,0 +1,72 @@
|
||||
From: Tony Jones <tonyj@suse.de>
|
||||
Subject: Export audit subsystem for use by modules
|
||||
|
||||
Update kenel audit range comments to show AppArmor's registered range of
|
||||
1500-1599. This range used to be reserved for LSPP but LSPP uses the
|
||||
SE Linux range and the range was given to AppArmor.
|
||||
Adds necessary export symbols for audit subsystem routines.
|
||||
Changes audit_log_vformat to be externally visible (analagous to vprintf)
|
||||
Patch is not in mainline -- pending AppArmor code submission to lkml
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Signed-off-by: John Johansen <jjohansen@suse.de>
|
||||
|
||||
---
|
||||
include/linux/audit.h | 12 +++++++++++-
|
||||
kernel/audit.c | 6 ++++--
|
||||
2 files changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/include/linux/audit.h
|
||||
+++ b/include/linux/audit.h
|
||||
@@ -33,7 +33,7 @@
|
||||
* 1200 - 1299 messages internal to the audit daemon
|
||||
* 1300 - 1399 audit event messages
|
||||
* 1400 - 1499 SE Linux use
|
||||
- * 1500 - 1599 kernel LSPP events
|
||||
+ * 1500 - 1599 AppArmor use
|
||||
* 1600 - 1699 kernel crypto events
|
||||
* 1700 - 1799 kernel anomaly records
|
||||
* 1800 - 1999 future kernel use (maybe integrity labels and related events)
|
||||
@@ -119,6 +119,13 @@
|
||||
#define AUDIT_MAC_UNLBL_STCADD 1416 /* NetLabel: add a static label */
|
||||
#define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */
|
||||
|
||||
+#define AUDIT_APPARMOR_AUDIT 1501 /* AppArmor audited grants */
|
||||
+#define AUDIT_APPARMOR_ALLOWED 1502 /* Allowed Access for learning */
|
||||
+#define AUDIT_APPARMOR_DENIED 1503
|
||||
+#define AUDIT_APPARMOR_HINT 1504 /* Process Tracking information */
|
||||
+#define AUDIT_APPARMOR_STATUS 1505 /* Changes in config */
|
||||
+#define AUDIT_APPARMOR_ERROR 1506 /* Internal AppArmor Errors */
|
||||
+
|
||||
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
|
||||
#define AUDIT_LAST_KERN_ANOM_MSG 1799
|
||||
#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
|
||||
@@ -518,6 +525,9 @@ extern void audit_log(struct audit_
|
||||
__attribute__((format(printf,4,5)));
|
||||
|
||||
extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
|
||||
+extern void audit_log_vformat(struct audit_buffer *ab,
|
||||
+ const char *fmt, va_list args)
|
||||
+ __attribute__((format(printf,2,0)));
|
||||
extern void audit_log_format(struct audit_buffer *ab,
|
||||
const char *fmt, ...)
|
||||
__attribute__((format(printf,2,3)));
|
||||
--- a/kernel/audit.c
|
||||
+++ b/kernel/audit.c
|
||||
@@ -1136,8 +1136,7 @@ static inline int audit_expand(struct au
|
||||
* will be called a second time. Currently, we assume that a printk
|
||||
* can't format message larger than 1024 bytes, so we don't either.
|
||||
*/
|
||||
-static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
|
||||
- va_list args)
|
||||
+void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args)
|
||||
{
|
||||
int len, avail;
|
||||
struct sk_buff *skb;
|
||||
@@ -1407,3 +1406,6 @@ EXPORT_SYMBOL(audit_log_start);
|
||||
EXPORT_SYMBOL(audit_log_end);
|
||||
EXPORT_SYMBOL(audit_log_format);
|
||||
EXPORT_SYMBOL(audit_log);
|
||||
+EXPORT_SYMBOL_GPL(audit_log_vformat);
|
||||
+EXPORT_SYMBOL_GPL(audit_log_untrustedstring);
|
||||
+EXPORT_SYMBOL_GPL(audit_log_d_path);
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user