From f184ff9ef75f566eab32b6e37318a55c3cf248be Mon Sep 17 00:00:00 2001 From: geos_one Date: Tue, 6 Mar 2007 23:01:34 +0000 Subject: [PATCH] Drop old apparmor ebuilds --- .../app-doc/apparmor-docs/Manifest | 8 - .../apparmor-docs-2.0_p6269.ebuild | 42 - .../files/digest-apparmor-docs-2.0_p6269 | 3 - .../app-vim/apparmor-syntax/Manifest | 8 - .../apparmor-syntax-200609.ebuild | 14 - .../files/digest-apparmor-syntax-200609 | 3 - trunk/novell4gentoo/app-vim/metadata.xml | 37 - .../distfiles/apparmor-syntax-200609.tar.bz2 | Bin 2213 -> 0 bytes .../sec-policy/apparmor-profiles/ChangeLog | 10 - .../sec-policy/apparmor-profiles/Manifest | 24 - .../apparmor-profiles-2.0_p119.ebuild | 60 - .../apparmor-profiles-2.0_p6376.ebuild | 58 - .../files/digest-apparmor-profiles-2.0_p119 | 3 - .../files/digest-apparmor-profiles-2.0_p6376 | 3 - .../sec-policy/apparmor-profiles/metadata.xml | 11 - trunk/novell4gentoo/sec-policy/metadata.xml | 41 - .../sys-apps/apparmor-modules/Manifest | 16 - .../apparmor-modules-2.0_p20061013.ebuild | 85 - ...r-modules-2.0_2.6.17.9_symbol_export.patch | 83 - .../digest-apparmor-modules-2.0_p20061013 | 3 - .../sys-apps/apparmor-modules/metadata.xml | 11 - .../sys-apps/apparmor-parser/Manifest | 28 - .../apparmor-parser-2.0_p150.ebuild | 62 - .../sys-apps/apparmor-parser/files/aaeventd | 40 - .../sys-apps/apparmor-parser/files/apparmor | 55 - .../files/digest-apparmor-parser-2.0_p150 | 3 - .../files/rc.apparmor.functions | 443 - .../apparmor-parser/files/rc.helper.functions | 47 - .../sys-apps/apparmor-parser/metadata.xml | 11 - .../sys-apps/apparmor-utils/Manifest | 12 - .../apparmor-utils-2.0_p142.ebuild | 54 - .../files/digest-apparmor-utils-2.0_p142 | 3 - .../sys-apps/apparmor-utils/metadata.xml | 11 - trunk/novell4gentoo/sys-apps/metadata.xml | 45 - .../sys-kernel/apparmor-sources/ChangeLog | 23 - .../sys-kernel/apparmor-sources/Manifest | 93 - .../apparmor-sources-2.6.17-r1.ebuild | 43 - .../apparmor-sources-2.6.17.ebuild | 45 - .../apparmor-sources-2.6.18.ebuild | 45 - .../files/5000_apparmor-integrate.patch | 76 - .../files/5001_apparmor-core-header.patch | 728 -- .../files/5002_apparmor-lsm-interface.patch | 880 -- .../5003_apparmor-core-access-controls.patch | 1643 ---- .../files/5004_apparmor-filesystem.patch | 472 - .../5005_apparmor-userspace-interface.patch | 907 -- .../files/5006_apparmor-misc.patch | 681 -- ...apparmor-pathname-matching-submodule.patch | 246 - .../files/5008_apparmor-audit-changes.patch | 58 - .../files/5009_apparmor-add-flags.patch | 170 - ...0_apparmor-export-namespace-semaphor.patch | 53 - ...mor-sources-2.6.17-r1-apparmor_audit.patch | 59 - ...rmor-sources-2.6.17-r1-apparmor_main.patch | 7917 ----------------- ...rces-2.6.17-r1-apparmor_namespacesem.patch | 36 - .../files/digest-apparmor-sources-2.6.17 | 12 - .../files/digest-apparmor-sources-2.6.17-r1 | 9 - .../files/digest-apparmor-sources-2.6.18 | 12 - .../sys-kernel/apparmor-sources/metadata.xml | 11 - .../sys-libs/libapparmor/ChangeLog | 10 - .../sys-libs/libapparmor/Manifest | 24 - .../files/digest-libapparmor-2.0_p132 | 3 - .../files/digest-libapparmor-2.0_p6288 | 3 - .../libapparmor/libapparmor-2.0_p132.ebuild | 39 - .../libapparmor/libapparmor-2.0_p6288.ebuild | 38 - .../sys-libs/libapparmor/metadata.xml | 11 - 64 files changed, 15684 deletions(-) delete mode 100644 trunk/novell4gentoo/app-doc/apparmor-docs/Manifest delete mode 100644 trunk/novell4gentoo/app-doc/apparmor-docs/apparmor-docs-2.0_p6269.ebuild delete mode 100644 trunk/novell4gentoo/app-doc/apparmor-docs/files/digest-apparmor-docs-2.0_p6269 delete mode 100644 trunk/novell4gentoo/app-vim/apparmor-syntax/Manifest delete mode 100644 trunk/novell4gentoo/app-vim/apparmor-syntax/apparmor-syntax-200609.ebuild delete mode 100644 trunk/novell4gentoo/app-vim/apparmor-syntax/files/digest-apparmor-syntax-200609 delete mode 100644 trunk/novell4gentoo/app-vim/metadata.xml delete mode 100644 trunk/novell4gentoo/distfiles/apparmor-syntax-200609.tar.bz2 delete mode 100644 trunk/novell4gentoo/sec-policy/apparmor-profiles/ChangeLog delete mode 100644 trunk/novell4gentoo/sec-policy/apparmor-profiles/Manifest delete mode 100644 trunk/novell4gentoo/sec-policy/apparmor-profiles/apparmor-profiles-2.0_p119.ebuild delete mode 100644 trunk/novell4gentoo/sec-policy/apparmor-profiles/apparmor-profiles-2.0_p6376.ebuild delete mode 100644 trunk/novell4gentoo/sec-policy/apparmor-profiles/files/digest-apparmor-profiles-2.0_p119 delete mode 100644 trunk/novell4gentoo/sec-policy/apparmor-profiles/files/digest-apparmor-profiles-2.0_p6376 delete mode 100644 trunk/novell4gentoo/sec-policy/apparmor-profiles/metadata.xml delete mode 100644 trunk/novell4gentoo/sec-policy/metadata.xml delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-modules/Manifest delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-modules/apparmor-modules-2.0_p20061013.ebuild delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-modules/files/apparmor-modules-2.0_2.6.17.9_symbol_export.patch delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-modules/files/digest-apparmor-modules-2.0_p20061013 delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-modules/metadata.xml delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-parser/Manifest delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-parser/apparmor-parser-2.0_p150.ebuild delete mode 100755 trunk/novell4gentoo/sys-apps/apparmor-parser/files/aaeventd delete mode 100755 trunk/novell4gentoo/sys-apps/apparmor-parser/files/apparmor delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-parser/files/digest-apparmor-parser-2.0_p150 delete mode 100755 trunk/novell4gentoo/sys-apps/apparmor-parser/files/rc.apparmor.functions delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-parser/files/rc.helper.functions delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-parser/metadata.xml delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-utils/Manifest delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-utils/apparmor-utils-2.0_p142.ebuild delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-utils/files/digest-apparmor-utils-2.0_p142 delete mode 100644 trunk/novell4gentoo/sys-apps/apparmor-utils/metadata.xml delete mode 100644 trunk/novell4gentoo/sys-apps/metadata.xml delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/ChangeLog delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/Manifest delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.17-r1.ebuild delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.17.ebuild delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.18.ebuild delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5000_apparmor-integrate.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5001_apparmor-core-header.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5002_apparmor-lsm-interface.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5003_apparmor-core-access-controls.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5004_apparmor-filesystem.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5005_apparmor-userspace-interface.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5006_apparmor-misc.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5007_apparmor-pathname-matching-submodule.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5008_apparmor-audit-changes.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5009_apparmor-add-flags.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5010_apparmor-export-namespace-semaphor.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_audit.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_main.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_namespacesem.patch delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.17 delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.17-r1 delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.18 delete mode 100644 trunk/novell4gentoo/sys-kernel/apparmor-sources/metadata.xml delete mode 100644 trunk/novell4gentoo/sys-libs/libapparmor/ChangeLog delete mode 100644 trunk/novell4gentoo/sys-libs/libapparmor/Manifest delete mode 100644 trunk/novell4gentoo/sys-libs/libapparmor/files/digest-libapparmor-2.0_p132 delete mode 100644 trunk/novell4gentoo/sys-libs/libapparmor/files/digest-libapparmor-2.0_p6288 delete mode 100644 trunk/novell4gentoo/sys-libs/libapparmor/libapparmor-2.0_p132.ebuild delete mode 100644 trunk/novell4gentoo/sys-libs/libapparmor/libapparmor-2.0_p6288.ebuild delete mode 100644 trunk/novell4gentoo/sys-libs/libapparmor/metadata.xml diff --git a/trunk/novell4gentoo/app-doc/apparmor-docs/Manifest b/trunk/novell4gentoo/app-doc/apparmor-docs/Manifest deleted file mode 100644 index ded1a252..00000000 --- a/trunk/novell4gentoo/app-doc/apparmor-docs/Manifest +++ /dev/null @@ -1,8 +0,0 @@ -DIST apparmor-docs-2.0-6269.tar.gz 2697657 RMD160 474048d988d72cbf9bf21d50e8aef37d06d9b000 SHA1 792f4339d86d02d179b786de87a47394abfdadae SHA256 9c2d63bfe42cc4582e24d1248a7560dd19cee718db513c7dedb12d45fe168221 -EBUILD apparmor-docs-2.0_p6269.ebuild 955 RMD160 7d0ef9d6bc1a7742684c3c3ced41fd846647a659 SHA1 1f46784c84ea199daa365a19e5d2ff500b84540b SHA256 0db0811764e7dee4543a7d8435f998a76d01ac54335d1b6603295a7a7d929c12 -MD5 38dd72e1548593a135e9e3554d583b3a apparmor-docs-2.0_p6269.ebuild 955 -RMD160 7d0ef9d6bc1a7742684c3c3ced41fd846647a659 apparmor-docs-2.0_p6269.ebuild 955 -SHA256 0db0811764e7dee4543a7d8435f998a76d01ac54335d1b6603295a7a7d929c12 apparmor-docs-2.0_p6269.ebuild 955 -MD5 2729ec9e31f63d936db2d7745ef9be57 files/digest-apparmor-docs-2.0_p6269 271 -RMD160 1c537c1e781a06a7bac39b2cfb7170ba281bb875 files/digest-apparmor-docs-2.0_p6269 271 -SHA256 1a62f3ad2e11540f9e65c1c623357a588f44ecd1244c2559c6436f426aa210ba files/digest-apparmor-docs-2.0_p6269 271 diff --git a/trunk/novell4gentoo/app-doc/apparmor-docs/apparmor-docs-2.0_p6269.ebuild b/trunk/novell4gentoo/app-doc/apparmor-docs/apparmor-docs-2.0_p6269.ebuild deleted file mode 100644 index 640416c2..00000000 --- a/trunk/novell4gentoo/app-doc/apparmor-docs/apparmor-docs-2.0_p6269.ebuild +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit eutils perl-module toolchain-funcs - -MY_PV="${PV/_p/-}" -MY_P="${PN}-${MY_PV}" -MY_S="${WORKDIR}/${PN}-${PV/_p*/}" -MONTH="April" - -DESCRIPTION="Documentation for AppArmor." -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -SRC_URI="http://forgeftp.novell.com/apparmor/Development%20-%20${MONTH}%20Snapshot/${MY_P}.tar.gz" - -LICENSE="GPL-2" -SLOT="0" -KEYWORDS="~x86 ~amd64" -IUSE="doc" - -DEPEND="" -RDEPEND="${DEPEND}" - -src_unpack() { - unpack ${A} - - cd ${MY_S} - sed -i "s:NOVELL/SUSE:Gentoo:g" Makefile -} - -src_compile() { - cd ${MY_S} - emake CC="$(tc-getCC)" CFLAGS="${CFLAGS}" || die -} - -src_install() { - cd ${MY_S} - make DESTDIR=${D} install_manpages || die - # Some files are missing from the doc distribution, so no '|| die' - # bug submitted upstream - make DESTDIR=${D} DOCDIR=/usr/share/doc/${P} install_documents -} diff --git a/trunk/novell4gentoo/app-doc/apparmor-docs/files/digest-apparmor-docs-2.0_p6269 b/trunk/novell4gentoo/app-doc/apparmor-docs/files/digest-apparmor-docs-2.0_p6269 deleted file mode 100644 index 9c4eee3e..00000000 --- a/trunk/novell4gentoo/app-doc/apparmor-docs/files/digest-apparmor-docs-2.0_p6269 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 a5130a30a6a9e7cac316fe7658af031a apparmor-docs-2.0-6269.tar.gz 2697657 -RMD160 474048d988d72cbf9bf21d50e8aef37d06d9b000 apparmor-docs-2.0-6269.tar.gz 2697657 -SHA256 9c2d63bfe42cc4582e24d1248a7560dd19cee718db513c7dedb12d45fe168221 apparmor-docs-2.0-6269.tar.gz 2697657 diff --git a/trunk/novell4gentoo/app-vim/apparmor-syntax/Manifest b/trunk/novell4gentoo/app-vim/apparmor-syntax/Manifest deleted file mode 100644 index 327e7821..00000000 --- a/trunk/novell4gentoo/app-vim/apparmor-syntax/Manifest +++ /dev/null @@ -1,8 +0,0 @@ -DIST apparmor-syntax-200609.tar.bz2 1944 RMD160 ffffda77d691edfdbdc2044f6b7aa6f33f7bb223 SHA1 602a63663b4c82183cdee568fffee6eea53b3ee1 SHA256 db5aa288aa500f6b7d3bbe3a51949d3a427ee015b385c5353ada8d78846dfe0a -EBUILD apparmor-syntax-200609.ebuild 424 RMD160 7791f7d04affb46b767f0d329a888c7be42d984e SHA1 420618adeb7b0ed315cdb1a8e29e0fa8bddc3995 SHA256 60ec62ca7820c57ca4caa25a913c476cf6ea5a060d6befab151a5335fb3303f1 -MD5 780f8eead7c9f97774e2fb98d66a12c0 apparmor-syntax-200609.ebuild 424 -RMD160 7791f7d04affb46b767f0d329a888c7be42d984e apparmor-syntax-200609.ebuild 424 -SHA256 60ec62ca7820c57ca4caa25a913c476cf6ea5a060d6befab151a5335fb3303f1 apparmor-syntax-200609.ebuild 424 -MD5 c72538221b6d11278c4aa3364e2818bb files/digest-apparmor-syntax-200609 265 -RMD160 feff8dcf95a810e9ee6eba1e03a135379d2434ef files/digest-apparmor-syntax-200609 265 -SHA256 e7cfd2f74c1811198bee4763f1f5f8400d8780bd9d3c49eeed2a977540d2e6f5 files/digest-apparmor-syntax-200609 265 diff --git a/trunk/novell4gentoo/app-vim/apparmor-syntax/apparmor-syntax-200609.ebuild b/trunk/novell4gentoo/app-vim/apparmor-syntax/apparmor-syntax-200609.ebuild deleted file mode 100644 index 06fddf41..00000000 --- a/trunk/novell4gentoo/app-vim/apparmor-syntax/apparmor-syntax-200609.ebuild +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright 1999-2005 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit vim-plugin - -DESCRIPTION="vim plugin: AppArmor policy syntax" -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -LICENSE="vim" -KEYWORDS="alpha amd64 ia64 mips ~ppc ppc64 sparc x86" -IUSE="" - -VIM_PLUGIN_HELPTEXT="This plugin provides syntax highlighting for Apparmor -policy files." diff --git a/trunk/novell4gentoo/app-vim/apparmor-syntax/files/digest-apparmor-syntax-200609 b/trunk/novell4gentoo/app-vim/apparmor-syntax/files/digest-apparmor-syntax-200609 deleted file mode 100644 index f424879e..00000000 --- a/trunk/novell4gentoo/app-vim/apparmor-syntax/files/digest-apparmor-syntax-200609 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 c44d7356708377424d641aa0c66a72a8 apparmor-syntax-200609.tar.bz2 1944 -RMD160 ffffda77d691edfdbdc2044f6b7aa6f33f7bb223 apparmor-syntax-200609.tar.bz2 1944 -SHA256 db5aa288aa500f6b7d3bbe3a51949d3a427ee015b385c5353ada8d78846dfe0a apparmor-syntax-200609.tar.bz2 1944 diff --git a/trunk/novell4gentoo/app-vim/metadata.xml b/trunk/novell4gentoo/app-vim/metadata.xml deleted file mode 100644 index df7f6037..00000000 --- a/trunk/novell4gentoo/app-vim/metadata.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - The app-vim category contains plugins, syntax file and spelling - packages for the Vim text editor. - - - Die Kategorie app-vim enthält Plugins und - Syntax-Pakete für den Vim Texteditor. - - - La categoría app-vim contiene extensiones y paquetes - de syntaxis para el editor de texto Vim. - - - De app-vim categorie bevat plugins en syntax-bestanden - voor de vim text editor. - - - Nhóm app-vim chứa các plugin và các gói syntax cho - trình soạn thảo văn bản Vim. - - - La categoria app-vim contiene estensioni e pacchetti di sintassi - per l'editor di testo Vim. - - - A categoria app-vim contém plugins e pacotes de sintaxe e grafia - para o editor de texto Vim. - - - Kategoria app-vim zawiera rozszerzenia, schematy podświetlania składni - oraz dodatki służące do sprawdzania pisowni dla edytora tekstu Vim. - - - diff --git a/trunk/novell4gentoo/distfiles/apparmor-syntax-200609.tar.bz2 b/trunk/novell4gentoo/distfiles/apparmor-syntax-200609.tar.bz2 deleted file mode 100644 index fc1961c4cfbb5a9a34811e714f08447409ea1f63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2213 zcmV;W2wL|-T4*^jL0KkKS-mB4Qvd`|e}n$806<;;|NsB*-~a#b|NlS$00ICAU6x=eRO}j3rAk7g;gr!dPg4_0dsE73riuC{jZA7{F{EQrk+dK-lL$1!KpL7R z&`lF5p^>9N28{p!00000XaG2900x6WpfErU4K&CGhK(`+Vg`T&h=LO$G{_Y42B)Ys zJV4OWG7O9WhoWsGO^^eIfBf zrk5kdVu`}^JUY>4+O2_r*7Vv< z3_}2E5XOc!*OhrQr`5o?G4j0!@0r$I$^Xk$&Z|)BUmX@%=>d99n(-1(6Wb74Yik5U zV2a~Pd1;T6{}ay|Mz15IsgN=sJ+jqrHkBpBX_?wYK?Jnn!3c?1h5%Y|WUXT+A>&>@ zF3AL|Z#)lBD&-RrPVC48fnpVfQ*3n$KQ^bN;PaG|jLf}}pXzwvd9h-aoKTL%AYUw? zevJaSXrO#1j!A~L7F{hAMv2|QAraF7b_6`2@>L9m)~k!QZO8yula+F+@UXs1K05wHq1$g5F} z$N*BNDOs)H>!Kn=(dp?u-8~vpW=7kEIW?N)#6BJ_!@=@CjZs$0L^kORmgXBx&wpj~ zcvodH)xTjF|Jk<&sO7@g*m0Il%A$#GHJ2lozNf#i9gC zm~sF6h;x`Q;|%Sr4di>ULEUqrp&S{_0o(9gh!*jn{mi_Jvz$@A!T|518|L-uowg#X zD%?XxOI1j`xHYjeuO--x^Eh z^Z8~6dhxj#SGAGB(%WzR@lhGJ{CaX9f_zKo3kzpQO!K}Ky(m%Uc{=}o8XAJ+baw$` zdWN$OjoO(Ti#T3)4qFw5n0=Iy5F$S)*mwVr9~(3Z7I5$22MG0+`*lhAgVtDqO-V_# zr7205MMuYATC*wfbm+{^29`SfBW^joKK%wVt{Xo-T}IcsxHYKN=3B9!O^-nW|5Y=}Emor#hJJ zK!*fUr6+#-R#zoW>b@tr0F0wSs4$f&@{Tn|Bj~xOQnRjDQ?)kl;%aofXT!samPW?n zN?AK zw#CdmQr9tI%g`XM;g?McoyZFIL+@>%vZ4J3+1J}toKqAcBD}y8>7J#TUtwPSJE4sR zl~jwrTSdd;b?RkI$mPOl`GJtKFyoe>|3=T(&k1#zG#t-uw~8WF#H|8}6d~txit2|3 z*xEKOJZPxerEybJu}pX@22%|4FGUkGW5oq_fYv5iSzS1otr$BxM5N?c9YtGKo+QN! zm7AV^o?q?GO>v}Xw;*^3I@>3;KmDD0>7?i0Zu8a7p z1v!%-Js=iXq7dwP)ue(cFhz5$w?n)|c|IH|5K>^EOh_ZVWKn35l~b@il8SXd1f*SA zf@upuDKnxPNUj5IA=>U^P53@H?cUUgw ziR&?lNW+;%zXF!Dx%Fawg^Ql>BZPG|s+>8<=7#ue5zaaYI!2sLSL$O49OY>c4hB|M z`)dYw5i~W-E+%Ffjj(7>F|Jj|k;aX9V~EDv%FjNv3zv&ECcMSUA&+(A&4UfD?(Wz$Eh^G$mNi5yQwsJpuhG39F;pM8kN#C zUppK1+1g}){(u<_Y?ebB28v8e2ooX08+~|dc@KAO?4kxkyL*)N`WroG{aX&;(E;U=&Vl#D|6Ats+kvf7nqztjfBcQ0#sz|0;~?m z!--8rP(gudLMh)NEeNN$m8gK`8ZRa{y}7j&$(ZJ36vL}5*+yteHO}i5urm>dn*L)cD8gLPW4y0Xdmd9O - +apparmor-profiles-2.0_p6376.ebuild: - Initial Import of - Matthew Snelham - Apparmor ebuilds - diff --git a/trunk/novell4gentoo/sec-policy/apparmor-profiles/Manifest b/trunk/novell4gentoo/sec-policy/apparmor-profiles/Manifest deleted file mode 100644 index 5756df00..00000000 --- a/trunk/novell4gentoo/sec-policy/apparmor-profiles/Manifest +++ /dev/null @@ -1,24 +0,0 @@ -DIST apparmor-profiles-2.0-119.tar.gz 38442 RMD160 41960baad897408ef9fed48829975b7d7ad5381a SHA1 ced8c4e1a8837b9c243fba9146454cf284e357f6 SHA256 747be3c170cd9bb599e6c5a6b1c19a1ec8e8f614b469ef52d7e6640830698efd -DIST apparmor-profiles-2.0-6376.tar.gz 33651 RMD160 cd64269b9c12fd60256f624b7b81aa1bddbb74c3 SHA1 151a18c3bc05355f24188cd1bc4b77cbae7e15dd SHA256 55103b0ce98616b6860fb43eff23587ad0faf5e38ab828bdd025d87a55b0f073 -EBUILD apparmor-profiles-2.0_p119.ebuild 1770 RMD160 685fb1f50b304a0e926a4cfe5f83f56668e66089 SHA1 2f99943e2dd586f370a44930a2fe77bf4c5d5d24 SHA256 e45329f2b1d6ee704507ca81af87b910b24390cb215de7ef198029661c720433 -MD5 237f7fa6f27dbff8548383c39213645d apparmor-profiles-2.0_p119.ebuild 1770 -RMD160 685fb1f50b304a0e926a4cfe5f83f56668e66089 apparmor-profiles-2.0_p119.ebuild 1770 -SHA256 e45329f2b1d6ee704507ca81af87b910b24390cb215de7ef198029661c720433 apparmor-profiles-2.0_p119.ebuild 1770 -EBUILD apparmor-profiles-2.0_p6376.ebuild 1761 RMD160 c71682fbb885b3be54813c691258d4c6a3d6de59 SHA1 778fa06e704b167e03946a0a26f2b6e5f282f37f SHA256 350943388432d8280888d86ea36e3fb92af128c64553ef99f3421c07b2274d04 -MD5 84869f70eb14cb24d0d296fa2f764cef apparmor-profiles-2.0_p6376.ebuild 1761 -RMD160 c71682fbb885b3be54813c691258d4c6a3d6de59 apparmor-profiles-2.0_p6376.ebuild 1761 -SHA256 350943388432d8280888d86ea36e3fb92af128c64553ef99f3421c07b2274d04 apparmor-profiles-2.0_p6376.ebuild 1761 -MISC ChangeLog 298 RMD160 b9b60d4693e022c3a3b51d7a125fcfb8a81accff SHA1 f5cace28303705a7765c4b80748f2d17918bdad8 SHA256 d0ed57cfaa564a15c378fd4ed2417338c1f228a7facf33f2dc7e2679ccc514c1 -MD5 754dcad22d0341872441dba94bca8272 ChangeLog 298 -RMD160 b9b60d4693e022c3a3b51d7a125fcfb8a81accff ChangeLog 298 -SHA256 d0ed57cfaa564a15c378fd4ed2417338c1f228a7facf33f2dc7e2679ccc514c1 ChangeLog 298 -MISC metadata.xml 409 RMD160 968882ff27e0b0a3f97af92b6f537b8b00a646ff SHA1 3fcb95fd59a93e7aa310e0a41474df97187da15a SHA256 3043f699fbff382064ac346e6be45c4bdfa03ab4e0a92f8cdaea0737f9edce0f -MD5 042c5aa592b5d0dbb5fce79de0cd78d8 metadata.xml 409 -RMD160 968882ff27e0b0a3f97af92b6f537b8b00a646ff metadata.xml 409 -SHA256 3043f699fbff382064ac346e6be45c4bdfa03ab4e0a92f8cdaea0737f9edce0f metadata.xml 409 -MD5 009b398f5b231e38fc3422558483629e files/digest-apparmor-profiles-2.0_p119 274 -RMD160 d85cd1212273237347788ba31a1b757e9aec6635 files/digest-apparmor-profiles-2.0_p119 274 -SHA256 a51796af9a3ecb31ff8752d4f3d3d19a6c3f613e8da9e32d02b7a79101996232 files/digest-apparmor-profiles-2.0_p119 274 -MD5 45e145b77a88f384033973676b4cf1c0 files/digest-apparmor-profiles-2.0_p6376 277 -RMD160 75b6c9ba5340bafa72a8410339ceeeda13a71d00 files/digest-apparmor-profiles-2.0_p6376 277 -SHA256 b4229927d9665b3c60a9ba4d956d942083d5d7c59b8f3ced3c36d8741efad10d files/digest-apparmor-profiles-2.0_p6376 277 diff --git a/trunk/novell4gentoo/sec-policy/apparmor-profiles/apparmor-profiles-2.0_p119.ebuild b/trunk/novell4gentoo/sec-policy/apparmor-profiles/apparmor-profiles-2.0_p119.ebuild deleted file mode 100644 index 36848209..00000000 --- a/trunk/novell4gentoo/sec-policy/apparmor-profiles/apparmor-profiles-2.0_p119.ebuild +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit eutils toolchain-funcs - -MY_P="${P/_p/-}" -MY_S="${WORKDIR}/${P/_p*/}" -MONTH="October" - -DESCRIPTION="AppArmor pre-built application encapsulation profiles." -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -SRC_URI="http://forgeftp.novell.com/apparmor/Development%20-%20${MONTH}%20Snapshot/${MY_P}.tar.gz" - -LICENSE="GPL-2" -SLOT="0" -KEYWORDS="~x86 ~amd64" -IUSE="" - -DEPEND="" -RDEPEND="sys-apps/apparmor" - -pkg_postinst() { - ewarn - ewarn "DO NOT EXPECT THESE PROFILES TO WORK ON YOUR SYSTEM!!!" - ewarn " Expect that ENABLING THEM WILL BREAK things" - ewarn " " - ewarn "These profiles were built to work with a SuSE base install, and " - ewarn "make many assumptions about file placement and system facilities " - ewarn "that are quite possibly untrue on any Gentoo system ever emerged." - ewarn " " - ewarn "They are provided for reference purposes only, until profiles can " - ewarn "be created and verified for Gentoo. If you are interested in using " - ewarn "AppArmor, and modifiying these base profiles for a Gentoo package, " - ewarn "please feel free to do so, and contact the AppArmor package " - ewarn "maintainer with your working profiles!" - ewarn - epause -} - -src_unpack() { - unpack ${A} - - cd ${MY_S} - # Move profiles to a different dir so that none of - # them are sourced by default on startup. - sed -i 's:apparmor.d$:apparmor.d/suse-defaults:g' Makefile -} - -src_compile() { - cd ${MY_S} - emake CC="$(tc-getCC)" CFLAGS="${CFLAGS}" || die -} - -src_install() { - cd ${MY_S} - # Place profiles in /usr/share, instead of /usr/src/Immunix - MY_SHAREDIR="/usr/share/${PN}" - make DESTDIR=${D} EXTRASDIR=${D}/${MY_SHAREDIR} install || die -} diff --git a/trunk/novell4gentoo/sec-policy/apparmor-profiles/apparmor-profiles-2.0_p6376.ebuild b/trunk/novell4gentoo/sec-policy/apparmor-profiles/apparmor-profiles-2.0_p6376.ebuild deleted file mode 100644 index 6b5b1888..00000000 --- a/trunk/novell4gentoo/sec-policy/apparmor-profiles/apparmor-profiles-2.0_p6376.ebuild +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit eutils - -MY_P="${P/_p/-}" -MY_S="${WORKDIR}/${P/_p*//}" -DESCRIPTION="AppArmor pre-built application encapsulation profiles." -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -SRC_URI="http://forge.novell.com/modules/xfcontent/private.php/apparmor/Development%20-%20April%20Snapshot/${MY_P}.tar.gz" - -LICENSE="GPL-2" -SLOT="0" -KEYWORDS="~x86" -IUSE="" - -DEPEND="" -RDEPEND=">=sys-apps/apparmor-2.0" - -pkg_postinst() { - ewarn - ewarn "DO NOT EXPECT THESE PROFILES TO WORK ON YOUR SYSTEM!!!" - ewarn " Expect that ENABLING THEM WILL BREAK things" - ewarn " " - ewarn "These profiles were built to work with a SuSE base install, and " - ewarn "make many assumptions about file placement and system facilities " - ewarn "that are quite possibly untrue on any Gentoo system ever emerged." - ewarn " " - ewarn "They are provided for reference purposes only, until profiles can " - ewarn "be created and verified for Gentoo. If you are interested in using " - ewarn "AppArmor, and modifiying these base profiles for a Gentoo package, " - ewarn "please feel free to do so, and contact the AppArmor package " - ewarn "maintainer with your working profiles!" - ewarn - epause -} - -src_unpack() { - unpack ${A} - - cd ${MY_S} - # Move profiles to a different dir so that none of - # them are sourced by default on startup. - sed -i 's:apparmor.d$:apparmor.d/suse-defaults:g' Makefile -} - -src_compile() { - cd ${MY_S} - emake CC="$(tc-getCC)" CFLAGS="${CFLAGS}" || die -} - -src_install() { - cd ${MY_S} - # Place profiles in /usr/share, instead of /usr/src/Immunix - MY_SHAREDIR="/usr/share/${PN}" - make DESTDIR=${D} EXTRASDIR=${D}/${MY_SHAREDIR} install || die -} diff --git a/trunk/novell4gentoo/sec-policy/apparmor-profiles/files/digest-apparmor-profiles-2.0_p119 b/trunk/novell4gentoo/sec-policy/apparmor-profiles/files/digest-apparmor-profiles-2.0_p119 deleted file mode 100644 index d55b1229..00000000 --- a/trunk/novell4gentoo/sec-policy/apparmor-profiles/files/digest-apparmor-profiles-2.0_p119 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 93e3dbee491b4dc5c12ea6b4ccf7309a apparmor-profiles-2.0-119.tar.gz 38442 -RMD160 41960baad897408ef9fed48829975b7d7ad5381a apparmor-profiles-2.0-119.tar.gz 38442 -SHA256 747be3c170cd9bb599e6c5a6b1c19a1ec8e8f614b469ef52d7e6640830698efd apparmor-profiles-2.0-119.tar.gz 38442 diff --git a/trunk/novell4gentoo/sec-policy/apparmor-profiles/files/digest-apparmor-profiles-2.0_p6376 b/trunk/novell4gentoo/sec-policy/apparmor-profiles/files/digest-apparmor-profiles-2.0_p6376 deleted file mode 100644 index 5144385b..00000000 --- a/trunk/novell4gentoo/sec-policy/apparmor-profiles/files/digest-apparmor-profiles-2.0_p6376 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 526e971c18cc6588271e9ad1787adf2a apparmor-profiles-2.0-6376.tar.gz 33651 -RMD160 cd64269b9c12fd60256f624b7b81aa1bddbb74c3 apparmor-profiles-2.0-6376.tar.gz 33651 -SHA256 55103b0ce98616b6860fb43eff23587ad0faf5e38ab828bdd025d87a55b0f073 apparmor-profiles-2.0-6376.tar.gz 33651 diff --git a/trunk/novell4gentoo/sec-policy/apparmor-profiles/metadata.xml b/trunk/novell4gentoo/sec-policy/apparmor-profiles/metadata.xml deleted file mode 100644 index 966145c4..00000000 --- a/trunk/novell4gentoo/sec-policy/apparmor-profiles/metadata.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - -apparmor - - zepher@sigalrm.com - Matthew Snelham - Primary Maintainer - -Default Apparmor profiles from the official Novell releases. - diff --git a/trunk/novell4gentoo/sec-policy/metadata.xml b/trunk/novell4gentoo/sec-policy/metadata.xml deleted file mode 100644 index 054eb1da..00000000 --- a/trunk/novell4gentoo/sec-policy/metadata.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - The sec-policy category contains security policies for - access control systems such as SELinux. - - - La categoría sec-policy contiene políticas de seguridad para sistemas de - control de acceso como SELinux. - - - Die Kategorie sec-policy enthält Sicherheitsrichtlinien für - Zugriffskontrollsysteme wie SELinux. - - - sec-policyカテゴリーにはSELinuxのようなアクセス・コントロール・システムの - ためのセキュリティポリシー(修正をが加えられたパッケージ)が含まれています。 - - - De sec-policy categorie bevat beveilingsrichtlijnen voor toegangscontrole- - systemen als SELinux. - - - Nhóm sec-policy chứa các chính sách an ninh cho các hệ thống - điều khiển quyền truy cập như SELinux. - - - La categoria sec-policy contiene le politiche di sicurezza per i sistemi di controllo - di accesso come SELinux. - - - A categoria sec-policy contém políticas de segurança para - sistemas de controle de acesso como SELinux. - - - Kategoria sec-policy zawiera polityki bezpieczeństwa i programy kontroli - dostępu takie jak np. SELinux. - - - diff --git a/trunk/novell4gentoo/sys-apps/apparmor-modules/Manifest b/trunk/novell4gentoo/sys-apps/apparmor-modules/Manifest deleted file mode 100644 index 2cf7a529..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-modules/Manifest +++ /dev/null @@ -1,16 +0,0 @@ -AUX apparmor-modules-2.0_2.6.17.9_symbol_export.patch 2976 RMD160 b9232cb4b78bfccd7154f27af554aedc0a01b53f SHA1 19ac2f051379f6733f7760eee2c37dde670bb746 SHA256 f364111249e598379886880d427435474609898dd77df8770112b3594305bd80 -MD5 fb0f6966a5fafacc3ca5cd453973e3f9 files/apparmor-modules-2.0_2.6.17.9_symbol_export.patch 2976 -RMD160 b9232cb4b78bfccd7154f27af554aedc0a01b53f files/apparmor-modules-2.0_2.6.17.9_symbol_export.patch 2976 -SHA256 f364111249e598379886880d427435474609898dd77df8770112b3594305bd80 files/apparmor-modules-2.0_2.6.17.9_symbol_export.patch 2976 -DIST apparmor-external-module.tar.gz 112408 RMD160 b333459588b0ccaaf36c6247555ff560daa3f95c SHA1 fbef407f3611c8c38ca66ce977fc5271e4140eec SHA256 70d66089a46f87f7fbaf504a3e40e4511e21c4a03345f0142315743bb9278d2f -EBUILD apparmor-modules-2.0_p20061013.ebuild 2247 RMD160 2d24031783f504a6b14c851ad6b17c71321734c6 SHA1 654ad904b3fc212aac414ac1f5d5232481521dbd SHA256 6bb6ab77b7031d06f15ca6e7d184106bdac67cb5fb1140a4fb5e7c49c4ae878e -MD5 28986c695d0e89060b84df4f2ba26ef0 apparmor-modules-2.0_p20061013.ebuild 2247 -RMD160 2d24031783f504a6b14c851ad6b17c71321734c6 apparmor-modules-2.0_p20061013.ebuild 2247 -SHA256 6bb6ab77b7031d06f15ca6e7d184106bdac67cb5fb1140a4fb5e7c49c4ae878e apparmor-modules-2.0_p20061013.ebuild 2247 -MISC metadata.xml 380 RMD160 95812084d1fe1893b607bec7b448d2bd7920600a SHA1 766cf3cabd61149d9041b84aee4953f4f4e89b86 SHA256 5decb87b114447cecedd46af9b0ee264093dd4b0b1550aa6414c2fdf44ef26ee -MD5 cf1a96cd124b5fc5b8646794bbc6b3cc metadata.xml 380 -RMD160 95812084d1fe1893b607bec7b448d2bd7920600a metadata.xml 380 -SHA256 5decb87b114447cecedd46af9b0ee264093dd4b0b1550aa6414c2fdf44ef26ee metadata.xml 380 -MD5 ada15501d8ce59813443b9fb8b7359ef files/digest-apparmor-modules-2.0_p20061013 274 -RMD160 76b75c7fd71ca82c198ecb095af6723f6314188e files/digest-apparmor-modules-2.0_p20061013 274 -SHA256 f382eb61c05a9f0e47d7b5e336bb296846875f76e2fe59261eaab4cf9d42d93c files/digest-apparmor-modules-2.0_p20061013 274 diff --git a/trunk/novell4gentoo/sys-apps/apparmor-modules/apparmor-modules-2.0_p20061013.ebuild b/trunk/novell4gentoo/sys-apps/apparmor-modules/apparmor-modules-2.0_p20061013.ebuild deleted file mode 100644 index 284d0d61..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-modules/apparmor-modules-2.0_p20061013.ebuild +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit linux-mod - -MY_S="${WORKDIR}/apparmor_modules/module" -MONTH="October" - -DESCRIPTION="Kernel modules for AppArmor" -HOMEPAGE="ihttp://forge.novell.com/modules/xfmod/project/?apparmor" -SRC_URI="http://forgeftp.novell.com/apparmor/Development%20-%20${MONTH}%20Snapshot/apparmor-external-module.tar.gz" - -LICENSE="LGPL-2.1" -SLOT="0" -KEYWORDS="~x86 ~amd64" -IUSE="" - -DEPEND="virtual/libc" -RDEPEND="${DEPEND} - sys-apps/apparmor-parser" - -pkg_setup() { - linux-info_pkg_setup - - if kernel_is lt 2 6 16 ; then - eerror "You must have at least a 2.6.16 kernel to use this package." - die "Insufficent kernel version" - fi - - #if kernel_is eq 2 6 18 ; then - # eerror "Support for 2.6.18 and forward kernels is not yet availible" - # die "Unsupported kernel version" - #fi - - if linux_chkconfig_present CONFIG_SECURITY ; then - eerror "CONFIG_SECURITY must be enabled in your kernel to build ${PN}" - die "Bad kernel config" - fi - - if (grep 'namespace_sem' ${KV_DIR}/include/linux/namespace.h >/dev/null 2>&1 && grep 'AUDIT_SD' ${KV_DIR}/include/linux/audit.h >/dev/null 2>&1 ) - then - einfo "Required Symbol patch seems to have been applied; continuing." - else - eerror "Required symbols do not appear to be exported." - ewarn - ewarn "AppArmor modules requires a patch be applied against the" - ewarn "kernel source to export several symbols." - ewarn - ewarn "Current patches can currently be found in: " - ewarn " ${FILESDIR}" - ewarn "where the clostest matching KERNEL_VER patch:" - ewarn " ${P/_p*/}_[KERNEL_VER]_symbol_export.patch" - ewarn "should apply cleanly." - ewarn - ewarn "After applying this patch and re-compiling," - ewarn "re-emerge this package" - ewarn - die "Missing apparmor symbol export patch" - fi - -} - -src_unpack() { - unpack ${A} - cd "${MY_S}" - - sed -i 's/^all:/modules:/g' Makefile - sed -i 's/mv/#mv/g' Makefile -} - -src_compile() { - cd "${MY_S}" - unset ARCH - CONFIG_SECURITY_APPARMOR=m make -} - -src_install() { - cd "${MY_S}" - - insinto /lib/modules/${KV_FULL}/kernel/security/apparmor - doins apparmor.ko - insinto /lib/modules/${KV_FULL}/kernel/security/apparmor/aamatch - doins aamatch/aamatch_pcre.ko -} diff --git a/trunk/novell4gentoo/sys-apps/apparmor-modules/files/apparmor-modules-2.0_2.6.17.9_symbol_export.patch b/trunk/novell4gentoo/sys-apps/apparmor-modules/files/apparmor-modules-2.0_2.6.17.9_symbol_export.patch deleted file mode 100644 index c0e97bb9..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-modules/files/apparmor-modules-2.0_2.6.17.9_symbol_export.patch +++ /dev/null @@ -1,83 +0,0 @@ -From: tonyj@suse.de -Subject: Export namespace semaphore -Patch-mainline: no - -Export global namespace_sem (this used to be a per namespace semaphore). -Alas, this isn't going to win _any_ points for style. -Patch is not in mainline -- pending AppArmor code submission to lkml - ---- ---- linux-2.6.17.9.orig/fs/namespace.c -+++ linux-2.6.17.9/fs/namespace.c -@@ -46,7 +46,8 @@ static int event; - static struct list_head *mount_hashtable __read_mostly; - static int hash_mask __read_mostly, hash_bits __read_mostly; - static kmem_cache_t *mnt_cache __read_mostly; --static struct rw_semaphore namespace_sem; -+struct rw_semaphore namespace_sem; -+EXPORT_SYMBOL_GPL(namespace_sem); - - /* /sys/fs */ - decl_subsys(fs, NULL, NULL); ---- linux-2.6.17.9.orig/include/linux/namespace.h -+++ linux-2.6.17.9/include/linux/namespace.h -@@ -5,6 +5,9 @@ - #include - #include - -+/* exported for AppArmor (SubDomain) */ -+extern struct rw_semaphore namespace_sem; -+ - struct namespace { - atomic_t count; - struct vfsmount * root; - - -From: tonyj@suse.de -Subject: Export audit subsystem for use by modules -Patch-mainline: no - -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 - ---- linux-2.6.17.9.orig/include/linux/audit.h -+++ linux-2.6.17.9/include/linux/audit.h -@@ -96,6 +96,8 @@ - #define AUDIT_LAST_KERN_ANOM_MSG 1799 - #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */ - -+#define AUDIT_SD 1500 /* AppArmor (SubDomain) audit */ -+ - #define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */ - - /* Rule flags */ -@@ -357,6 +359,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))); ---- linux-2.6.17.9.orig/kernel/audit.c -+++ linux-2.6.17.9/kernel/audit.c -@@ -893,8 +893,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; -@@ -1096,3 +1095,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); diff --git a/trunk/novell4gentoo/sys-apps/apparmor-modules/files/digest-apparmor-modules-2.0_p20061013 b/trunk/novell4gentoo/sys-apps/apparmor-modules/files/digest-apparmor-modules-2.0_p20061013 deleted file mode 100644 index 9f05f658..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-modules/files/digest-apparmor-modules-2.0_p20061013 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 919d64ba6c357a24a3c8e78ea0f94058 apparmor-external-module.tar.gz 112408 -RMD160 b333459588b0ccaaf36c6247555ff560daa3f95c apparmor-external-module.tar.gz 112408 -SHA256 70d66089a46f87f7fbaf504a3e40e4511e21c4a03345f0142315743bb9278d2f apparmor-external-module.tar.gz 112408 diff --git a/trunk/novell4gentoo/sys-apps/apparmor-modules/metadata.xml b/trunk/novell4gentoo/sys-apps/apparmor-modules/metadata.xml deleted file mode 100644 index 4f3db4fa..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-modules/metadata.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - -apparmor-modules - - zepher@sigalrm.com - Matthew Snelham - Primary Maintainer - -Apparmor kernel modules - diff --git a/trunk/novell4gentoo/sys-apps/apparmor-parser/Manifest b/trunk/novell4gentoo/sys-apps/apparmor-parser/Manifest deleted file mode 100644 index 21cda47d..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-parser/Manifest +++ /dev/null @@ -1,28 +0,0 @@ -AUX aaeventd 824 RMD160 032cce20f81b7b0e1f6f38cb6e1c392d70407ad5 SHA1 8adaa5e21867cab21c5fa907c974fb94cb280f70 SHA256 dbaa7fd1197388146c7a1a9b59553815fdcd0498510f7b7bf752af88f8eb1780 -MD5 379ee71ea946bd90c98e94e362bf9f2c files/aaeventd 824 -RMD160 032cce20f81b7b0e1f6f38cb6e1c392d70407ad5 files/aaeventd 824 -SHA256 dbaa7fd1197388146c7a1a9b59553815fdcd0498510f7b7bf752af88f8eb1780 files/aaeventd 824 -AUX apparmor 1090 RMD160 8d9781974318232731ef26881d7d57fc5991044c SHA1 2acee7585d1329bcb92cb8902ec36e1d0b94f5d6 SHA256 5c7b251473e7bf6a876e0d59d89cff3707bf5a6fcda0d9e95d50a463c8eddc8f -MD5 7771cab70810b82185f0ed211f131018 files/apparmor 1090 -RMD160 8d9781974318232731ef26881d7d57fc5991044c files/apparmor 1090 -SHA256 5c7b251473e7bf6a876e0d59d89cff3707bf5a6fcda0d9e95d50a463c8eddc8f files/apparmor 1090 -AUX rc.apparmor.functions 11898 RMD160 12453790ffd14deed48b062f27d12bf2b2910ee4 SHA1 ec936b69474750dfd0205f451472e7d81b66f41a SHA256 d9cdb82c10bb5aa40c39d0f93c418a11020abc2d6df7154a831a71c816345618 -MD5 2adf748409596598872530ec06ef8717 files/rc.apparmor.functions 11898 -RMD160 12453790ffd14deed48b062f27d12bf2b2910ee4 files/rc.apparmor.functions 11898 -SHA256 d9cdb82c10bb5aa40c39d0f93c418a11020abc2d6df7154a831a71c816345618 files/rc.apparmor.functions 11898 -AUX rc.helper.functions 690 RMD160 d0b3b06a45645be5bc9d30b8ef19d518ac59940a SHA1 a58ba3ca5d59e099a3570ee21a62f5b4a6eb25fa SHA256 d065ac76a66d856716d77dd06b64478ed90c3b487d414cf8e33fc46ea77a723d -MD5 5d9c000b99bd66788b988cb6d14b9b3d files/rc.helper.functions 690 -RMD160 d0b3b06a45645be5bc9d30b8ef19d518ac59940a files/rc.helper.functions 690 -SHA256 d065ac76a66d856716d77dd06b64478ed90c3b487d414cf8e33fc46ea77a723d files/rc.helper.functions 690 -DIST apparmor-parser-2.0-150.tar.gz 189171 RMD160 cf3299716fdf042cf326cf884d93fdcb5089dba6 SHA1 099ae08655ee2fc1d206166a7a4f8622637c02fc SHA256 678027c88cf69b42f8c7a36adfbe917489eb80800bc9eefe3b3f043bf01e6ee6 -EBUILD apparmor-parser-2.0_p150.ebuild 1534 RMD160 652650ef546dc3c89047c57ad786d26b7dc01a9e SHA1 88f2bc8bc7edf9e78191de27da30d657d1de8f58 SHA256 57b280dbe289c33afc5bee01eccaf6656db9a3d6836b2c1a00d5a307207e19cf -MD5 cca56bab055f29313b607265af189cb4 apparmor-parser-2.0_p150.ebuild 1534 -RMD160 652650ef546dc3c89047c57ad786d26b7dc01a9e apparmor-parser-2.0_p150.ebuild 1534 -SHA256 57b280dbe289c33afc5bee01eccaf6656db9a3d6836b2c1a00d5a307207e19cf apparmor-parser-2.0_p150.ebuild 1534 -MISC metadata.xml 436 RMD160 e15033b9b3e6c069ebf4fc0e0470c5792e33030a SHA1 a441df5f7fca5964bd09ff8f81af063aada1d157 SHA256 5781a6c617edd46a5bb4976d24b07d8df048a7e03b2cf36ea9edcee4fc9e3cfc -MD5 832848da3df614d8f1bcb956856bb75e metadata.xml 436 -RMD160 e15033b9b3e6c069ebf4fc0e0470c5792e33030a metadata.xml 436 -SHA256 5781a6c617edd46a5bb4976d24b07d8df048a7e03b2cf36ea9edcee4fc9e3cfc metadata.xml 436 -MD5 f8b11c14f5b9a1945c17a5f94b338d2b files/digest-apparmor-parser-2.0_p150 271 -RMD160 a70e60c1977d77b9b90bca4617758a60e1449115 files/digest-apparmor-parser-2.0_p150 271 -SHA256 0d5798506f6e78b3f6f8bff3f1d8d98d43d040576e2edbe3c893ac8fa164847a files/digest-apparmor-parser-2.0_p150 271 diff --git a/trunk/novell4gentoo/sys-apps/apparmor-parser/apparmor-parser-2.0_p150.ebuild b/trunk/novell4gentoo/sys-apps/apparmor-parser/apparmor-parser-2.0_p150.ebuild deleted file mode 100644 index 49d7a19d..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-parser/apparmor-parser-2.0_p150.ebuild +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit eutils perl-module toolchain-funcs - -MY_PV="${PV/_p/-}" -MY_P="${PN}-${MY_PV}" -MY_S="${WORKDIR}/${PN}-${PV/_p*/}" -MONTH="October" - -DESCRIPTION="The userspace tools and init scripts to load security profiles into the apparmor kernel security module." -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -SRC_URI="http://forgeftp.novell.com/apparmor/Development%20-%20${MONTH}%20Snapshot/${MY_P}.tar.gz" - - -LICENSE="GPL-2" -SLOT="0" -KEYWORDS="~x86 ~amd64" -IUSE="" - -DEPEND="sys-libs/libapparmor - sys-libs/libcap - dev-libs/libpcre - sys-devel/bison - sys-devel/flex" - -RDEPEND="(sys-kernel/apparmor-sources || sys-apps/apparmor-modules)" - -src_unpack() { - unpack ${A} - - ## apparmor-parser - cd ${MY_S} - # the Make.rules isn't needed for Gentoo - sed -i "s/^include Make.rules//g" Makefile - # Un-needed historical artifact, AND ugly non-LSB path - # This is mounted at /sys/kernel/security/subdomain, not /subdomain - sed -i 's/^.*\/subdomain//g' Makefile -} - -src_compile() { - cd ${MY_S} - emake CC="$(tc-getCC)" CFLAGS="${CFLAGS}" || die -} - -src_install() { - - ## apparmor-parser - cd ${MY_S} - make DESTDIR=${D} install || die - - ## Init script and addtional files - doinitd ${FILESDIR}/apparmor - doinitd ${FILESDIR}/aaeventd - insopts -m0644 - insinto /lib/apparmor - doins ${FILESDIR}/rc.helper.functions - doins ${FILESDIR}/rc.apparmor.functions - - dodir /etc/apparmor.d/abstractions -} diff --git a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/aaeventd b/trunk/novell4gentoo/sys-apps/apparmor-parser/files/aaeventd deleted file mode 100755 index efe9cc39..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/aaeventd +++ /dev/null @@ -1,40 +0,0 @@ -#!/sbin/runscript -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions -APPARMOR_HELPERS=/lib/apparmor/rc.helper.functions -if [ -f "${APPARMOR_HELPERS}" -a -f "${APPARMOR_FUNCTIONS}" ]; then - source ${APPARMOR_HELPERS} - source ${APPARMOR_FUNCTIONS} -else - eend 1 "Unable to find AppArmor initscript functions" -fi - -depend() { - need apparmor - use logger dns -} - -start() { - ebegin "Starting aaeventd (AppArmor Event Daemon)" - - if [ "${APPARMOR_ENABLE_AAEVENTD}" = "no" ]; then - eend 1 " aaeventd disabled in ${APPARMOR_CONF}." - fi - - start_sd_event - eend $waserror -} - -stop() { - ebegin "Stopping aaeventd (AppArmor Event Daemon)" - stop_sd_event - eend $waserror -} - -restart() { - srv_stop - srv_start -} diff --git a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/apparmor b/trunk/novell4gentoo/sys-apps/apparmor-parser/files/apparmor deleted file mode 100755 index 26daeca0..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/apparmor +++ /dev/null @@ -1,55 +0,0 @@ -#!/sbin/runscript -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ -# -# rc.apparmor.gentoo: contribuited by Matthew Snelham -# /etc/init.d/apparmor - -APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions -APPARMOR_HELPERS=/lib/apparmor/rc.helper.functions -if [ -f "${APPARMOR_HELPERS}" -a -f "${APPARMOR_FUNCTIONS}" ]; then - source ${APPARMOR_HELPERS} - source ${APPARMOR_FUNCTIONS} -else - eend 1 "Unable to find AppArmor initscript functions" -fi - -opts="${opts} reload status" - -depend() { - need localmount - ## AppArmor needs to be loaded before any other - ## (potentially protected) user-space services come up. - #before * -} - -start() { - ebegin "Starting AppArmor" - subdomain_start - einfo "...AppArmor Start" - eend $waserror -} - -stop() { - ebegin "Stopping AppArmor" - subdomain_stop - einfo "...AppArmor Stop" - eend $waserror -} - -restart() { - svc_stop; svc_start -} - -reload() { - ebegin "Restarting AppArmor" - subdomain_restart - eend $? -} - -status() { - ebegin "Checking AppArmor Status" - subdomain_status - eend $? -} diff --git a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/digest-apparmor-parser-2.0_p150 b/trunk/novell4gentoo/sys-apps/apparmor-parser/files/digest-apparmor-parser-2.0_p150 deleted file mode 100644 index 1b254d32..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/digest-apparmor-parser-2.0_p150 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 cbb25435e4353b10b5fdd96f80c854b9 apparmor-parser-2.0-150.tar.gz 189171 -RMD160 cf3299716fdf042cf326cf884d93fdcb5089dba6 apparmor-parser-2.0-150.tar.gz 189171 -SHA256 678027c88cf69b42f8c7a36adfbe917489eb80800bc9eefe3b3f043bf01e6ee6 apparmor-parser-2.0-150.tar.gz 189171 diff --git a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/rc.apparmor.functions b/trunk/novell4gentoo/sys-apps/apparmor-parser/files/rc.apparmor.functions deleted file mode 100755 index 890f3fbb..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/rc.apparmor.functions +++ /dev/null @@ -1,443 +0,0 @@ -#!/bin/sh -# -# ---------------------------------------------------------------------- -# Copyright (c) 1999, 2000, 20001, 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. -# ---------------------------------------------------------------------- -# rc.subdomain.functions by Steve Beattie -# Modified for Gentoo Linux, by Matthew Snelham -# -# Modifications Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - - -# NOTE: rc.subdomain initscripts that source this file need to implement -# the following set of functions: -# sd_action -# sd_log_info_msg -# sd_log_success_msg -# sd_log_warning_msg -# sd_log_failure_msg - - -CONFIG_DIR=/etc/apparmor -MODULE=apparmor -OLD_MODULE=subdomain -if [ -f "${CONFIG_DIR}/${MODULE}.conf" ] ; then - APPARMOR_CONF="${CONFIG_DIR}/${MODULE}.conf" -elif [ -f "${CONFIG_DIR}/${OLD_MODULE}.conf" ] ; then - APPARMOR_CONF="${CONFIG_DIR}/${OLD_MODULE}.conf" -else - sd_log_warning_msg "Unable to find config file in ${CONFIG_DIR}, installation problem?" -fi - -# Read configuration options from ${APPARMOR_CONF}, default is to -# warn if subdomain won't load. -APPARMOR_MODULE_PANIC="warn" -SUBDOMAIN_ENABLE_OWLSM="no" -APPARMOR_ENABLE_AAEVENTD="no" - -if [ -f "${APPARMOR_CONF}" ] ; then - source "${APPARMOR_CONF}" -fi - -if [ -f /sbin/apparmor_parser ] ; then - PARSER=/sbin/apparmor_parser -else - sd_log_failure_msg "Unable to find apparmor_parser, installation problem?" - exit 1 -fi - -# APPARMOR_DIR might be redefined in ${APPARMOR_CONF} -if [ -d "${APPAMROR_DIR}" ] ; then - PROFILE_DIR=${APPARMOR_DIR} -elif [ -d /etc/apparmor.d ] ; then - PROFILE_DIR=/etc/apparmor.d -fi -ABSTRACTIONS="-I${PROFILE_DIR}" -AA_EV_BIN=/usr/sbin/aa-eventd -AA_EV_PIDFILE=/var/run/aa-eventd.pid -AA_STATUS=/usr/sbin/apparmor_status -SD_EV_BIN=/usr/sbin/sd-event-dispatch.pl -SD_EV_PIDFILE=/var/run/sd-event-dispatch.init.pid -SD_STATUS=/usr/sbin/subdomain_status -if grep -q securityfs /proc/filesystems ; then - SECURITYFS=/sys/kernel/security -fi - -SUBDOMAINFS_MOUNTPOINT=$(grep subdomainfs /etc/fstab | \ - sed -e 's|^[[:space:]]*[^[:space:]]\+[[:space:]]\+\(/[^[:space:]]*\)[[:space:]]\+subdomainfs.*$|\1|' 2> /dev/null) - -if [ -d "/var/lib/${MODULE}" ] ; then - APPARMOR_TMPDIR="/var/lib/${MODULE}" -else - APPARMOR_TMPDIR="/tmp" -fi - - -function parse_profiles() { - # get parser arg - case "$1" in - load) - PARSER_ARGS="--add" - PARSER_MSG="Loading AppArmor profiles " - ;; - reload) - PARSER_ARGS="--replace" - PARSER_MSG="Reloading AppArmor profiles " - ;; - *) - exit 1 - ;; - esac - sd_log_info_msg "$PARSER_MSG" - - # run the parser on all of the apparmor profiles - if [ ! -f "$PARSER" ]; then - sd_log_failure_msg "$PARSER_MSG - AppArmor parser not found" - exit 1 - fi - - if [ ! -d "$PROFILE_DIR" ]; then - sd_log_failure_msg "$PARSER_MSG - Profile directory not found" - exit 1 - fi - - if [ "X" == "X$(ls $PROFILE_DIR/)" ]; then - sd_log_warning_msg "$PARSER_MSG - No profiles found" - exit 1 - fi - - for profile in $PROFILE_DIR/*; do - if [ "${profile%.rpmnew}" != "${profile}" -o \ - "${profile%.rpmsave}" != "${profile}" -o \ - "${profile%\~}" != "${profile}" ] - then - sd_log_warning_msg "Skipping profile $profile" - elif [ -f "${profile}" ] ; then - sd_action " Adding profile: `basename ${profile}`" $PARSER $ABSTRACTIONS $PARSER_ARGS ${profile} - if [ $? -ne 0 ]; then - waserror=1 - fi - fi - done -} - -function profiles_names_list() { - # run the parser on all of the apparmor profiles - TMPFILE=$1 - if [ ! -f "$PARSER" ]; then - sd_log_failure_msg "AppArmor parser ($PARSER) not found" - exit 1 - fi - - if [ ! -d "$PROFILE_DIR" ]; then - sd_log_failure_msg "Profile directory ($PROFILE_DIR) not found" - exit 1 - fi - - for profile in $PROFILE_DIR/*; do - if [ "${profile%.rpmnew}" != "${profile}" -o \ - "${profile%.rpmsave}" != "${profile}" -o \ - "${profile%\~}" != "${profile}" ] - then - echo "nop" >/dev/null - elif [ -f "${profile}" ] ; then - LIST_ADD=$($PARSER $ABSTRACTIONS -N "$profile" | grep -v '\^') - if [ $? -eq 0 ]; then - echo "$LIST_ADD" >>$TMPFILE - fi - fi - done -} - -function is_securityfs_mounted() { - if grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts ; then - if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then - SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}" - return 0 - fi - fi - return 1 -} - -function mount_securityfs() { - if [ "X" != "X${SECURITYFS}" ]; then - if ! grep -q securityfs /proc/mounts ; then - sd_action "Mounting securityfs on ${SECURITYFS}" \ - mount -t securityfs securityfs "${SECURITYFS}" - rc=$? - if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then - SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}" - else - SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}" - fi - return $rc - fi - fi - return 0 -} - -function unmount_securityfs() { - SUBDOMAINFS=$(grep subdomainfs /proc/mounts | cut -d" " -f2 2> /dev/null) - if [ "X" != "X${SUBDOMAINFS}" ]; then - sd_action "Unmounting securityfs" umount ${SUBDOMAINFS} - fi -} - -function failstop_system() { - level=$(runlevel | cut -d" " -f2) - if [ $level -ne "1" ] ; then - sd_log_failure_msg "Could not start AppArmor. Changing to runlevel 1" - telinit 1; - return -1; - fi - sd_log_failure_msg "Could not start AppArmor." - return -1 -} - -function module_panic() { - # the module failed to load, determine what action should be taken - - case "$APPARMOR_MODULE_PANIC" in - "warn"|"WARN") sd_log_failure_msg "Could not start AppArmor" - return -1 ;; - "panic"|"PANIC") failstop_system - rc=$? - return $rc ;; - *) sd_log_failure_msg "Invalid AppArmor module fail option" - return -1 ;; - esac -} - -function load_module() { - if modinfo -F filename apparmor > /dev/null 2>&1 ; then - MODULE=apparmor - elif modinfo -F filename subdomain > /dev/null 2>&1 ; then - MODULE=subdomain - fi - if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then - sd_action "Loading AppArmor module" /sbin/modprobe $MODULE $1 - rc=$? - if [ $rc -ne 0 ] ; then - # we couldn't find the module - module_panic - rc=$? - if [ $rc -ne 0 ] ; then - exit $rc - fi - fi - fi -} - -function start_sd_event() { - if [ -x "$AA_EV_BIN" -a "${APPARMOR_ENABLE_AAEVENTD}" = "yes" ] ; then - sd_action "Starting AppArmor Event daemon" startproc -f -p $AA_EV_PIDFILE $AA_EV_BIN -p $AA_EV_PIDFILE - elif [ -x "$SD_EV_BIN" -a "${APPARMOR_ENABLE_AAEVENTD}" = "yes" ] ; then - sd_action "Starting AppArmor Event daemon" startproc -f -p $SD_EV_PIDFILE $SD_EV_BIN -p $SD_EV_PIDFILE - fi -} - -function stop_sd_event() { - if [ -x "$AA_EV_BIN" -a -f "$AA_EV_PIDFILE" ] ; then - sd_action "Shutting down AppArmor Event daemon" killproc -G -p $AA_EV_PIDFILE -INT $AA_EV_BIN - fi - if [ -f "$SD_EV_PIDFILE" ] ; then - sd_action "Shutting down AppArmor Event daemon" killproc -G -p $SD_EV_PIDFILE -INT $SD_EV_BIN - fi -} - -function subdomain_start() { - if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then - load_module - rc=$? - if [ $rc -ne 0 ] ; then - return $rc - fi - fi - - if ! is_securityfs_mounted ; then - mount_securityfs - rc=$? - if [ $rc -ne 0 ] ; then - return $rc - fi - fi - - if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then - sd_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?" - return 1 - fi - - configure_owlsm - - if [ $(wc -l "$SFS_MOUNTPOINT/profiles" | awk '{print $1}') -eq 0 ] ; then - parse_profiles load - else - sd_log_warning_msg "Loading AppArmor profiles - AppArmor already loaded with profiles." - fi -} - -function remove_profiles() { - # removing profiles as we directly read from subdomainfs - # doesn't work, since we are removing entries which screws up - # our position. Lets hope there are never enough profiles to - # overflow the variable - if ! is_securityfs_mounted ; then - sd_log_failure_msg "failed: is securityfs loaded?" - return 1 - fi - - if [ ! -w "$SFS_MOUNTPOINT/.remove" ] ; then - sd_log_failure_msg "failed: Do you have the correct privileges?" - return 1 - fi - - if [ ! -x "${PARSER}" ] ; then - sd_log_failure_msg "failed: unable to execute subdomain parser" - return 1 - fi - - retval=0 - IFS=$'\n' - enforced_profiles=$(sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles") - for profile in $enforced_profiles ; do - sd_action " Removing profile: ${profile}" sh -c "echo \"$profile { }\" | $PARSER -R" - rc=$? - if [ ${rc} -ne 0 ] ; then - retval=${rc} - fi - done - if [ ${retval} -ne 0 ] ; then - waserror=1 - fi -} - -function subdomain_stop() { - stop_sd_event - sd_log_info_msg "Unloading AppArmor profiles" - remove_profiles -} - -function subdomain_kill() { - stop_sd_event - unmount_securityfs - if grep -qE "^apparmor[[:space:]]" /proc/modules ; then - MODULE=apparmor - elif grep -qE "^subdomain[[:space:]]" /proc/modules ; then - MODULE=subdomain - else - MODULE=apparmor - fi - sd_action "Unloading AppArmor modules" /sbin/modprobe -r $MODULE -} - -function __subdomain_restart() { - if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then - sd_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?" - return 4 - fi - - configure_owlsm - parse_profiles reload - PNAMES_LIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX) - profiles_names_list ${PNAMES_LIST} - MODULE_PLIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX) - sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | sort >"$MODULE_PLIST" - #profiles=$(cat $PNAMES_LIST | sort | comm -2 -3 "$MODULE_PLIST" -) - #for profile in $profiles ; do - IFS=$'\n' && for profile in $(cat $PNAMES_LIST | sort | comm -2 -3 "$MODULE_PLIST" -) ; do - echo "\"$profile\" {}" | $PARSER -R >/dev/null - done - rm "$MODULE_PLIST" - rm "$PNAMES_LIST" - return 0 -} - -function subdomain_restart() { - if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then - subdomain_start - rc=$? - return $rc - fi - - if ! is_securityfs_mounted ; then - mount_securityfs - rc=$? - if [ $rc -ne 0 ] ; then - return $rc - fi - fi - - __subdomain_restart - rc=$? - return $rc -} - -function subdomain_try_restart() { - if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then - return 1 - fi - - if ! is_securityfs_mounted ; then - return 1 - fi - - __subdomain_restart - rc=$? - return $rc -} - -function subdomain_debug() { - subdomain_kill - load_module "subdomain_debug=1" - mount_securityfs - configure_owlsm - parse_profiles load -} - -function configure_owlsm () { - if [ "${SUBDOMAIN_ENABLE_OWLSM}" = "yes" -a -f ${SFS_MOUNTPOINT}/control/owlsm ] ; then - # Sigh, the "sh -c" is necessary for the SuSE sd_action - # and it can't be abstracted out as a seperate function, as - # that breaks under RedHat's action, which needs a - # binary to invoke. - sd_action "Enabling OWLSM extension" sh -c "echo -n \"1\" > \"${SFS_MOUNTPOINT}/control/owlsm\"" - elif [ -f "${SFS_MOUNTPOINT}/control/owlsm" ] ; then - sd_action "Disabling OWLSM extension" sh -c "echo -n \"0\" > \"${SFS_MOUNTPOINT}/control/owlsm\"" - fi -} - -function subdomain_status () { - if test -x ${AA_STATUS} ; then - ${AA_STATUS} --verbose - return $? - fi - if test -x ${SD_STATUS} ; then - ${SD_STATUS} --verbose - return $? - fi - if ! grep -qE "^(subdomain|apparmor)[[:space:]]" /proc/modules ; then - sd_log_failure_msg "AppArmor not loaded." - rc=1 - else - sd_log_success_msg "AppArmor module enabled." - rc=0 - fi - sd_log_warning_msg "Install the apparmor-utils package to receive more detailed" - sd_log_warning_msg "status information here (or examine ${SFS_MOUNTPOINT} directly)." - - return $rc -} diff --git a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/rc.helper.functions b/trunk/novell4gentoo/sys-apps/apparmor-parser/files/rc.helper.functions deleted file mode 100644 index 692414e3..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-parser/files/rc.helper.functions +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -waserror=0 - -function sd_action() { - MSG=$1 - shift - #echo "ACTION: $*" - $* > /dev/null - rc=$? - if [ $rc -ne 0 ] ; then - sd_log_failure_msg $"$MSG" - else - sd_log_success_msg $"$MSG" - fi - return $rc -} - -function sd_log_info_msg() { - einfo " $*" -} - -function sd_log_warning_msg() { - ewarn " $*" -} - -function sd_log_success_msg() { - einfo " $*" - eend 0 -} - -function sd_log_failure_msg() { - waserror=1 - einfo " $*" - eend 1 -} - -function startproc() { - /sbin/start-stop-daemon --start -p $3 --exec $4 -- -p $3 -} - -function killproc() { - /sbin/start-stop-daemon --stop -p $3 -} - diff --git a/trunk/novell4gentoo/sys-apps/apparmor-parser/metadata.xml b/trunk/novell4gentoo/sys-apps/apparmor-parser/metadata.xml deleted file mode 100644 index 9f03219f..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-parser/metadata.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - -apparmor - - zepher@sigalrm.com - Matthew Snelham - Primary Maintainer - -Core Apparmor package containing userspace policy parser, utilities, and documentation. - diff --git a/trunk/novell4gentoo/sys-apps/apparmor-utils/Manifest b/trunk/novell4gentoo/sys-apps/apparmor-utils/Manifest deleted file mode 100644 index 8524a70e..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-utils/Manifest +++ /dev/null @@ -1,12 +0,0 @@ -DIST apparmor-utils-2.0-142.tar.gz 87393 RMD160 306371feded05fd6fc0daeb418aa85ed0a07f95b SHA1 7686dbc1e5a1df0f7fba9fff95d6d692372e3360 SHA256 27e1d9716bcfa82ebb12163e59734b1ce3a8598b9af3031b04498142e872c6b8 -EBUILD apparmor-utils-2.0_p142.ebuild 1179 RMD160 876ccf1fab163dcc310280f8d489efc9e7079a17 SHA1 795fa5c5558185638062cf011b26a78547e213a3 SHA256 9fd1410245fbca6c76de0f67f8a10e430e50d154d9facc82ceb840cd806bfd21 -MD5 a05a89d6ce564e3215e08ef3e7ecd20f apparmor-utils-2.0_p142.ebuild 1179 -RMD160 876ccf1fab163dcc310280f8d489efc9e7079a17 apparmor-utils-2.0_p142.ebuild 1179 -SHA256 9fd1410245fbca6c76de0f67f8a10e430e50d154d9facc82ceb840cd806bfd21 apparmor-utils-2.0_p142.ebuild 1179 -MISC metadata.xml 412 RMD160 7e37f8a3e1009597bbd430fd280b15009e3b01d8 SHA1 681094f0550454d2931d0e08f50ab9829b61c625 SHA256 658f844f1a47f69962d42d4fd00961327f7a42bdfee2737bfe22605c4a23d8ec -MD5 f3a4b4e95726969c96d8930966395051 metadata.xml 412 -RMD160 7e37f8a3e1009597bbd430fd280b15009e3b01d8 metadata.xml 412 -SHA256 658f844f1a47f69962d42d4fd00961327f7a42bdfee2737bfe22605c4a23d8ec metadata.xml 412 -MD5 fa93f53f0da00233ecf5f96ca3205461 files/digest-apparmor-utils-2.0_p142 265 -RMD160 fb95c24dd19ede19556c35a65085736241a5a868 files/digest-apparmor-utils-2.0_p142 265 -SHA256 9e4f3666c0beaa61748c798a3937b529cc8110901f5405bdc498f4668c8d6eb9 files/digest-apparmor-utils-2.0_p142 265 diff --git a/trunk/novell4gentoo/sys-apps/apparmor-utils/apparmor-utils-2.0_p142.ebuild b/trunk/novell4gentoo/sys-apps/apparmor-utils/apparmor-utils-2.0_p142.ebuild deleted file mode 100644 index 2a48e33f..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-utils/apparmor-utils-2.0_p142.ebuild +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit eutils perl-module toolchain-funcs - -#MY_PN="apparmor-utils" -MY_PV="${PV/_p/-}" -MY_P="${PN}-${MY_PV}" -MY_S="${WORKDIR}/${PN}-${PV/_p*/}" -MONTH="October" - -DESCRIPTION="AppArmor utilities for profile creation and management." -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -SRC_URI="http://forgeftp.novell.com/apparmor/Development%20-%20${MONTH}%20Snapshot/${MY_P}.tar.gz" - -LICENSE="GPL-2" -SLOT="0" -KEYWORDS="~x86 ~amd64" -IUSE="" - -DEPEND="sys-libs/libapparmor - sys-apps/aparmor-parser - sys-libs/libcap - dev-libs/libpcre - dev-lang/perl - perl-core/Test-Harness - perl-core/Getopt-Long - dev-perl/DBI - dev-perl/DBD-SQLite - dev-perl/TimeDate - dev-perl/File-Tail - dev-perl/Locale-gettext" -RDEPEND="${DEPEND}" - - -src_unpack() { - unpack ${A} - cd ${MY_S} - - # Correct path for logger - sed -i "s/\/bin\/logger/\/usr\/bin\/logger/g" genprof -} - -src_compile() { - cd ${MY_S} - emake CC="$(tc-getCC)" CFLAGS="${CFLAGS}" || die -} - -src_install() { - cd ${MY_S} - perlinfo - make DESTDIR=${D} PERLDIR="${D}/${VENDOR_LIB}/Immunix" install || die -} diff --git a/trunk/novell4gentoo/sys-apps/apparmor-utils/files/digest-apparmor-utils-2.0_p142 b/trunk/novell4gentoo/sys-apps/apparmor-utils/files/digest-apparmor-utils-2.0_p142 deleted file mode 100644 index 3829459b..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-utils/files/digest-apparmor-utils-2.0_p142 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 b2447c84edc2df843b7bc4baa8a1eb2c apparmor-utils-2.0-142.tar.gz 87393 -RMD160 306371feded05fd6fc0daeb418aa85ed0a07f95b apparmor-utils-2.0-142.tar.gz 87393 -SHA256 27e1d9716bcfa82ebb12163e59734b1ce3a8598b9af3031b04498142e872c6b8 apparmor-utils-2.0-142.tar.gz 87393 diff --git a/trunk/novell4gentoo/sys-apps/apparmor-utils/metadata.xml b/trunk/novell4gentoo/sys-apps/apparmor-utils/metadata.xml deleted file mode 100644 index 38f73850..00000000 --- a/trunk/novell4gentoo/sys-apps/apparmor-utils/metadata.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - -apparmor - - zepher@sigalrm.com - Matthew Snelham - Primary Maintainer - -Apparmor utilities allowing for profile creation and mangement. - diff --git a/trunk/novell4gentoo/sys-apps/metadata.xml b/trunk/novell4gentoo/sys-apps/metadata.xml deleted file mode 100644 index e780a895..00000000 --- a/trunk/novell4gentoo/sys-apps/metadata.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - The sys-apps category contains various core system applications, and - some non-core system applications which have not yet been moved out into - other sys- categories. - - - La categoría sys-apps contiene varios paquetes esenciales del sistema, y - algunos paquetes no esenciales que aún no han sido movidos a otras - categorías sys-. - - - Die Kategorie sys-apps enthält sowohl Programme die Bestandteil des Basissystems sind, - als auch Applikationen die noch nicht in eine der anderen sys- Kategorien eingeordnet - wurden. - - - sys-appsカテゴリには様々なコアシステムアプリケーションの他、まだ他のsys-カテゴリに - 移動されていないシステムアプリケーションが含まれています。 - - - De sys-apps categorie bevat kerenbestanddelen van het systeem, en bepaalde - niet-kern toepassingen die nog niet in andere categorien zijn geplaatst. - - - Nhóm sys-apps chứa các phần mềm hệ thống cốt lõi, và vài phần mềm - hệ thống không phải cốt lõi mà chưa được chuyển sang các nhóm sys- khác. - - - La categoria sys-apps contiene vari pacchetti essenziali per il sistema, e alcuni pacchetti - non essenziali che non sono ancora stati spostati in altre categorie sys-. - - - A categoria sys-apps contém vários pacotes essenciais do sistema, e - algumas aplicações não-centrais que ainda não foram colocadas em - outras categorias sys-. - - - Kategoria sys-apps zawiera programy systemowe oraz inne dodatkowe - programy, których jeszcze nie przeniesiono do kategorii sys-. - - - diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/ChangeLog b/trunk/novell4gentoo/sys-kernel/apparmor-sources/ChangeLog deleted file mode 100644 index 64e901f7..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/ChangeLog +++ /dev/null @@ -1,23 +0,0 @@ -# ChangeLog for sys-kernel/apparmor-sources -# Copyright 1999-2006 Gentoo Foundation; Distributed under the GPL v2 -# $Header: $ - - 13 Aug 2006; Mario Fetka - +files/5000_apparmor-integrate.patch, - +files/5001_apparmor-core-header.patch, - +files/5002_apparmor-lsm-interface.patch, - +files/5004_apparmor-filesystem.patch, +apparmor-sources-2.6.17.ebuild, - +files/5003_apparmor-core-access-controls.patch, - +files/5006_apparmor-misc.patch, +files/5008_apparmor-audit-changes.patch, - +apparmor-sources-2.6.17-r1.ebuild, - +files/apparmor-sources-2.6.17-r1-apparmor_main.patch, - +files/5007_apparmor-pathname-matching-submodule.patch, - +files/5010_apparmor-export-namespace-semaphor.patch, - +files/apparmor-sources-2.6.17-r1-apparmor_audit.patch, - +files/apparmor-sources-2.6.17-r1-apparmor_namespacesem.patch, - +files/5005_apparmor-userspace-interface.patch, - +files/5009_apparmor-add-flags.patch: - Initial Import of - Matthew Snelham - Apparmor ebuilds - diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/Manifest b/trunk/novell4gentoo/sys-kernel/apparmor-sources/Manifest deleted file mode 100644 index 36145c27..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/Manifest +++ /dev/null @@ -1,93 +0,0 @@ -AUX 5000_apparmor-integrate.patch 2398 RMD160 4f3100e01a64531217137303b151d4b8f57cb5ea SHA1 c61a433e8449cd2e173eaf4526de807cd074d12b SHA256 558a025803b209d2502562553e7ec1a42dde706c6a3de4d1a442f4a4a17e8b89 -MD5 d98fc30c0c02d3b6e1fdb5a56973ed67 files/5000_apparmor-integrate.patch 2398 -RMD160 4f3100e01a64531217137303b151d4b8f57cb5ea files/5000_apparmor-integrate.patch 2398 -SHA256 558a025803b209d2502562553e7ec1a42dde706c6a3de4d1a442f4a4a17e8b89 files/5000_apparmor-integrate.patch 2398 -AUX 5001_apparmor-core-header.patch 21692 RMD160 d991a62378cf9394ed785ce170567c5a1636ed3a SHA1 6646b0ab9603356241ca09ac26093649b264e6f5 SHA256 104c8a90f300b967937d2930bfdb46fccc14d1c33e0eeeaccc2539795b02c9f7 -MD5 589ca3ad54269790ce4ff0ac86bf1e22 files/5001_apparmor-core-header.patch 21692 -RMD160 d991a62378cf9394ed785ce170567c5a1636ed3a files/5001_apparmor-core-header.patch 21692 -SHA256 104c8a90f300b967937d2930bfdb46fccc14d1c33e0eeeaccc2539795b02c9f7 files/5001_apparmor-core-header.patch 21692 -AUX 5002_apparmor-lsm-interface.patch 21459 RMD160 b61ddaab908a7a790472d7de3c0ee03dfe576489 SHA1 464d3806b9db782adfba98e37884f538f4f02fdd SHA256 8f22edd4509598b9188ef05b47028a745905af4402482f1698bf123f66d3b407 -MD5 2ef63832bbbef8442cbf8a08d0279425 files/5002_apparmor-lsm-interface.patch 21459 -RMD160 b61ddaab908a7a790472d7de3c0ee03dfe576489 files/5002_apparmor-lsm-interface.patch 21459 -SHA256 8f22edd4509598b9188ef05b47028a745905af4402482f1698bf123f66d3b407 files/5002_apparmor-lsm-interface.patch 21459 -AUX 5003_apparmor-core-access-controls.patch 42703 RMD160 fa685b1526b69cc5e436707b0e94513c963cf7e5 SHA1 756e4adac0c15e216b21c4b86bd390d2318f2092 SHA256 585f135ce0b07bc325503cccd5da07afa559ca75c9c3c0aeef3b1309f59aacb5 -MD5 282fc71ae3ba0b0f37b10e856cb0bbb7 files/5003_apparmor-core-access-controls.patch 42703 -RMD160 fa685b1526b69cc5e436707b0e94513c963cf7e5 files/5003_apparmor-core-access-controls.patch 42703 -SHA256 585f135ce0b07bc325503cccd5da07afa559ca75c9c3c0aeef3b1309f59aacb5 files/5003_apparmor-core-access-controls.patch 42703 -AUX 5004_apparmor-filesystem.patch 11823 RMD160 c356279b0a7aa3c86b7e61fa4fd19fcae01e4e28 SHA1 7bac3503d5d3c1c89c3c83824ce4db5fb4b76d4d SHA256 8ff511068c44f09fa9e9b0892323876373a0dd20cbdafab1847439fb7293228a -MD5 9b00001fd17410a6c5c8d93e1d791a4f files/5004_apparmor-filesystem.patch 11823 -RMD160 c356279b0a7aa3c86b7e61fa4fd19fcae01e4e28 files/5004_apparmor-filesystem.patch 11823 -SHA256 8ff511068c44f09fa9e9b0892323876373a0dd20cbdafab1847439fb7293228a files/5004_apparmor-filesystem.patch 11823 -AUX 5005_apparmor-userspace-interface.patch 25246 RMD160 1aa62cbead83275308c9b2e5bf3658261d1a9381 SHA1 93a99de540ffbec0946192851832b823956cb3a6 SHA256 970934bf9e9d9a4e98e4d78eb4540d1b8d5409f5c97bbbd266ae473b7263d92f -MD5 f9ca3674c76ad58917df78d9ca55a461 files/5005_apparmor-userspace-interface.patch 25246 -RMD160 1aa62cbead83275308c9b2e5bf3658261d1a9381 files/5005_apparmor-userspace-interface.patch 25246 -SHA256 970934bf9e9d9a4e98e4d78eb4540d1b8d5409f5c97bbbd266ae473b7263d92f files/5005_apparmor-userspace-interface.patch 25246 -AUX 5006_apparmor-misc.patch 16419 RMD160 7be689597785f339dd8d8d41fc46c48283acd329 SHA1 728e32285aeb1e8e7ef28c2d8aa8a775ad4b1ab2 SHA256 c44468fd5a698d11095cccb439541feac587388f348bec5f8105449294e1b8f6 -MD5 eda12351340ca5e03ce2df5be7ab1396 files/5006_apparmor-misc.patch 16419 -RMD160 7be689597785f339dd8d8d41fc46c48283acd329 files/5006_apparmor-misc.patch 16419 -SHA256 c44468fd5a698d11095cccb439541feac587388f348bec5f8105449294e1b8f6 files/5006_apparmor-misc.patch 16419 -AUX 5007_apparmor-pathname-matching-submodule.patch 7130 RMD160 53203c04619a1d1491f32af7b67d645cab2b42fd SHA1 f6e08796e9de778de5614f7dc0b3226ec3e0c886 SHA256 08f8cef053a986ac38130743cba28a584c0539f1e7d370cdff3e829e4cd48567 -MD5 2d77b49c08b0f975660174c410f57cfe files/5007_apparmor-pathname-matching-submodule.patch 7130 -RMD160 53203c04619a1d1491f32af7b67d645cab2b42fd files/5007_apparmor-pathname-matching-submodule.patch 7130 -SHA256 08f8cef053a986ac38130743cba28a584c0539f1e7d370cdff3e829e4cd48567 files/5007_apparmor-pathname-matching-submodule.patch 7130 -AUX 5008_apparmor-audit-changes.patch 2107 RMD160 d333371405ac7c595763bc35f312784cc811d366 SHA1 8801e85d409017c6693656b9e41973703170cad8 SHA256 adfed39273b71c470f8eebddf43f0eef2146b3114e517eb574f033005f5a95e5 -MD5 2a4a92e7b58dafaee09f69fa05ebd89a files/5008_apparmor-audit-changes.patch 2107 -RMD160 d333371405ac7c595763bc35f312784cc811d366 files/5008_apparmor-audit-changes.patch 2107 -SHA256 adfed39273b71c470f8eebddf43f0eef2146b3114e517eb574f033005f5a95e5 files/5008_apparmor-audit-changes.patch 2107 -AUX 5009_apparmor-add-flags.patch 5477 RMD160 fc48784cb74cba9cdbdf61c2f561e8951152344e SHA1 f70cad7a35362ff584991c70c1b481127e4b3799 SHA256 adae3a61e66d527586d8118b94843b3021b4c99224d2d8888e37f7dbed5ef783 -MD5 29efc91d396797479864537b9f1e1b6f files/5009_apparmor-add-flags.patch 5477 -RMD160 fc48784cb74cba9cdbdf61c2f561e8951152344e files/5009_apparmor-add-flags.patch 5477 -SHA256 adae3a61e66d527586d8118b94843b3021b4c99224d2d8888e37f7dbed5ef783 files/5009_apparmor-add-flags.patch 5477 -AUX 5010_apparmor-export-namespace-semaphor.patch 2052 RMD160 70bae68ca3aef38c9aea0b4add916fc759efb420 SHA1 4f553490593ebaddec1a8695e6da471466e4cc70 SHA256 42fd27dc8e65a450b6369638495ebcd1d615a23881f4ff7c4a8a334ac6e1e00a -MD5 5d38d075644b24d5018152b2b4a29514 files/5010_apparmor-export-namespace-semaphor.patch 2052 -RMD160 70bae68ca3aef38c9aea0b4add916fc759efb420 files/5010_apparmor-export-namespace-semaphor.patch 2052 -SHA256 42fd27dc8e65a450b6369638495ebcd1d615a23881f4ff7c4a8a334ac6e1e00a files/5010_apparmor-export-namespace-semaphor.patch 2052 -AUX apparmor-sources-2.6.17-r1-apparmor_audit.patch 2247 RMD160 d6c5937273d30de4a83a42ad9256416bf2931a03 SHA1 113abbb7664e6cf205606c78c39086c4aea5883d SHA256 27b8c610ec1dd4b6b8474194061a6616359aa942f3dddf3ae197cadeea8e411c -MD5 aa55bffe2d0bf05ef6b6281dfb4c459c files/apparmor-sources-2.6.17-r1-apparmor_audit.patch 2247 -RMD160 d6c5937273d30de4a83a42ad9256416bf2931a03 files/apparmor-sources-2.6.17-r1-apparmor_audit.patch 2247 -SHA256 27b8c610ec1dd4b6b8474194061a6616359aa942f3dddf3ae197cadeea8e411c files/apparmor-sources-2.6.17-r1-apparmor_audit.patch 2247 -AUX apparmor-sources-2.6.17-r1-apparmor_main.patch 219968 RMD160 8ac7a4ee65da4180684634b82bd468e2ff0ff790 SHA1 610451e2eb4c7b03ed4a37d527543dea8a0f6743 SHA256 f799f9f570dd1de355aad61a3583a6e06aba6138f4b7c064274ad524d4c6ab18 -MD5 665706462da47fc5dde62b016bb6af49 files/apparmor-sources-2.6.17-r1-apparmor_main.patch 219968 -RMD160 8ac7a4ee65da4180684634b82bd468e2ff0ff790 files/apparmor-sources-2.6.17-r1-apparmor_main.patch 219968 -SHA256 f799f9f570dd1de355aad61a3583a6e06aba6138f4b7c064274ad524d4c6ab18 files/apparmor-sources-2.6.17-r1-apparmor_main.patch 219968 -AUX apparmor-sources-2.6.17-r1-apparmor_namespacesem.patch 1197 RMD160 99acdb25d6384f650edb2914fb05205abe2a4f48 SHA1 21ee82c1bc2089f8af1985fcc57049422f5e02ba SHA256 1c6c97d3ef47c3b21e335246fabc4dbdb446e5fd638250a928ed62c8277ac015 -MD5 ebc4034d4b5410191a67a3d5f2e7d82b files/apparmor-sources-2.6.17-r1-apparmor_namespacesem.patch 1197 -RMD160 99acdb25d6384f650edb2914fb05205abe2a4f48 files/apparmor-sources-2.6.17-r1-apparmor_namespacesem.patch 1197 -SHA256 1c6c97d3ef47c3b21e335246fabc4dbdb446e5fd638250a928ed62c8277ac015 files/apparmor-sources-2.6.17-r1-apparmor_namespacesem.patch 1197 -DIST apparmor-kernel-patches-2.6.17.9.tar.gz 231231 RMD160 762d4b59aa508cfd82ebbeba4822ffb0551f5888 SHA1 bb754f57340ce90e25bb18be7030776ee4b9e823 SHA256 0884cd7bfdff4505fd5271ca68b72f74b352d209321ef60dc81620b0539f0ec7 -DIST apparmor-kernel-patches-2.6.18.tar.gz 231072 RMD160 f734125d986dcb3aec371f0e24126a5473d5637f SHA1 e6136d224d58ad90fd174d3c03290942644e5c45 SHA256 91224ff1f45de306c0720a5680a8f883888b52f296b0de24c63ec02668782b63 -DIST genpatches-2.6.17-1.base.tar.bz2 3337 RMD160 f9b5621fed8fcfee7da697d89097842287b41b24 SHA1 308e3daec11899f03103b5dcd2bfcff7e116c52c SHA256 2208b72729dce6daef7dc5700192aec0ae17327c794681621d2123f0c483ae21 -DIST genpatches-2.6.17-1.extras.tar.bz2 138704 RMD160 14b17e02b7893e6b023bee9e1b40f4bc85a30f05 SHA1 e671dbc29239116e627aea3d87ff7aefd8b5ca00 SHA256 fa10ec7d3d74c8bf57fb3bd01c33f83dcca3c1e4cd4601937cc2ef904cce1dfe -DIST genpatches-2.6.18-1.base.tar.bz2 2397 RMD160 1b02d9e5adba7a9a17f85691f312ee2c870c9a48 SHA1 790186d9d44c358d05489cdff417beab03124708 SHA256 e87db440591d48f74b8d50f47bde55a1652c969626befa94aba48cee57aa5da8 -DIST genpatches-2.6.18-1.extras.tar.bz2 147040 RMD160 f62b371d522fa8978cee4e809baea364ed8e804a SHA1 e98309b0203bf2f41e8efe1cd396dcfd5aec483a SHA256 080b19f98ffa8f5edbccabfa9dd4ac845ecc1b21c7fba761ad3d011893117b01 -DIST linux-2.6.17.tar.bz2 41272919 RMD160 26aad30c9a6610665c6c7d62401d79bf56a6a699 SHA1 0605c975b9dead2af31a3decf09dd4138fadaf2b SHA256 ab0f647d52f124958439517df9e1ae0efda90cdb851f59f522fa1749f1d87d58 -DIST linux-2.6.18.tar.bz2 41863580 RMD160 f92283f956880676bfb1f1d5288325461e4e02e7 SHA1 178f7d5bb3af0978d42b37651b8753323c7129c2 SHA256 c95280ff6c5d2a17788f7cc582d23ae8a9a7ba3f202ec6e4238eaadfce7c163d -EBUILD apparmor-sources-2.6.17-r1.ebuild 1142 RMD160 434a48918c3a4cff03e438c83918d7ba0d871311 SHA1 e8dc728915cf06e20da6dff8b10704f04be381d1 SHA256 48f9d6b7a3b8febc92fe5ef755e96d5d88354949947a355d77fce7300de7e332 -MD5 94d4c12fce6b5bb9e42a2d22942d7c61 apparmor-sources-2.6.17-r1.ebuild 1142 -RMD160 434a48918c3a4cff03e438c83918d7ba0d871311 apparmor-sources-2.6.17-r1.ebuild 1142 -SHA256 48f9d6b7a3b8febc92fe5ef755e96d5d88354949947a355d77fce7300de7e332 apparmor-sources-2.6.17-r1.ebuild 1142 -EBUILD apparmor-sources-2.6.17.ebuild 1233 RMD160 70a5b495ed179b57e825b99b26751725a6f12c8d SHA1 30744886818231b12ee378450aae835bb2ab35f9 SHA256 ddb3a0c0fa067b2ef1c32ad12925ee96c6467660e8f0ac896c56f8202ce40e5c -MD5 e52d364ef1955d471e087f21fb2d3e3c apparmor-sources-2.6.17.ebuild 1233 -RMD160 70a5b495ed179b57e825b99b26751725a6f12c8d apparmor-sources-2.6.17.ebuild 1233 -SHA256 ddb3a0c0fa067b2ef1c32ad12925ee96c6467660e8f0ac896c56f8202ce40e5c apparmor-sources-2.6.17.ebuild 1233 -EBUILD apparmor-sources-2.6.18.ebuild 1229 RMD160 f3a233d92a3b085426e64129a46d4eeae762be45 SHA1 5d4206a1521d63c4df44a472f49933cce9fe82cc SHA256 d97f7607222cb43076f73e9a549384d55dbfc6470ac5be6d3ea0d5047c5fff68 -MD5 9aeafb7f5c77d3a0841c4e9fb71eeb5f apparmor-sources-2.6.18.ebuild 1229 -RMD160 f3a233d92a3b085426e64129a46d4eeae762be45 apparmor-sources-2.6.18.ebuild 1229 -SHA256 d97f7607222cb43076f73e9a549384d55dbfc6470ac5be6d3ea0d5047c5fff68 apparmor-sources-2.6.18.ebuild 1229 -MISC ChangeLog 1008 RMD160 88f5deb153f61b500a1eb1672d9f01c87ab553f9 SHA1 8478c09f09812bf558e31516c03e21ae4f493c35 SHA256 83a27b6318f963a9668ce161f8c57969d3d1fa066df89850d85b727566a14bdc -MD5 2d787835eb0dc12e4feb5e29420c2927 ChangeLog 1008 -RMD160 88f5deb153f61b500a1eb1672d9f01c87ab553f9 ChangeLog 1008 -SHA256 83a27b6318f963a9668ce161f8c57969d3d1fa066df89850d85b727566a14bdc ChangeLog 1008 -MISC metadata.xml 478 RMD160 207b43ac7f50efbd5d3c8fdad96559adf422b0d2 SHA1 3adc61e526559bc5ac91aace569a588c4171e8cd SHA256 183e2d218aa6c62702bb9b81ee598eea27e51b6703b33fbf1a34d4b9674fd67a -MD5 c2ac84763e2d8238dea3eb3ba93b59aa metadata.xml 478 -RMD160 207b43ac7f50efbd5d3c8fdad96559adf422b0d2 metadata.xml 478 -SHA256 183e2d218aa6c62702bb9b81ee598eea27e51b6703b33fbf1a34d4b9674fd67a metadata.xml 478 -MD5 fb69ab075d009cf49c155c082fe75937 files/digest-apparmor-sources-2.6.17 1099 -RMD160 4c24baa45ae97f17ed503bfc4f0ed6ae8db520b4 files/digest-apparmor-sources-2.6.17 1099 -SHA256 a2efb919c008a7777773d5faed808c1b64b7e5dd97408131904897c5154520ce files/digest-apparmor-sources-2.6.17 1099 -MD5 0e1ade0aa9228c7dad088db16e4f1d3a files/digest-apparmor-sources-2.6.17-r1 801 -RMD160 74e1080cfdd78f0b7cc0314a2822efbe02ec2333 files/digest-apparmor-sources-2.6.17-r1 801 -SHA256 482238abaafe1482e35b0de5d6fbde3cc5f3e307aa885f823693b5bf01edcc09 files/digest-apparmor-sources-2.6.17-r1 801 -MD5 e08285915ab6ffc164d7178cd2d01c59 files/digest-apparmor-sources-2.6.18 1093 -RMD160 2b50e09bbfb91bbb0b46974e7b22de322d3b8520 files/digest-apparmor-sources-2.6.18 1093 -SHA256 71f364dffa2f917a0ce28c423627808f06dd547bc7d3d0599ea13e6a28d94693 files/digest-apparmor-sources-2.6.18 1093 diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.17-r1.ebuild b/trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.17-r1.ebuild deleted file mode 100644 index 5c1e43f3..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.17-r1.ebuild +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -ETYPE="sources" -K_WANT_GENPATCHES="base extras" -K_GENPATCHES_VER="1" -inherit eutils kernel-2 -detect_version -detect_arch - -KEYWORDS="~x86 ~amd64" -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -DESCRIPTION="Full sources to provide the required AppArmor modules and kernel hooks. Based on the gentoo-sources tree." - -SRC_URI="${KERNEL_URI} ${GENPATCHES_URI} ${ARCH_URI}" - -src_unpack() { - ABI=${KERNEL_ABI} - kernel-2_src_unpack - - EPATCH_FORCE="yes" - EPATCH_OPTS="" - epatch ${FILESDIR}/${PF}*.patch -} - -pkg_postinst() { - postinst_sources - - einfo - einfo "For more info on this patchset, and how to report problems, see:" - einfo "${HOMEPAGE}" - - einfo - einfo "Make sure that your kernel configuration file is set with:" - einfo " CONFIG_SECURITY=y" - einfo " CONFIG_SECURITY_APPARMOR=m" - einfo "Without these, apparmor will not function." - einfo - einfo "Apparmor can be sensitive to module load order. Make sure" - einfo "it is listed before any other modules that rely on the " - einfo "'capability' module." -} diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.17.ebuild b/trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.17.ebuild deleted file mode 100644 index 93fc471c..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.17.ebuild +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 1999-2005 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -ETYPE="sources" -K_WANT_GENPATCHES="base extras" -K_GENPATCHES_VER="1" -inherit eutils kernel-2 -detect_version -detect_arch - -KEYWORDS="~x86 ~amd64" -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -DESCRIPTION="Full sources to provide the required AppArmor modules and kernel hooks. Based on the gentoo-sources tree." - -MONTH="October" -UP_KPVER="2.6.17.9" - -AA_SRC="http://forgeftp.novell.com/apparmor/Development%20-%20${MONTH}%20Snapshot/apparmor-kernel-patches-${UP_KPVER}.tar.gz" - -SRC_URI="${KERNEL_URI} ${GENPATCHES_URI} ${ARCH_URI} ${AA_SRC}" - -src_unpack() { - unpack "apparmor-kernel-patches-${UP_KPVER}.tar.gz" - - kernel-2_src_unpack - - EPATCH_FORCE="yes" - EPATCH_OPTS="" - epatch ${WORKDIR}/${UP_KPVER}/current/apparmor-2.6.17.9-v154-fullseries.patch -} - -pkg_postinst() { - postinst_sources - - einfo - einfo "For more info on this patchset, and how to report problems, see:" - einfo "${HOMEPAGE}" - einfo - einfo "Make sure that your kernel configuration file is set with:" - einfo " CONFIG_SECURITY=y" - einfo " CONFIG_SECURITY_APPARMOR=m" - einfo "Without these, apparmor will not function." - einfo -} diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.18.ebuild b/trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.18.ebuild deleted file mode 100644 index e1730574..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/apparmor-sources-2.6.18.ebuild +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 1999-2005 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -ETYPE="sources" -K_WANT_GENPATCHES="base extras" -K_GENPATCHES_VER="1" -inherit eutils kernel-2 -detect_version -detect_arch - -KEYWORDS="~x86 ~amd64" -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -DESCRIPTION="Full sources to provide the required AppArmor modules and kernel hooks. Based on the gentoo-sources tree." - -MONTH="October" -UP_KPVER="2.6.18" - -AA_SRC="http://forgeftp.novell.com/apparmor/Development%20-%20${MONTH}%20Snapshot/apparmor-kernel-patches-${UP_KPVER}.tar.gz" - -SRC_URI="${KERNEL_URI} ${GENPATCHES_URI} ${ARCH_URI} ${AA_SRC}" - -src_unpack() { - unpack "apparmor-kernel-patches-${UP_KPVER}.tar.gz" - - kernel-2_src_unpack - - EPATCH_FORCE="yes" - EPATCH_OPTS="" - epatch ${WORKDIR}/${UP_KPVER}/current/apparmor-2.6.18-v154-fullseries.patch -} - -pkg_postinst() { - postinst_sources - - einfo - einfo "For more info on this patchset, and how to report problems, see:" - einfo "${HOMEPAGE}" - einfo - einfo "Make sure that your kernel configuration file is set with:" - einfo " CONFIG_SECURITY=y" - einfo " CONFIG_SECURITY_APPARMOR=m" - einfo "Without these, apparmor will not function." - einfo -} diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5000_apparmor-integrate.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5000_apparmor-integrate.patch deleted file mode 100644 index f7290728..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5000_apparmor-integrate.patch +++ /dev/null @@ -1,76 +0,0 @@ -This patch glues AppArmor into the security configuration and Makefile. -It also creates the AppArmor configuration and Makefile. - - -Signed-off-by: Tony Jones - ---- - MAINTAINERS | 7 +++++++ - security/Kconfig | 1 + - security/Makefile | 1 + - security/apparmor/Kconfig | 9 +++++++++ - security/apparmor/Makefile | 6 ++++++ - 5 files changed, 24 insertions(+) - ---- linux-2.6.17-rc1.orig/MAINTAINERS -+++ linux-2.6.17-rc1/MAINTAINERS -@@ -284,6 +284,13 @@ - W: http://www.canb.auug.org.au/~sfr/ - S: Supported - -+APPARMOR SECURITY MODULE -+P: Tony Jones -+M: tonyj@suse.de -+L: apparmor-dev@forge.novell.com -+W: http://forge.novell.com/modules/xfmod/project/?apparmor -+S: Supported -+ - APPLETALK NETWORK LAYER - P: Arnaldo Carvalho de Melo - M: acme@conectiva.com.br ---- linux-2.6.17-rc1.orig/security/Kconfig -+++ linux-2.6.17-rc1/security/Kconfig -@@ -100,6 +100,7 @@ - If you are unsure how to answer this question, answer N. - - source security/selinux/Kconfig -+source security/apparmor/Kconfig - - endmenu - ---- linux-2.6.17-rc1.orig/security/Makefile -+++ linux-2.6.17-rc1/security/Makefile -@@ -4,6 +4,7 @@ - - obj-$(CONFIG_KEYS) += keys/ - subdir-$(CONFIG_SECURITY_SELINUX) += selinux -+subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor - - # if we don't select a security model, use the default capabilities - ifneq ($(CONFIG_SECURITY),y) ---- /dev/null -+++ linux-2.6.17-rc1/security/apparmor/Kconfig -@@ -0,0 +1,9 @@ -+config SECURITY_APPARMOR -+ tristate "AppArmor support" -+ depends on SECURITY!=n -+ help -+ This enables the AppArmor security module. -+ Required userspace tools (if they are not included in your -+ distribution) and further information may be found at -+ -+ If you are unsure how to answer this question, answer N. ---- /dev/null -+++ linux-2.6.17-rc1/security/apparmor/Makefile -@@ -0,0 +1,6 @@ -+# Makefile for AppArmor Linux Security Module -+# -+subdir-$(CONFIG_SECURITY_APPARMOR) += match -+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o -+ -+apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o capabilities.o module_interface.o -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5001_apparmor-core-header.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5001_apparmor-core-header.patch deleted file mode 100644 index 3bd74bec..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5001_apparmor-core-header.patch +++ /dev/null @@ -1,728 +0,0 @@ -This patch provides the various common headerfiles used by the AppArmor module. - -apparmor.h contains the core data structures. -shared.h contains definitions that are common to the userspace policy loader. -inline.h implements various inline utility functions - - -Signed-off-by: Tony Jones - ---- - security/apparmor/apparmor.h | 325 +++++++++++++++++++++++++++++++++++++++++ - security/apparmor/inline.h | 333 +++++++++++++++++++++++++++++++++++++++++++ - security/apparmor/shared.h | 41 +++++ - 3 files changed, 699 insertions(+) - ---- security/apparmor/apparmor.h.orig -+++ security/apparmor/apparmor.h -@@ -0,0 +1,325 @@ -+/* -+ * Copyright (C) 1998-2005 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 internal prototypes -+ */ -+ -+#ifndef __SUBDOMAIN_H -+#define __SUBDOMAIN_H -+ -+#include /* Include for defn of iattr */ -+#include -+ -+#include "shared.h" -+ -+/* Control parameters (0 or 1), settable thru module/boot flags or -+ * via /sys/kernel/security/apparmor/control */ -+extern int apparmor_complain; -+extern int apparmor_debug; -+extern int apparmor_audit; -+extern int apparmor_logsyscall; -+ -+/* PIPEFS_MAGIC */ -+#include -+/* from net/socket.c */ -+#define SOCKFS_MAGIC 0x534F434B -+/* from inotify.c */ -+#define INOTIFYFS_MAGIC 0xBAD1DEA -+ -+#define VALID_FSTYPE(inode) ((inode)->i_sb->s_magic != PIPEFS_MAGIC && \ -+ (inode)->i_sb->s_magic != SOCKFS_MAGIC && \ -+ (inode)->i_sb->s_magic != INOTIFYFS_MAGIC) -+ -+#define PROFILE_COMPLAIN(_profile) \ -+ (apparmor_complain == 1 || ((_profile) && (_profile)->flags.complain)) -+ -+#define SUBDOMAIN_COMPLAIN(_sd) \ -+ (apparmor_complain == 1 || \ -+ ((_sd) && (_sd)->active && (_sd)->active->flags.complain)) -+ -+#define PROFILE_AUDIT(_profile) \ -+ (apparmor_audit == 1 || ((_profile) && (_profile)->flags.audit)) -+ -+#define SUBDOMAIN_AUDIT(_sd) \ -+ (apparmor_audit == 1 || \ -+ ((_sd) && (_sd)->active && (_sd)->active->flags.audit)) -+ -+/* -+ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl -+ * which is not related to profile accesses. -+ */ -+ -+#define AA_DEBUG(fmt, args...) \ -+ do { \ -+ if (apparmor_debug) \ -+ printk(KERN_DEBUG "AppArmor: " fmt, ##args); \ -+ } while (0) -+#define AA_INFO(fmt, args...) printk(KERN_INFO "AppArmor: " fmt, ##args) -+#define AA_WARN(fmt, args...) printk(KERN_WARNING "AppArmor: " fmt, ##args) -+#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args) -+ -+/* basic AppArmor data structures */ -+ -+struct flagval { -+ int debug; -+ int complain; -+ int audit; -+}; -+ -+enum entry_match_type { -+ aa_entry_literal, -+ aa_entry_tailglob, -+ aa_entry_pattern, -+ aa_entry_invalid -+}; -+ -+/* struct aa_entry - file ACL * -+ * @filename: filename controlled by this ACL -+ * @mode: permissions granted by ACL -+ * @type: type of match to perform against @filename -+ * @extradata: any extra data needed by an extended matching type -+ * @list: list the ACL is on -+ * @listp: permission partitioned lists this ACL is on. -+ * -+ * Each entry describes a file and an allowed access mode. -+ */ -+struct aa_entry { -+ char *filename; -+ int mode; /* mode is 'or' of READ, WRITE, EXECUTE, -+ * INHERIT, UNCONSTRAINED, and LIBRARY -+ * (meaning don't prefetch). */ -+ -+ enum entry_match_type type; -+ void *extradata; -+ -+ struct list_head list; -+ struct list_head listp[POS_AA_FILE_MAX + 1]; -+}; -+ -+#define AA_EXEC_MODIFIER_MASK(mask) ((mask) & (AA_EXEC_UNCONSTRAINED |\ -+ AA_EXEC_INHERIT |\ -+ AA_EXEC_PROFILE)) -+ -+#define AA_EXEC_MASK(mask) ((mask) & (AA_MAY_EXEC |\ -+ AA_EXEC_UNCONSTRAINED |\ -+ AA_EXEC_INHERIT |\ -+ AA_EXEC_PROFILE)) -+ -+ -+/* struct aaprofile - basic confinement data -+ * @parent: non refcounted pointer to parent profile -+ * @name: the profiles name -+ * @file_entry: file ACL -+ * @file_entryp: vector of file ACL by permission granted -+ * @list: list this profile is on -+ * @sub: profiles list of subprofiles (HATS) -+ * @flags: flags controlling profile behavior -+ * @null_profile: if needed per profile learning and null confinement profile -+ * @isstale: flag to indicate the profile is stale -+ * @num_file_entries: number of file entries the profile contains -+ * @num_file_pentries: number of file entries for each partitioned list -+ * @capabilities: capabilities granted by the process -+ * @rcu: rcu head used when freeing the profile -+ * @count: reference count of the profile -+ * -+ * The AppArmor profile contains the basic confinement data. Each profile -+ * has a name and potentially a list of profile entries. The profiles are -+ * connected in a list -+ */ -+struct aaprofile { -+ struct aaprofile *parent; -+ char *name; -+ -+ struct list_head file_entry; -+ struct list_head file_entryp[POS_AA_FILE_MAX + 1]; -+ struct list_head list; -+ struct list_head sub; -+ struct flagval flags; -+ struct aaprofile *null_profile; -+ int isstale; -+ -+ int num_file_entries; -+ int num_file_pentries[POS_AA_FILE_MAX + 1]; -+ -+ kernel_cap_t capabilities; -+ -+ struct rcu_head rcu; -+ -+ struct kref count; -+}; -+ -+/** -+ * struct subdomain - primary label for confined tasks -+ * @active: the current active profile -+ * @hat_magic: the magic token controling the ability to leave a hat -+ * @list: list this subdomain is on -+ * @task: task that the subdomain confines -+ * -+ * Contains the tasks current active profile (which could change due to -+ * change_hat). Plus the hat_magic needed during change_hat. -+ * -+ * N.B AppArmor's previous product name SubDomain was derived from the name -+ * of this structure/concept (changehat reducing a task into a sub-domain). -+ */ -+struct subdomain { -+ struct aaprofile *active; /* The current active profile */ -+ u32 hat_magic; /* used with change_hat */ -+ struct list_head list; /* list of subdomains */ -+ struct task_struct *task; -+}; -+ -+typedef int (*aa_iter) (struct subdomain *, void *); -+ -+/* aa_path_data -+ * temp (cookie) data used by aa_path_* functions, see inline.h -+ */ -+struct aa_path_data { -+ struct dentry *root, *dentry; -+ struct namespace *namespace; -+ struct list_head *head, *pos; -+ int errno; -+}; -+ -+#define AA_SUBDOMAIN(sec) ((struct subdomain*)(sec)) -+#define AA_PROFILE(sec) ((struct aaprofile*)(sec)) -+ -+/* Lock protecting access to 'struct subdomain' accesses */ -+extern spinlock_t sd_lock; -+ -+extern struct aaprofile *null_complain_profile; -+ -+/* aa_audit - AppArmor auditing structure -+ * Structure is populated by access control code and passed to aa_audit which -+ * provides for a single point of logging. -+ */ -+ -+struct aa_audit { -+ unsigned short type, flags; -+ unsigned int result; -+ unsigned int gfp_mask; -+ int error_code; -+ -+ const char *name; -+ unsigned int ival; -+ union { -+ const void *pval; -+ va_list vaval; -+ }; -+}; -+ -+/* audit types */ -+#define AA_AUDITTYPE_FILE 1 -+#define AA_AUDITTYPE_DIR 2 -+#define AA_AUDITTYPE_ATTR 3 -+#define AA_AUDITTYPE_XATTR 4 -+#define AA_AUDITTYPE_LINK 5 -+#define AA_AUDITTYPE_CAP 6 -+#define AA_AUDITTYPE_MSG 7 -+#define AA_AUDITTYPE_SYSCALL 8 -+#define AA_AUDITTYPE__END 9 -+ -+/* audit flags */ -+#define AA_AUDITFLAG_AUDITSS_SYSCALL 1 /* log syscall context */ -+#define AA_AUDITFLAG_LOGERR 2 /* log operations that failed due to -+ non permission errors */ -+ -+#define HINT_UNKNOWN_HAT "unknown_hat" -+#define HINT_FORK "fork" -+#define HINT_MANDPROF "missing_mandatory_profile" -+#define HINT_CHGPROF "changing_profile" -+ -+#define LOG_HINT(p, gfp, hint, fmt, args...) \ -+ do {\ -+ aa_audit_message(p, gfp, 0, \ -+ "LOGPROF-HINT " hint " " fmt, ##args);\ -+ } while(0) -+ -+/* directory op type, for aa_perm_dir */ -+enum aa_diroptype { -+ aa_dir_mkdir, -+ aa_dir_rmdir -+}; -+ -+/* xattr op type, for aa_xattr */ -+enum aa_xattroptype { -+ aa_xattr_get, -+ aa_xattr_set, -+ aa_xattr_list, -+ aa_xattr_remove -+}; -+ -+#define BASE_PROFILE(p) ((p)->parent ? (p)->parent : (p)) -+#define IN_SUBPROFILE(p) ((p)->parent) -+ -+/* main.c */ -+extern int alloc_null_complain_profile(void); -+extern void free_null_complain_profile(void); -+extern int attach_nullprofile(struct aaprofile *profile); -+extern int aa_audit_message(struct aaprofile *active, unsigned int gfp, int, -+ const char *, ...); -+extern int aa_audit_syscallreject(struct aaprofile *active, unsigned int gfp, -+ const char *); -+extern int aa_audit(struct aaprofile *active, const struct aa_audit *); -+extern char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt); -+ -+extern int aa_attr(struct aaprofile *active, struct dentry *dentry, -+ struct iattr *iattr); -+extern int aa_xattr(struct aaprofile *active, struct dentry *dentry, -+ const char *xattr, enum aa_xattroptype xattroptype); -+extern int aa_capability(struct aaprofile *active, int cap); -+extern int aa_perm(struct aaprofile *active, struct dentry *dentry, -+ struct vfsmount *mnt, int mask); -+extern int aa_perm_nameidata(struct aaprofile *active, struct nameidata *nd, -+ int mask); -+extern int aa_perm_dentry(struct aaprofile *active, struct dentry *dentry, -+ int mask); -+extern int aa_perm_dir(struct aaprofile *active, struct dentry *dentry, -+ enum aa_diroptype diroptype); -+extern int aa_link(struct aaprofile *active, -+ struct dentry *link, struct dentry *target); -+extern int aa_fork(struct task_struct *p); -+extern int aa_register(struct file *file); -+extern void aa_release(struct task_struct *p); -+extern int aa_change_hat(const char *id, u32 hat_magic); -+extern int aa_associate_filp(struct file *filp); -+ -+/* list.c */ -+extern struct aaprofile *aa_profilelist_find(const char *name); -+extern int aa_profilelist_add(struct aaprofile *profile); -+extern struct aaprofile *aa_profilelist_remove(const char *name); -+extern void aa_profilelist_release(void); -+extern struct aaprofile *aa_profilelist_replace(struct aaprofile *profile); -+extern void aa_profile_dump(struct aaprofile *); -+extern void aa_profilelist_dump(void); -+extern void aa_subdomainlist_add(struct subdomain *); -+extern void aa_subdomainlist_remove(struct subdomain *); -+extern void aa_subdomainlist_iterate(aa_iter, void *); -+extern void aa_subdomainlist_iterateremove(aa_iter, void *); -+extern void aa_subdomainlist_release(void); -+ -+/* module_interface.c */ -+extern ssize_t aa_file_prof_add(void *, size_t); -+extern ssize_t aa_file_prof_repl(void *, size_t); -+extern ssize_t aa_file_prof_remove(const char *, size_t); -+extern void free_aaprofile(struct aaprofile *profile); -+extern void free_aaprofile_kref(struct kref *kref); -+ -+/* procattr.c */ -+extern size_t aa_getprocattr(struct aaprofile *active, char *str, size_t size); -+extern int aa_setprocattr_changehat(char *hatinfo, size_t infosize); -+extern int aa_setprocattr_setprofile(struct task_struct *p, char *profilename, -+ size_t profilesize); -+ -+/* apparmorfs.c */ -+extern int create_apparmorfs(void); -+extern void destroy_apparmorfs(void); -+ -+/* capabilities.c */ -+extern const char *capability_to_name(unsigned int cap); -+ -+#endif /* __SUBDOMAIN_H */ ---- security/apparmor/inline.h.orig -+++ security/apparmor/inline.h -@@ -0,0 +1,333 @@ -+/* -+ * Copyright (C) 2005 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. -+ */ -+ -+#ifndef __INLINE_H -+#define __INLINE_H -+ -+#include -+ -+static inline int __aa_is_confined(struct subdomain *sd) -+{ -+ return (sd && sd->active); -+} -+ -+/** -+ * aa_is_confined -+ * Determine whether current task contains a valid profile (confined). -+ * Return %1 if confined, %0 otherwise. -+ */ -+static inline int aa_is_confined(void) -+{ -+ struct subdomain *sd = AA_SUBDOMAIN(current->security); -+ return __aa_is_confined(sd); -+} -+ -+static inline int __aa_sub_defined(struct subdomain *sd) -+{ -+ return __aa_is_confined(sd) && !list_empty(&BASE_PROFILE(sd->active)->sub); -+} -+ -+/** -+ * aa_sub_defined - check to see if current task has any subprofiles -+ * Return 1 if true, 0 otherwise -+ */ -+static inline int aa_sub_defined(void) -+{ -+ struct subdomain *sd = AA_SUBDOMAIN(current->security); -+ return __aa_sub_defined(sd); -+} -+ -+/** -+ * get_aaprofile - increment refcount on profile @p -+ * @p: profile -+ */ -+static inline struct aaprofile *get_aaprofile(struct aaprofile *p) -+{ -+ if (p) -+ kref_get(&(BASE_PROFILE(p)->count)); -+ -+ return p; -+} -+ -+/** -+ * put_aaprofile - decrement refcount on profile @p -+ * @p: profile -+ */ -+static inline void put_aaprofile(struct aaprofile *p) -+{ -+ if (p) -+ kref_put(&BASE_PROFILE(p)->count, free_aaprofile_kref); -+} -+ -+/** -+ * get_task_activeptr_rcu - get pointer to @tsk's active profile. -+ * @tsk: task to get active profile from -+ * -+ * Requires rcu_read_lock is held -+ */ -+static inline struct aaprofile *get_task_activeptr_rcu(struct task_struct *tsk) -+{ -+ struct subdomain *sd = AA_SUBDOMAIN(tsk->security); -+ struct aaprofile *active = NULL; -+ -+ if (sd) -+ active = (struct aaprofile *) rcu_dereference(sd->active); -+ -+ return active; -+} -+ -+/** -+ * get_activeptr_rcu - get pointer to current task's active profile -+ * Requires rcu_read_lock is held -+ */ -+static inline struct aaprofile *get_activeptr_rcu(void) -+{ -+ return get_task_activeptr_rcu(current); -+} -+ -+/** -+ * get_task_active_aaprofile - get a reference to tsk's active profile. -+ * @tsk: the task to get the active profile reference for -+ */ -+static inline struct aaprofile *get_task_active_aaprofile(struct task_struct *tsk) -+{ -+ struct aaprofile *active; -+ -+ rcu_read_lock(); -+ active = get_aaprofile(get_task_activeptr_rcu(tsk)); -+ rcu_read_unlock(); -+ -+ return active; -+} -+ -+/** -+ * get_active_aaprofile - get a reference to the current tasks active profile -+ */ -+static inline struct aaprofile *get_active_aaprofile(void) -+{ -+ return get_task_active_aaprofile(current); -+} -+ -+/** -+ * aa_switch - change subdomain to use a new profile -+ * @sd: subdomain to switch the active profile on -+ * @newactive: new active profile -+ * -+ * aa_switch handles the changing of a subdomain's active profile. The -+ * sd_lock must be held to ensure consistency against other writers. -+ * Some write paths (ex. aa_register) require sd->active not to change -+ * over several operations, so the calling function is responsible -+ * for grabing the sd_lock to meet its consistency constraints before -+ * calling aa_switch -+ */ -+static inline void aa_switch(struct subdomain *sd, struct aaprofile *newactive) -+{ -+ struct aaprofile *oldactive = sd->active; -+ -+ /* noop if NULL */ -+ rcu_assign_pointer(sd->active, get_aaprofile(newactive)); -+ put_aaprofile(oldactive); -+} -+ -+/** -+ * aa_switch_unconfined - change subdomain to be unconfined (no profile) -+ * @sd: subdomain to switch -+ * -+ * aa_switch_unconfined handles the removal of a subdomain's active profile. -+ * The sd_lock must be held to ensure consistency against other writers. -+ * Like aa_switch the sd_lock is used to maintain consistency. -+ */ -+static inline void aa_switch_unconfined(struct subdomain *sd) -+{ -+ aa_switch(sd, NULL); -+ -+ /* reset magic in case we were in a subhat before */ -+ sd->hat_magic = 0; -+} -+ -+/** -+ * alloc_subdomain - allocate a new subdomain -+ * @tsk: task struct -+ * -+ * Allocate a new subdomain including a backpointer to it's referring task. -+ */ -+static inline struct subdomain *alloc_subdomain(struct task_struct *tsk) -+{ -+ struct subdomain *sd; -+ -+ sd = kzalloc(sizeof(struct subdomain), GFP_KERNEL); -+ if (!sd) -+ goto out; -+ -+ /* back pointer to task */ -+ sd->task = tsk; -+ -+ /* any readers of the list must make sure that they can handle -+ * case where sd->active is not yet set (null) -+ */ -+ aa_subdomainlist_add(sd); -+ -+out: -+ return sd; -+} -+ -+/** -+ * free_subdomain - Free a subdomain previously allocated by alloc_subdomain -+ * @sd: subdomain -+ */ -+static inline void free_subdomain(struct subdomain *sd) -+{ -+ aa_subdomainlist_remove(sd); -+ kfree(sd); -+} -+ -+/** -+ * alloc_aaprofile - Allocate, initialize and return a new zeroed profile. -+ * Returns NULL on failure. -+ */ -+static inline struct aaprofile *alloc_aaprofile(void) -+{ -+ struct aaprofile *profile; -+ -+ profile = (struct aaprofile *)kzalloc(sizeof(struct aaprofile), -+ GFP_KERNEL); -+ AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); -+ if (profile) { -+ int i; -+ -+ INIT_LIST_HEAD(&profile->list); -+ INIT_LIST_HEAD(&profile->sub); -+ INIT_LIST_HEAD(&profile->file_entry); -+ for (i = 0; i <= POS_AA_FILE_MAX; i++) { -+ INIT_LIST_HEAD(&profile->file_entryp[i]); -+ } -+ INIT_RCU_HEAD(&profile->rcu); -+ kref_init(&profile->count); -+ } -+ return profile; -+} -+ -+/** -+ * aa_put_name -+ * @name: name to release. -+ * -+ * Release space (free_page) allocated to hold pathname -+ * name may be NULL (checked for by free_page) -+ */ -+static inline void aa_put_name(const char *name) -+{ -+ free_page((unsigned long)name); -+} -+ -+/** __aa_find_profile -+ * @name: name of profile to find -+ * @head: list to search -+ * -+ * Return reference counted copy of profile. NULL if not found -+ * Caller must hold any necessary locks -+ */ -+static inline struct aaprofile *__aa_find_profile(const char *name, -+ struct list_head *head) -+{ -+ struct aaprofile *p; -+ -+ if (!name || !head) -+ return NULL; -+ -+ AA_DEBUG("%s: finding profile %s\n", __FUNCTION__, name); -+ list_for_each_entry(p, head, list) { -+ if (!strcmp(p->name, name)) { -+ /* return refcounted object */ -+ p = get_aaprofile(p); -+ return p; -+ } else { -+ AA_DEBUG("%s: skipping %s\n", __FUNCTION__, p->name); -+ } -+ } -+ return NULL; -+} -+ -+/** __aa_path_begin -+ * @rdentry: filesystem root dentry (searching for vfsmnts matching this) -+ * @dentry: dentry object to obtain pathname from (relative to matched vfsmnt) -+ * -+ * Setup data for iterating over vfsmounts (in current tasks namespace). -+ */ -+static inline void __aa_path_begin(struct dentry *rdentry, -+ struct dentry *dentry, -+ struct aa_path_data *data) -+{ -+ data->dentry = dentry; -+ data->root = dget(rdentry->d_sb->s_root); -+ data->namespace = current->namespace; -+ data->head = &data->namespace->list; -+ data->pos = data->head->next; -+ prefetch(data->pos->next); -+ data->errno = 0; -+ -+ down_read(&namespace_sem); -+} -+ -+/** aa_path_begin -+ * @dentry: filesystem root dentry and object to obtain pathname from -+ * -+ * Utility function for calling _aa_path_begin for when the dentry we are -+ * looking for and the root are the same (this is the usual case). -+ */ -+static inline void aa_path_begin(struct dentry *dentry, -+ struct aa_path_data *data) -+{ -+ __aa_path_begin(dentry, dentry, data); -+} -+ -+/** aa_path_end -+ * @data: data object previously initialized by aa_path_begin -+ * -+ * End iterating over vfsmounts. -+ * If an error occured in begin or get, it is returned. Otherwise 0. -+ */ -+static inline int aa_path_end(struct aa_path_data *data) -+{ -+ up_read(&namespace_sem); -+ dput(data->root); -+ -+ return data->errno; -+} -+ -+/** aa_path_getname -+ * @data: data object previously initialized by aa_path_begin -+ * -+ * Return the next mountpoint which has the same root dentry as data->root. -+ * If no more mount points exist (or in case of error) NULL is returned -+ * (caller should call aa_path_end() and inspect return code to differentiate) -+ */ -+static inline char *aa_path_getname(struct aa_path_data *data) -+{ -+ char *name = NULL; -+ struct vfsmount *mnt; -+ -+ while (data->pos != data->head) { -+ mnt = list_entry(data->pos, struct vfsmount, mnt_list); -+ -+ /* advance to next -- so that it is done before we break */ -+ data->pos = data->pos->next; -+ prefetch(data->pos->next); -+ -+ if (mnt->mnt_root == data->root) { -+ name = aa_get_name(data->dentry, mnt); -+ if (!name) -+ data->errno = -ENOMEM; -+ break; -+ } -+ } -+ -+ return name; -+} -+ -+#endif /* __INLINE_H__ */ ---- security/apparmor/shared.h.orig -+++ security/apparmor/shared.h -@@ -0,0 +1,41 @@ -+/* -+ * Copyright (C) 2000, 2001, 2004, 2005 Novell/SUSE -+ * -+ * Immunix AppArmor LSM -+ * -+ * 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. -+ */ -+ -+#ifndef _SHARED_H -+#define _SHARED_H -+ -+/* start of system offsets */ -+#define POS_AA_FILE_MIN 0 -+#define POS_AA_MAY_EXEC POS_AA_FILE_MIN -+#define POS_AA_MAY_WRITE (POS_AA_MAY_EXEC + 1) -+#define POS_AA_MAY_READ (POS_AA_MAY_WRITE + 1) -+#define POS_AA_MAY_APPEND (POS_AA_MAY_READ + 1) -+/* end of system offsets */ -+ -+#define POS_AA_MAY_LINK (POS_AA_MAY_APPEND + 1) -+#define POS_AA_EXEC_INHERIT (POS_AA_MAY_LINK + 1) -+#define POS_AA_EXEC_UNCONSTRAINED (POS_AA_EXEC_INHERIT + 1) -+#define POS_AA_EXEC_PROFILE (POS_AA_EXEC_UNCONSTRAINED + 1) -+#define POS_AA_FILE_MAX POS_AA_EXEC_PROFILE -+ -+/* Modeled after MAY_READ, MAY_WRITE, MAY_EXEC def'ns */ -+#define AA_MAY_EXEC (0x01 << POS_AA_MAY_EXEC) -+#define AA_MAY_WRITE (0x01 << POS_AA_MAY_WRITE) -+#define AA_MAY_READ (0x01 << POS_AA_MAY_READ) -+#define AA_MAY_LINK (0x01 << POS_AA_MAY_LINK) -+#define AA_EXEC_INHERIT (0x01 << POS_AA_EXEC_INHERIT) -+#define AA_EXEC_UNCONSTRAINED (0x01 << POS_AA_EXEC_UNCONSTRAINED) -+#define AA_EXEC_PROFILE (0x01 << POS_AA_EXEC_PROFILE) -+#define AA_EXEC_MODIFIERS(X) (X & (AA_EXEC_INHERIT | \ -+ A_EXEC_UNCONSTRAINED | \ -+ AA_EXEC_PROFILE)) -+ -+#endif /* _SHARED_H */ -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5002_apparmor-lsm-interface.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5002_apparmor-lsm-interface.patch deleted file mode 100644 index d4b66175..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5002_apparmor-lsm-interface.patch +++ /dev/null @@ -1,880 +0,0 @@ -Implements the lsm interface used by AppArmor. - -The code composes the functionality provided by commoncap therefore there -is no requirement for it to stack with the capability module. - -See linux/include/security.h for a full description of all the LSM hooks. - -Consistency of the subdomain (task) data is implemented on the reader side -via rcu. Logical consistency across profile replacement/removal and change -hat is provided via the spinlock sd_lock. Since profile manipulation and -change_hat are infrequent, most syscall accesses requires no spin lock. - -Certain syscalls are prevented for confined processes. These are: - ptrace - mount - umount - sysctl writes also require CAP_SYS_ADMIN - -File access checks are performed when a file is initially opened -(inode_permission) and cached to avoid revalidation unless where necessary -(passing descriptors between tasks confined with differing profiles, and -profile replacement, for example). Further patches are in development -to support caching of multiple profiles against an open file to minimise -the need for subsequent revalidation across profiles. - - -Signed-off-by: Tony Jones - ---- - security/apparmor/lsm.c | 840 ++++++++++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 840 insertions(+) - ---- security/apparmor/lsm.c.orig -+++ security/apparmor/lsm.c -@@ -0,0 +1,840 @@ -+/* -+ * Copyright (C) 2002-2005 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. -+ * -+ * http://forge.novell.com/modules/xfmod/project/?apparmor -+ * -+ * Immunix AppArmor LSM interface -+ */ -+ -+#include -+#include -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+ -+/* struct subdomain write update lock (read side is RCU). */ -+spinlock_t sd_lock = SPIN_LOCK_UNLOCKED; -+ -+/* Flag values, also controllable via apparmorfs/control. -+ * We explicitly do not allow these to be modifiable when exported via -+ * /sys/modules/parameters, as we want to do additional mediation and -+ * don't want to add special path code. */ -+ -+/* 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, int, S_IRUSR); -+MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode"); -+ -+/* Debug mode */ -+int apparmor_debug = 0; -+module_param_named(debug, apparmor_debug, int, S_IRUSR); -+MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode"); -+ -+/* Audit mode */ -+int apparmor_audit = 0; -+module_param_named(audit, apparmor_audit, int, S_IRUSR); -+MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode"); -+ -+/* Syscall logging mode */ -+int apparmor_logsyscall = 0; -+module_param_named(logsyscall, apparmor_logsyscall, int, S_IRUSR); -+MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode"); -+ -+#ifndef MODULE -+static int __init aa_getopt_complain(char *str) -+{ -+ get_option(&str, &apparmor_complain); -+ return 1; -+} -+__setup("apparmor_complain=", aa_getopt_complain); -+ -+static int __init aa_getopt_debug(char *str) -+{ -+ get_option(&str, &apparmor_debug); -+ return 1; -+} -+__setup("apparmor_debug=", aa_getopt_debug); -+ -+static int __init aa_getopt_audit(char *str) -+{ -+ get_option(&str, &apparmor_audit); -+ return 1; -+} -+__setup("apparmor_audit=", aa_getopt_audit); -+ -+static int __init aa_getopt_logsyscall(char *str) -+{ -+ get_option(&str, &apparmor_logsyscall); -+ return 1; -+} -+__setup("apparmor_logsyscall=", aa_getopt_logsyscall); -+#endif -+ -+static int apparmor_ptrace(struct task_struct *parent, -+ struct task_struct *child) -+{ -+ int error; -+ struct aaprofile *active; -+ -+ error = cap_ptrace(parent, child); -+ -+ active = get_active_aaprofile(); -+ -+ if (!error && active) { -+ error = aa_audit_syscallreject(active, GFP_KERNEL, "ptrace"); -+ WARN_ON(error != -EPERM); -+ } -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_capget(struct task_struct *target, -+ kernel_cap_t *effective, -+ kernel_cap_t *inheritable, -+ kernel_cap_t *permitted) -+{ -+ return cap_capget(target, effective, inheritable, permitted); -+} -+ -+static int apparmor_capset_check(struct task_struct *target, -+ kernel_cap_t *effective, -+ kernel_cap_t *inheritable, -+ kernel_cap_t *permitted) -+{ -+ return cap_capset_check(target, effective, inheritable, permitted); -+} -+ -+static void apparmor_capset_set(struct task_struct *target, -+ kernel_cap_t *effective, -+ kernel_cap_t *inheritable, -+ kernel_cap_t *permitted) -+{ -+ cap_capset_set(target, effective, inheritable, permitted); -+ return; -+} -+ -+static int apparmor_capable(struct task_struct *tsk, int cap) -+{ -+ int error; -+ -+ /* cap_capable returns 0 on success, else -EPERM */ -+ error = cap_capable(tsk, cap); -+ -+ if (error == 0) { -+ struct aaprofile *active; -+ -+ active = get_task_active_aaprofile(tsk); -+ -+ if (active) -+ error = aa_capability(active, cap); -+ -+ put_aaprofile(active); -+ } -+ -+ return error; -+} -+ -+static int apparmor_sysctl(struct ctl_table *table, int op) -+{ -+ int error = 0; -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ -+ if ((op & 002) && active && !capable(CAP_SYS_ADMIN)) { -+ error = aa_audit_syscallreject(active, GFP_KERNEL, -+ "sysctl (write)"); -+ WARN_ON(error != -EPERM); -+ } -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_syslog(int type) -+{ -+ return cap_syslog(type); -+} -+ -+static int apparmor_netlink_send(struct sock *sk, struct sk_buff *skb) -+{ -+ return cap_netlink_send(sk, skb); -+} -+ -+static int apparmor_netlink_recv(struct sk_buff *skb) -+{ -+ return cap_netlink_recv(skb); -+} -+ -+static void apparmor_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) -+{ -+ cap_bprm_apply_creds(bprm, unsafe); -+ return; -+} -+ -+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->file); -+} -+ -+static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type, -+ unsigned long flags, void *data) -+{ -+ int error = 0; -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ -+ if (active) { -+ error = aa_audit_syscallreject(active, GFP_KERNEL, "mount"); -+ WARN_ON(error != -EPERM); -+ } -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_umount(struct vfsmount *mnt, int flags) -+{ -+ int error = 0; -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ -+ if (active) { -+ error = aa_audit_syscallreject(active, GFP_KERNEL, "umount"); -+ WARN_ON(error != -EPERM); -+ } -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_inode_mkdir(struct inode *inode, struct dentry *dentry, -+ int mask) -+{ -+ struct aaprofile *active; -+ int error = 0; -+ -+ active = get_active_aaprofile(); -+ -+ if (active) -+ error = aa_perm_dir(active, dentry, aa_dir_mkdir); -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_inode_rmdir(struct inode *inode, struct dentry *dentry) -+{ -+ struct aaprofile *active; -+ int error = 0; -+ -+ active = get_active_aaprofile(); -+ -+ if (active) -+ error = aa_perm_dir(active, dentry, aa_dir_rmdir); -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_inode_create(struct inode *inode, struct dentry *dentry, -+ int mask) -+{ -+ struct aaprofile *active; -+ int error = 0; -+ -+ active = get_active_aaprofile(); -+ -+ /* At a minimum, need write perm to create */ -+ if (active) -+ error = aa_perm_dentry(active, dentry, MAY_WRITE); -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_inode_link(struct dentry *old_dentry, struct inode *inode, -+ struct dentry *new_dentry) -+{ -+ int error = 0; -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ -+ if (active) -+ error = aa_link(active, new_dentry, old_dentry); -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_inode_unlink(struct inode *inode, struct dentry *dentry) -+{ -+ struct aaprofile *active; -+ int error = 0; -+ -+ active = get_active_aaprofile(); -+ -+ if (active) -+ error = aa_perm_dentry(active, dentry, MAY_WRITE); -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_inode_mknod(struct inode *inode, struct dentry *dentry, -+ int mode, dev_t dev) -+{ -+ struct aaprofile *active; -+ int error = 0; -+ -+ active = get_active_aaprofile(); -+ -+ if (active) -+ error = aa_perm_dentry(active, dentry, MAY_WRITE); -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_inode_rename(struct inode *old_inode, -+ struct dentry *old_dentry, -+ struct inode *new_inode, -+ struct dentry *new_dentry) -+{ -+ struct aaprofile *active; -+ int error = 0; -+ -+ active = get_active_aaprofile(); -+ -+ if (active) { -+ error = aa_perm_dentry(active, old_dentry, MAY_READ | -+ MAY_WRITE); -+ -+ if (!error) -+ error = aa_perm_dentry(active, new_dentry, -+ MAY_WRITE); -+ } -+ -+ put_aaprofile(active); -+ -+ return error; -+} -+ -+static int apparmor_inode_permission(struct inode *inode, int mask, -+ struct nameidata *nd) -+{ -+ int error = 0; -+ -+ /* Do not perform check on pipes or sockets -+ * Same as apparmor_file_permission -+ */ -+ if (VALID_FSTYPE(inode)) { -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ if (active) -+ error = aa_perm_nameidata(active, nd, mask); -+ put_aaprofile(active); -+ } -+ -+ return error; -+} -+ -+static int apparmor_inode_setattr(struct dentry *dentry, struct iattr *iattr) -+{ -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ /* -+ * Mediate any attempt to change attributes of a file -+ * (chmod, chown, chgrp, etc) -+ */ -+ if (active) -+ error = aa_attr(active, dentry, iattr); -+ -+ put_aaprofile(active); -+ } -+ -+ return error; -+} -+ -+static int apparmor_inode_setxattr(struct dentry *dentry, char *name, -+ void *value, size_t size, int flags) -+{ -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ if (active) -+ error = aa_xattr(active, dentry, name, aa_xattr_set); -+ put_aaprofile(active); -+ } -+ -+ return error; -+} -+ -+static int apparmor_inode_getxattr(struct dentry *dentry, char *name) -+{ -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ if (active) -+ error = aa_xattr(active, dentry, name, aa_xattr_get); -+ put_aaprofile(active); -+ } -+ -+ return error; -+} -+static int apparmor_inode_listxattr(struct dentry *dentry) -+{ -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ if (active) -+ error = aa_xattr(active, dentry, NULL, aa_xattr_list); -+ put_aaprofile(active); -+ } -+ -+ return error; -+} -+ -+static int apparmor_inode_removexattr(struct dentry *dentry, char *name) -+{ -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ if (active) -+ error = aa_xattr(active, dentry, name, -+ aa_xattr_remove); -+ put_aaprofile(active); -+ } -+ -+ return error; -+} -+ -+static int apparmor_file_permission(struct file *file, int mask) -+{ -+ struct aaprofile *active; -+ struct aaprofile *f_profile; -+ int error = 0; -+ -+ f_profile = AA_PROFILE(file->f_security); -+ /* bail out early if this isn't a mediated file */ -+ if (!(f_profile && VALID_FSTYPE(file->f_dentry->d_inode))) -+ goto out; -+ -+ active = get_active_aaprofile(); -+ if (active && f_profile != active) -+ error = aa_perm(active, file->f_dentry, file->f_vfsmnt, -+ mask & (MAY_EXEC | MAY_WRITE | MAY_READ)); -+ put_aaprofile(active); -+ -+out: -+ return error; -+} -+ -+static int apparmor_file_alloc_security(struct file *file) -+{ -+ struct aaprofile *active; -+ -+ active = get_active_aaprofile(); -+ file->f_security = get_aaprofile(active); -+ put_aaprofile(active); -+ -+ return 0; -+} -+ -+static void apparmor_file_free_security(struct file *file) -+{ -+ struct aaprofile *p = AA_PROFILE(file->f_security); -+ put_aaprofile(p); -+} -+ -+static int apparmor_file_mmap(struct file *file, unsigned long reqprot, -+ unsigned long prot, unsigned long flags) -+{ -+ int error = 0, mask = 0; -+ struct aaprofile *active; -+ -+ if (!file) -+ goto out; -+ -+ active = get_active_aaprofile(); -+ -+ 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 |= MAY_EXEC; -+ -+ AA_DEBUG("%s: 0x%x\n", __FUNCTION__, mask); -+ -+ error = aa_perm(active, file->f_dentry, file->f_vfsmnt, mask); -+ -+ put_aaprofile(active); -+ -+out: -+ return error; -+} -+ -+static int apparmor_task_alloc_security(struct task_struct *p) -+{ -+ return aa_fork(p); -+} -+ -+static void apparmor_task_free_security(struct task_struct *p) -+{ -+ aa_release(p); -+} -+ -+static int apparmor_task_post_setuid(uid_t id0, uid_t id1, uid_t id2, -+ int flags) -+{ -+ return cap_task_post_setuid(id0, id1, id2, flags); -+} -+ -+static void apparmor_task_reparent_to_init(struct task_struct *p) -+{ -+ cap_task_reparent_to_init(p); -+ return; -+} -+ -+static int apparmor_getprocattr(struct task_struct *p, char *name, void *value, -+ size_t size) -+{ -+ int error; -+ struct aaprofile *active; -+ char *str = value; -+ -+ /* Subdomain only supports the "current" process attribute */ -+ if (strcmp(name, "current") != 0) { -+ error = -EINVAL; -+ goto out; -+ } -+ -+ if (!size) { -+ error = -ERANGE; -+ goto out; -+ } -+ -+ /* must be task querying itself or admin */ -+ if (current != p && !capable(CAP_SYS_ADMIN)) { -+ error = -EPERM; -+ goto out; -+ } -+ -+ active = get_task_active_aaprofile(p); -+ error = aa_getprocattr(active, str, size); -+ put_aaprofile(active); -+ -+out: -+ return error; -+} -+ -+static int apparmor_setprocattr(struct task_struct *p, char *name, void *value, -+ size_t size) -+{ -+ const char *cmd_changehat = "changehat ", -+ *cmd_setprofile = "setprofile "; -+ -+ int error = -EACCES; /* default to a perm denied */ -+ char *cmd = (char *)value; -+ -+ /* only support messages to current */ -+ if (strcmp(name, "current") != 0) { -+ error = -EINVAL; -+ goto out; -+ } -+ -+ if (!size) { -+ error = -ERANGE; -+ goto out; -+ } -+ -+ /* CHANGE HAT -- switch task into a subhat (subprofile) if defined */ -+ if (size > strlen(cmd_changehat) && -+ strncmp(cmd, cmd_changehat, strlen(cmd_changehat)) == 0) { -+ char *hatinfo = cmd + strlen(cmd_changehat); -+ size_t infosize = size - strlen(cmd_changehat); -+ -+ /* Only the current process may change it's hat */ -+ if (current != p) { -+ AA_WARN("%s: Attempt by foreign task %s(%d) " -+ "[user %d] to changehat of task %s(%d)\n", -+ __FUNCTION__, -+ current->comm, -+ current->pid, -+ current->uid, -+ p->comm, -+ p->pid); -+ -+ error = -EACCES; -+ goto out; -+ } -+ -+ error = aa_setprocattr_changehat(hatinfo, infosize); -+ if (error == 0) -+ /* success, set return to #bytes in orig request */ -+ error = size; -+ -+ /* SET NEW PROFILE */ -+ } else if (size > strlen(cmd_setprofile) && -+ strncmp(cmd, cmd_setprofile, strlen(cmd_setprofile)) == 0) { -+ struct aaprofile *active; -+ -+ /* only an unconfined process with admin capabilities -+ * may change the profile of another task -+ */ -+ -+ if (!capable(CAP_SYS_ADMIN)) { -+ AA_WARN("%s: Unprivileged attempt by task %s(%d) " -+ "[user %d] to assign profile to task %s(%d)\n", -+ __FUNCTION__, -+ current->comm, -+ current->pid, -+ current->uid, -+ p->comm, -+ p->pid); -+ error = -EACCES; -+ goto out; -+ } -+ -+ active = get_active_aaprofile(); -+ if (!active) { -+ char *profile = cmd + strlen(cmd_setprofile); -+ size_t profilesize = size - strlen(cmd_setprofile); -+ -+ error = aa_setprocattr_setprofile(p, profile, profilesize); -+ if (error == 0) -+ /* success, -+ * set return to #bytes in orig request -+ */ -+ error = size; -+ } else { -+ AA_WARN("%s: Attempt by confined task %s(%d) " -+ "[user %d] to assign profile to task %s(%d)\n", -+ __FUNCTION__, -+ current->comm, -+ current->pid, -+ current->uid, -+ p->comm, -+ p->pid); -+ -+ error = -EACCES; -+ } -+ put_aaprofile(active); -+ } else { -+ /* unknown operation */ -+ AA_WARN("%s: Unknown setprocattr command '%.*s' by task %s(%d) " -+ "[user %d] for task %s(%d)\n", -+ __FUNCTION__, -+ size < 16 ? (int)size : 16, -+ cmd, -+ current->comm, -+ current->pid, -+ current->uid, -+ p->comm, -+ p->pid); -+ -+ error = -EINVAL; -+ } -+ -+out: -+ return error; -+} -+ -+struct security_operations apparmor_ops = { -+ .ptrace = apparmor_ptrace, -+ .capget = apparmor_capget, -+ .capset_check = apparmor_capset_check, -+ .capset_set = apparmor_capset_set, -+ .sysctl = apparmor_sysctl, -+ .capable = apparmor_capable, -+ .syslog = apparmor_syslog, -+ -+ .netlink_send = apparmor_netlink_send, -+ .netlink_recv = apparmor_netlink_recv, -+ -+ .bprm_apply_creds = apparmor_bprm_apply_creds, -+ .bprm_set_security = apparmor_bprm_set_security, -+ -+ .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_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, -+ -+ .task_alloc_security = apparmor_task_alloc_security, -+ .task_free_security = apparmor_task_free_security, -+ .task_post_setuid = apparmor_task_post_setuid, -+ .task_reparent_to_init = apparmor_task_reparent_to_init, -+ -+ .getprocattr = apparmor_getprocattr, -+ .setprocattr = apparmor_setprocattr, -+}; -+ -+static int __init apparmor_init(void) -+{ -+ int error; -+ const char *complainmsg = ": complainmode enabled"; -+ -+ if ((error = create_apparmorfs())) { -+ AA_ERROR("Unable to activate AppArmor filesystem\n"); -+ goto createfs_out; -+ } -+ -+ if ((error = alloc_null_complain_profile())){ -+ AA_ERROR("Unable to allocate null complain profile\n"); -+ goto alloc_out; -+ } -+ -+ if ((error = register_security(&apparmor_ops))) { -+ AA_ERROR("Unable to load AppArmor\n"); -+ goto register_security_out; -+ } -+ -+ AA_INFO("AppArmor initialized%s\n", -+ apparmor_complain ? complainmsg : ""); -+ aa_audit_message(NULL, GFP_KERNEL, 0, -+ "AppArmor initialized%s\n", -+ apparmor_complain ? complainmsg : ""); -+ -+ return error; -+ -+register_security_out: -+ free_null_complain_profile(); -+ -+alloc_out: -+ (void)destroy_apparmorfs(); -+ -+createfs_out: -+ return error; -+ -+} -+ -+static int apparmor_exit_removeall_iter(struct subdomain *sd, void *cookie) -+{ -+ /* spin_lock(&sd_lock) held here */ -+ -+ if (__aa_is_confined(sd)) { -+ AA_DEBUG("%s: Dropping profiles %s(%d) " -+ "profile %s(%p) active %s(%p)\n", -+ __FUNCTION__, -+ sd->task->comm, sd->task->pid, -+ BASE_PROFILE(sd->active)->name, -+ BASE_PROFILE(sd->active), -+ sd->active->name, sd->active); -+ aa_switch_unconfined(sd); -+ } -+ -+ return 0; -+} -+ -+static void __exit apparmor_exit(void) -+{ -+ unsigned long flags; -+ -+ /* Remove profiles from the global profile list. -+ * This is just for tidyness as there is no way to reference this -+ * list once the AppArmor lsm hooks are detached (below) -+ */ -+ aa_profilelist_release(); -+ -+ /* Remove profiles from active tasks -+ * If this is not done, if module is reloaded after being removed, -+ * old profiles (still refcounted in memory) will become 'magically' -+ * reattached -+ */ -+ -+ spin_lock_irqsave(&sd_lock, flags); -+ aa_subdomainlist_iterate(apparmor_exit_removeall_iter, NULL); -+ spin_unlock_irqrestore(&sd_lock, flags); -+ -+ /* Free up list of active subdomain */ -+ aa_subdomainlist_release(); -+ -+ free_null_complain_profile(); -+ -+ destroy_apparmorfs(); -+ -+ if (unregister_security(&apparmor_ops)) -+ AA_WARN("Unable to properly unregister AppArmor\n"); -+ -+ /* delay for an rcu cycle to make ensure that profiles pending -+ * destruction in the rcu callback are freed. -+ */ -+ synchronize_rcu(); -+ -+ AA_INFO("AppArmor protection removed\n"); -+ aa_audit_message(NULL, GFP_KERNEL, 0, -+ "AppArmor protection removed\n"); -+} -+ -+security_initcall(apparmor_init); -+module_exit(apparmor_exit); -+ -+MODULE_DESCRIPTION("AppArmor process confinement"); -+MODULE_AUTHOR("Tony Jones "); -+MODULE_LICENSE("GPL"); -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5003_apparmor-core-access-controls.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5003_apparmor-core-access-controls.patch deleted file mode 100644 index 66b44d8c..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5003_apparmor-core-access-controls.patch +++ /dev/null @@ -1,1643 +0,0 @@ -This patch implements core AppArmor access control (where appropriate using -functionality provided by the sub matching module [apparmor_match]), code to -assign policy (subdomains and by connection profiles) to tasks during task -creation, remove them during task release and for determining appropiate -confinement upon domain changes (exec). It is also responsible for the low -level implementation of change_hat, switching confined tasks between their -primary and child profiles. Finally it implements the interface to the kernel -audit subsystem through which enforcement and learning events are passed to -userspace. - - -Signed-off-by: Tony Jones - ---- - security/apparmor/main.c | 1618 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 1618 insertions(+) - ---- security/apparmor/main.c.orig -+++ security/apparmor/main.c -@@ -0,0 +1,1618 @@ -+/* -+ * Copyright (C) 2002-2005 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 Core -+ */ -+ -+#include -+#include -+#include -+ -+#include "apparmor.h" -+#include "match/match.h" -+ -+#include "inline.h" -+ -+/* NULL complain profile -+ * -+ * Used when in complain mode, to emit Permitting messages for non-existant -+ * profiles and hats. This is necessary because of selective mode, in which -+ * case we need a complain null_profile and enforce null_profile -+ * -+ * The null_complain_profile cannot be statically allocated, because it -+ * can be associated to files which keep their reference even if subdomain is -+ * unloaded -+ */ -+struct aaprofile *null_complain_profile; -+ -+/*************************** -+ * Private utility functions -+ **************************/ -+ -+/** -+ * aa_taskattr_access -+ * @procrelname: name of file to check permission -+ * -+ * Determine if request is for write access to /proc/self/attr/current -+ * This file is the usermode iterface for changing it's hat. -+ */ -+static inline int aa_taskattr_access(const char *procrelname) -+{ -+ char buf[sizeof("/attr/current") + 10]; -+ const int maxbuflen = sizeof(buf); -+ /* assumption, 32bit pid (10 decimal digits incl \0) */ -+ -+ snprintf(buf, maxbuflen, "%d/attr/current", current->pid); -+ buf[maxbuflen - 1] = 0; -+ -+ return strcmp(buf, procrelname) == 0; -+} -+ -+/** -+ * aa_file_mode - get full mode for file entry from profile -+ * @profile: profile -+ * @name: filename -+ */ -+static inline int aa_file_mode(struct aaprofile *profile, const char *name) -+{ -+ struct aa_entry *entry; -+ int mode = 0; -+ -+ AA_DEBUG("%s: %s\n", __FUNCTION__, name); -+ if (!name) { -+ AA_DEBUG("%s: no name\n", __FUNCTION__); -+ goto out; -+ } -+ -+ if (!profile) { -+ AA_DEBUG("%s: no profile\n", __FUNCTION__); -+ goto out; -+ } -+ list_for_each_entry(entry, &profile->file_entry, list) { -+ if (aamatch_match(name, entry->filename, -+ entry->type, entry->extradata)) -+ mode |= entry->mode; -+ } -+out: -+ return mode; -+} -+ -+/** -+ * aa_get_execmode - calculate what qualifier to apply to an exec -+ * @active: profile to search -+ * @name: name of file to exec -+ * @xmod: pointer to a execution mode bit for the rule that was matched -+ * if the rule has no execuition qualifier {pui} then -+ * %AA_MAY_EXEC is returned indicating a naked x -+ * if the has an exec qualifier then only the qualifier bit {pui} -+ * is returned (%AA_MAY_EXEC) is not set. -+ * -+ * Returns %0 (false): -+ * if unable to find profile or there are conflicting pattern matches. -+ * *xmod - is not modified -+ * -+ * Returns %1 (true): -+ * if not confined -+ * *xmod = %AA_MAY_EXEC -+ * if exec rule matched -+ * if the rule has an execution mode qualifier {pui} then -+ * *xmod = the execution qualifier of the rule {pui} -+ * else -+ * *xmod = %AA_MAY_EXEC -+ */ -+static inline int aa_get_execmode(struct aaprofile *active, const char *name, -+ int *xmod) -+{ -+ struct aa_entry *entry; -+ struct aa_entry *match = NULL; -+ -+ int pattern_match_invalid = 0, rc = 0; -+ -+ /* search list of profiles with 'x' permission -+ * this will also include entries with 'p', 'u' and 'i' -+ * qualifiers. -+ * -+ * If we find a pattern match we will keep looking for an exact match -+ * If we find conflicting pattern matches we will flag (while still -+ * looking for an exact match). If all we have is a conflict, FALSE -+ * is returned. -+ */ -+ -+ list_for_each_entry(entry, &active->file_entryp[POS_AA_MAY_EXEC], -+ listp[POS_AA_MAY_EXEC]) { -+ if (!pattern_match_invalid && -+ entry->type == aa_entry_pattern && -+ aamatch_match(name, entry->filename, -+ entry->type, entry->extradata)) { -+ if (match && -+ AA_EXEC_MASK(entry->mode) != -+ AA_EXEC_MASK(match->mode)) -+ pattern_match_invalid = 1; -+ else -+ /* keep searching for an exact match */ -+ match = entry; -+ } else if ((entry->type == aa_entry_literal || -+ (!pattern_match_invalid && -+ entry->type == aa_entry_tailglob)) && -+ aamatch_match(name, entry->filename, -+ entry->type, -+ entry->extradata)) { -+ if (entry->type == aa_entry_literal) { -+ /* got an exact match -- there can be only -+ * one, asserted at profile load time -+ */ -+ match = entry; -+ pattern_match_invalid = 0; -+ break; -+ } else { -+ if (match && -+ AA_EXEC_MASK(entry->mode) != -+ AA_EXEC_MASK(match->mode)) -+ pattern_match_invalid = 1; -+ else -+ /* got a tailglob match, keep searching -+ * for an exact match -+ */ -+ match = entry; -+ } -+ } -+ -+ } -+ -+ rc = match && !pattern_match_invalid; -+ -+ if (rc) { -+ int mode = AA_EXEC_MASK(match->mode); -+ -+ /* check for qualifiers, if present -+ * we just return the qualifier -+ */ -+ if (mode & ~AA_MAY_EXEC) -+ mode = mode & ~AA_MAY_EXEC; -+ -+ *xmod = mode; -+ } else if (!match) { -+ AA_DEBUG("%s: Unable to find execute entry in profile " -+ "for image '%s'\n", -+ __FUNCTION__, -+ name); -+ } else if (pattern_match_invalid) { -+ AA_WARN("%s: Inconsistency in profile %s. " -+ "Two (or more) patterns specify conflicting exec " -+ "qualifiers ('u', 'i' or 'p') for image %s\n", -+ __FUNCTION__, -+ active->name, -+ name); -+ } -+ -+ return rc; -+ -+ *xmod = AA_MAY_EXEC; -+ return 1; -+} -+ -+/** -+ * aa_filter_mask -+ * @mask: requested mask -+ * @inode: potential directory inode -+ * -+ * This fn performs pre-verification of the requested mask -+ * We ignore append. Previously we required 'w' on a dir to add a file. -+ * No longer. Now we require 'w' on just the file itself. Traversal 'x' is -+ * also ignored for directories. -+ * -+ * Returned value of %0 indicates no need to perform a perm check. -+ */ -+static inline int aa_filter_mask(int mask, struct inode *inode) -+{ -+ if (mask) { -+ int elim = MAY_APPEND; -+ -+ if (inode && S_ISDIR(inode->i_mode)) -+ elim |= (MAY_EXEC | MAY_WRITE); -+ -+ mask &= ~elim; -+ } -+ -+ return mask; -+} -+ -+static inline void aa_permerror2result(int perm_result, struct aa_audit *sa) -+{ -+ if (perm_result == 0) { /* success */ -+ sa->result = 1; -+ sa->error_code = 0; -+ } else { /* -ve internal error code or +ve mask of denied perms */ -+ sa->result = 0; -+ sa->error_code = perm_result; -+ } -+} -+ -+/************************* -+ * Main internal functions -+ ************************/ -+ -+/** -+ * aa_file_perm - calculate access mode for file -+ * @active: profile to check against -+ * @name: name of file to calculate mode for -+ * @mask: permission mask requested for file -+ * -+ * Search the aa_entry list in @active. -+ * Search looking to verify all permissions passed in mask. -+ * Perform the search by looking at the partitioned list of entries, one -+ * partition per permission bit. -+ * -+ * Return %0 on success, else mask of non-allowed permissions -+ */ -+static unsigned int aa_file_perm(struct aaprofile *active, const char *name, -+ int mask) -+{ -+ int i, error = 0, mode; -+ -+#define PROCPFX "/proc/" -+#define PROCLEN sizeof(PROCPFX) - 1 -+ -+ AA_DEBUG("%s: %s 0x%x\n", __FUNCTION__, name, mask); -+ -+ /* should not enter with other than R/W/X/L */ -+ WARN_ON(mask & -+ ~(AA_MAY_READ | AA_MAY_WRITE | AA_MAY_EXEC | AA_MAY_LINK)); -+ -+ /* Special case access to /proc/self/attr/current -+ * Currently we only allow access if opened O_WRONLY -+ */ -+ if (mask == MAY_WRITE && strncmp(PROCPFX, name, PROCLEN) == 0 && -+ (!list_empty(&BASE_PROFILE(active)->sub) || -+ PROFILE_COMPLAIN(active)) && aa_taskattr_access(name + PROCLEN)) -+ goto done; -+ -+ mode = 0; -+ -+ /* iterate over partition, one permission bit at a time */ -+ for (i = 0; i <= POS_AA_FILE_MAX; i++) { -+ struct aa_entry *entry; -+ -+ /* do we have to accumulate this bit? -+ * or have we already accumulated it (shortcut below)? */ -+ if (!(mask & (1 << i)) || mode & (1 << i)) -+ continue; -+ -+ list_for_each_entry(entry, &active->file_entryp[i], -+ listp[i]) { -+ if (aamatch_match(name, entry->filename, -+ entry->type, entry->extradata)) { -+ /* Shortcut, accumulate all bits present */ -+ mode |= entry->mode; -+ -+ /* Mask bits are overloaded -+ * MAY_{EXEC,WRITE,READ,APPEND} are used by -+ * kernel, other values are used locally only. -+ */ -+ if ((mode & mask) == mask) { -+ AA_DEBUG("MATCH! %s=0x%x [total mode=0x%x]\n", -+ name, mask, mode); -+ -+ goto done; -+ } -+ } -+ } -+ } -+ -+ /* return permissions not satisfied */ -+ error = mask & ~mode; -+ -+done: -+ return error; -+} -+ -+/** -+ * aa_link_perm - test permission to link to a file -+ * @active: profile to check against -+ * @link: name of link being created -+ * @target: name of target to be linked to -+ * -+ * Look up permission mode on both @link and @target. @link must have same -+ * permission mode as @target. At least @link must have the link bit enabled. -+ * Return %0 on success, error otherwise. -+ */ -+static int aa_link_perm(struct aaprofile *active, -+ const char *link, const char *target) -+{ -+ int l_mode, t_mode, ret; -+ -+ l_mode = aa_file_mode(active, link); -+ if (l_mode & AA_MAY_LINK) { -+ /* mask off link bit */ -+ l_mode &= ~AA_MAY_LINK; -+ -+ t_mode = aa_file_mode(active, target); -+ t_mode &= ~AA_MAY_LINK; -+ -+ ret = (l_mode == t_mode); -+ } else { -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+/** -+ * _aa_perm_dentry -+ * @active: profile to check against -+ * @dentry: requested dentry -+ * @mask: mask of requested operations -+ * @pname: pointer to hold matched pathname (if any) -+ * -+ * Helper function. Obtain pathname for specified dentry. Verify if profile -+ * authorizes mask operations on pathname (due to lack of vfsmnt it is sadly -+ * necessary to search mountpoints in namespace -- when nameidata is passed -+ * more fully, this code can go away). If more than one mountpoint matches -+ * but none satisfy the profile, only the first pathname (mountpoint) is -+ * returned for subsequent logging. -+ * -+ * Return %0 (success), +ve (mask of permissions not satisfied) or -ve (system -+ * error, most likely -%ENOMEM). -+ */ -+static int _aa_perm_dentry(struct aaprofile *active, struct dentry *dentry, -+ int mask, const char **pname) -+{ -+ char *name = NULL, *failed_name = NULL; -+ struct aa_path_data data; -+ int error = 0, failed_error = 0, path_error, -+ complain = PROFILE_COMPLAIN(active); -+ -+ /* search all paths to dentry */ -+ -+ aa_path_begin(dentry, &data); -+ do { -+ name = aa_path_getname(&data); -+ if (name) { -+ /* error here is 0 (success) or +ve (mask of perms) */ -+ error = aa_file_perm(active, name, mask); -+ -+ /* access via any path is enough */ -+ if (complain || error == 0) -+ break; /* Caller must free name */ -+ -+ /* Already have an path that failed? */ -+ if (failed_name) { -+ aa_put_name(name); -+ } else { -+ failed_name = name; -+ failed_error = error; -+ } -+ } -+ } while (name); -+ -+ if ((path_error = aa_path_end(&data)) != 0) { -+ AA_ERROR("%s: An error occured while translating dentry %p " -+ "inode# %lu to a pathname. Error %d\n", -+ __FUNCTION__, -+ dentry, -+ dentry->d_inode->i_ino, -+ path_error); -+ -+ WARN_ON(name); /* name should not be set if error */ -+ error = path_error; -+ name = NULL; -+ } else if (name) { -+ if (failed_name) -+ aa_put_name(failed_name); -+ } else { -+ name = failed_name; -+ error = failed_error; -+ } -+ -+ *pname = name; -+ -+ return error; -+} -+ -+/************************** -+ * Global utility functions -+ *************************/ -+ -+/** -+ * attach_nullprofile - allocate and attach a null_profile hat to profile -+ * @profile: profile to attach a null_profile hat to. -+ * -+ * Return %0 (success) or error (-%ENOMEM) -+ */ -+int attach_nullprofile(struct aaprofile *profile) -+{ -+ struct aaprofile *hat = NULL; -+ char *hatname = NULL; -+ -+ hat = alloc_aaprofile(); -+ if (!hat) -+ goto fail; -+ if (profile->flags.complain) -+ hatname = kstrdup("null-complain-profile", GFP_KERNEL); -+ else -+ hatname = kstrdup("null-profile", GFP_KERNEL); -+ if (!hatname) -+ goto fail; -+ -+ hat->flags.complain = profile->flags.complain; -+ hat->name = hatname; -+ hat->parent = profile; -+ -+ profile->null_profile = hat; -+ -+ return 0; -+ -+fail: -+ kfree(hatname); -+ free_aaprofile(hat); -+ -+ return -ENOMEM; -+} -+ -+ -+/** -+ * alloc_null_complain_profile - Allocate the global null_complain_profile. -+ * -+ * Return %0 (success) or error (-%ENOMEM) -+ */ -+int alloc_null_complain_profile(void) -+{ -+ null_complain_profile = alloc_aaprofile(); -+ if (!null_complain_profile) -+ goto fail; -+ -+ null_complain_profile->name = -+ kstrdup("null-complain-profile", GFP_KERNEL); -+ -+ if (!null_complain_profile->name) -+ goto fail; -+ -+ null_complain_profile->flags.complain = 1; -+ if (attach_nullprofile(null_complain_profile)) -+ goto fail; -+ -+ return 0; -+ -+fail: -+ /* free_aaprofile is safe for freeing partially constructed objects */ -+ free_aaprofile(null_complain_profile); -+ null_complain_profile = NULL; -+ -+ return -ENOMEM; -+} -+ -+/** -+ * free_null_complain_profile - Free null profiles -+ */ -+void free_null_complain_profile(void) -+{ -+ put_aaprofile(null_complain_profile); -+ null_complain_profile = NULL; -+} -+ -+/** -+ * aa_audit_message - Log a message to the audit subsystem -+ * @active: profile to check against -+ * @gfp: allocation flags -+ * @flags: audit flags -+ * @fmt: varargs fmt -+ */ -+int aa_audit_message(struct aaprofile *active, unsigned int gfp, int flags, -+ const char *fmt, ...) -+{ -+ int ret; -+ struct aa_audit sa; -+ -+ sa.type = AA_AUDITTYPE_MSG; -+ sa.name = fmt; -+ va_start(sa.vaval, fmt); -+ sa.flags = flags; -+ sa.gfp_mask = gfp; -+ sa.error_code = 0; -+ sa.result = 0; /* fake failure: force message to be logged */ -+ -+ ret = aa_audit(active, &sa); -+ -+ va_end(sa.vaval); -+ -+ return ret; -+} -+ -+/** -+ * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem -+ * @active: profile to check against -+ * @msg: string describing syscall being rejected -+ * @gfp: memory allocation flags -+ */ -+int aa_audit_syscallreject(struct aaprofile *active, unsigned int gfp, -+ const char *msg) -+{ -+ struct aa_audit sa; -+ -+ sa.type = AA_AUDITTYPE_SYSCALL; -+ sa.name = msg; -+ sa.flags = 0; -+ sa.gfp_mask = gfp; -+ sa.error_code = 0; -+ sa.result = 0; /* failure */ -+ -+ return aa_audit(active, &sa); -+} -+ -+/** -+ * aa_audit - Log an audit event to the audit subsystem -+ * @active: profile to check against -+ * @sa: audit event -+ */ -+int aa_audit(struct aaprofile *active, const struct aa_audit *sa) -+{ -+ struct audit_buffer *ab = NULL; -+ struct audit_context *ctx; -+ -+ const char *logcls; -+ unsigned int flags; -+ int audit = 0, -+ complain = 0, -+ error = -EINVAL, -+ opspec_error = -EACCES; -+ -+ const unsigned int gfp_mask = sa->gfp_mask; -+ -+ WARN_ON(sa->type >= AA_AUDITTYPE__END); -+ -+ /* -+ * sa->result: 1 success, 0 failure -+ * sa->error_code: success: 0 -+ * failure: +ve mask of failed permissions or -ve -+ * system error -+ */ -+ -+ if (likely(sa->result)) { -+ if (likely(!PROFILE_AUDIT(active))) { -+ /* nothing to log */ -+ error = 0; -+ goto out; -+ } else { -+ audit = 1; -+ logcls = "AUDITING"; -+ } -+ } else if (sa->error_code < 0) { -+ audit_log(current->audit_context, gfp_mask, AUDIT_AA, -+ "Internal error auditing event type %d (error %d)", -+ sa->type, sa->error_code); -+ AA_ERROR("Internal error auditing event type %d (error %d)\n", -+ sa->type, sa->error_code); -+ error = sa->error_code; -+ goto out; -+ } else if (sa->type == AA_AUDITTYPE_SYSCALL) { -+ /* Currently AA_AUDITTYPE_SYSCALL is for rejects only. -+ * Values set by aa_audit_syscallreject will get us here. -+ */ -+ logcls = "REJECTING"; -+ } else { -+ complain = PROFILE_COMPLAIN(active); -+ logcls = complain ? "PERMITTING" : "REJECTING"; -+ } -+ -+ /* In future extend w/ per-profile flags -+ * (flags |= sa->active->flags) -+ */ -+ flags = sa->flags; -+ if (apparmor_logsyscall) -+ flags |= AA_AUDITFLAG_AUDITSS_SYSCALL; -+ -+ -+ /* Force full audit syscall logging regardless of global setting if -+ * we are rejecting a syscall -+ */ -+ if (sa->type == AA_AUDITTYPE_SYSCALL) { -+ ctx = current->audit_context; -+ } else { -+ ctx = (flags & AA_AUDITFLAG_AUDITSS_SYSCALL) ? -+ current->audit_context : NULL; -+ } -+ -+ ab = audit_log_start(ctx, gfp_mask, AUDIT_AA); -+ -+ if (!ab) { -+ AA_ERROR("Unable to log event (%d) to audit subsys\n", -+ sa->type); -+ if (complain) -+ error = 0; -+ goto out; -+ } -+ -+ /* messages get special handling */ -+ if (sa->type == AA_AUDITTYPE_MSG) { -+ audit_log_vformat(ab, sa->name, sa->vaval); -+ audit_log_end(ab); -+ error = 0; -+ goto out; -+ } -+ -+ /* log operation */ -+ -+ audit_log_format(ab, "%s ", logcls); /* REJECTING/ALLOWING/etc */ -+ -+ if (sa->type == AA_AUDITTYPE_FILE) { -+ int perm = audit ? sa->ival : sa->error_code; -+ -+ audit_log_format(ab, "%s%s%s%s access to %s ", -+ perm & AA_MAY_READ ? "r" : "", -+ perm & AA_MAY_WRITE ? "w" : "", -+ perm & AA_MAY_EXEC ? "x" : "", -+ perm & AA_MAY_LINK ? "l" : "", -+ sa->name); -+ -+ opspec_error = -EPERM; -+ -+ } else if (sa->type == AA_AUDITTYPE_DIR) { -+ audit_log_format(ab, "%s on %s ", -+ sa->ival == aa_dir_mkdir ? "mkdir" : "rmdir", -+ sa->name); -+ -+ } else if (sa->type == AA_AUDITTYPE_ATTR) { -+ struct iattr *iattr = (struct iattr*)sa->pval; -+ -+ audit_log_format(ab, -+ "attribute (%s%s%s%s%s%s%s) change to %s ", -+ iattr->ia_valid & ATTR_MODE ? "mode," : "", -+ iattr->ia_valid & ATTR_UID ? "uid," : "", -+ iattr->ia_valid & ATTR_GID ? "gid," : "", -+ iattr->ia_valid & ATTR_SIZE ? "size," : "", -+ ((iattr->ia_valid & ATTR_ATIME_SET) || -+ (iattr->ia_valid & ATTR_ATIME)) ? "atime," : "", -+ ((iattr->ia_valid & ATTR_MTIME_SET) || -+ (iattr->ia_valid & ATTR_MTIME)) ? "mtime," : "", -+ iattr->ia_valid & ATTR_CTIME ? "ctime," : "", -+ sa->name); -+ -+ } else if (sa->type == AA_AUDITTYPE_XATTR) { -+ const char *fmt; -+ switch (sa->ival) { -+ case aa_xattr_get: -+ fmt = "xattr get"; -+ break; -+ case aa_xattr_set: -+ fmt = "xattr set"; -+ break; -+ case aa_xattr_list: -+ fmt = "xattr list"; -+ break; -+ case aa_xattr_remove: -+ fmt = "xattr remove"; -+ break; -+ default: -+ fmt = "xattr "; -+ break; -+ } -+ -+ audit_log_format(ab, "%s on %s ", fmt, sa->name); -+ -+ } else if (sa->type == AA_AUDITTYPE_LINK) { -+ audit_log_format(ab, -+ "link access from %s to %s ", -+ sa->name, -+ (char*)sa->pval); -+ -+ } else if (sa->type == AA_AUDITTYPE_CAP) { -+ audit_log_format(ab, -+ "access to capability '%s' ", -+ capability_to_name(sa->ival)); -+ -+ opspec_error = -EPERM; -+ } else if (sa->type == AA_AUDITTYPE_SYSCALL) { -+ audit_log_format(ab, "access to syscall '%s' ", sa->name); -+ -+ opspec_error = -EPERM; -+ } else { -+ /* -EINVAL -- will WARN_ON above */ -+ goto out; -+ } -+ -+ audit_log_format(ab, "(%s(%d) ", current->comm, current->pid); -+ -+ if (0) -+ audit_log_format(ab, "[global deny])"); -+ else -+ audit_log_format(ab, "profile %s active %s)", -+ BASE_PROFILE(active)->name, -+ active->name); -+ -+ audit_log_end(ab); -+ -+ if (complain) -+ error = 0; -+ else -+ error = sa->result ? 0 : opspec_error; -+ -+out: -+ return error; -+} -+ -+/** -+ * aa_get_name - retrieve fully qualified path name -+ * @dentry: relative path element -+ * @mnt: where in tree -+ * -+ * Returns fully qualified path name on sucess, NULL on failure. -+ * aa_put_name must be used to free allocated buffer. -+ */ -+char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt) -+{ -+ char *page, *name = NULL; -+ -+ page = (char *)__get_free_page(GFP_KERNEL); -+ if (!page) -+ goto out; -+ -+ name = d_path_flags(dentry, mnt, page, PAGE_SIZE, -+ DPATH_SYSROOT|DPATH_NODELETED); -+ -+ AA_DEBUG("%s: full_path=%s\n", __FUNCTION__, name); -+out: -+ return name; -+} -+ -+/*********************************** -+ * Global permission check functions -+ ***********************************/ -+ -+/** -+ * aa_attr - check whether attribute change allowed -+ * @active: profile to check against -+ * @dentry: file to check -+ * @iattr: attribute changes requested -+ */ -+int aa_attr(struct aaprofile *active, struct dentry *dentry, -+ struct iattr *iattr) -+{ -+ int error = 0, permerror; -+ struct aa_audit sa; -+ -+ sa.type = AA_AUDITTYPE_ATTR; -+ sa.pval = iattr; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = _aa_perm_dentry(active, dentry, MAY_WRITE, &sa.name); -+ aa_permerror2result(permerror, &sa); -+ -+ error = aa_audit(active, &sa); -+ -+ aa_put_name(sa.name); -+ -+ return error; -+} -+ -+/** -+ * aa_xattr - check whether xattr attribute change allowed -+ * @active: profile to check against -+ * @dentry: file to check -+ * @xattr: xattr to check -+ * @xattroptype: type of xattr operation -+ */ -+int aa_xattr(struct aaprofile *active, struct dentry *dentry, -+ const char *xattr, enum aa_xattroptype xattroptype) -+{ -+ int error = 0, permerror, mask = 0; -+ struct aa_audit sa; -+ -+ /* if not confined or empty mask permission granted */ -+ if (!active) -+ goto out; -+ -+ if (xattroptype == aa_xattr_get || xattroptype == aa_xattr_list) -+ mask = MAY_READ; -+ else if (xattroptype == aa_xattr_set || xattroptype == aa_xattr_remove) -+ mask = MAY_WRITE; -+ -+ sa.type = AA_AUDITTYPE_XATTR; -+ sa.ival = xattroptype; -+ sa.pval = xattr; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = _aa_perm_dentry(active, dentry, mask, &sa.name); -+ aa_permerror2result(permerror, &sa); -+ -+ error = aa_audit(active, &sa); -+ -+ aa_put_name(sa.name); -+ -+out: -+ return error; -+} -+ -+/** -+ * aa_perm - basic subdomain permissions check -+ * @active: profile to check against -+ * @dentry: dentry -+ * @mnt: mountpoint -+ * @mask: access mode requested -+ * -+ * Determine if access (mask) for dentry is authorized by subdomain active -+ * profile. Result, %0 (success), -ve (error) -+ */ -+int aa_perm(struct aaprofile *active, struct dentry *dentry, -+ struct vfsmount *mnt, int mask) -+{ -+ int error = 0, permerror; -+ struct aa_audit sa; -+ -+ if (!active) -+ goto out; -+ -+ if ((mask = aa_filter_mask(mask, dentry->d_inode)) == 0) -+ goto out; -+ -+ sa.type = AA_AUDITTYPE_FILE; -+ sa.name = aa_get_name(dentry, mnt); -+ sa.ival = mask; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = (sa.name ? aa_file_perm(active, sa.name, mask) : -ENOMEM); -+ -+ aa_permerror2result(permerror, &sa); -+ -+ error = aa_audit(active, &sa); -+ -+ aa_put_name(sa.name); -+ -+out: -+ return error; -+} -+ -+/** -+ * aa_perm_nameidata: interface to sd_perm accepting nameidata -+ * @active: profile to check against -+ * @nd: namespace data (for vfsmnt and dentry) -+ * @mask: access mode requested -+ */ -+int aa_perm_nameidata(struct aaprofile *active, struct nameidata *nd, int mask) -+{ -+ int error = 0; -+ -+ if (nd) -+ error = aa_perm(active, nd->dentry, nd->mnt, mask); -+ -+ return error; -+} -+ -+/** -+ * aa_perm_dentry - file permissions interface when no vfsmnt available -+ * @active: profile to check against -+ * @dentry: requested dentry -+ * @mask: access mode requested -+ * -+ * Determine if access (mask) for dentry is authorized by active profile. -+ * Result, %0 (success), -ve (error) -+ */ -+int aa_perm_dentry(struct aaprofile *active, struct dentry *dentry, int mask) -+{ -+ int error = 0, permerror; -+ struct aa_audit sa; -+ -+ if (!active) -+ goto out; -+ -+ if ((mask = aa_filter_mask(mask, dentry->d_inode)) == 0) -+ goto out; -+ -+ sa.type = AA_AUDITTYPE_FILE; -+ sa.ival = mask; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = _aa_perm_dentry(active, dentry, mask, &sa.name); -+ aa_permerror2result(permerror, &sa); -+ -+ error = aa_audit(active, &sa); -+ -+ aa_put_name(sa.name); -+ -+out: -+ return error; -+} -+ -+/** -+ * aa_perm_dir -+ * @active: profile to check against -+ * @dentry: requested dentry -+ * @diroptype: aa_dir_mkdir or aa_dir_rmdir -+ * -+ * Determine if directory operation (make/remove) for dentry is authorized -+ * by @active profile. -+ * Result, %0 (success), -ve (error) -+ */ -+int aa_perm_dir(struct aaprofile *active, struct dentry *dentry, -+ enum aa_diroptype diroptype) -+{ -+ int error = 0, permerror, mask; -+ struct aa_audit sa; -+ -+ WARN_ON(diroptype != aa_dir_mkdir && diroptype != aa_dir_rmdir); -+ -+ if (!active) -+ goto out; -+ -+ mask = MAY_WRITE; -+ -+ sa.type = AA_AUDITTYPE_DIR; -+ sa.ival = diroptype; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = _aa_perm_dentry(active, dentry, mask, &sa.name); -+ aa_permerror2result(permerror, &sa); -+ -+ error = aa_audit(active, &sa); -+ -+ aa_put_name(sa.name); -+ -+out: -+ return error; -+} -+ -+/** -+ * aa_capability - test permission to use capability -+ * @active: profile to check against -+ * @cap: capability to be tested -+ * -+ * Look up capability in active profile capability set. -+ * Return %0 (success), -%EPERM (error) -+ */ -+int aa_capability(struct aaprofile *active, int cap) -+{ -+ int error = 0; -+ -+ struct aa_audit sa; -+ -+ sa.type = AA_AUDITTYPE_CAP; -+ sa.name = NULL; -+ sa.ival = cap; -+ sa.flags = 0; -+ sa.error_code = 0; -+ sa.result = cap_raised(active->capabilities, cap); -+ sa.gfp_mask = GFP_ATOMIC; -+ -+ error = aa_audit(active, &sa); -+ -+ return error; -+} -+ -+/** -+ * aa_link - hard link check -+ * @active: profile to check against -+ * @link: dentry for link being created -+ * @target: dentry for link target -+ * -+ * Checks link permissions for all possible name combinations. This is -+ * particularly ugly. Returns %0 on sucess, error otherwise. -+ */ -+int aa_link(struct aaprofile *active, struct dentry *link, -+ struct dentry *target) -+{ -+ char *iname = NULL, *oname = NULL, -+ *failed_iname = NULL, *failed_oname = NULL; -+ unsigned int result = 0; -+ int error, path_error, error_code = 0, match = 0, -+ complain = PROFILE_COMPLAIN(active); -+ struct aa_path_data idata, odata; -+ struct aa_audit sa; -+ -+ if (!active) -+ return 0; -+ -+ /* Perform nested lookup for names. -+ * This is necessary in the case where /dev/block is mounted -+ * multiple times, i.e /dev/block->/a and /dev/block->/b -+ * This allows us to detect links where src/dest are on different -+ * mounts. N.B no support yet for links across bind mounts of -+ * the form mount -bind /mnt/subpath /mnt2 -+ * -+ * Getting direct access to vfsmounts (via nameidata) for link and -+ * target would allow all this uglyness to go away. -+ * -+ * If more than one mountpoint matches but none satisfy the profile, -+ * only the first pathname (mountpoint) is logged. -+ */ -+ -+ __aa_path_begin(target, link, &odata); -+ do { -+ oname = aa_path_getname(&odata); -+ if (oname) { -+ aa_path_begin(target, &idata); -+ do { -+ iname = aa_path_getname(&idata); -+ if (iname) { -+ result = aa_link_perm(active, oname, -+ iname); -+ -+ /* access via any path is enough */ -+ if (result || complain) { -+ match = 1; -+ break; -+ } -+ -+ /* Already have an path that failed? */ -+ if (failed_iname) { -+ aa_put_name(iname); -+ } else { -+ failed_iname = iname; -+ failed_oname = oname; -+ } -+ } -+ } while (iname && !match); -+ -+ /* should not be possible if we matched */ -+ if ((path_error = aa_path_end(&idata)) != 0) { -+ AA_ERROR("%s: An error occured while " -+ "translating inner dentry %p " -+ "inode %lu to a pathname. Error %d\n", -+ __FUNCTION__, -+ target, -+ target->d_inode->i_ino, -+ path_error); -+ -+ /* name should not be set if error */ -+ WARN_ON(iname); -+ -+ error_code = path_error; -+ } -+ -+ /* don't release if we're saving it */ -+ if (!match && failed_oname != oname) -+ aa_put_name(oname); -+ } -+ } while (oname && !match); -+ -+ if (error_code != 0) { -+ /* inner error */ -+ (void)aa_path_end(&odata); -+ } else if ((path_error = aa_path_end(&odata)) != 0) { -+ AA_ERROR("%s: An error occured while translating outer " -+ "dentry %p inode %lu to a pathname. Error %d\n", -+ __FUNCTION__, -+ link, -+ link->d_inode->i_ino, -+ path_error); -+ -+ error_code = path_error; -+ } -+ -+ if (error_code != 0) { -+ /* inner or outer error */ -+ result = 0; -+ } else if (match) { -+ result = 1; -+ } else { -+ /* failed to match */ -+ WARN_ON(iname); -+ WARN_ON(oname); -+ -+ result = 0; -+ iname = failed_iname; -+ oname = failed_oname; -+ } -+ -+ sa.type = AA_AUDITTYPE_LINK; -+ sa.name = oname; /* link */ -+ sa.pval = iname; /* target */ -+ sa.flags = 0; -+ sa.error_code = error_code; -+ sa.result = result; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ error = aa_audit(active, &sa); -+ -+ if (failed_oname != oname) -+ aa_put_name(failed_oname); -+ if (failed_iname != iname) -+ aa_put_name(failed_iname); -+ -+ aa_put_name(oname); -+ aa_put_name(iname); -+ -+ return error; -+} -+ -+/******************************* -+ * Global task related functions -+ *******************************/ -+ -+/** -+ * aa_fork - create a new subdomain -+ * @p: new process -+ * -+ * Create a new subdomain struct for the newly created process @p. -+ * Copy parent info to child. If parent has no subdomain, child -+ * will get one with %NULL values. Return %0 on sucess. -+ * -+ * The sd_lock is used to maintain consistency against profile -+ * replacement/removal. -+ */ -+ -+int aa_fork(struct task_struct *p) -+{ -+ struct subdomain *sd = AA_SUBDOMAIN(current->security); -+ struct subdomain *newsd = alloc_subdomain(p); -+ -+ AA_DEBUG("%s\n", __FUNCTION__); -+ -+ if (!newsd) -+ return -ENOMEM; -+ -+ if (sd) { -+ unsigned long flags; -+ -+ /* Use locking here instead of getting the reference -+ * because we need both the old reference and the -+ * new reference to be consistent. -+ */ -+ spin_lock_irqsave(&sd_lock, flags); -+ aa_switch(newsd, sd->active); -+ newsd->hat_magic = sd->hat_magic; -+ spin_unlock_irqrestore(&sd_lock, flags); -+ -+ if (SUBDOMAIN_COMPLAIN(sd) && -+ sd->active == null_complain_profile) -+ LOG_HINT(sd->active, GFP_KERNEL, HINT_FORK, -+ "pid=%d child=%d\n", -+ current->pid, p->pid); -+ } -+ p->security = newsd; -+ return 0; -+} -+ -+/** -+ * aa_register - register a new program -+ * @filp: file of program being registered -+ * -+ * Try to register a new program during execve(). This should give the -+ * new program a valid subdomain. -+ */ -+int aa_register(struct file *filp) -+{ -+ char *filename; -+ struct subdomain *sd; -+ struct aaprofile *active; -+ struct aaprofile *newprofile = NULL, unconstrained_flag; -+ int error = -ENOMEM, -+ exec_mode = 0, -+ find_profile = 0, -+ find_profile_mandatory = 0, -+ complain = 0; -+ -+ AA_DEBUG("%s\n", __FUNCTION__); -+ -+ sd = AA_SUBDOMAIN(current->security); -+ -+ if (sd) { -+ complain = SUBDOMAIN_COMPLAIN(sd); -+ } else { -+ /* task has no subdomain. This can happen when a task is -+ * created when subdomain is not loaded. Allocate and -+ * attach a subdomain to the task -+ */ -+ sd = alloc_subdomain(current); -+ if (!sd) { -+ AA_WARN("%s: Failed to allocate subdomain\n", -+ __FUNCTION__); -+ goto out; -+ } -+ -+ current->security = sd; -+ } -+ -+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt); -+ if (!filename) { -+ AA_WARN("%s: Failed to get filename\n", __FUNCTION__); -+ goto out; -+ } -+ -+ error = 0; -+ -+ active = get_active_aaprofile(); -+ -+ if (!active) { -+ /* Unconfined task, load profile if it exists */ -+ find_profile = 1; -+ goto find_profile; -+ } -+ -+ /* Confined task, determine what mode inherit, unconstrained or -+ * mandatory to load new profile -+ */ -+ if (aa_get_execmode(active, filename, &exec_mode)) { -+ switch (exec_mode) { -+ case AA_EXEC_INHERIT: -+ /* do nothing - setting of profile -+ * already handed in aa_fork -+ */ -+ AA_DEBUG("%s: INHERIT %s\n", -+ __FUNCTION__, -+ filename); -+ break; -+ -+ case AA_EXEC_UNCONSTRAINED: -+ AA_DEBUG("%s: UNCONSTRAINED %s\n", -+ __FUNCTION__, -+ filename); -+ -+ /* unload profile */ -+ newprofile = &unconstrained_flag; -+ break; -+ -+ case AA_EXEC_PROFILE: -+ AA_DEBUG("%s: PROFILE %s\n", -+ __FUNCTION__, -+ filename); -+ -+ find_profile = 1; -+ find_profile_mandatory = 1; -+ break; -+ -+ case AA_MAY_EXEC: -+ /* this should not happen, entries -+ * with just EXEC only should be -+ * rejected at profile load time -+ */ -+ AA_ERROR("%s: Rejecting exec(2) of image '%s'. " -+ "AA_MAY_EXEC without exec qualifier invalid " -+ "(%s(%d) profile %s active %s\n", -+ __FUNCTION__, -+ filename, -+ current->comm, current->pid, -+ BASE_PROFILE(active)->name, active->name); -+ error = -EPERM; -+ break; -+ -+ default: -+ AA_ERROR("%s: Rejecting exec(2) of image '%s'. " -+ "Unknown exec qualifier %x " -+ "(%s (pid %d) profile %s active %s)\n", -+ __FUNCTION__, -+ filename, -+ exec_mode, -+ current->comm, current->pid, -+ BASE_PROFILE(active)->name, sd->active->name); -+ error = -EPERM; -+ break; -+ } -+ -+ } else if (complain) { -+ /* There was no entry in calling profile -+ * describing mode to execute image in. -+ * Drop into null-profile -+ */ -+ newprofile = get_aaprofile(null_complain_profile); -+ } else { -+ AA_WARN("%s: Rejecting exec(2) of image '%s'. " -+ "Unable to determine exec qualifier " -+ "(%s (pid %d) profile %s active %s)\n", -+ __FUNCTION__, -+ filename, -+ current->comm, current->pid, -+ BASE_PROFILE(active)->name, active->name); -+ error = -EPERM; -+ } -+ -+ -+find_profile: -+ if (!find_profile) -+ goto apply_profile; -+ -+ /* Locate new profile */ -+ newprofile = aa_profilelist_find(filename); -+ if (newprofile) { -+ AA_DEBUG("%s: setting profile %s\n", -+ __FUNCTION__, newprofile->name); -+ } else if (find_profile_mandatory) { -+ /* Profile (mandatory) could not be found */ -+ -+ if (complain) { -+ LOG_HINT(active, GFP_KERNEL, HINT_MANDPROF, -+ "image=%s pid=%d profile=%s active=%s\n", -+ filename, -+ current->pid, -+ BASE_PROFILE(active)->name, active->name); -+ -+ newprofile = get_aaprofile(null_complain_profile); -+ } else { -+ AA_WARN("REJECTING exec(2) of image '%s'. " -+ "Profile mandatory and not found " -+ "(%s(%d) profile %s active %s)\n", -+ filename, -+ current->comm, current->pid, -+ BASE_PROFILE(active)->name, active->name); -+ error = -EPERM; -+ } -+ } else { -+ /* Profile (non-mandatory) could not be found */ -+ -+ /* Only way we can get into this code is if task -+ * is unconstrained. -+ */ -+ -+ WARN_ON(active); -+ -+ AA_DEBUG("%s: No profile found for exec image %s\n", -+ __FUNCTION__, -+ filename); -+ } /* newprofile */ -+ -+ -+apply_profile: -+ /* Apply profile if necessary */ -+ if (newprofile) { -+ unsigned long flags; -+ -+ if (newprofile == &unconstrained_flag) -+ newprofile = NULL; -+ -+ /* grab a lock - this is to guarentee consistency against -+ * other writers of subdomain (replacement/removal) -+ * -+ * Several things may have changed since the code above -+ * -+ * - If we are a confined process, active is a refcounted copy -+ * of the profile that was on the subdomain at entry. -+ * This allows us to not have to hold a lock around -+ * all this code. If profile replacement has taken place -+ * our sd->active may not equal sd->active any more. -+ * This is okay since the operation is treated as if -+ * the transition occured before replacement. -+ * -+ * - If newprofile points to an actual profile (result of -+ * aa_profilelist_find above), this profile may have been -+ * replaced. We need to fix it up. Doing this to avoid -+ * having to hold a lock around all this code. -+ */ -+ -+ spin_lock_irqsave(&sd_lock, flags); -+ -+ /* Determine if profile we found earlier is stale. -+ * If so, reobtain it. N.B stale flag should never be -+ * set on null_complain profile. -+ */ -+ if (newprofile && unlikely(newprofile->isstale)) { -+ WARN_ON(newprofile == null_complain_profile); -+ -+ /* drop refcnt obtained from earlier get_aaprofile */ -+ put_aaprofile(newprofile); -+ -+ newprofile = aa_profilelist_find(filename); -+ -+ if (!newprofile) { -+ /* Race, profile was removed, not replaced. -+ * Redo with error checking -+ */ -+ spin_unlock_irqrestore(&sd_lock, flags); -+ goto find_profile; -+ } -+ } -+ -+ aa_switch(sd, newprofile); -+ put_aaprofile(newprofile); -+ -+ if (complain && newprofile == null_complain_profile) -+ LOG_HINT(newprofile, GFP_ATOMIC, HINT_CHGPROF, -+ "pid=%d\n", -+ current->pid); -+ -+ spin_unlock_irqrestore(&sd_lock, flags); -+ } -+ -+ aa_put_name(filename); -+ -+ put_aaprofile(active); -+ -+out: -+ return error; -+} -+ -+/** -+ * aa_release - release the task's subdomain -+ * @p: task being released -+ * -+ * This is called after a task has exited and the parent has reaped it. -+ * @p->security blob is freed. -+ * -+ * This is the one case where we don't need to hold the sd_lock before -+ * removing a profile from a subdomain. Once the subdomain has been -+ * removed from the subdomain_list, we are no longer racing other writers. -+ * There may still be other readers so we must still use aa_switch -+ * to put the subdomain's reference safely. -+ */ -+void aa_release(struct task_struct *p) -+{ -+ struct subdomain *sd = AA_SUBDOMAIN(p->security); -+ if (sd) { -+ p->security = NULL; -+ -+ aa_subdomainlist_remove(sd); -+ -+ aa_switch_unconfined(sd); -+ -+ kfree(sd); -+ } -+} -+ -+/***************************** -+ * global subprofile functions -+ ****************************/ -+ -+/** -+ * do_change_hat - actually switch hats -+ * @hat_name: name of hat to swtich to -+ * @sd: current subdomain -+ * -+ * Switch to a new hat. Return %0 on success, error otherwise. -+ */ -+static inline int do_change_hat(const char *hat_name, struct subdomain *sd) -+{ -+ struct aaprofile *sub; -+ int error = 0; -+ -+ sub = __aa_find_profile(hat_name, &BASE_PROFILE(sd->active)->sub); -+ -+ if (sub) { -+ /* change hat */ -+ aa_switch(sd, sub); -+ put_aaprofile(sub); -+ } else { -+ /* There is no such subprofile change to a NULL profile. -+ * The NULL profile grants no file access. -+ * -+ * This feature is used by changehat_apache. -+ * -+ * N.B from the null-profile the task can still changehat back -+ * out to the parent profile (assuming magic != NULL) -+ */ -+ if (SUBDOMAIN_COMPLAIN(sd)) { -+ LOG_HINT(sd->active, GFP_ATOMIC, HINT_UNKNOWN_HAT, -+ "%s pid=%d " -+ "profile=%s active=%s\n", -+ hat_name, -+ current->pid, -+ BASE_PROFILE(sd->active)->name, -+ sd->active->name); -+ } else { -+ AA_DEBUG("%s: Unknown hatname '%s'. " -+ "Changing to NULL profile " -+ "(%s(%d) profile %s active %s)\n", -+ __FUNCTION__, -+ hat_name, -+ current->comm, current->pid, -+ BASE_PROFILE(sd->active)->name, -+ sd->active->name); -+ error = -EACCES; -+ } -+ aa_switch(sd, sd->active->null_profile); -+ } -+ -+ return error; -+} -+ -+/** -+ * aa_change_hat - change hat to/from subprofile -+ * @hat_name: specifies hat to change to -+ * @hat_magic: token to validate hat change -+ * -+ * Change to new @hat_name when current hat is top level profile, and store -+ * the @hat_magic in the current subdomain. If the new @hat_name is -+ * %NULL, and the @hat_magic matches that stored in the current subdomain -+ * return to original top level profile. Returns %0 on success, error -+ * otherwise. -+ */ -+int aa_change_hat(const char *hat_name, u32 hat_magic) -+{ -+ struct subdomain *sd = AA_SUBDOMAIN(current->security); -+ int error = 0; -+ -+ AA_DEBUG("%s: %p, 0x%x (pid %d)\n", -+ __FUNCTION__, -+ hat_name, hat_magic, -+ current->pid); -+ -+ /* Dump out above debugging in WARN mode if we are in AUDIT mode */ -+ if (SUBDOMAIN_AUDIT(sd)) { -+ AA_WARN("%s: %s, 0x%x (pid %d)\n", -+ __FUNCTION__, hat_name ? hat_name : "NULL", -+ hat_magic, current->pid); -+ } -+ -+ /* check to see if an unconfined process is doing a changehat. */ -+ if (!__aa_is_confined(sd)) { -+ error = -EACCES; -+ goto out; -+ } -+ -+ /* Check whether current domain is parent -+ * or one of the sibling children -+ */ -+ if (!IN_SUBPROFILE(sd->active)) { -+ /* -+ * parent -+ */ -+ if (hat_name) { -+ AA_DEBUG("%s: switching to %s, 0x%x\n", -+ __FUNCTION__, -+ hat_name, -+ hat_magic); -+ -+ /* -+ * N.B hat_magic == 0 has a special meaning -+ * this indicates that the task may never changehat -+ * back to it's parent, it will stay in this subhat -+ * (or null-profile, if the hat doesn't exist) until -+ * the task terminates -+ */ -+ sd->hat_magic = hat_magic; -+ error = do_change_hat(hat_name, sd); -+ } else { -+ /* Got here via changehat(NULL, magic) -+ * -+ * We used to simply update the magic cookie. -+ * That's an odd behaviour, so just do nothing. -+ */ -+ } -+ } else { -+ /* -+ * child -- check to make sure magic is same as what was -+ * passed when we switched into this profile, -+ * Handle special casing of NULL magic which confines task -+ * to subprofile and prohibits further changehats -+ */ -+ if (hat_magic == sd->hat_magic && sd->hat_magic) { -+ if (!hat_name) { -+ /* -+ * Got here via changehat(NULL, magic) -+ * Return from subprofile, back to parent -+ */ -+ aa_switch(sd, sd->active->parent); -+ -+ /* Reset hat_magic to zero. -+ * New value will be passed on next changehat -+ */ -+ sd->hat_magic = 0; -+ } else { -+ /* change to another (sibling) profile */ -+ error = do_change_hat(hat_name, sd); -+ } -+ } else if (sd->hat_magic) { -+ AA_ERROR("KILLING process %s(%d) " -+ "Invalid change_hat() magic# 0x%x " -+ "(hatname %s profile %s active %s)\n", -+ current->comm, current->pid, -+ hat_magic, -+ hat_name ? hat_name : "NULL", -+ BASE_PROFILE(sd->active)->name, -+ sd->active->name); -+ -+ /* terminate current process */ -+ (void)send_sig_info(SIGKILL, NULL, current); -+ } else { /* sd->hat_magic == NULL */ -+ AA_ERROR("KILLING process %s(%d) " -+ "Task was confined to current subprofile " -+ "(profile %s active %s)\n", -+ current->comm, current->pid, -+ BASE_PROFILE(sd->active)->name, -+ sd->active->name); -+ -+ /* terminate current process */ -+ (void)send_sig_info(SIGKILL, NULL, current); -+ } -+ -+ } -+ -+out: -+ return error; -+} -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5004_apparmor-filesystem.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5004_apparmor-filesystem.patch deleted file mode 100644 index 16b00bc7..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5004_apparmor-filesystem.patch +++ /dev/null @@ -1,472 +0,0 @@ -This patch implements the AppArmor file structure underneath securityfs. -Securityfs is normally mounted as /sys/kernel/security - -The following files are created under /sys/kernel/security/apparmor - control - audit - Controls the global setting for auditing all - accesses. - complain - Controls the global setting for learning mode - (usually this is set per profile rather than - globally) - debug - Controls whether debugging is enabled. - This needs to be made more fine grained - logsyscall - Controls whether when logging to the audit - subsystem full syscall auditing is enabled. - - The values by default for all of the above are 0. - - matching - Returns the features of the installed matching submodule - profiles - Returns the profiles currently loaded and for each whether - it is in complain (learning) or enforce mode. - .load - .remove - .replace - Used by userspace tools to load, remove and replace new - profiles. - - -Signed-off-by: Tony Jones - ---- - security/apparmor/apparmorfs.c | 432 +++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 432 insertions(+) - ---- security/apparmor/apparmorfs.c.orig -+++ security/apparmor/apparmorfs.c -@@ -0,0 +1,432 @@ -+/* -+ * Copyright (C) 2005 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 filesystem (part of securityfs) -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+#include "match/match.h" -+ -+#define SECFS_AA "apparmor" -+static struct dentry *aafs_dentry = NULL; -+ -+/* profile */ -+extern struct seq_operations apparmorfs_profiles_op; -+static int aa_prof_open(struct inode *inode, struct file *file); -+static int aa_prof_release(struct inode *inode, struct file *file); -+ -+static struct file_operations apparmorfs_profiles_fops = { -+ .open = aa_prof_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = aa_prof_release, -+}; -+ -+/* matching */ -+static ssize_t aa_matching_read(struct file *file, char __user *buf, -+ size_t size, loff_t *ppos); -+ -+static struct file_operations apparmorfs_matching_fops = { -+ .read = aa_matching_read, -+}; -+ -+ -+/* interface */ -+static ssize_t aa_profile_load(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos); -+static ssize_t aa_profile_replace(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos); -+static ssize_t aa_profile_remove(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos); -+ -+static struct file_operations apparmorfs_profile_load = { -+ .write = aa_profile_load -+}; -+ -+static struct file_operations apparmorfs_profile_replace = { -+ .write = aa_profile_replace -+}; -+ -+static struct file_operations apparmorfs_profile_remove = { -+ .write = aa_profile_remove -+}; -+ -+ -+/* control */ -+static u64 aa_control_get(void *data); -+static void aa_control_set(void *data, u64 val); -+ -+DEFINE_SIMPLE_ATTRIBUTE(apparmorfs_control_fops, aa_control_get, -+ aa_control_set, "%lld\n"); -+ -+ -+ -+/* table of static entries */ -+ -+static struct root_entry { -+ const char *name; -+ int mode; -+ int access; -+ struct file_operations *fops; -+ void *data; -+ -+ /* internal fields */ -+ struct dentry *dentry; -+ int parent_index; -+} root_entries[] = { -+ /* our root, normally /sys/kernel/security/apparmor */ -+ {SECFS_AA, S_IFDIR, 0550}, /* DO NOT EDIT/MOVE */ -+ -+ /* interface for obtaining list of profiles currently loaded */ -+ {"profiles", S_IFREG, 0440, &apparmorfs_profiles_fops, -+ NULL}, -+ -+ /* interface for obtaining matching features supported */ -+ {"matching", S_IFREG, 0440, &apparmorfs_matching_fops, -+ NULL}, -+ -+ /* interface for loading/removing/replacing profiles */ -+ {".load", S_IFREG, 0640, &apparmorfs_profile_load, -+ NULL}, -+ {".replace", S_IFREG, 0640, &apparmorfs_profile_replace, -+ NULL}, -+ {".remove", S_IFREG, 0640, &apparmorfs_profile_remove, -+ NULL}, -+ -+ /* interface for setting binary config values */ -+ {"control", S_IFDIR, 0550}, -+ {"complain", S_IFREG, 0640, &apparmorfs_control_fops, -+ &apparmor_complain}, -+ {"audit", S_IFREG, 0640, &apparmorfs_control_fops, -+ &apparmor_audit}, -+ {"debug", S_IFREG, 0640, &apparmorfs_control_fops, -+ &apparmor_debug}, -+ {"logsyscall", S_IFREG, 0640, &apparmorfs_control_fops, -+ &apparmor_logsyscall}, -+ {NULL, S_IFDIR, 0}, -+ -+ /* root end */ -+ {NULL, S_IFDIR, 0} -+}; -+ -+#define AAFS_DENTRY root_entries[0].dentry -+ -+static const unsigned int num_entries = -+ sizeof(root_entries) / sizeof(struct root_entry); -+ -+ -+ -+static int aa_prof_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &apparmorfs_profiles_op); -+} -+ -+ -+static int aa_prof_release(struct inode *inode, struct file *file) -+{ -+ return seq_release(inode, file); -+} -+ -+static ssize_t aa_matching_read(struct file *file, char __user *buf, -+ size_t size, loff_t *ppos) -+{ -+ const char *matching = aamatch_features(); -+ -+ return simple_read_from_buffer(buf, size, ppos, matching, -+ strlen(matching)); -+} -+ -+static char *aa_simple_write_to_buffer(const char __user *userbuf, -+ size_t alloc_size, size_t copy_size, -+ loff_t *pos, const char *msg) -+{ -+ struct aaprofile *active; -+ char *data; -+ -+ if (*pos != 0) { -+ /* only writes from pos 0, that is complete writes */ -+ data = ERR_PTR(-ESPIPE); -+ goto out; -+ } -+ -+ /* Don't allow confined processes to load/replace/remove profiles. -+ * No sane person would add rules allowing this to a profile -+ * but we enforce the restriction anyways. -+ */ -+ rcu_read_lock(); -+ active = get_activeptr_rcu(); -+ if (active) { -+ AA_WARN("REJECTING access to profile %s (%s(%d) " -+ "profile %s active %s)\n", -+ msg, current->comm, current->pid, -+ BASE_PROFILE(active)->name, active->name); -+ -+ data = ERR_PTR(-EPERM); -+ goto out; -+ } -+ rcu_read_unlock(); -+ -+ data = vmalloc(alloc_size); -+ if (data == NULL) { -+ data = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ if (copy_from_user(data, userbuf, copy_size)) { -+ vfree(data); -+ data = ERR_PTR(-EFAULT); -+ goto out; -+ } -+ -+out: -+ return data; -+} -+ -+static ssize_t aa_profile_load(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos) -+{ -+ char *data; -+ ssize_t error; -+ -+ data = aa_simple_write_to_buffer(buf, size, size, pos, "load"); -+ -+ if (!IS_ERR(data)) { -+ error = aa_file_prof_add(data, size); -+ vfree(data); -+ } else { -+ error = PTR_ERR(data); -+ } -+ -+ return error; -+} -+ -+static ssize_t aa_profile_replace(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos) -+{ -+ char *data; -+ ssize_t error; -+ -+ data = aa_simple_write_to_buffer(buf, size, size, pos, "replacement"); -+ -+ if (!IS_ERR(data)) { -+ error = aa_file_prof_repl(data, size); -+ vfree(data); -+ } else { -+ error = PTR_ERR(data); -+ } -+ -+ return error; -+} -+ -+static ssize_t aa_profile_remove(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos) -+{ -+ char *data; -+ ssize_t error; -+ -+ /* aa_file_prof_remove needs a null terminated string so 1 extra -+ * byte is allocated and null the copied data is then null terminated -+ */ -+ data = aa_simple_write_to_buffer(buf, size+1, size, pos, "removal"); -+ -+ if (!IS_ERR(data)) { -+ data[size] = 0; -+ error = aa_file_prof_remove(data, size); -+ vfree(data); -+ } else { -+ error = PTR_ERR(data); -+ } -+ -+ return error; -+} -+ -+static u64 aa_control_get(void *data) -+{ -+ return *(int *)data; -+} -+ -+static void aa_control_set(void *data, u64 val) -+{ -+ if (val > 1) -+ val = 1; -+ -+ *(int*)data = (int)val; -+} -+ -+static void clear_apparmorfs(void) -+{ -+ unsigned int i; -+ -+ for (i=0; i < num_entries;i++) { -+ unsigned int index; -+ -+ if (root_entries[i].mode == S_IFDIR) { -+ if (root_entries[i].name) -+ /* defer dir free till all sub-entries freed */ -+ continue; -+ else -+ /* cleanup parent */ -+ index = root_entries[i].parent_index; -+ } else { -+ index = i; -+ } -+ -+ if (root_entries[index].dentry) { -+ securityfs_remove(root_entries[index].dentry); -+ -+ AA_DEBUG("%s: deleted apparmorfs entry name=%s " -+ "dentry=%p\n", -+ __FUNCTION__, -+ root_entries[index].name, -+ root_entries[index].dentry); -+ -+ root_entries[index].dentry = NULL; -+ root_entries[index].parent_index = 0; -+ } -+ } -+} -+ -+static int populate_apparmorfs(struct dentry *root) -+{ -+ unsigned int i, parent_index, depth; -+ -+ for (i = 0; i < num_entries; i++) { -+ root_entries[i].dentry = NULL; -+ root_entries[i].parent_index = 0; -+ } -+ -+ /* 1. Verify entry 0 is valid [sanity check] */ -+ if (num_entries == 0 || -+ !root_entries[0].name || -+ strcmp(root_entries[0].name, SECFS_AA) != 0 || -+ root_entries[0].mode != S_IFDIR) { -+ AA_ERROR("%s: root entry 0 is not SECFS_AA/dir\n", -+ __FUNCTION__); -+ goto error; -+ } -+ -+ /* 2. Build back pointers */ -+ parent_index = 0; -+ depth = 1; -+ -+ for (i = 1; i < num_entries; i++) { -+ root_entries[i].parent_index = parent_index; -+ -+ if (root_entries[i].name && -+ root_entries[i].mode == S_IFDIR) { -+ depth++; -+ parent_index = i; -+ } else if (!root_entries[i].name) { -+ if (root_entries[i].mode != S_IFDIR || depth == 0) { -+ AA_ERROR("%s: root_entry %d invalid (%u %d)", -+ __FUNCTION__, i, -+ root_entries[i].mode, -+ root_entries[i].parent_index); -+ goto error; -+ } -+ -+ depth--; -+ parent_index = root_entries[parent_index].parent_index; -+ } -+ } -+ -+ if (depth != 0) { -+ AA_ERROR("%s: root_entry table not correctly terminated\n", -+ __FUNCTION__); -+ goto error; -+ } -+ -+ /* 3. Create root (parent=NULL) */ -+ root_entries[0].dentry = securityfs_create_file( -+ root_entries[0].name, -+ root_entries[0].mode | -+ root_entries[0].access, -+ NULL, NULL, NULL); -+ -+ if (IS_ERR(root_entries[0].dentry)) -+ goto error; -+ else -+ AA_DEBUG("%s: created securityfs/apparmor [dentry=%p]\n", -+ __FUNCTION__, root_entries[0].dentry); -+ -+ -+ /* 4. create remaining nodes */ -+ for (i = 1; i < num_entries; i++) { -+ struct dentry *parent; -+ void *data = NULL; -+ struct file_operations *fops = NULL; -+ -+ /* end of directory ? */ -+ if (!root_entries[i].name) -+ continue; -+ -+ parent = root_entries[root_entries[i].parent_index].dentry; -+ -+ if (root_entries[i].mode != S_IFDIR) { -+ data = root_entries[i].data; -+ fops = root_entries[i].fops; -+ } -+ -+ root_entries[i].dentry = securityfs_create_file( -+ root_entries[i].name, -+ root_entries[i].mode | -+ root_entries[i].access, -+ parent, -+ data, -+ fops); -+ -+ if (IS_ERR(root_entries[i].dentry)) -+ goto cleanup_error; -+ -+ AA_DEBUG("%s: added apparmorfs entry " -+ "name=%s mode=%x dentry=%p [parent %p]\n", -+ __FUNCTION__, root_entries[i].name, -+ root_entries[i].mode|root_entries[i].access, -+ root_entries[i].dentry, parent); -+ } -+ -+ return 0; -+ -+cleanup_error: -+ clear_apparmorfs(); -+ -+error: -+ return -EINVAL; -+} -+ -+int create_apparmorfs(void) -+{ -+ int error = 0; -+ -+ if (AAFS_DENTRY) { -+ error = -EEXIST; -+ AA_ERROR("%s: Subdomain securityfs already exists\n", -+ __FUNCTION__); -+ } else { -+ error = populate_apparmorfs(aafs_dentry); -+ if (error != 0) { -+ AA_ERROR("%s: Error populating Subdomain securityfs\n", -+ __FUNCTION__); -+ } -+ } -+ -+ return error; -+} -+ -+void destroy_apparmorfs(void) -+{ -+ if (AAFS_DENTRY) -+ clear_apparmorfs(); -+} -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5005_apparmor-userspace-interface.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5005_apparmor-userspace-interface.patch deleted file mode 100644 index a460e650..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5005_apparmor-userspace-interface.patch +++ /dev/null @@ -1,907 +0,0 @@ -This patch implements the interface between the userspace policy loader -and the kernel module. It is called by the .load, .remove and .replace -file_operations hooks implemented in apparmorfs.c. - -The code is reponsible for serializing data in a platform independant -manner from userspace and creating/activating the necessary apparmor -profiles. - -Certain aspects are delegated to the sub matching module which implements -the aamatch_* functions. - - -Signed-off-by: Tony Jones - ---- - security/apparmor/module_interface.c | 840 +++++++++++++++++++++++++++++++++++ - security/apparmor/module_interface.h | 37 + - 2 files changed, 877 insertions(+) - ---- security/apparmor/module_interface.c.orig -+++ security/apparmor/module_interface.c -@@ -0,0 +1,840 @@ -+/* -+ * Copyright (C) 1998-2005 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 userspace policy interface -+ */ -+ -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+#include "module_interface.h" -+#include "match/match.h" -+ -+/* aa_code defined in module_interface.h */ -+ -+const int aacode_datasize[] = { 1, 2, 4, 8, 2, 2, 4, 0, 0, 0, 0, 0, 0 }; -+ -+struct aa_taskreplace_data { -+ struct aaprofile *old_profile; -+ struct aaprofile *new_profile; -+}; -+ -+/* inlines must be forward of there use in newer version of gcc, -+ just forward declaring with a prototype won't work anymore */ -+ -+static inline void free_aa_entry(struct aa_entry *entry) -+{ -+ if (entry) { -+ kfree(entry->filename); -+ aamatch_free(entry->extradata); -+ kfree(entry); -+ } -+} -+ -+/** -+ * alloc_aa_entry - create new empty aa_entry -+ * This routine allocates, initializes, and returns a new aa_entry -+ * file entry structure. Structure is zeroed. Returns new structure on -+ * success, %NULL on failure. -+ */ -+static inline struct aa_entry *alloc_aa_entry(void) -+{ -+ struct aa_entry *entry; -+ -+ AA_DEBUG("%s\n", __FUNCTION__); -+ entry = kzalloc(sizeof(struct aa_entry), GFP_KERNEL); -+ if (entry) { -+ int i; -+ INIT_LIST_HEAD(&entry->list); -+ for (i = 0; i <= POS_AA_FILE_MAX; i++) { -+ INIT_LIST_HEAD(&entry->listp[i]); -+ } -+ } -+ return entry; -+} -+ -+/** -+ * free_aaprofile_rcu - rcu callback for free profiles -+ * @head: rcu_head struct of the profile whose reference is being put. -+ * -+ * the rcu callback routine, which delays the freeing of a profile when -+ * its last reference is put. -+ */ -+static void free_aaprofile_rcu(struct rcu_head *head) -+{ -+ struct aaprofile *p = container_of(head, struct aaprofile, rcu); -+ free_aaprofile(p); -+} -+ -+/** -+ * task_remove - remove profile from a task's subdomain -+ * @sd: task's subdomain -+ * -+ * remove the active profile from a task's subdomain, switching the task -+ * to an unconfined state. -+ */ -+static inline void task_remove(struct subdomain *sd) -+{ -+ /* spin_lock(&sd_lock) held here */ -+ AA_DEBUG("%s: removing profile from task %s(%d) profile %s active %s\n", -+ __FUNCTION__, -+ sd->task->comm, -+ sd->task->pid, -+ BASE_PROFILE(sd->active)->name, -+ sd->active->name); -+ -+ aa_switch_unconfined(sd); -+} -+ -+/** taskremove_iter - Iterator to unconfine subdomains which match cookie -+ * @sd: subdomain to consider for profile removal -+ * @cookie: pointer to the oldprofile which is being removed -+ * -+ * If the subdomain's active profile matches old_profile, then call -+ * task_remove() to remove the profile leaving the task (subdomain) unconfined. -+ */ -+static int taskremove_iter(struct subdomain *sd, void *cookie) -+{ -+ struct aaprofile *old_profile = (struct aaprofile *)cookie; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&sd_lock, flags); -+ -+ if (__aa_is_confined(sd) && BASE_PROFILE(sd->active) == old_profile) { -+ task_remove(sd); -+ } -+ -+ spin_unlock_irqrestore(&sd_lock, flags); -+ -+ return 0; -+} -+ -+/** task_replace - replace subdomain's current profile with a new profile -+ * @sd: subdomain to replace the profile on -+ * @new: new profile -+ * -+ * Replace a task's (subdomain's) active profile with a new profile. If -+ * task was in a hat then the new profile will also be in the equivalent -+ * hat in the new profile if it exists. If it doesn't exist the -+ * task will be placed in the special null_profile state. -+ */ -+static inline void task_replace(struct subdomain *sd, struct aaprofile *new) -+{ -+ AA_DEBUG("%s: replacing profile for task %s(%d) " -+ "profile=%s (%p) active=%s (%p)\n", -+ __FUNCTION__, -+ sd->task->comm, sd->task->pid, -+ BASE_PROFILE(sd->active)->name, BASE_PROFILE(sd->active), -+ sd->active->name, sd->active); -+ -+ if (!sd->active) -+ goto out; -+ -+ if (IN_SUBPROFILE(sd->active)) { -+ struct aaprofile *nactive; -+ -+ /* The old profile was in a hat, check to see if the new -+ * profile has an equivalent hat */ -+ nactive = __aa_find_profile(sd->active->name, &new->sub); -+ -+ if (!nactive) -+ nactive = get_aaprofile(new->null_profile); -+ -+ aa_switch(sd, nactive); -+ put_aaprofile(nactive); -+ } else { -+ aa_switch(sd, new); -+ } -+ -+ out: -+ return; -+} -+ -+/** taskreplace_iter - Iterator to replace a subdomain's profile -+ * @sd: subdomain to consider for profile replacement -+ * @cookie: pointer to the old profile which is being replaced. -+ * -+ * If the subdomain's active profile matches old_profile call -+ * task_replace() to replace with the subdomain's active profile with -+ * the new profile. -+ */ -+static int taskreplace_iter(struct subdomain *sd, void *cookie) -+{ -+ struct aa_taskreplace_data *data = (struct aa_taskreplace_data *)cookie; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&sd_lock, flags); -+ -+ if (__aa_is_confined(sd) && -+ BASE_PROFILE(sd->active) == data->old_profile) -+ task_replace(sd, data->new_profile); -+ -+ spin_unlock_irqrestore(&sd_lock, flags); -+ -+ return 0; -+} -+ -+static inline int aa_inbounds(struct aa_ext *e, size_t size) -+{ -+ return (e->pos + size <= e->end); -+} -+ -+/** -+ * aaconvert - convert trailing values of serialized type codes -+ * @code: type code -+ * @dest: pointer to object to receive the converted value -+ * @src: pointer to value to convert -+ * -+ * for serialized type codes which have a trailing value, convert it -+ * and place it in @dest. If a code does not have a trailing value nop. -+ */ -+static void aaconvert(enum aa_code code, void *dest, void *src) -+{ -+ switch (code) { -+ case AA_U8: -+ *(u8 *)dest = *(u8 *) src; -+ break; -+ case AA_U16: -+ case AA_NAME: -+ case AA_DYN_STRING: -+ *(u16 *)dest = le16_to_cpu(get_unaligned((u16 *)src)); -+ break; -+ case AA_U32: -+ case AA_STATIC_BLOB: -+ *(u32 *)dest = le32_to_cpu(get_unaligned((u32 *)src)); -+ break; -+ case AA_U64: -+ *(u64 *)dest = le64_to_cpu(get_unaligned((u64 *)src)); -+ break; -+ default: -+ /* nop - all other type codes do not have a trailing value */ -+ ; -+ } -+} -+ -+/** -+ * aa_is_X - check if the next element is of type X -+ * @e: serialized data extent information -+ * @code: type code -+ * @data: object located at @e->pos (of type @code) is written into @data -+ * if @data is non-null. if data is null it means skip this -+ * entry -+ * check to see if the next element in the serialized data stream is of type -+ * X and check that it is with in bounds, if so put the associated value in -+ * @data. -+ * return the size of bytes associated with the returned data -+ * for complex object like blob and string a pointer to the allocated -+ * data is returned in data, but the size of the blob or string is -+ * returned. -+ */ -+static u32 aa_is_X(struct aa_ext *e, enum aa_code code, void *data) -+{ -+ void *pos = e->pos; -+ int ret = 0; -+ if (!aa_inbounds(e, AA_CODE_BYTE + aacode_datasize[code])) -+ goto fail; -+ if (code != *(u8 *)e->pos) -+ goto out; -+ e->pos += AA_CODE_BYTE; -+ if (code == AA_NAME) { -+ u16 size; -+ /* name codes are followed by X bytes */ -+ size = le16_to_cpu(get_unaligned((u16 *)e->pos)); -+ if (!aa_inbounds(e, (size_t) size)) -+ goto fail; -+ if (data) -+ *(u16 *)data = size; -+ e->pos += aacode_datasize[code]; -+ ret = 1 + aacode_datasize[code]; -+ } else if (code == AA_DYN_STRING) { -+ u16 size; -+ char *str; -+ /* strings codes are followed by X bytes */ -+ size = le16_to_cpu(get_unaligned((u16 *)e->pos)); -+ e->pos += aacode_datasize[code]; -+ if (!aa_inbounds(e, (size_t) size)) -+ goto fail; -+ if (data) { -+ * (char **)data = NULL; -+ str = kmalloc(size, GFP_KERNEL); -+ if (!str) -+ goto fail; -+ memcpy(str, e->pos, (size_t) size); -+ str[size-1] = '\0'; -+ * (char **)data = str; -+ } -+ e->pos += size; -+ ret = size; -+ } else if (code == AA_STATIC_BLOB) { -+ u32 size; -+ /* blobs are followed by X bytes, that can be 2^32 */ -+ size = le32_to_cpu(get_unaligned((u32 *)e->pos)); -+ e->pos += aacode_datasize[code]; -+ if (!aa_inbounds(e, (size_t) size)) -+ goto fail; -+ if (data) -+ memcpy(data, e->pos, (size_t) size); -+ e->pos += size; -+ ret = size; -+ } else { -+ if (data) -+ aaconvert(code, data, e->pos); -+ e->pos += aacode_datasize[code]; -+ ret = 1 + aacode_datasize[code]; -+ } -+out: -+ return ret; -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+/** -+ * aa_is_nameX - check is the next element is of type X with a name of @name -+ * @e: serialized data extent information -+ * @code: type code -+ * @data: location to store deserialized data if match isX criteria -+ * @name: name to match to the serialized element. -+ * -+ * check that the next serialized data element is of type X and has a tag -+ * name @name. If the code matches and name (if specified) matches then -+ * the packed data is unpacked into *data. (Note for strings this is the -+ * size, and the next data in the stream is the string data) -+ * returns %0 if either match failes -+ */ -+static int aa_is_nameX(struct aa_ext *e, enum aa_code code, void *data, -+ const char *name) -+{ -+ void *pos = e->pos; -+ u16 size; -+ u32 ret; -+ /* check for presence of a tagname, and if present name size -+ * AA_NAME tag value is a u16 */ -+ if (aa_is_X(e, AA_NAME, &size)) { -+ /* if a name is specified it must match. otherwise skip tag */ -+ if (name && ((strlen(name) != size-1) || -+ strncmp(name, (char *)e->pos, (size_t)size-1))) -+ goto fail; -+ e->pos += size; -+ } -+ /* now check if data actually matches */ -+ ret = aa_is_X(e, code, data); -+ if (!ret) -+ goto fail; -+ return ret; -+ -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+/* macro to wrap error case to make a block of reads look nicer */ -+#define AA_READ_X(E, C, D, N) \ -+ do { \ -+ u32 __ret; \ -+ __ret = aa_is_nameX((E), (C), (D), (N)); \ -+ if (!__ret) \ -+ goto fail; \ -+ } while (0) -+ -+/** -+ * aa_activate_net_entry - unpacked serialized net entries -+ * @e: serialized data extent information -+ * -+ * Ignore/skips net entries if they are present in the serialized data -+ * stream. Network confinement rules are currently unsupported but some -+ * user side tools can generate them so they are currently ignored. -+ */ -+static inline int aa_activate_net_entry(struct aa_ext *e) -+{ -+ AA_READ_X(e, AA_STRUCT, NULL, "ne"); -+ AA_READ_X(e, AA_U32, NULL, NULL); -+ AA_READ_X(e, AA_U32, NULL, NULL); -+ AA_READ_X(e, AA_U32, NULL, NULL); -+ AA_READ_X(e, AA_U16, NULL, NULL); -+ AA_READ_X(e, AA_U16, NULL, NULL); -+ AA_READ_X(e, AA_U32, NULL, NULL); -+ AA_READ_X(e, AA_U32, NULL, NULL); -+ AA_READ_X(e, AA_U16, NULL, NULL); -+ AA_READ_X(e, AA_U16, NULL, NULL); -+ /* interface name is optional so just ignore return code */ -+ aa_is_nameX(e, AA_DYN_STRING, NULL, NULL); -+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL); -+ -+ return 1; -+fail: -+ return 0; -+} -+ -+/** -+ * aa_activate_file_entry - unpack serialized file entry -+ * @e: serialized data extent information -+ * -+ * unpack the information used for a file ACL entry. -+ */ -+static inline struct aa_entry *aa_activate_file_entry(struct aa_ext *e) -+{ -+ struct aa_entry *entry = NULL; -+ -+ if (!(entry = alloc_aa_entry())) -+ goto fail; -+ -+ AA_READ_X(e, AA_STRUCT, NULL, "fe"); -+ AA_READ_X(e, AA_DYN_STRING, &entry->filename, NULL); -+ AA_READ_X(e, AA_U32, &entry->mode, "file.mode"); -+ AA_READ_X(e, AA_U32, &entry->type, "file.pattern_type"); -+ -+ entry->extradata = aamatch_alloc(entry->type); -+ if (IS_ERR(entry->extradata)) { -+ entry->extradata = NULL; -+ goto fail; -+ } -+ -+ if (entry->extradata && -+ aamatch_serialize(entry->extradata, e, aa_is_nameX) != 0) { -+ goto fail; -+ } -+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL); -+ -+ switch (entry->type) { -+ case aa_entry_literal: -+ AA_DEBUG("%s: %s [no pattern] mode=0x%x\n", -+ __FUNCTION__, -+ entry->filename, -+ entry->mode); -+ break; -+ case aa_entry_tailglob: -+ AA_DEBUG("%s: %s [tailglob] mode=0x%x\n", -+ __FUNCTION__, -+ entry->filename, -+ entry->mode); -+ break; -+ case aa_entry_pattern: -+ AA_DEBUG("%s: %s mode=0x%x\n", -+ __FUNCTION__, -+ entry->filename, -+ entry->mode); -+ break; -+ default: -+ AA_WARN("%s: INVALID entry_match_type %d\n", -+ __FUNCTION__, -+ (int)entry->type); -+ goto fail; -+ } -+ -+ return entry; -+ -+fail: -+ aamatch_free(entry->extradata); -+ free_aa_entry(entry); -+ return NULL; -+} -+ -+/** -+ * check_rule_and_add - check a file rule is valid and add to a profile -+ * @file_entry: file rule to add -+ * @profile: profile to add the rule to -+ * @message: error message returned if the addition failes. -+ * -+ * perform consistency check to ensure that a file rule entry is valid. -+ * If the rule is valid it is added to the profile. -+ */ -+static inline int check_rule_and_add(struct aa_entry *file_entry, -+ struct aaprofile *profile, -+ const char **message) -+{ -+ /* verify consistency of x, px, ix, ux for entry against -+ possible duplicates for this entry */ -+ int mode = AA_EXEC_MODIFIER_MASK(file_entry->mode); -+ int i; -+ -+ if (mode && !(AA_MAY_EXEC & file_entry->mode)) { -+ *message = "inconsistent rule, x modifiers without x"; -+ goto out; -+ } -+ -+ /* check that only 1 of the modifiers is set */ -+ if (mode && (mode & (mode - 1))) { -+ *message = "inconsistent rule, multiple x modifiers"; -+ goto out; -+ } -+ -+ list_add(&file_entry->list, &profile->file_entry); -+ profile->num_file_entries++; -+ -+ mode = file_entry->mode; -+ -+ /* Handle partitioned lists -+ * Chain entries onto sublists based on individual -+ * permission bits. This allows more rapid searching. -+ */ -+ for (i = 0; i <= POS_AA_FILE_MAX; i++) { -+ if (mode & (1 << i)) -+ /* profile->file_entryp[i] initially set to -+ * NULL in alloc_aaprofile() */ -+ list_add(&file_entry->listp[i], -+ &profile->file_entryp[i]); -+ } -+ -+ return 1; -+ -+out: -+ free_aa_entry(file_entry); -+ return 0; -+} -+ -+#define AA_ENTRY_LIST(NAME) \ -+ do { \ -+ if (aa_is_nameX(e, AA_LIST, NULL, (NAME))) { \ -+ rulename = ""; \ -+ error_string = "Invalid file entry"; \ -+ while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) { \ -+ struct aa_entry *file_entry; \ -+ file_entry = aa_activate_file_entry(e); \ -+ if (!file_entry) \ -+ goto fail; \ -+ if (!check_rule_and_add(file_entry, profile, \ -+ &error_string)) { \ -+ rulename = file_entry->filename; \ -+ goto fail; \ -+ } \ -+ } \ -+ } \ -+ } while (0) -+ -+/** -+ * aa_activate_profile - unpack a serialized profile -+ * @e: serialized data extent information -+ * @error: error code returned if unpacking fails -+ */ -+static struct aaprofile *aa_activate_profile(struct aa_ext *e, ssize_t *error) -+{ -+ struct aaprofile *profile = NULL; -+ const char *rulename = ""; -+ const char *error_string = "Invalid Profile"; -+ -+ *error = -EPROTO; -+ -+ profile = alloc_aaprofile(); -+ if (!profile) { -+ error_string = "Could not allocate profile"; -+ *error = -ENOMEM; -+ goto fail; -+ } -+ -+ /* check that we have the right struct being passed */ -+ AA_READ_X(e, AA_STRUCT, NULL, "profile"); -+ AA_READ_X(e, AA_DYN_STRING, &profile->name, NULL); -+ -+ error_string = "Invalid flags"; -+ /* per profile debug flags (debug, complain, audit) */ -+ AA_READ_X(e, AA_STRUCT, NULL, "flags"); -+ AA_READ_X(e, AA_U32, &(profile->flags.debug), "profile.flags.debug"); -+ AA_READ_X(e, AA_U32, &(profile->flags.complain), -+ "profile.flags.complain"); -+ AA_READ_X(e, AA_U32, &(profile->flags.audit), "profile.flags.audit"); -+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL); -+ -+ error_string = "Invalid capabilities"; -+ AA_READ_X(e, AA_U32, &(profile->capabilities), "profile.capabilities"); -+ -+ /* get the file entries. */ -+ AA_ENTRY_LIST("pgent"); /* pcre rules */ -+ AA_ENTRY_LIST("sgent"); /* simple globs */ -+ AA_ENTRY_LIST("fent"); /* regular file entries */ -+ -+ /* get the net entries */ -+ if (aa_is_nameX(e, AA_LIST, NULL, "net")) { -+ error_string = "Invalid net entry"; -+ while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) { -+ if (!aa_activate_net_entry(e)) -+ goto fail; -+ } -+ } -+ rulename = ""; -+ -+ /* get subprofiles */ -+ if (aa_is_nameX(e, AA_LIST, NULL, "hats")) { -+ error_string = "Invalid profile hat"; -+ while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) { -+ struct aaprofile *subprofile; -+ subprofile = aa_activate_profile(e, error); -+ if (!subprofile) -+ goto fail; -+ subprofile->parent = profile; -+ list_add(&subprofile->list, &profile->sub); -+ } -+ } -+ -+ error_string = "Invalid end of profile"; -+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL); -+ -+ return profile; -+ -+fail: -+ AA_WARN("%s: %s %s in profile %s\n", INTERFACE_ID, rulename, -+ error_string, profile && profile->name ? profile->name -+ : "unknown"); -+ -+ if (profile) { -+ free_aaprofile(profile); -+ profile = NULL; -+ } -+ -+ return NULL; -+} -+ -+/** -+ * aa_activate_top_profile - unpack a serialized base profile -+ * @e: serialized data extent information -+ * @error: error code returned if unpacking fails -+ * -+ * check interface version unpack a profile and all its hats and patch -+ * in any extra information that the profile needs. -+ */ -+static void *aa_activate_top_profile(struct aa_ext *e, ssize_t *error) -+{ -+ struct aaprofile *profile = NULL; -+ -+ /* get the interface version */ -+ if (!aa_is_nameX(e, AA_U32, &e->version, "version")) { -+ AA_WARN("%s: version missing\n", INTERFACE_ID); -+ *error = -EPROTONOSUPPORT; -+ goto fail; -+ } -+ -+ /* check that the interface version is currently supported */ -+ if (e->version != 2) { -+ AA_WARN("%s: unsupported interface version (%d)\n", -+ INTERFACE_ID, e->version); -+ *error = -EPROTONOSUPPORT; -+ goto fail; -+ } -+ -+ profile = aa_activate_profile(e, error); -+ if (!profile) -+ goto fail; -+ -+ if (!list_empty(&profile->sub) || profile->flags.complain) { -+ if (attach_nullprofile(profile)) -+ goto fail; -+ } -+ return profile; -+ -+fail: -+ free_aaprofile(profile); -+ return NULL; -+} -+ -+/** -+ * aa_file_prof_add - add a new profile to the profile list -+ * @data: serialized data stream -+ * @size: size of the serialized data stream -+ * -+ * unpack and add a profile to the profile list. Return %0 or error -+ */ -+ssize_t aa_file_prof_add(void *data, size_t size) -+{ -+ struct aaprofile *profile = NULL; -+ -+ struct aa_ext e = { -+ .start = data, -+ .end = data + size, -+ .pos = data -+ }; -+ ssize_t error; -+ -+ profile = aa_activate_top_profile(&e, &error); -+ if (!profile) { -+ AA_DEBUG("couldn't activate profile\n"); -+ goto out; -+ } -+ -+ /* aa_activate_top_profile allocates profile with initial 1 count -+ * aa_profilelist_add transfers that ref to profile list without -+ * further incrementing -+ */ -+ if (aa_profilelist_add(profile)) { -+ error = size; -+ } else { -+ AA_WARN("trying to add profile (%s) that already exists.\n", -+ profile->name); -+ put_aaprofile(profile); -+ error = -EEXIST; -+ } -+ -+out: -+ return error; -+} -+ -+/** -+ * aa_file_prof_repl - replace a profile on the profile list -+ * @udata: serialized data stream -+ * @size: size of the serialized data stream -+ * -+ * unpack and replace a profile on the profile list and uses of that profile -+ * by any subdomain. If the profile does not exist on the profile list -+ * it is added. Return %0 or error. -+ */ -+ssize_t aa_file_prof_repl(void *udata, size_t size) -+{ -+ struct aa_taskreplace_data data; -+ struct aa_ext e = { -+ .start = udata, -+ .end = udata + size, -+ .pos = udata -+ }; -+ -+ ssize_t error; -+ -+ data.new_profile = aa_activate_top_profile(&e, &error); -+ if (!data.new_profile) { -+ AA_DEBUG("couldn't activate profile\n"); -+ goto out; -+ } -+ -+ /* Refcount on data.new_profile is 1 (aa_activate_top_profile). -+ * -+ * This reference will be inherited by aa_profilelist_replace for it's -+ * profile list reference but this isn't sufficient. -+ * -+ * Another replace (*for-same-profile*) may race us here. -+ * Task A calls aa_profilelist_replace(new_profile) and is interrupted. -+ * Task B old_profile = aa_profilelist_replace() will return task A's -+ * new_profile with the count of 1. If task B proceeeds to put this -+ * profile it will dissapear from under task A. -+ * -+ * Grab extra reference on new_profile to prevent this -+ */ -+ -+ get_aaprofile(data.new_profile); -+ -+ data.old_profile = aa_profilelist_replace(data.new_profile); -+ -+ /* If there was an old profile, find all currently executing tasks -+ * using this profile and replace the old profile with the new. -+ */ -+ if (data.old_profile) { -+ AA_DEBUG("%s: try to replace profile (%p)%s\n", -+ __FUNCTION__, -+ data.old_profile, -+ data.old_profile->name); -+ -+ aa_subdomainlist_iterate(taskreplace_iter, (void *)&data); -+ -+ /* it's off global list, and we are done replacing */ -+ put_aaprofile(data.old_profile); -+ } -+ -+ /* release extra reference obtained above (race) */ -+ put_aaprofile(data.new_profile); -+ -+ error = size; -+ -+out: -+ return error; -+} -+ -+/** -+ * aa_file_prof_remove - remove a profile from the system -+ * @name: name of the profile to remove -+ * @size: size of the name -+ * -+ * remove a profile from the profile list and all subdomain references -+ * to said profile. Return %0 on success, else error. -+ */ -+ssize_t aa_file_prof_remove(const char *name, size_t size) -+{ -+ struct aaprofile *old_profile; -+ -+ /* if the old profile exists it will be removed from the list and -+ * a reference is returned. -+ */ -+ old_profile = aa_profilelist_remove(name); -+ -+ if (old_profile) { -+ /* remove profile from any tasks using it */ -+ aa_subdomainlist_iterate(taskremove_iter, (void *)old_profile); -+ -+ /* drop reference obtained by aa_profilelist_remove */ -+ put_aaprofile(old_profile); -+ } else { -+ AA_WARN("%s: trying to remove profile (%s) that " -+ "doesn't exist - skipping.\n", __FUNCTION__, name); -+ return -ENOENT; -+ } -+ -+ return size; -+} -+ -+/** -+ * free_aaprofile_kref - free aaprofile by kref (called by put_aaprofile) -+ * @kr: kref callback for freeing of a profile -+ */ -+void free_aaprofile_kref(struct kref *kr) -+{ -+ struct aaprofile *p=container_of(kr, struct aaprofile, count); -+ -+ call_rcu(&p->rcu, free_aaprofile_rcu); -+} -+ -+/** -+ * free_aaprofile - free aaprofile structure -+ * @profile: the profile to free -+ * -+ * free a profile, its file entries hats and null_profile. All references -+ * to the profile, its hats and null_profile must have been put. -+ * If the profile was referenced by a subdomain free_aaprofile should be -+ * called from an rcu callback routine. -+ */ -+void free_aaprofile(struct aaprofile *profile) -+{ -+ struct aa_entry *ent, *tmp; -+ struct aaprofile *p, *ptmp; -+ -+ AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); -+ -+ if (!profile) -+ return; -+ -+ /* profile is still on global profile list -- invalid */ -+ if (!list_empty(&profile->list)) { -+ AA_ERROR("%s: internal error, " -+ "profile '%s' still on global list\n", -+ __FUNCTION__, -+ profile->name); -+ BUG(); -+ } -+ -+ list_for_each_entry_safe(ent, tmp, &profile->file_entry, list) { -+ if (ent->filename) -+ AA_DEBUG("freeing aa_entry: %p %s\n", -+ ent->filename, ent->filename); -+ list_del_init(&ent->list); -+ free_aa_entry(ent); -+ } -+ -+ /* use free_aaprofile instead of put_aaprofile to destroy the -+ * null_profile, because the null_profile use the same reference -+ * counting as hats, ie. the count goes to the base profile. -+ */ -+ free_aaprofile(profile->null_profile); -+ list_for_each_entry_safe(p, ptmp, &profile->sub, list) { -+ list_del_init(&p->list); -+ p->parent = NULL; -+ put_aaprofile(p); -+ } -+ -+ if (profile->name) { -+ AA_DEBUG("%s: %s\n", __FUNCTION__, profile->name); -+ kfree(profile->name); -+ } -+ -+ kfree(profile); -+} ---- security/apparmor/module_interface.h.orig -+++ security/apparmor/module_interface.h -@@ -0,0 +1,37 @@ -+#ifndef __MODULEINTERFACE_H -+#define __MODULEINTERFACE_H -+ -+/* Codes of the types of basic structures that are understood */ -+#define AA_CODE_BYTE (sizeof(u8)) -+#define INTERFACE_ID "INTERFACE" -+ -+#define SUBDOMAIN_INTERFACE_VERSION 2 -+ -+enum aa_code { -+ AA_U8, -+ AA_U16, -+ AA_U32, -+ AA_U64, -+ AA_NAME, /* same as string except it is items name */ -+ AA_DYN_STRING, -+ AA_STATIC_BLOB, -+ AA_STRUCT, -+ AA_STRUCTEND, -+ AA_LIST, -+ AA_LISTEND, -+ AA_OFFSET, -+ AA_BAD -+}; -+ -+/* aa_ext tracks the kernel buffer and read position in it. The interface -+ * data is copied into a kernel buffer in apparmorfs and then handed off to -+ * the activate routines. -+ */ -+struct aa_ext { -+ void *start; -+ void *end; -+ void *pos; /* pointer to current position in the buffer */ -+ u32 version; -+}; -+ -+#endif /* __MODULEINTERFACE_H */ -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5006_apparmor-misc.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5006_apparmor-misc.patch deleted file mode 100644 index 9336bda7..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5006_apparmor-misc.patch +++ /dev/null @@ -1,681 +0,0 @@ -This patch implements three distinct chunks. -- list management, for profiles loaded into the system (profile_list) and for - the set of confined tasks (subdomain_list) -- the proc/pid/attr interface used by userspace for setprofile (forcing - a task into a new profile) and changehat (switching a task into one of it's - defined sub profiles). Access to change_hat is normally via code provided - in libapparmor. See the overview posting for more information in change hat. -- capability utility functions (for displaying capability names) - - -Signed-off-by: Tony Jones - ---- - security/apparmor/capabilities.c | 54 ++++++ - security/apparmor/list.c | 268 +++++++++++++++++++++++++++++++ - security/apparmor/procattr.c | 327 +++++++++++++++++++++++++++++++++++++++ - 3 files changed, 649 insertions(+) - ---- security/apparmor/capabilities.c.orig -+++ security/apparmor/capabilities.c -@@ -0,0 +1,54 @@ -+/* -+ * Copyright (C) 2005 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 capability definitions -+ */ -+ -+#include "apparmor.h" -+ -+static const char *cap_names[] = { -+ "chown", -+ "dac_override", -+ "dac_read_search", -+ "fowner", -+ "fsetid", -+ "kill", -+ "setgid", -+ "setuid", -+ "setpcap", -+ "linux_immutable", -+ "net_bind_service", -+ "net_broadcast", -+ "net_admin", -+ "net_raw", -+ "ipc_lock", -+ "ipc_owner", -+ "sys_module", -+ "sys_rawio", -+ "sys_chroot", -+ "sys_ptrace", -+ "sys_pacct", -+ "sys_admin", -+ "sys_boot", -+ "sys_nice", -+ "sys_resource", -+ "sys_time", -+ "sys_tty_config", -+ "mknod", -+ "lease" -+}; -+ -+const char *capability_to_name(unsigned int cap) -+{ -+ const char *name; -+ -+ name = (cap < (sizeof(cap_names) / sizeof(char *)) -+ ? cap_names[cap] : "invalid-capability"); -+ -+ return name; -+} ---- security/apparmor/list.c.orig -+++ security/apparmor/list.c -@@ -0,0 +1,268 @@ -+/* -+ * Copyright (C) 1998-2005 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 Profile List Management -+ */ -+ -+#include -+#include "apparmor.h" -+#include "inline.h" -+ -+/* list of all profiles and lock */ -+static LIST_HEAD(profile_list); -+static rwlock_t profile_lock = RW_LOCK_UNLOCKED; -+ -+/* list of all subdomains and lock */ -+static LIST_HEAD(subdomain_list); -+static rwlock_t subdomain_lock = RW_LOCK_UNLOCKED; -+ -+/** -+ * aa_profilelist_find -+ * @name: profile name (program name) -+ * -+ * Search the profile list for profile @name. Return refcounted profile on -+ * success, NULL on failure. -+ */ -+struct aaprofile *aa_profilelist_find(const char *name) -+{ -+ struct aaprofile *p = NULL; -+ if (name) { -+ read_lock(&profile_lock); -+ p = __aa_find_profile(name, &profile_list); -+ read_unlock(&profile_lock); -+ } -+ return p; -+} -+ -+/** -+ * aa_profilelist_add - add new profile to list -+ * @profile: new profile to add to list -+ * -+ * NOTE: Caller must allocate necessary reference count that will be used -+ * by the profile_list. This is because profile allocation alloc_aaprofile() -+ * returns an unreferenced object with a initial count of %1. -+ * -+ * Return %1 on success, %0 on failure (already exists) -+ */ -+int aa_profilelist_add(struct aaprofile *profile) -+{ -+ struct aaprofile *old_profile; -+ int ret = 0; -+ -+ if (!profile) -+ goto out; -+ -+ write_lock(&profile_lock); -+ old_profile = __aa_find_profile(profile->name, &profile_list); -+ if (old_profile) { -+ put_aaprofile(old_profile); -+ goto out; -+ } -+ -+ list_add(&profile->list, &profile_list); -+ ret = 1; -+ out: -+ write_unlock(&profile_lock); -+ return ret; -+} -+ -+/** -+ * aa_profilelist_remove - remove a profile from the list by name -+ * @name: name of profile to be removed -+ * -+ * If the profile exists remove profile from list and return its reference. -+ * The reference count on profile is not decremented and should be decremented -+ * when the profile is no longer needed -+ */ -+struct aaprofile *aa_profilelist_remove(const char *name) -+{ -+ struct aaprofile *profile = NULL; -+ struct aaprofile *p, *tmp; -+ -+ if (!name) -+ goto out; -+ -+ write_lock(&profile_lock); -+ list_for_each_entry_safe(p, tmp, &profile_list, list) { -+ if (!strcmp(p->name, name)) { -+ list_del_init(&p->list); -+ /* mark old profile as stale */ -+ p->isstale = 1; -+ profile = p; -+ break; -+ } -+ } -+ write_unlock(&profile_lock); -+ -+out: -+ return profile; -+} -+ -+/** -+ * aa_profilelist_replace - replace a profile on the list -+ * @profile: new profile -+ * -+ * Replace a profile on the profile list. Find the old profile by name in -+ * the list, and replace it with the new profile. NOTE: Caller must allocate -+ * necessary initial reference count for new profile as aa_profilelist_add(). -+ * -+ * This is an atomic list operation. Returns the old profile (which is still -+ * refcounted) if there was one, or NULL. -+ */ -+struct aaprofile *aa_profilelist_replace(struct aaprofile *profile) -+{ -+ struct aaprofile *oldprofile; -+ -+ write_lock(&profile_lock); -+ oldprofile = __aa_find_profile(profile->name, &profile_list); -+ if (oldprofile) { -+ list_del_init(&oldprofile->list); -+ /* mark old profile as stale */ -+ oldprofile->isstale = 1; -+ -+ /* __aa_find_profile incremented count, so adjust down */ -+ put_aaprofile(oldprofile); -+ } -+ -+ list_add(&profile->list, &profile_list); -+ write_unlock(&profile_lock); -+ -+ return oldprofile; -+} -+ -+/** -+ * aa_profilelist_release - Remove all profiles from profile_list -+ */ -+void aa_profilelist_release(void) -+{ -+ struct aaprofile *p, *tmp; -+ -+ write_lock(&profile_lock); -+ list_for_each_entry_safe(p, tmp, &profile_list, list) { -+ list_del_init(&p->list); -+ put_aaprofile(p); -+ } -+ write_unlock(&profile_lock); -+} -+ -+/** -+ * aa_subdomainlist_add - Add subdomain to subdomain_list -+ * @sd: new subdomain -+ */ -+void aa_subdomainlist_add(struct subdomain *sd) -+{ -+ unsigned long flags; -+ -+ if (!sd) { -+ AA_INFO("%s: bad subdomain\n", __FUNCTION__); -+ return; -+ } -+ -+ write_lock_irqsave(&subdomain_lock, flags); -+ /* new subdomains must be added to the end of the list due to a -+ * subtle interaction between fork and profile replacement. -+ */ -+ list_add_tail(&sd->list, &subdomain_list); -+ write_unlock_irqrestore(&subdomain_lock, flags); -+} -+ -+/** -+ * aa_subdomainlist_remove - Remove subdomain from subdomain_list -+ * @sd: subdomain to be removed -+ */ -+void aa_subdomainlist_remove(struct subdomain *sd) -+{ -+ unsigned long flags; -+ -+ if (sd) { -+ write_lock_irqsave(&subdomain_lock, flags); -+ list_del_init(&sd->list); -+ write_unlock_irqrestore(&subdomain_lock, flags); -+ } -+} -+ -+/** -+ * aa_subdomainlist_iterate - iterate over the subdomain list applying @func -+ * @func: method to be called for each element -+ * @cookie: user passed data -+ * -+ * Iterate over subdomain list applying @func, stop when @func returns -+ * non zero -+ */ -+void aa_subdomainlist_iterate(aa_iter func, void *cookie) -+{ -+ struct subdomain *node; -+ int ret = 0; -+ unsigned long flags; -+ -+ read_lock_irqsave(&subdomain_lock, flags); -+ list_for_each_entry(node, &subdomain_list, list) { -+ ret = (*func) (node, cookie); -+ if (ret != 0) -+ break; -+ } -+ read_unlock_irqrestore(&subdomain_lock, flags); -+} -+ -+/** -+ * aa_subdomainlist_release - Remove all subdomains from subdomain_list -+ */ -+void aa_subdomainlist_release() -+{ -+ struct subdomain *node, *tmp; -+ unsigned long flags; -+ -+ write_lock_irqsave(&subdomain_lock, flags); -+ list_for_each_entry_safe(node, tmp, &subdomain_list, list) { -+ list_del_init(&node->list); -+ } -+ write_unlock_irqrestore(&subdomain_lock, flags); -+} -+ -+/* seq_file helper routines -+ * Used by apparmorfs.c to iterate over profile_list -+ */ -+static void *p_start(struct seq_file *f, loff_t *pos) -+{ -+ struct aaprofile *node; -+ loff_t l = *pos; -+ -+ read_lock(&profile_lock); -+ list_for_each_entry(node, &profile_list, list) -+ if (!l--) -+ return node; -+ return NULL; -+} -+ -+static void *p_next(struct seq_file *f, void *p, loff_t *pos) -+{ -+ struct list_head *lh = ((struct aaprofile *)p)->list.next; -+ (*pos)++; -+ return lh == &profile_list ? -+ NULL : list_entry(lh, struct aaprofile, list); -+} -+ -+static void p_stop(struct seq_file *f, void *v) -+{ -+ read_unlock(&profile_lock); -+} -+ -+static int seq_show_profile(struct seq_file *f, void *v) -+{ -+ struct aaprofile *profile = (struct aaprofile *)v; -+ seq_printf(f, "%s (%s)\n", profile->name, -+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); -+ return 0; -+} -+ -+struct seq_operations apparmorfs_profiles_op = { -+ .start = p_start, -+ .next = p_next, -+ .stop = p_stop, -+ .show = seq_show_profile, -+}; ---- security/apparmor/procattr.c.orig -+++ security/apparmor/procattr.c -@@ -0,0 +1,327 @@ -+/* -+ * Copyright (C) 2005 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 /proc/pid/attr handling -+ */ -+ -+/* for isspace */ -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+ -+size_t aa_getprocattr(struct aaprofile *active, char *str, size_t size) -+{ -+ int error = -EACCES; /* default to a perm denied */ -+ size_t len; -+ -+ if (active) { -+ size_t lena, lenm, lenp = 0; -+ const char *enforce_str = " (enforce)"; -+ const char *complain_str = " (complain)"; -+ const char *mode_str = -+ PROFILE_COMPLAIN(active) ? complain_str : enforce_str; -+ -+ lenm = strlen(mode_str); -+ -+ lena = strlen(active->name); -+ -+ len = lena; -+ if (IN_SUBPROFILE(active)) { -+ lenp = strlen(BASE_PROFILE(active)->name); -+ len += (lenp + 1); /* +1 for ^ */ -+ } -+ /* DONT null terminate strings we output via proc */ -+ len += (lenm + 1); /* for \n */ -+ -+ if (len <= size) { -+ if (lenp) { -+ memcpy(str, BASE_PROFILE(active)->name, -+ lenp); -+ str += lenp; -+ *str++ = '^'; -+ } -+ -+ memcpy(str, active->name, lena); -+ str += lena; -+ memcpy(str, mode_str, lenm); -+ str += lenm; -+ *str++ = '\n'; -+ error = len; -+ } else { -+ error = -ERANGE; -+ } -+ } else { -+ const char *unconstrained_str = "unconstrained\n"; -+ len = strlen(unconstrained_str); -+ -+ /* DONT null terminate strings we output via proc */ -+ if (len <= size) { -+ memcpy(str, unconstrained_str, len); -+ error = len; -+ } else { -+ error = -ERANGE; -+ } -+ } -+ -+ return error; -+ -+} -+ -+int aa_setprocattr_changehat(char *hatinfo, size_t infosize) -+{ -+ int error = -EINVAL; -+ char *token = NULL, *hat, *smagic, *tmp; -+ u32 magic; -+ int rc, len, consumed; -+ unsigned long flags; -+ -+ AA_DEBUG("%s: %p %zd\n", __FUNCTION__, hatinfo, infosize); -+ -+ /* strip leading white space */ -+ while (infosize && isspace(*hatinfo)) { -+ hatinfo++; -+ infosize--; -+ } -+ -+ if (infosize == 0) -+ goto out; -+ -+ /* -+ * Copy string to a new buffer so we can play with it -+ * It may be zero terminated but we add a trailing 0 -+ * for 100% safety -+ */ -+ token = kmalloc(infosize + 1, GFP_KERNEL); -+ -+ if (!token) { -+ error = -ENOMEM; -+ goto out; -+ } -+ -+ memcpy(token, hatinfo, infosize); -+ token[infosize] = 0; -+ -+ /* error is INVAL until we have at least parsed something */ -+ error = -EINVAL; -+ -+ tmp = token; -+ while (*tmp && *tmp != '^') { -+ tmp++; -+ } -+ -+ if (!*tmp || tmp == token) { -+ AA_WARN("%s: Invalid input '%s'\n", __FUNCTION__, token); -+ goto out; -+ } -+ -+ /* split magic and hat into two strings */ -+ *tmp = 0; -+ smagic = token; -+ -+ /* -+ * Initially set consumed=strlen(magic), as if sscanf -+ * consumes all input via the %x it will not process the %n -+ * directive. Otherwise, if sscanf does not consume all the -+ * input it will process the %n and update consumed. -+ */ -+ consumed = len = strlen(smagic); -+ -+ rc = sscanf(smagic, "%x%n", &magic, &consumed); -+ -+ if (rc != 1 || consumed != len) { -+ AA_WARN("%s: Invalid hex magic %s\n", -+ __FUNCTION__, -+ smagic); -+ goto out; -+ } -+ -+ hat = tmp + 1; -+ -+ if (!*hat) -+ hat = NULL; -+ -+ if (!hat && !magic) { -+ AA_WARN("%s: Invalid input, NULL hat and NULL magic\n", -+ __FUNCTION__); -+ goto out; -+ } -+ -+ AA_DEBUG("%s: Magic 0x%x Hat '%s'\n", -+ __FUNCTION__, magic, hat ? hat : NULL); -+ -+ spin_lock_irqsave(&sd_lock, flags); -+ error = aa_change_hat(hat, magic); -+ spin_unlock_irqrestore(&sd_lock, flags); -+ -+out: -+ if (token) { -+ memset(token, 0, infosize); -+ kfree(token); -+ } -+ -+ return error; -+} -+ -+int aa_setprocattr_setprofile(struct task_struct *p, char *profilename, -+ size_t profilesize) -+{ -+ int error = -EINVAL; -+ struct aaprofile *profile = NULL; -+ struct subdomain *sd; -+ char *name = NULL; -+ unsigned long flags; -+ -+ AA_DEBUG("%s: current %s(%d)\n", -+ __FUNCTION__, current->comm, current->pid); -+ -+ /* strip leading white space */ -+ while (profilesize && isspace(*profilename)) { -+ profilename++; -+ profilesize--; -+ } -+ -+ if (profilesize == 0) -+ goto out; -+ -+ /* -+ * Copy string to a new buffer so we guarantee it is zero -+ * terminated -+ */ -+ name = kmalloc(profilesize + 1, GFP_KERNEL); -+ -+ if (!name) { -+ error = -ENOMEM; -+ goto out; -+ } -+ -+ strncpy(name, profilename, profilesize); -+ name[profilesize] = 0; -+ -+ repeat: -+ if (strcmp(name, "unconstrained") != 0) { -+ profile = aa_profilelist_find(name); -+ if (!profile) { -+ AA_WARN("%s: Unable to switch task %s(%d) to profile" -+ "'%s'. No such profile.\n", -+ __FUNCTION__, -+ p->comm, p->pid, -+ name); -+ -+ error = -EINVAL; -+ goto out; -+ } -+ } -+ -+ spin_lock_irqsave(&sd_lock, flags); -+ -+ sd = AA_SUBDOMAIN(p->security); -+ -+ /* switch to unconstrained */ -+ if (!profile) { -+ if (__aa_is_confined(sd)) { -+ AA_WARN("%s: Unconstraining task %s(%d) " -+ "profile %s active %s\n", -+ __FUNCTION__, -+ p->comm, p->pid, -+ BASE_PROFILE(sd->active)->name, -+ sd->active->name); -+ -+ aa_switch_unconfined(sd); -+ } else { -+ AA_WARN("%s: task %s(%d) " -+ "is already unconstrained\n", -+ __FUNCTION__, p->comm, p->pid); -+ } -+ } else { -+ if (!sd) { -+ /* this task was created before module was -+ * loaded, allocate a subdomain -+ */ -+ AA_WARN("%s: task %s(%d) has no subdomain\n", -+ __FUNCTION__, p->comm, p->pid); -+ -+ /* unlock so we can safely GFP_KERNEL */ -+ spin_unlock_irqrestore(&sd_lock, flags); -+ -+ sd = alloc_subdomain(p); -+ if (!sd) { -+ AA_WARN("%s: Unable to allocate subdomain for " -+ "task %s(%d). Cannot confine task to " -+ "profile %s\n", -+ __FUNCTION__, -+ p->comm, p->pid, -+ name); -+ -+ error = -ENOMEM; -+ put_aaprofile(profile); -+ -+ goto out; -+ } -+ -+ spin_lock_irqsave(&sd_lock, flags); -+ if (!AA_SUBDOMAIN(p->security)) { -+ p->security = sd; -+ } else { /* race */ -+ free_subdomain(sd); -+ sd = AA_SUBDOMAIN(p->security); -+ } -+ } -+ -+ /* ensure the profile hasn't been replaced */ -+ -+ if (unlikely(profile->isstale)) { -+ WARN_ON(profile == null_complain_profile); -+ -+ /* drop refcnt obtained from earlier get_aaprofile */ -+ put_aaprofile(profile); -+ profile = aa_profilelist_find(name); -+ -+ if (!profile) { -+ /* Race, profile was removed. */ -+ spin_unlock_irqrestore(&sd_lock, flags); -+ goto repeat; -+ } -+ } -+ -+ /* we do not do a normal task replace since we are not -+ * replacing with the same profile. -+ * If existing process is in a hat, it will be moved -+ * into the new parent profile, even if this new -+ * profile has a identical named hat. -+ */ -+ -+ AA_WARN("%s: Switching task %s(%d) " -+ "profile %s active %s to new profile %s\n", -+ __FUNCTION__, -+ p->comm, p->pid, -+ sd->active ? BASE_PROFILE(sd->active)->name : -+ "unconstrained", -+ sd->active ? sd->active->name : "unconstrained", -+ name); -+ -+ aa_switch(sd, profile); -+ -+ put_aaprofile(profile); /* drop ref we obtained above -+ * from aa_profilelist_find -+ */ -+ -+ /* Reset magic in case we were in a subhat before -+ * This is the only case where we zero the magic after -+ * calling aa_switch -+ */ -+ sd->hat_magic = 0; -+ } -+ -+ spin_unlock_irqrestore(&sd_lock, flags); -+ -+out: -+ kfree(name); -+ -+ return error; -+} -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5007_apparmor-pathname-matching-submodule.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5007_apparmor-pathname-matching-submodule.patch deleted file mode 100644 index a51d9c0b..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5007_apparmor-pathname-matching-submodule.patch +++ /dev/null @@ -1,246 +0,0 @@ -The file match.h specifies a sub module interface consisting of the following -functions: - - aamatch_alloc - aamatch_free - Allocates/deallocates submodule specific data used by each - loaded profile (policy). - - aamatch_features - Returns the list of features implemented by the submodule. - These are literal, tailglob ("/path/**" match all paths - below /path) and pattern (full shell based pathname expansion). - - aamatch_serialize - Called by the module interface to serialize submodule specific - data from userspace. - - aamatch_match - Called to perform matching on a generated pathname. - - -The submodule submitted here implements only "literal" and "tailglob". -The version included with SuSE Linux implements "pattern" but via a method -that is not acceptable for mainline inclusion. We plan on developing -a new submodule as soon as possible that will implement the missing -functionality of the SuSE release using the textsearch framework and -a new bounded textsearch algorithm acceptable for subsequent inclusion -into the mainline kernel. - - -Signed-off-by: Tony Jones - ---- - security/apparmor/match/Makefile | 5 + - security/apparmor/match/match.h | 132 ++++++++++++++++++++++++++++++++ - security/apparmor/match/match_default.c | 57 +++++++++++++ - 3 files changed, 194 insertions(+) - ---- security/apparmor/match/Makefile.orig -+++ security/apparmor/match/Makefile -@@ -0,0 +1,5 @@ -+# Makefile for AppArmor aamatch submodule -+# -+obj-$(CONFIG_SECURITY_APPARMOR) += aamatch_default.o -+ -+aamatch_default-y := match_default.o ---- security/apparmor/match/match.h.orig -+++ security/apparmor/match/match.h -@@ -0,0 +1,132 @@ -+/* -+ * Copyright (C) 2002-2005 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 submodule (match) prototypes -+ */ -+ -+#ifndef __MATCH_H -+#define __MATCH_H -+ -+#include "../module_interface.h" -+#include "../apparmor.h" -+ -+/* The following functions implement an interface used by the primary -+ * AppArmor module to perform name matching (n.b. "AppArmor" was previously -+ * called "SubDomain"). -+ -+ * aamatch_alloc -+ * aamatch_free -+ * aamatch_features -+ * aamatch_serialize -+ * aamatch_match -+ * -+ * The intent is for the primary module to export (via virtual fs entries) -+ * the features provided by the submodule (aamatch_features) so that the -+ * parser may only load policy that can be supported. -+ * -+ * The primary module will call aamatch_serialize to allow the submodule -+ * to consume submodule specific data from parser data stream and will call -+ * aamatch_match to determine if a pathname matches an aa_entry. -+ */ -+ -+typedef int (*aamatch_serializecb) -+ (struct aa_ext *, enum aa_code, void *, const char *); -+ -+/** -+ * aamatch_alloc: allocate extradata (if necessary) -+ * @type: type of entry being allocated -+ * Return value: NULL indicates no data was allocated (ERR_PTR(x) on error) -+ */ -+extern void* aamatch_alloc(enum entry_match_type type); -+ -+/** -+ * aamatch_free: release data allocated by aamatch_alloc -+ * @entry_extradata: data previously allocated by aamatch_alloc -+ */ -+extern void aamatch_free(void *entry_extradata); -+ -+/** -+ * aamatch_features: return match types supported -+ * Return value: space seperated string (of types supported - use type=value -+ * to indicate variants of a type) -+ */ -+extern const char* aamatch_features(void); -+ -+/** -+ * aamatch_serialize: serialize extradata -+ * @entry_extradata: data previously allocated by aamatch_alloc -+ * @e: input stream -+ * @cb: callback fn (consume incoming data stream) -+ * Return value: 0 success, -ve error -+ */ -+extern int aamatch_serialize(void *entry_extradata, struct aa_ext *e, -+ aamatch_serializecb cb); -+ -+/** -+ * aamatch_match: determine if pathname matches entry -+ * @pathname: pathname to verify -+ * @entry_name: entry name -+ * @type: type of entry -+ * @entry_extradata: data previously allocated by aamatch_alloc -+ * Return value: 1 match, 0 othersise -+ */ -+extern unsigned int aamatch_match(const char *pathname, const char *entry_name, -+ enum entry_match_type type, -+ void *entry_extradata); -+ -+ -+/** -+ * sd_getmatch_type - return string representation of entry_match_type -+ * @type: entry match type -+ */ -+static inline const char *sd_getmatch_type(enum entry_match_type type) -+{ -+ const char *names[] = { -+ "aa_entry_literal", -+ "aa_entry_tailglob", -+ "aa_entry_pattern", -+ "aa_entry_invalid" -+ }; -+ -+ if (type >= aa_entry_invalid) { -+ type = aa_entry_invalid; -+ } -+ -+ return names[type]; -+} -+ -+/** -+ * aamatch_match_common - helper function to check if a pathname matches -+ * a literal/tailglob -+ * @path: path requested to search for -+ * @entry_name: name from aa_entry -+ * @type: type of entry -+ */ -+static inline int aamatch_match_common(const char *path, -+ const char *entry_name, -+ enum entry_match_type type) -+{ -+ int retval; -+ -+ /* literal, no pattern matching characters */ -+ if (type == aa_entry_literal) { -+ retval = (strcmp(entry_name, path) == 0); -+ /* trailing ** glob pattern */ -+ } else if (type == aa_entry_tailglob) { -+ retval = (strncmp(entry_name, path, -+ strlen(entry_name) - 2) == 0); -+ } else { -+ AA_WARN("%s: Invalid entry_match_type %d\n", -+ __FUNCTION__, type); -+ retval = 0; -+ } -+ -+ return retval; -+} -+ -+#endif /* __MATCH_H */ ---- security/apparmor/match/match_default.c.orig -+++ security/apparmor/match/match_default.c -@@ -0,0 +1,57 @@ -+/* -+ * Copyright (C) 2002-2005 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. -+ * -+ * http://forge.novell.com/modules/xfmod/project/?apparmor -+ * -+ * AppArmor default match submodule (literal and tailglob) -+ */ -+ -+#include -+#include "match.h" -+ -+static const char *features="literal tailglob"; -+ -+void* aamatch_alloc(enum entry_match_type type) -+{ -+ return NULL; -+} -+ -+void aamatch_free(void *ptr) -+{ -+} -+ -+const char *aamatch_features(void) -+{ -+ return features; -+} -+ -+int aamatch_serialize(void *entry_extradata, struct aa_ext *e, -+ aamatch_serializecb cb) -+{ -+ return 0; -+} -+ -+unsigned int aamatch_match(const char *pathname, const char *entry_name, -+ enum entry_match_type type, void *entry_extradata) -+{ -+ int ret; -+ -+ ret = aamatch_match_common(pathname, entry_name, type); -+ -+ return ret; -+} -+ -+EXPORT_SYMBOL_GPL(aamatch_alloc); -+EXPORT_SYMBOL_GPL(aamatch_free); -+EXPORT_SYMBOL_GPL(aamatch_features); -+EXPORT_SYMBOL_GPL(aamatch_serialize); -+EXPORT_SYMBOL_GPL(aamatch_match); -+ -+MODULE_DESCRIPTION("AppArmor match module (aamatch) [default]"); -+MODULE_AUTHOR("Tony Jones "); -+MODULE_LICENSE("GPL"); -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5008_apparmor-audit-changes.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5008_apparmor-audit-changes.patch deleted file mode 100644 index 917ca584..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5008_apparmor-audit-changes.patch +++ /dev/null @@ -1,58 +0,0 @@ -This patch adds AppArmor support to the audit subsystem. - -It creates id 1500 (already included in the the upstream auditd package) for -AppArmor messages. - -It also exports the audit_log_vformat function (analagous to having both -printk and vprintk exported). - -Signed-off-by: Tony Jones - ---- - include/linux/audit.h | 5 +++++ - kernel/audit.c | 3 ++- - 2 files changed, 7 insertions(+), 1 deletion(-) - ---- linux-2.6.17-rc1.orig/include/linux/audit.h -+++ linux-2.6.17-rc1/include/linux/audit.h -@@ -95,6 +95,8 @@ - #define AUDIT_LAST_KERN_ANOM_MSG 1799 - #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */ - -+#define AUDIT_AA 1500 /* AppArmor audit */ -+ - #define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */ - - /* Rule flags */ -@@ -349,6 +351,9 @@ - __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))); ---- linux-2.6.17-rc1.orig/kernel/audit.c -+++ linux-2.6.17-rc1/kernel/audit.c -@@ -797,7 +797,7 @@ - * 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, -+void audit_log_vformat(struct audit_buffer *ab, const char *fmt, - va_list args) - { - int len, avail; -@@ -999,4 +999,5 @@ - EXPORT_SYMBOL(audit_log_start); - EXPORT_SYMBOL(audit_log_end); - EXPORT_SYMBOL(audit_log_format); -+EXPORT_SYMBOL(audit_log_vformat); - EXPORT_SYMBOL(audit_log); -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5009_apparmor-add-flags.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5009_apparmor-add-flags.patch deleted file mode 100644 index 3a749889..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5009_apparmor-add-flags.patch +++ /dev/null @@ -1,170 +0,0 @@ -This patch adds a new function d_path_flags which takes an additional flags -parameter. Adding a new function rather than ammending the existing d_path -was done to avoid impact on the current users. - -It is not essential for inclusion with AppArmor (the apparmor_mediation.patch -can easily be revised to use plain d_path) but it enables cleaner code -["(delete)" handling] and closes a loophole with pathname generation for -chrooted tasks. - -It currently adds two flags: - -DPATH_SYSROOT: - d_path should generate a path from the system root rather than the - task's current root. - - For AppArmor this enables generation of absolute pathnames in all - cases. Currently when a task is chrooted, file access is reported - relative to the chroot. Because it is currently not possible to - obtain the absolute path in an SMP safe way, without this patch - AppArmor will have to report chroot-relative pathnames. - -DPATH_NODELETED: - d_path should not append "(deleted)" to unhashed entries. Sometimes - this information is not useful for the caller and the string can - exist as the suffix of a valid pathname. - -Signed-off-by: Tony Jones - ---- - fs/dcache.c | 48 ++++++++++++++++++++++++++++++++---------------- - include/linux/dcache.h | 7 +++++++ - 2 files changed, 39 insertions(+), 16 deletions(-) - ---- linux-2.6.17-rc1.orig/fs/dcache.c -+++ linux-2.6.17-rc1/fs/dcache.c -@@ -1381,9 +1381,11 @@ - * @rootmnt: vfsmnt to which the root dentry belongs - * @buffer: buffer to return value in - * @buflen: buffer length -+ * @flags: control flags - * - * Convert a dentry into an ASCII path name. If the entry has been deleted -- * the string " (deleted)" is appended. Note that this is ambiguous. -+ * and DPATH_NODELETED is not specified in flags then the string " (deleted)" -+ * is appended. Note that this is ambiguous. - * - * Returns the buffer or an error code if the path was too long. - * -@@ -1391,7 +1393,7 @@ - */ - static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt, - struct dentry *root, struct vfsmount *rootmnt, -- char *buffer, int buflen) -+ char *buffer, int buflen, unsigned int flags) - { - char * end = buffer+buflen; - char * retval; -@@ -1399,7 +1401,8 @@ - - *--end = '\0'; - buflen--; -- if (!IS_ROOT(dentry) && d_unhashed(dentry)) { -+ if (!(flags & DPATH_NODELETED) && -+ !IS_ROOT(dentry) && d_unhashed(dentry)) { - buflen -= 10; - end -= 10; - if (buflen < 0) -@@ -1416,7 +1419,8 @@ - for (;;) { - struct dentry * parent; - -- if (dentry == root && vfsmnt == rootmnt) -+ if (!(flags & DPATH_SYSROOT) && -+ dentry == root && vfsmnt == rootmnt) - break; - if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { - /* Global root? */ -@@ -1458,25 +1462,36 @@ - } - - /* 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_flags(struct dentry *dentry, struct vfsmount *vfsmnt, -+ char *buf, int buflen, unsigned int flags) - { - char *res; -- struct vfsmount *rootmnt; -- struct dentry *root; -+ struct vfsmount *rootmnt = NULL; -+ struct dentry *root = NULL; - -- read_lock(¤t->fs->lock); -- rootmnt = mntget(current->fs->rootmnt); -- root = dget(current->fs->root); -- read_unlock(¤t->fs->lock); -+ if (!(flags & DPATH_SYSROOT)){ -+ read_lock(¤t->fs->lock); -+ 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); -+ res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, flags); - spin_unlock(&dcache_lock); -- dput(root); -- mntput(rootmnt); -+ if (!(flags & DPATH_SYSROOT)){ -+ dput(root); -+ mntput(rootmnt); -+ } - return res; - } - -+/* original d_path without support for flags */ -+char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, -+ char *buf, int buflen) -+{ -+ return d_path_flags(dentry, vfsmnt, buf, buflen, 0); -+} -+ - /* - * NOTE! The user-level library version returns a - * character pointer. The kernel system call just -@@ -1519,7 +1534,7 @@ - unsigned long len; - char * cwd; - -- cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE); -+ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 0); - spin_unlock(&dcache_lock); - - error = PTR_ERR(cwd); -@@ -1771,6 +1786,7 @@ - EXPORT_SYMBOL(d_invalidate); - EXPORT_SYMBOL(d_lookup); - EXPORT_SYMBOL(d_move); -+EXPORT_SYMBOL(d_path_flags); - EXPORT_SYMBOL(d_path); - EXPORT_SYMBOL(d_prune_aliases); - EXPORT_SYMBOL(d_rehash); ---- linux-2.6.17-rc1.orig/include/linux/dcache.h -+++ linux-2.6.17-rc1/include/linux/dcache.h -@@ -164,6 +164,10 @@ - - #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched */ - -+/* dpath flags */ -+#define DPATH_SYSROOT 0x0001 /* continue past fsroot (chroot) */ -+#define DPATH_NODELETED 0x0002 /* do not append " (deleted)" */ -+ - extern spinlock_t dcache_lock; - - /** -@@ -281,6 +285,9 @@ - extern int d_validate(struct dentry *, struct dentry *); - - extern char * d_path(struct dentry *, struct vfsmount *, char *, int); -+ -+extern char * d_path_flags(struct dentry *, struct vfsmount *, char *, int, -+ unsigned int); - - /* Allocation counts.. */ - -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5010_apparmor-export-namespace-semaphor.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5010_apparmor-export-namespace-semaphor.patch deleted file mode 100644 index 8504f754..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/5010_apparmor-export-namespace-semaphor.patch +++ /dev/null @@ -1,53 +0,0 @@ -This patch exports the namespace_sem semaphore. - -The shared subtree patches which went into 2.6.15-rc1 replaced the old -namespace semaphore which used to be per namespace (and visible) with a -new single static semaphore. - -The reason for this change is that currently visibility of vfsmount information -to the LSM hooks is fairly patchy. Either there is no passed parameter or -it can be NULL. For the case of the former, several LSM hooks that we -require to mediate have no vfsmount/nameidata passed. We previously (mis)used -the visibility of the old per namespace semaphore to walk the processes -namespace looking for vfsmounts with a root dentry matching the dentry we were -trying to mediate. - -Clearly this is not viable long term strategy and changes working towards -passing a vfsmount to all relevant LSM hooks would seem necessary (and also -useful for other users of LSM). Alternative suggestions and ideas are welcomed. - -Signed-off-by: Tony Jones - ---- - fs/namespace.c | 3 ++- - include/linux/namespace.h | 2 ++ - 2 files changed, 4 insertions(+), 1 deletion(-) - ---- linux-2.6.17-rc1.orig/fs/namespace.c -+++ linux-2.6.17-rc1/fs/namespace.c -@@ -46,7 +46,8 @@ - static struct list_head *mount_hashtable __read_mostly; - static int hash_mask __read_mostly, hash_bits __read_mostly; - static kmem_cache_t *mnt_cache __read_mostly; --static struct rw_semaphore namespace_sem; -+struct rw_semaphore namespace_sem; -+EXPORT_SYMBOL_GPL(namespace_sem); - - /* /sys/fs */ - decl_subsys(fs, NULL, NULL); ---- linux-2.6.17-rc1.orig/include/linux/namespace.h -+++ linux-2.6.17-rc1/include/linux/namespace.h -@@ -5,6 +5,8 @@ - #include - #include - -+extern struct rw_semaphore namespace_sem; -+ - struct namespace { - atomic_t count; - struct vfsmount * root; -- -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html -Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_audit.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_audit.patch deleted file mode 100644 index 89c65e2d..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_audit.patch +++ /dev/null @@ -1,59 +0,0 @@ -Subject: Export audit subsystem for use by modules -Patch-mainline: no - -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 - -Index: linux-2.6.17/include/linux/audit.h -=================================================================== ---- linux-2.6.17.orig/include/linux/audit.h -+++ linux-2.6.17/include/linux/audit.h -@@ -92,6 +92,8 @@ - #define AUDIT_MAC_STATUS 1404 /* Changed enforcing,permissive,off */ - #define AUDIT_MAC_CONFIG_CHANGE 1405 /* Changes to booleans */ - -+#define AUDIT_SD 1500 /* AppArmor (SubDomain) audit */ -+ - #define AUDIT_FIRST_KERN_ANOM_MSG 1700 - #define AUDIT_LAST_KERN_ANOM_MSG 1799 - #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */ -@@ -357,6 +359,9 @@ - __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))); - -Index: linux-2.6.17/kernel/audit.c -=================================================================== ---- linux-2.6.17.orig/kernel/audit.c -+++ linux-2.6.17/kernel/audit.c -@@ -893,7 +893,7 @@ - * 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, -+void audit_log_vformat(struct audit_buffer *ab, const char *fmt, - va_list args) - { - int len, avail; -@@ -1092,7 +1092,10 @@ - } - } - --EXPORT_SYMBOL(audit_log_start); --EXPORT_SYMBOL(audit_log_end); --EXPORT_SYMBOL(audit_log_format); --EXPORT_SYMBOL(audit_log); -+EXPORT_SYMBOL_GPL(audit_log_start); -+EXPORT_SYMBOL_GPL(audit_log_vformat); -+EXPORT_SYMBOL_GPL(audit_log_format); -+EXPORT_SYMBOL_GPL(audit_log_untrustedstring); -+EXPORT_SYMBOL_GPL(audit_log_d_path); -+EXPORT_SYMBOL_GPL(audit_log_end); -+EXPORT_SYMBOL_GPL(audit_log); diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_main.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_main.patch deleted file mode 100644 index faba6863..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_main.patch +++ /dev/null @@ -1,7917 +0,0 @@ -From: tonyj@suse.de -Subject: AppArmor (SubDomain) -Patch-mainline: no - -AppArmor security module (previously called SubDomain) -Patch is not in mainline -- pending code submission to lkml - - ---- linux-2.6.16-SL101_BRANCH.orig/security/Kconfig -+++ linux-2.6.16-SL101_BRANCH/security/Kconfig -@@ -100,6 +100,7 @@ - If you are unsure how to answer this question, answer N. - - source security/selinux/Kconfig -+source security/apparmor/Kconfig - - endmenu - ---- linux-2.6.16-SL101_BRANCH.orig/security/Makefile -+++ linux-2.6.16-SL101_BRANCH/security/Makefile -@@ -4,6 +4,7 @@ - - obj-$(CONFIG_KEYS) += keys/ - subdir-$(CONFIG_SECURITY_SELINUX) += selinux -+subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor - - # We always need commoncap as it's default - obj-y += commoncap.o ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/Makefile -@@ -0,0 +1,10 @@ -+# Makefile for AppArmor Linux Security Module (previously called "SubDomain") -+# -+APPARMOR_VER=2.0-19.43r6320 -+ -+EXTRA_CFLAGS += -DAPPARMOR_VERSION=\"${APPARMOR_VER}\" -+ -+subdir-$(CONFIG_SECURITY_APPARMOR) += aamatch -+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o -+ -+apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o capabilities.o module_interface.o apparmor_version.o ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/capabilities.c -@@ -0,0 +1,54 @@ -+/* -+ * Copyright (C) 2005 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 capability definitions -+ */ -+ -+#include "apparmor.h" -+ -+static const char *capnames[] = { -+ "chown", -+ "dac_override", -+ "dac_read_search", -+ "fowner", -+ "fsetid", -+ "kill", -+ "setgid", -+ "setuid", -+ "setpcap", -+ "linux_immutable", -+ "net_bind_service", -+ "net_broadcast", -+ "net_admin", -+ "net_raw", -+ "ipc_lock", -+ "ipc_owner", -+ "sys_module", -+ "sys_rawio", -+ "sys_chroot", -+ "sys_ptrace", -+ "sys_pacct", -+ "sys_admin", -+ "sys_boot", -+ "sys_nice", -+ "sys_resource", -+ "sys_time", -+ "sys_tty_config", -+ "mknod", -+ "lease" -+}; -+ -+const char *capability_to_name(unsigned int cap) -+{ -+ const char *capname; -+ -+ capname = (cap < (sizeof(capnames) / sizeof(char *)) -+ ? capnames[cap] : "invalid-capability"); -+ -+ return capname; -+} ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/inline.h -@@ -0,0 +1,362 @@ -+/* -+ * Copyright (C) 2005 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. -+ */ -+ -+#ifndef __INLINE_H -+#define __INLINE_H -+ -+#include -+ -+static inline int __sd_is_confined(struct subdomain *sd) -+{ -+ int rc = 0; -+ -+ if (sd && sd->sd_magic == SD_ID_MAGIC && sd->profile) { -+ BUG_ON(!sd->active); -+ rc = 1; -+ } -+ -+ return rc; -+} -+ -+/** -+ * sd_is_confined -+ * @sd: subdomain -+ * -+ * Check if @sd is confined (contains a valid profile) -+ * Return 1 if confined, 0 otherwise. -+ */ -+static inline int sd_is_confined(void) -+{ -+ struct subdomain *sd = SD_SUBDOMAIN(current->security); -+ return __sd_is_confined(sd); -+} -+ -+static inline int __sd_sub_defined(struct subdomain *sd) -+{ -+ return __sd_is_confined(sd) && !list_empty(&sd->profile->sub); -+} -+ -+/** -+ * sd_sub_defined -+ * @sd: subdomain -+ * -+ * Check if @sd has at least one subprofile -+ * Return 1 if true, 0 otherwise -+ */ -+static inline int sd_sub_defined(void) -+{ -+ struct subdomain *sd = SD_SUBDOMAIN(current->security); -+ return __sd_sub_defined(sd); -+} -+ -+/** -+ * get_sdprofile -+ * @p: profile -+ * -+ * Increment refcount on profile -+ */ -+static inline struct sdprofile *get_sdprofile(struct sdprofile *p) -+{ -+ if (p) -+ atomic_inc(&p->count); -+ return p; -+} -+ -+/** -+ * put_sdprofile -+ * @p: profile -+ * -+ * Decrement refcount on profile -+ */ -+static inline void put_sdprofile(struct sdprofile *p) -+{ -+ if (p) -+ if (atomic_dec_and_test(&p->count)) -+ free_sdprofile(p); -+} -+ -+/** -+ * sd_switch -+ * @sd: subdomain to switch -+ * @profile: new profile -+ * @active: new active -+ * -+ * Change subdomain to use new profiles. -+ */ -+static inline void sd_switch(struct subdomain *sd, -+ struct sdprofile *profile, -+ struct sdprofile *active) -+{ -+ /* noop if NULL */ -+ put_sdprofile(sd->profile); -+ put_sdprofile(sd->active); -+ -+ sd->profile = get_sdprofile(profile); -+ sd->active = get_sdprofile(active); -+} -+ -+/** -+ * sd_switch_unconfined -+ * @sd: subdomain to switch -+ * -+ * Change subdomain to unconfined -+ */ -+static inline void sd_switch_unconfined(struct subdomain *sd) -+{ -+ sd_switch(sd, NULL, NULL); -+ -+ /* reset magic in case we were in a subhat before */ -+ sd->sd_hat_magic = 0; -+} -+ -+/** -+ * alloc_subdomain -+ * @tsk: task struct -+ * -+ * Allocate a new subdomain including a backpointer to it's referring task. -+ */ -+static inline struct subdomain *alloc_subdomain(struct task_struct *tsk) -+{ -+ struct subdomain *sd; -+ -+ sd = kmalloc(sizeof(struct subdomain), GFP_KERNEL); -+ if (!sd) -+ goto out; -+ -+ /* zero it first */ -+ memset(sd, 0, sizeof(struct subdomain)); -+ sd->sd_magic = SD_ID_MAGIC; -+ -+ /* back pointer to task */ -+ sd->task = tsk; -+ -+ /* any readers of the list must make sure that they can handle -+ * case where sd->profile and sd->active are not yet set (null) -+ */ -+ sd_subdomainlist_add(sd); -+ -+out: -+ return sd; -+} -+ -+/** -+ * free_subdomain -+ * @sd: subdomain -+ * -+ * Free a subdomain previously allocated by alloc_subdomain -+ */ -+static inline void free_subdomain(struct subdomain *sd) -+{ -+ sd_subdomainlist_remove(sd); -+ kfree(sd); -+} -+ -+/** -+ * alloc_sdprofile -+ * -+ * Allocate, initialize and return a new zeroed profile. -+ * Returns NULL on failure. -+ */ -+static inline struct sdprofile *alloc_sdprofile(void) -+{ -+ struct sdprofile *profile; -+ -+ profile = (struct sdprofile *)kmalloc(sizeof(struct sdprofile), -+ GFP_KERNEL); -+ SD_DEBUG("%s(%p)\n", __FUNCTION__, profile); -+ if (profile) { -+ int i; -+ memset(profile, 0, sizeof(struct sdprofile)); -+ INIT_LIST_HEAD(&profile->list); -+ INIT_LIST_HEAD(&profile->sub); -+ INIT_LIST_HEAD(&profile->file_entry); -+ for (i = 0; i <= POS_SD_FILE_MAX; i++) { -+ INIT_LIST_HEAD(&profile->file_entryp[i]); -+ } -+ } -+ return profile; -+} -+ -+/** -+ * sd_put_name -+ * @name: name to release. -+ * -+ * Release space (free_page) allocated to hold pathname -+ * name may be NULL (checked for by free_page) -+ */ -+static inline void sd_put_name(const char *name) -+{ -+ free_page((unsigned long)name); -+} -+ -+/** __sd_find_profile -+ * @name: name of profile to find -+ * @head: list to search -+ * -+ * Return reference counted copy of profile. NULL if not found -+ * Caller must hold any necessary locks -+ */ -+static inline struct sdprofile *__sd_find_profile(const char *name, -+ struct list_head *head) -+{ -+ struct sdprofile *p; -+ -+ if (!name || !head) -+ return NULL; -+ -+ SD_DEBUG("%s: finding profile %s\n", __FUNCTION__, name); -+ list_for_each_entry(p, head, list) { -+ if (!strcmp(p->name, name)) { -+ /* return refcounted object */ -+ p = get_sdprofile(p); -+ return p; -+ } else { -+ SD_DEBUG("%s: skipping %s\n", __FUNCTION__, p->name); -+ } -+ } -+ return NULL; -+} -+ -+static inline struct subdomain *__get_sdcopy(struct subdomain *new, -+ struct task_struct *tsk) -+{ -+ struct subdomain *old, *temp = NULL; -+ -+ old = SD_SUBDOMAIN(tsk->security); -+ -+ if (old) { -+ new->sd_magic = old->sd_magic; -+ new->sd_hat_magic = old->sd_hat_magic; -+ -+ new->active = get_sdprofile(old->active); -+ -+ if (old->profile == old->active) -+ new->profile = new->active; -+ else -+ new->profile = get_sdprofile(old->profile); -+ -+ temp = new; -+ } -+ -+ return temp; -+} -+ -+/** get_sdcopy -+ * @new: subdomain to hold copy -+ * -+ * Make copy of current subdomain containing refcounted profile and active -+ * Used to protect readers against racing writers (changehat and profile -+ * replacement). -+ */ -+static inline struct subdomain *get_sdcopy(struct subdomain *new) -+{ -+ struct subdomain *temp; -+ unsigned long flags; -+ -+ read_lock_irqsave(&sd_lock, flags); -+ -+ temp = __get_sdcopy(new, current); -+ -+ read_unlock_irqrestore(&sd_lock, flags); -+ -+ return temp; -+} -+ -+/** get_sdcopy -+ * @temp: subdomain to drop refcounts on -+ * -+ * Drop refcounted profile/active in copy of subdomain made by get_sdcopy -+ */ -+static inline void put_sdcopy(struct subdomain *temp) -+{ -+ if (temp) { -+ put_sdprofile(temp->active); -+ if (temp->active != temp->profile) -+ (void)put_sdprofile(temp->profile); -+ } -+} -+ -+/** sd_path_begin2 -+ * @rdentry: filesystem root dentry (searching for vfsmnts matching this) -+ * @dentry: dentry object to obtain pathname from (relative to matched vfsmnt) -+ * -+ * Setup data for iterating over vfsmounts (in current tasks namespace). -+ */ -+static inline void sd_path_begin2(struct dentry *rdentry, -+ struct dentry *dentry, -+ struct sd_path_data *data) -+{ -+ data->dentry = dentry; -+ data->root = dget(rdentry->d_sb->s_root); -+ data->namespace = current->namespace; -+ data->head = &data->namespace->list; -+ data->pos = data->head->next; -+ prefetch(data->pos->next); -+ data->errno = 0; -+ -+ down_read(&namespace_sem); -+} -+ -+/** sd_path_begin -+ * @dentry filesystem root dentry and object to obtain pathname from -+ * -+ * Utility function for calling _sd_path_begin for when the dentry we are -+ * looking for and the root are the same (this is the usual case). -+ */ -+static inline void sd_path_begin(struct dentry *dentry, -+ struct sd_path_data *data) -+{ -+ sd_path_begin2(dentry, dentry, data); -+} -+ -+/** sd_path_end -+ * @data: data object previously initialized by sd_path_begin -+ * -+ * End iterating over vfsmounts. -+ * If an error occured in begin or get, it is returned. Otherwise 0. -+ */ -+static inline int sd_path_end(struct sd_path_data *data) -+{ -+ up_read(&namespace_sem); -+ dput(data->root); -+ -+ return data->errno; -+} -+ -+/** sd_path_getname -+ * @data: data object previously initialized by sd_path_begin -+ * -+ * Return the next mountpoint which has the same root dentry as data->root. -+ * If no more mount points exist (or in case of error) NULL is returned -+ * (caller should call sd_path_end() and inspect return code to differentiate) -+ */ -+static inline char *sd_path_getname(struct sd_path_data *data) -+{ -+ char *name = NULL; -+ struct vfsmount *mnt; -+ -+ while (data->pos != data->head) { -+ mnt = list_entry(data->pos, struct vfsmount, mnt_list); -+ -+ /* advance to next -- so that it is done before we break */ -+ data->pos = data->pos->next; -+ prefetch(data->pos->next); -+ -+ if (mnt->mnt_root == data->root) { -+ name = sd_get_name(data->dentry, mnt); -+ if (!name) -+ data->errno = -ENOMEM; -+ break; -+ } -+ } -+ -+ return name; -+} -+ -+#endif /* __INLINE_H__ */ ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/list.c -@@ -0,0 +1,289 @@ -+/* -+ * Copyright (C) 1998-2005 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 Profile List Management -+ */ -+ -+#include -+#include "apparmor.h" -+#include "inline.h" -+ -+/* list of all profiles and lock */ -+static LIST_HEAD(profile_list); -+static rwlock_t profile_lock = RW_LOCK_UNLOCKED; -+ -+/* list of all subdomains and lock */ -+static LIST_HEAD(subdomain_list); -+static rwlock_t subdomain_lock = RW_LOCK_UNLOCKED; -+ -+/** -+ * sd_profilelist_find -+ * @name: profile name (program name) -+ * -+ * Search the profile list for profile @name. Return refcounted profile on -+ * success, NULL on failure. -+ */ -+struct sdprofile *sd_profilelist_find(const char *name) -+{ -+ struct sdprofile *p = NULL; -+ if (name) { -+ read_lock(&profile_lock); -+ p = __sd_find_profile(name, &profile_list); -+ read_unlock(&profile_lock); -+ } -+ return p; -+} -+ -+/** -+ * sd_profilelist_add -+ * @profile: new profile to add to list -+ * -+ * Add new profile to list. Reference count on profile is incremented. -+ * Return 1 on success, 0 on failure (bad profile or already exists) -+ */ -+int sd_profilelist_add(struct sdprofile *profile) -+{ -+ struct sdprofile *old_profile; -+ int ret = 0; -+ -+ if (!profile) -+ goto out; -+ -+ write_lock(&profile_lock); -+ old_profile = __sd_find_profile(profile->name, &profile_list); -+ if (old_profile) { -+ put_sdprofile(old_profile); -+ goto out; -+ } -+ profile = get_sdprofile(profile); -+ list_add(&profile->list, &profile_list); -+ ret = 1; -+ out: -+ write_unlock(&profile_lock); -+ return ret; -+} -+ -+/** -+ * sd_profilelist_remove -+ * @name: name of profile to be removed -+ * -+ * Remove profile from list. Reference count on profile is decremented. -+ */ -+int sd_profilelist_remove(const char *name) -+{ -+ struct sdprofile *profile = NULL; -+ struct sdprofile *p, *tmp; -+ int error = -ENOENT; -+ -+ if (!name) -+ goto out; -+ -+ write_lock(&profile_lock); -+ list_for_each_entry_safe(p, tmp, &profile_list, list) { -+ if (!strcmp(p->name, name)) { -+ list_del_init(&p->list); -+ profile = p; -+ break; -+ } -+ } -+ write_unlock(&profile_lock); -+ if (!profile) -+ goto out; -+ -+ put_sdprofile(profile); -+ error = 0; -+out: -+ return error; -+} -+ -+/** -+ * sd_profilelist_replace -+ * @profile - new profile -+ * -+ * Replace a profile on the profile list. Find the old profile by name in -+ * the list, and replace it with the new profile. This is an atomic -+ * list operation. Returns the old profile (which is still refcounted) if -+ * there was one, or NULL. -+ */ -+struct sdprofile *sd_profilelist_replace(struct sdprofile *profile) -+{ -+ struct sdprofile *oldprofile; -+ -+ write_lock(&profile_lock); -+ oldprofile = __sd_find_profile(profile->name, &profile_list); -+ if (oldprofile) { -+ list_del_init(&oldprofile->list); -+ -+ /* __sd_find_profile incremented count, so adjust down */ -+ put_sdprofile(oldprofile); -+ } -+ profile = get_sdprofile(profile); -+ list_add(&profile->list, &profile_list); -+ write_unlock(&profile_lock); -+ -+ return oldprofile; -+} -+ -+/** -+ * sd_profilelist_release -+ * -+ * Remove all profiles from profile_list -+ */ -+void sd_profilelist_release(void) -+{ -+ struct sdprofile *p, *tmp; -+ -+ write_lock(&profile_lock); -+ list_for_each_entry_safe(p, tmp, &profile_list, list) { -+ list_del_init(&p->list); -+ put_sdprofile(p); -+ } -+ write_unlock(&profile_lock); -+} -+ -+/** -+ * sd_subdomainlist_add -+ * @sd: new subdomain -+ * -+ * Add subdomain to subdomain_list -+ */ -+void sd_subdomainlist_add(struct subdomain *sd) -+{ -+ unsigned long flags; -+ -+ if (!sd) { -+ SD_INFO("%s: bad subdomain\n", __FUNCTION__); -+ return; -+ } -+ -+ write_lock_irqsave(&subdomain_lock, flags); -+ list_add(&sd->list, &subdomain_list); -+ write_unlock_irqrestore(&subdomain_lock, flags); -+} -+ -+/** -+ * sd_subdomainlist_remove -+ * @sd: subdomain to be removed -+ * -+ * Remove subdomain from subdomain_list -+ */ -+void sd_subdomainlist_remove(struct subdomain *sd) -+{ -+ unsigned long flags; -+ -+ if (sd) { -+ write_lock_irqsave(&subdomain_lock, flags); -+ list_del_init(&sd->list); -+ write_unlock_irqrestore(&subdomain_lock, flags); -+ } -+} -+ -+/** -+ * sd_subdomainlist_iterate -+ * @func: method to be called for each element -+ * @cookie: user passed data -+ * -+ * Iterate over subdomain list, stop when sd_iter func returns non zero -+ */ -+void sd_subdomainlist_iterate(sd_iter func, void *cookie) -+{ -+ struct subdomain *node; -+ int ret = 0; -+ unsigned long flags; -+ -+ read_lock_irqsave(&subdomain_lock, flags); -+ list_for_each_entry(node, &subdomain_list, list) { -+ ret = (*func) (node, cookie); -+ if (ret != 0) -+ break; -+ } -+ read_unlock_irqrestore(&subdomain_lock, flags); -+} -+ -+/** -+ * sd_subdomainlist_iterateremove -+ * @func: method to be called for each element -+ * @cookie: user passed data -+ * -+ * Iterate over subdomain_list, remove element when sd_iter func returns -+ * non zero -+ */ -+void sd_subdomainlist_iterateremove(sd_iter func, void *cookie) -+{ -+ struct subdomain *node, *tmp; -+ int ret = 0; -+ unsigned long flags; -+ -+ write_lock_irqsave(&subdomain_lock, flags); -+ list_for_each_entry_safe(node, tmp, &subdomain_list, list) { -+ ret = (*func) (node, cookie); -+ if (ret != 0) -+ list_del_init(&node->list); -+ } -+ write_unlock_irqrestore(&subdomain_lock, flags); -+} -+ -+/** -+ * sd_subdomainlist_release -+ * -+ * Remove all subdomains from subdomain_list -+ */ -+void sd_subdomainlist_release() -+{ -+ struct subdomain *node, *tmp; -+ unsigned long flags; -+ -+ write_lock_irqsave(&subdomain_lock, flags); -+ list_for_each_entry_safe(node, tmp, &subdomain_list, list) { -+ list_del_init(&node->list); -+ } -+ write_unlock_irqrestore(&subdomain_lock, flags); -+} -+ -+/* seq_file helper routines -+ * Used by subdomainfs.c to iterate over profile_list -+ */ -+static void *p_start(struct seq_file *f, loff_t *pos) -+{ -+ struct sdprofile *node; -+ loff_t l = *pos; -+ -+ read_lock(&profile_lock); -+ list_for_each_entry(node, &profile_list, list) -+ if (!l--) -+ return node; -+ return NULL; -+} -+ -+static void *p_next(struct seq_file *f, void *p, loff_t *pos) -+{ -+ struct list_head *lh = ((struct sdprofile *)p)->list.next; -+ (*pos)++; -+ return lh == &profile_list ? -+ NULL : list_entry(lh, struct sdprofile, list); -+} -+ -+static void p_stop(struct seq_file *f, void *v) -+{ -+ read_unlock(&profile_lock); -+} -+ -+static int seq_show_profile(struct seq_file *f, void *v) -+{ -+ struct sdprofile *profile = (struct sdprofile *)v; -+ seq_printf(f, "%s (%s)\n", profile->name, -+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); -+ return 0; -+} -+ -+struct seq_operations subdomainfs_profiles_op = { -+ .start = p_start, -+ .next = p_next, -+ .stop = p_stop, -+ .show = seq_show_profile, -+}; ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/lsm.c -@@ -0,0 +1,858 @@ -+/* -+ * Copyright (C) 2002-2005 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. -+ * -+ * http://forge.novell.com/modules/xfmod/project/?apparmor -+ * -+ * Immunix AppArmor LSM interface (previously called "SubDomain") -+ */ -+ -+#include -+#include -+ -+/* superblock types */ -+ -+/* PIPEFS_MAGIC */ -+#include -+/* from net/socket.c */ -+#define SOCKFS_MAGIC 0x534F434B -+/* from inotify.c */ -+#define INOTIFYFS_MAGIC 0xBAD1DEA -+ -+#define VALID_FSTYPE(inode) ((inode)->i_sb->s_magic != PIPEFS_MAGIC && \ -+ (inode)->i_sb->s_magic != SOCKFS_MAGIC && \ -+ (inode)->i_sb->s_magic != INOTIFYFS_MAGIC) -+ -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+ -+/* main SD lock [see get_sdcopy and put_sdcopy] */ -+rwlock_t sd_lock = RW_LOCK_UNLOCKED; -+ -+/* Flag values, also controllable via subdomainfs/control. -+ * We explicitly do not allow these to be modifiable when exported via -+ * /sys/modules/parameters, as we want to do additional mediation and -+ * don't want to add special path code. */ -+ -+/* Complain mode (used to be 'bitch' mode) */ -+int subdomain_complain = 0; -+module_param_named(complain, subdomain_complain, int, S_IRUSR); -+MODULE_PARM_DESC(subdomain_complain, "Toggle AppArmor complain mode"); -+ -+/* Debug mode */ -+int subdomain_debug = 0; -+module_param_named(debug, subdomain_debug, int, S_IRUSR); -+MODULE_PARM_DESC(subdomain_debug, "Toggle AppArmor debug mode"); -+ -+/* Audit mode */ -+int subdomain_audit = 0; -+module_param_named(audit, subdomain_audit, int, S_IRUSR); -+MODULE_PARM_DESC(subdomain_audit, "Toggle AppArmor audit mode"); -+ -+/* Syscall logging mode */ -+int subdomain_logsyscall = 0; -+module_param_named(logsyscall, subdomain_logsyscall, int, S_IRUSR); -+MODULE_PARM_DESC(subdomain_logsyscall, "Toggle AppArmor logsyscall mode"); -+ -+#ifndef MODULE -+static int __init sd_getopt_complain(char *str) -+{ -+ get_option(&str, &subdomain_complain); -+ return 1; -+} -+__setup("subdomain_complain=", sd_getopt_complain); -+ -+static int __init sd_getopt_debug(char *str) -+{ -+ get_option(&str, &subdomain_debug); -+ return 1; -+} -+__setup("subdomain_debug=", sd_getopt_debug); -+ -+static int __init sd_getopt_audit(char *str) -+{ -+ get_option(&str, &subdomain_audit); -+ return 1; -+} -+__setup("subdomain_audit=", sd_getopt_audit); -+ -+static int __init sd_getopt_logsyscall(char *str) -+{ -+ get_option(&str, &subdomain_logsyscall); -+ return 1; -+} -+__setup("subdomain_logsyscall=", sd_getopt_logsyscall); -+#endif -+ -+static int subdomain_ptrace(struct task_struct *parent, -+ struct task_struct *child) -+{ -+ int error; -+ struct subdomain *sd; -+ unsigned long flags; -+ -+ error = cap_ptrace(parent, child); -+ -+ read_lock_irqsave(&sd_lock, flags); -+ -+ sd = SD_SUBDOMAIN(current->security); -+ -+ if (!error && __sd_is_confined(sd)) { -+ error = sd_audit_syscallreject(sd, GFP_ATOMIC, "ptrace"); -+ WARN_ON(error != -EPERM); -+ } -+ -+ read_unlock_irqrestore(&sd_lock, flags); -+ -+ return error; -+} -+ -+static int subdomain_capget(struct task_struct *target, -+ kernel_cap_t * effective, -+ kernel_cap_t * inheritable, -+ kernel_cap_t * permitted) -+{ -+ return cap_capget(target, effective, inheritable, permitted); -+} -+ -+static int subdomain_capset_check(struct task_struct *target, -+ kernel_cap_t *effective, -+ kernel_cap_t *inheritable, -+ kernel_cap_t *permitted) -+{ -+ return cap_capset_check(target, effective, inheritable, permitted); -+} -+ -+static void subdomain_capset_set(struct task_struct *target, -+ kernel_cap_t *effective, -+ kernel_cap_t *inheritable, -+ kernel_cap_t *permitted) -+{ -+ cap_capset_set(target, effective, inheritable, permitted); -+ return; -+} -+ -+static int subdomain_capable(struct task_struct *tsk, int cap) -+{ -+ int error; -+ -+ /* cap_capable returns 0 on success, else -EPERM */ -+ error = cap_capable(tsk, cap); -+ -+ if (error == 0) { -+ struct subdomain *sd, sdcopy; -+ unsigned long flags; -+ -+ read_lock_irqsave(&sd_lock, flags); -+ sd = __get_sdcopy(&sdcopy, tsk); -+ read_unlock_irqrestore(&sd_lock, flags); -+ -+ error = sd_capability(sd, cap); -+ -+ put_sdcopy(sd); -+ } -+ -+ return error; -+} -+ -+static int subdomain_sysctl(struct ctl_table *table, int op) -+{ -+ int error = 0; -+ struct subdomain *sd; -+ unsigned long flags; -+ -+ read_lock_irqsave(&sd_lock, flags); -+ -+ sd = SD_SUBDOMAIN(current->security); -+ -+ if ((op & 002) && __sd_is_confined(sd) && !capable(CAP_SYS_ADMIN)) { -+ error = sd_audit_syscallreject(sd, GFP_ATOMIC, -+ "sysctl (write)"); -+ WARN_ON(error != -EPERM); -+ } -+ -+ read_unlock_irqrestore(&sd_lock, flags); -+ -+ return error; -+} -+ -+static int subdomain_syslog(int type) -+{ -+ return cap_syslog(type); -+} -+ -+static int subdomain_netlink_send(struct sock *sk, struct sk_buff *skb) -+{ -+ return cap_netlink_send(sk, skb); -+} -+ -+static int subdomain_netlink_recv(struct sk_buff *skb) -+{ -+ return cap_netlink_recv(skb); -+} -+ -+static void subdomain_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) -+{ -+ cap_bprm_apply_creds(bprm, unsafe); -+ return; -+} -+ -+static int subdomain_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 sd_register(bprm->file); -+} -+ -+static int subdomain_sb_mount(char *dev_name, struct nameidata *nd, char *type, -+ unsigned long flags, void *data) -+{ -+ int error = 0; -+ struct subdomain *sd; -+ unsigned long lockflags; -+ -+ read_lock_irqsave(&sd_lock, lockflags); -+ -+ sd = SD_SUBDOMAIN(current->security); -+ -+ if (__sd_is_confined(sd)) { -+ error = sd_audit_syscallreject(sd, GFP_ATOMIC, "mount"); -+ WARN_ON(error != -EPERM); -+ } -+ -+ read_unlock_irqrestore(&sd_lock, lockflags); -+ -+ return error; -+} -+ -+static int subdomain_umount(struct vfsmount *mnt, int flags) -+{ -+ int error = 0; -+ struct subdomain *sd; -+ unsigned long lockflags; -+ -+ read_lock_irqsave(&sd_lock, lockflags); -+ -+ sd = SD_SUBDOMAIN(current->security); -+ -+ if (__sd_is_confined(sd)) { -+ error = sd_audit_syscallreject(sd, GFP_KERNEL, "umount"); -+ WARN_ON(error != -EPERM); -+ } -+ -+ read_unlock_irqrestore(&sd_lock, lockflags); -+ -+ return error; -+} -+ -+static int subdomain_inode_mkdir(struct inode *inode, struct dentry *dentry, -+ int mask) -+{ -+ struct subdomain sdcopy, *sd; -+ int error; -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ error = sd_perm_dir(sd, dentry, SD_DIR_MKDIR); -+ -+ put_sdcopy(sd); -+ -+ return error; -+} -+ -+static int subdomain_inode_rmdir(struct inode *inode, struct dentry *dentry) -+{ -+ struct subdomain sdcopy, *sd; -+ int error; -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ error = sd_perm_dir(sd, dentry, SD_DIR_RMDIR); -+ -+ put_sdcopy(sd); -+ -+ return error; -+} -+ -+static int subdomain_inode_create(struct inode *inode, struct dentry *dentry, -+ int mask) -+{ -+ struct subdomain sdcopy, *sd; -+ int error; -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ /* At a minimum, need write perm to create */ -+ error = sd_perm_dentry(sd, dentry, MAY_WRITE); -+ -+ put_sdcopy(sd); -+ -+ return error; -+} -+ -+static int subdomain_inode_link(struct dentry *old_dentry, struct inode *inode, -+ struct dentry *new_dentry) -+{ -+ int error = 0; -+ struct subdomain sdcopy, *sd; -+ -+ sd = get_sdcopy(&sdcopy); -+ error = sd_link(sd, new_dentry, old_dentry); -+ put_sdcopy(sd); -+ -+ return error; -+} -+ -+static int subdomain_inode_unlink(struct inode *inode, struct dentry *dentry) -+{ -+ struct subdomain sdcopy, *sd; -+ int error; -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ error = sd_perm_dentry(sd, dentry, MAY_WRITE); -+ -+ put_sdcopy(sd); -+ -+ return error; -+} -+ -+static int subdomain_inode_mknod(struct inode *inode, struct dentry *dentry, -+ int mode, dev_t dev) -+{ -+ struct subdomain sdcopy, *sd; -+ int error = 0; -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ error = sd_perm_dentry(sd, dentry, MAY_WRITE); -+ -+ put_sdcopy(sd); -+ -+ return error; -+} -+ -+static int subdomain_inode_rename(struct inode *old_inode, -+ struct dentry *old_dentry, -+ struct inode *new_inode, -+ struct dentry *new_dentry) -+{ -+ struct subdomain sdcopy, *sd; -+ int error = 0; -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ error = sd_perm_dentry(sd, old_dentry, -+ MAY_READ | MAY_WRITE); -+ -+ if (!error) -+ error = sd_perm_dentry(sd, new_dentry, MAY_WRITE); -+ -+ put_sdcopy(sd); -+ -+ return error; -+} -+ -+static int subdomain_inode_permission(struct inode *inode, int mask, -+ struct nameidata *nd) -+{ -+ int error = 0; -+ -+ /* Do not perform check on pipes or sockets -+ * Same as subdomain_file_permission -+ */ -+ if (VALID_FSTYPE(inode)) { -+ struct subdomain sdcopy, *sd; -+ -+ sd = get_sdcopy(&sdcopy); -+ error = sd_perm_nameidata(sd, nd, mask); -+ put_sdcopy(sd); -+ } -+ -+ return error; -+} -+ -+static int subdomain_inode_setattr(struct dentry *dentry, struct iattr *iattr) -+{ -+ struct subdomain sdcopy, *sd; -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ /* -+ * Mediate any attempt to change attributes of a file -+ * (chmod, chown, chgrp, etc) -+ */ -+ error = sd_attr(sd, dentry, iattr); -+ -+ put_sdcopy(sd); -+ } -+ -+ return error; -+} -+ -+static int subdomain_inode_setxattr(struct dentry *dentry, char *name, -+ void *value, size_t size, int flags) -+{ -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ struct subdomain sdcopy, *sd; -+ -+ sd = get_sdcopy(&sdcopy); -+ error = sd_xattr(sd, dentry, name, SD_XATTR_SET); -+ put_sdcopy(sd); -+ } -+ -+ return error; -+} -+ -+static int subdomain_inode_getxattr(struct dentry *dentry, char *name) -+{ -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ struct subdomain sdcopy, *sd; -+ -+ sd = get_sdcopy(&sdcopy); -+ error = sd_xattr(sd, dentry, name, SD_XATTR_GET); -+ put_sdcopy(sd); -+ } -+ -+ return error; -+} -+static int subdomain_inode_listxattr(struct dentry *dentry) -+{ -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ struct subdomain sdcopy, *sd; -+ -+ sd = get_sdcopy(&sdcopy); -+ error = sd_xattr(sd, dentry, NULL, SD_XATTR_LIST); -+ put_sdcopy(sd); -+ } -+ -+ return error; -+} -+ -+static int subdomain_inode_removexattr(struct dentry *dentry, char *name) -+{ -+ int error = 0; -+ -+ if (VALID_FSTYPE(dentry->d_inode)) { -+ struct subdomain sdcopy, *sd; -+ -+ sd = get_sdcopy(&sdcopy); -+ error = sd_xattr(sd, dentry, name, SD_XATTR_REMOVE); -+ put_sdcopy(sd); -+ } -+ -+ return error; -+} -+ -+static int subdomain_file_permission(struct file *file, int mask) -+{ -+ struct subdomain sdcopy, *sd; -+ struct sdprofile *f_profile; -+ int error = 0; -+ -+ f_profile = SD_PROFILE(file->f_security); -+ /* bail out early if this isn't a mediated file */ -+ if (!(f_profile && VALID_FSTYPE(file->f_dentry->d_inode))) -+ goto out; -+ -+ sd = get_sdcopy(&sdcopy); -+ if (__sd_is_confined(sd) && f_profile != sd->active) -+ error = sd_perm(sd, file->f_dentry, file->f_vfsmnt, -+ mask & (MAY_EXEC | MAY_WRITE | MAY_READ)); -+ put_sdcopy(sd); -+ -+out: -+ return error; -+} -+ -+static int subdomain_file_alloc_security(struct file *file) -+{ -+ struct subdomain sdcopy, *sd; -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ if (__sd_is_confined(sd)) -+ file->f_security = get_sdprofile(sd->active); -+ -+ put_sdcopy(sd); -+ -+ return 0; -+} -+ -+static void subdomain_file_free_security(struct file *file) -+{ -+ struct sdprofile *p = SD_PROFILE(file->f_security); -+ put_sdprofile(p); -+} -+ -+static int subdomain_file_mmap (struct file *file, unsigned long reqprot, -+ unsigned long prot, unsigned long flags) -+{ -+ int error = 0, mask = 0; -+ struct subdomain sdcopy, *sd; -+ struct sdprofile *f_profile; -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ f_profile = file ? SD_PROFILE(file->f_security) : NULL; -+ -+ if (prot & PROT_READ) -+ mask |= MAY_READ; -+ if (prot & PROT_WRITE) -+ mask |= MAY_WRITE; -+ if (prot & PROT_EXEC) -+ mask |= MAY_EXEC; -+ -+ SD_DEBUG("%s: 0x%x\n", __FUNCTION__, mask); -+ -+ /* Don't check if no subdomain's, profiles haven't changed, or -+ * mapping in the executable -+ */ -+ if (file && __sd_sub_defined(sd) && -+ f_profile != sd->active && -+ !(flags & MAP_EXECUTABLE)) -+ error = sd_perm(sd, file->f_dentry, file->f_vfsmnt, mask); -+ -+ put_sdcopy(sd); -+ -+ return error; -+} -+ -+static int subdomain_task_alloc_security(struct task_struct *p) -+{ -+ return sd_fork(p); -+} -+ -+static void subdomain_task_free_security(struct task_struct *p) -+{ -+ sd_release(p); -+} -+ -+static int subdomain_task_post_setuid(uid_t id0, uid_t id1, uid_t id2, -+ int flags) -+{ -+ return cap_task_post_setuid(id0, id1, id2, flags); -+} -+ -+static void subdomain_task_reparent_to_init(struct task_struct *p) -+{ -+ cap_task_reparent_to_init(p); -+ return; -+} -+ -+static int subdomain_getprocattr(struct task_struct *p, char *name, void *value, -+ size_t size) -+{ -+ int error; -+ struct subdomain sdcopy, *sd; -+ char *str = value; -+ unsigned long flags; -+ -+ /* Subdomain only supports the "current" process attribute */ -+ if (strcmp(name, "current") != 0) { -+ error = -EINVAL; -+ goto out; -+ } -+ -+ if (!size) { -+ error = -ERANGE; -+ goto out; -+ } -+ -+ /* must be task querying itself or admin */ -+ if (current != p && !capable(CAP_SYS_ADMIN)) { -+ error = -EPERM; -+ goto out; -+ } -+ -+ read_lock_irqsave(&sd_lock, flags); -+ -+ sd = __get_sdcopy(&sdcopy, p); -+ -+ read_unlock_irqrestore(&sd_lock, flags); -+ -+ error = sd_getprocattr(sd, str, size); -+ put_sdcopy(sd); -+ -+out: -+ return error; -+} -+ -+static int subdomain_setprocattr(struct task_struct *p, char *name, void *value, -+ size_t size) -+{ -+ const char *cmd_changehat = "changehat ", -+ *cmd_setprofile = "setprofile "; -+ -+ int error = -EACCES; /* default to a perm denied */ -+ char *cmd = (char *)value; -+ -+ /* only support messages to current */ -+ if (strcmp(name, "current") != 0) { -+ error = -EINVAL; -+ goto out; -+ } -+ -+ if (!size) { -+ error = -ERANGE; -+ goto out; -+ } -+ -+ /* CHANGE HAT */ -+ if (size > strlen(cmd_changehat) && -+ strncmp(cmd, cmd_changehat, strlen(cmd_changehat)) == 0) { -+ char *hatinfo = cmd + strlen(cmd_changehat); -+ size_t infosize = size - strlen(cmd_changehat); -+ -+ /* Only the current process may change it's hat */ -+ if (current != p) { -+ SD_WARN("%s: Attempt by foreign task %s(%d) " -+ "[user %d] to changehat of task %s(%d)\n", -+ __FUNCTION__, -+ current->comm, -+ current->pid, -+ current->uid, -+ p->comm, -+ p->pid); -+ -+ error = -EACCES; -+ goto out; -+ } -+ -+ error = sd_setprocattr_changehat(hatinfo, infosize); -+ if (error == 0) -+ /* success, set return to #bytes in orig request */ -+ error = size; -+ -+ /* SET NEW PROFILE */ -+ } else if (size > strlen(cmd_setprofile) && -+ strncmp(cmd, cmd_setprofile, strlen(cmd_setprofile)) == 0) { -+ int confined; -+ unsigned long flags; -+ -+ /* only an unconfined process with admin capabilities -+ * may change the profile of another task -+ */ -+ -+ if (!capable(CAP_SYS_ADMIN)) { -+ SD_WARN("%s: Unprivileged attempt by task %s(%d) " -+ "[user %d] to assign profile to task %s(%d)\n", -+ __FUNCTION__, -+ current->comm, -+ current->pid, -+ current->uid, -+ p->comm, -+ p->pid); -+ error = -EACCES; -+ goto out; -+ } -+ -+ read_lock_irqsave(&sd_lock, flags); -+ confined = sd_is_confined(); -+ read_unlock_irqrestore(&sd_lock, flags); -+ -+ if (!confined) { -+ char *profile = cmd + strlen(cmd_setprofile); -+ size_t profilesize = size - strlen(cmd_setprofile); -+ -+ error = sd_setprocattr_setprofile(p, profile, profilesize); -+ if (error == 0) -+ /* success, -+ * set return to #bytes in orig request -+ */ -+ error = size; -+ } else { -+ SD_WARN("%s: Attempt by confined task %s(%d) " -+ "[user %d] to assign profile to task %s(%d)\n", -+ __FUNCTION__, -+ current->comm, -+ current->pid, -+ current->uid, -+ p->comm, -+ p->pid); -+ -+ error = -EACCES; -+ } -+ } else { -+ /* unknown operation */ -+ SD_WARN("%s: Unknown setprocattr command '%.*s' by task %s(%d) " -+ "[user %d] for task %s(%d)\n", -+ __FUNCTION__, -+ size < 16 ? (int)size : 16, -+ cmd, -+ current->comm, -+ current->pid, -+ current->uid, -+ p->comm, -+ p->pid); -+ -+ error = -EINVAL; -+ } -+ -+out: -+ return error; -+} -+ -+struct security_operations subdomain_ops = { -+ .ptrace = subdomain_ptrace, -+ .capget = subdomain_capget, -+ .capset_check = subdomain_capset_check, -+ .capset_set = subdomain_capset_set, -+ .sysctl = subdomain_sysctl, -+ .capable = subdomain_capable, -+ .syslog = subdomain_syslog, -+ -+ .netlink_send = subdomain_netlink_send, -+ .netlink_recv = subdomain_netlink_recv, -+ -+ .bprm_apply_creds = subdomain_bprm_apply_creds, -+ .bprm_set_security = subdomain_bprm_set_security, -+ -+ .sb_mount = subdomain_sb_mount, -+ .sb_umount = subdomain_umount, -+ -+ .inode_mkdir = subdomain_inode_mkdir, -+ .inode_rmdir = subdomain_inode_rmdir, -+ .inode_create = subdomain_inode_create, -+ .inode_link = subdomain_inode_link, -+ .inode_unlink = subdomain_inode_unlink, -+ .inode_mknod = subdomain_inode_mknod, -+ .inode_rename = subdomain_inode_rename, -+ .inode_permission = subdomain_inode_permission, -+ .inode_setattr = subdomain_inode_setattr, -+ .inode_setxattr = subdomain_inode_setxattr, -+ .inode_getxattr = subdomain_inode_getxattr, -+ .inode_listxattr = subdomain_inode_listxattr, -+ .inode_removexattr = subdomain_inode_removexattr, -+ .file_permission = subdomain_file_permission, -+ .file_alloc_security = subdomain_file_alloc_security, -+ .file_free_security = subdomain_file_free_security, -+ .file_mmap = subdomain_file_mmap, -+ -+ .task_alloc_security = subdomain_task_alloc_security, -+ .task_free_security = subdomain_task_free_security, -+ .task_post_setuid = subdomain_task_post_setuid, -+ .task_reparent_to_init = subdomain_task_reparent_to_init, -+ -+ .getprocattr = subdomain_getprocattr, -+ .setprocattr = subdomain_setprocattr, -+}; -+ -+static int __init subdomain_init(void) -+{ -+ int error = 0; -+ const char *complainmsg = ": complainmode enabled"; -+ -+ if (!create_subdomainfs()) { -+ SD_ERROR("Unable to activate AppArmor filesystem\n"); -+ error = -ENOENT; -+ goto createfs_out; -+ } -+ -+ if (!alloc_nullprofiles()){ -+ SD_ERROR("Unable to allocate null profiles\n"); -+ error = -ENOMEM; -+ goto createfs_out; -+ } -+ -+ if ((error = register_security(&subdomain_ops))) { -+ SD_WARN("Unable to load AppArmor\n"); -+ goto dealloc_out; -+ } -+ -+ SD_INFO("AppArmor (version %s) initialized%s\n", -+ apparmor_version(), -+ subdomain_complain ? complainmsg : ""); -+ sd_audit_message(NULL, GFP_KERNEL, 0, -+ "AppArmor (version %s) initialized%s\n", -+ apparmor_version(), -+ subdomain_complain ? complainmsg : ""); -+ -+ return error; -+ -+dealloc_out: -+ free_nullprofiles(); -+ (void)destroy_subdomainfs(); -+ -+createfs_out: -+ return error; -+ -+} -+ -+static int subdomain_exit_removeall_iter(struct subdomain *sd, void *cookie) -+{ -+ /* write_lock(&sd_lock) held here */ -+ -+ if (__sd_is_confined(sd)) { -+ SD_DEBUG("%s: Dropping profiles %s(%d) " -+ "profile %s(%p) active %s(%p)\n", -+ __FUNCTION__, -+ sd->task->comm, sd->task->pid, -+ sd->profile->name, sd->profile, -+ sd->active->name, sd->active); -+ sd_switch_unconfined(sd); -+ } -+ -+ return 0; -+} -+ -+static void __exit subdomain_exit(void) -+{ -+ unsigned long flags; -+ -+ /* Remove profiles from the global profile list. -+ * This is just for tidyness as there is no way to reference this -+ * list once the AppArmor lsm hooks are detached (below) -+ */ -+ sd_profilelist_release(); -+ -+ /* Remove profiles from active tasks -+ * If this is not done, if module is reloaded after being removed, -+ * old profiles (still refcounted in memory) will become 'magically' -+ * reattached -+ */ -+ -+ write_lock_irqsave(&sd_lock, flags); -+ sd_subdomainlist_iterate(subdomain_exit_removeall_iter, NULL); -+ write_unlock_irqrestore(&sd_lock, flags); -+ -+ /* Free up list of active subdomain */ -+ sd_subdomainlist_release(); -+ -+ free_nullprofiles(); -+ -+ if (!destroy_subdomainfs()) -+ SD_WARN("Unable to properly deactivate AppArmor fs\n"); -+ -+ if (unregister_security(&subdomain_ops)) -+ SD_WARN("Unable to properly unregister AppArmor\n"); -+ -+ SD_INFO("AppArmor protection removed\n"); -+ sd_audit_message(NULL, GFP_KERNEL, 0, -+ "AppArmor protection removed\n"); -+} -+ -+security_initcall(subdomain_init); -+module_exit(subdomain_exit); -+ -+MODULE_DESCRIPTION("AppArmor process confinement"); -+MODULE_AUTHOR("Tony Jones "); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/main.c -@@ -0,0 +1,1648 @@ -+/* -+ * Copyright (C) 2002-2005 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 Core -+ */ -+ -+#include -+#include -+#include -+ -+#include "apparmor.h" -+#include "aamatch/match.h" -+ -+#include "inline.h" -+ -+/* NULL profile -+ * -+ * Used when an attempt is made to changehat into a non-existant -+ * subhat. In the NULL profile, no file access is allowed -+ * (currently full network access is allowed). Using a NULL -+ * profile ensures that active is always non zero. -+ * -+ * Leaving the NULL profile is by either successfully changehatting -+ * into a sibling hat, or changehatting back to the parent (NULL hat). -+ */ -+struct sdprofile *null_profile; -+ -+/* NULL complain profile -+ * -+ * Used when in complain mode, to emit Permitting messages for non-existant -+ * profiles and hats. This is necessary because of selective mode, in which -+ * case we need a complain null_profile and enforce null_profile -+ * -+ * The null_complain_profile cannot be statically allocated, because it -+ * can be associated to files which keep their reference even if subdomain is -+ * unloaded -+ */ -+struct sdprofile *null_complain_profile; -+ -+/*************************** -+ * PRIVATE UTILITY FUNCTIONS -+ **************************/ -+ -+/** -+ * sd_taskattr_access: -+ * @name: name of file to check permission -+ * @mask: permission mask requested for file -+ * -+ * Determine if request is for write access to /proc/self/attr/current -+ */ -+static inline int sd_taskattr_access(const char *procrelname) -+{ -+/* -+ * assumes a 32bit pid, which requires max 10 decimal digits to represent -+ * sizeof includes trailing \0 -+ */ -+ char buf[sizeof("/attr/current") + 10]; -+ const int maxbuflen = sizeof(buf); -+ -+ snprintf(buf, maxbuflen, "%d/attr/current", current->pid); -+ buf[maxbuflen - 1] = 0; -+ -+ return strcmp(buf, procrelname) == 0; -+} -+ -+/** -+ * sd_file_mode - get full mode for file entry from profile -+ * @profile: profile -+ * @name: filename -+ */ -+static inline int sd_file_mode(struct sdprofile *profile, const char *name) -+{ -+ struct sd_entry *entry; -+ int mode = 0; -+ -+ SD_DEBUG("%s: %s\n", __FUNCTION__, name); -+ if (!name) { -+ SD_DEBUG("%s: no name\n", __FUNCTION__); -+ goto out; -+ } -+ -+ if (!profile) { -+ SD_DEBUG("%s: no profile\n", __FUNCTION__); -+ goto out; -+ } -+ list_for_each_entry(entry, &profile->file_entry, list) { -+ if (sdmatch_match(name, entry->filename, -+ entry->entry_type, entry->extradata)) -+ mode |= entry->mode; -+ } -+out: -+ return mode; -+} -+ -+/** -+ * sd_get_execmode - calculate what qualifier to apply to an exec -+ * @sd: subdomain to search -+ * @name: name of file to exec -+ * @xmod: pointer to a execution mode bit for the rule that was matched -+ * if the rule has no execuition qualifier {pui} then -+ * SD_MAY_EXEC is returned indicating a naked x -+ * if the has an exec qualifier then only the qualifier bit {pui} -+ * is returned (SD_MAY_EXEC) is not set. -+ * -+ * Returns 0 (false): -+ * if unable to find profile or there are conflicting pattern matches. -+ * *xmod - is not modified -+ * -+ * Returns 1 (true): -+ * if not confined -+ * *xmod = SD_MAY_EXEC -+ * if exec rule matched -+ * if the rule has an execution mode qualifier {pui} then -+ * *xmod = the execution qualifier of the rule {pui} -+ * else -+ * *xmod = SD_MAY_EXEC -+ */ -+static inline int sd_get_execmode(struct subdomain *sd, const char *name, -+ int *xmod) -+{ -+ struct sdprofile *profile; -+ struct sd_entry *entry; -+ struct sd_entry *match = NULL; -+ -+ int pattern_match_invalid = 0, rc = 0; -+ -+ /* not confined */ -+ if (!__sd_is_confined(sd)) { -+ SD_DEBUG("%s: not confined\n", __FUNCTION__); -+ goto not_confined; -+ } -+ -+ profile = sd->active; -+ -+ /* search list of profiles with 'x' permission -+ * this will also include entries with 'p', 'u' and 'i' -+ * qualifiers. -+ * -+ * If we find a pattern match we will keep looking for an exact match -+ * If we find conflicting pattern matches we will flag (while still -+ * looking for an exact match). If all we have is a conflict, FALSE -+ * is returned. -+ */ -+ -+ list_for_each_entry(entry, &profile->file_entryp[POS_SD_MAY_EXEC], -+ listp[POS_SD_MAY_EXEC]) { -+ if (!pattern_match_invalid && -+ entry->entry_type == sd_entry_pattern && -+ sdmatch_match(name, entry->filename, -+ entry->entry_type, entry->extradata)) { -+ if (match && -+ SD_EXEC_MASK(entry->mode) != -+ SD_EXEC_MASK(match->mode)) -+ pattern_match_invalid = 1; -+ else -+ /* keep searching for an exact match */ -+ match = entry; -+ } else if ((entry->entry_type == sd_entry_literal || -+ (!pattern_match_invalid && -+ entry->entry_type == sd_entry_tailglob)) && -+ sdmatch_match(name, entry->filename, -+ entry->entry_type, -+ entry->extradata)) { -+ if (entry->entry_type == sd_entry_literal) { -+ /* got an exact match -- there can be only -+ * one, asserted at profile load time -+ */ -+ match = entry; -+ pattern_match_invalid = 0; -+ break; -+ } else { -+ if (match && -+ SD_EXEC_MASK(entry->mode) != -+ SD_EXEC_MASK(match->mode)) -+ pattern_match_invalid = 1; -+ else -+ /* got a tailglob match, keep searching -+ * for an exact match -+ */ -+ match = entry; -+ } -+ } -+ -+ } -+ -+ rc = match && !pattern_match_invalid; -+ -+ if (rc) { -+ int mode = SD_EXEC_MASK(match->mode); -+ -+ /* check for qualifiers, if present -+ * we just return the qualifier -+ */ -+ if (mode & ~SD_MAY_EXEC) -+ mode = mode & ~SD_MAY_EXEC; -+ -+ *xmod = mode; -+ } else if (!match) { -+ SD_DEBUG("%s: Unable to find execute entry in profile " -+ "for image '%s'\n", -+ __FUNCTION__, -+ name); -+ } else if (pattern_match_invalid) { -+ SD_WARN("%s: Inconsistency in profile %s. " -+ "Two (or more) patterns specify conflicting exec " -+ "qualifiers ('u', 'i' or 'p') for image %s\n", -+ __FUNCTION__, -+ sd->active->name, -+ name); -+ } -+ -+ return rc; -+ -+not_confined: -+ *xmod = SD_MAY_EXEC; -+ return 1; -+} -+ -+/** -+ * sd_filter_mask -+ * @mask: requested mask -+ * @inode: potential directory inode -+ * -+ * This fn performs pre-verification of the requested mask -+ * We ignore append. Previously we required 'w' on a dir to add a file. -+ * No longer. Now we require 'w' on just the file itself. Traversal 'x' is -+ * also ignored for directories. -+ * -+ * Returned value of 0 indicates no need to perform a perm check. -+ */ -+static inline int sd_filter_mask(int mask, struct inode *inode) -+{ -+ if (mask) { -+ int elim = MAY_APPEND; -+ -+ if (inode && S_ISDIR(inode->i_mode)) -+ elim |= (MAY_EXEC | MAY_WRITE); -+ -+ mask &= ~elim; -+ } -+ -+ return mask; -+} -+ -+static inline void sd_permerror2result(int perm_result, struct sd_audit *sa) -+{ -+ if (perm_result == 0) { /* success */ -+ sa->result = 1; -+ sa->errorcode = 0; -+ } else { /* -ve internal error code or +ve mask of denied perms */ -+ sa->result = 0; -+ sa->errorcode = perm_result; -+ } -+} -+ -+/************************* -+ * MAIN INTERNAL FUNCTIONS -+ ************************/ -+ -+/** -+ * sd_file_perm - calculate access mode for file -+ * @subdomain: current subdomain -+ * @name: name of file to calculate mode for -+ * @mask: permission mask requested for file -+ * -+ * Search the sd_entry list in @profile. -+ * Search looking to verify all permissions passed in mask. -+ * Perform the search by looking at the partitioned list of entries, one -+ * partition per permission bit. -+ * -+ * Return 0 on success, else mask of non-allowed permissions -+ */ -+static unsigned int sd_file_perm(struct subdomain *sd, const char *name, -+ int mask) -+{ -+ struct sdprofile *profile; -+ int i, error = 0, mode; -+ -+#define PROCPFX "/proc/" -+#define PROCLEN sizeof(PROCPFX) - 1 -+ -+ SD_DEBUG("%s: %s 0x%x\n", __FUNCTION__, name, mask); -+ -+ /* should not enter with other than R/W/X/L */ -+ BUG_ON(mask & -+ ~(SD_MAY_READ | SD_MAY_WRITE | SD_MAY_EXEC | SD_MAY_LINK)); -+ -+ /* not confined */ -+ if (!__sd_is_confined(sd)) { -+ /* exit with access allowed */ -+ SD_DEBUG("%s: not confined\n", __FUNCTION__); -+ goto done; -+ } -+ -+ /* Special case access to /proc/self/attr/current -+ * Currently we only allow access if opened O_WRONLY -+ */ -+ if (mask == MAY_WRITE && strncmp(PROCPFX, name, PROCLEN) == 0 && -+ (!list_empty(&sd->profile->sub) || SUBDOMAIN_COMPLAIN(sd)) && -+ sd_taskattr_access(name + PROCLEN)) -+ goto done; -+ -+ profile = sd->active; -+ -+ mode = 0; -+ -+ /* iterate over partition, one permission bit at a time */ -+ for (i = 0; i <= POS_SD_FILE_MAX; i++) { -+ struct sd_entry *entry; -+ -+ /* do we have to accumulate this bit? -+ * or have we already accumulated it (shortcut below)? */ -+ if (!(mask & (1 << i)) || mode & (1 << i)) -+ continue; -+ -+ list_for_each_entry(entry, &profile->file_entryp[i], -+ listp[i]) { -+ if (sdmatch_match(name, entry->filename, -+ entry->entry_type, entry->extradata)) { -+ /* Shortcut, accumulate all bits present */ -+ mode |= entry->mode; -+ -+ /* -+ * Mask bits are overloaded -+ * MAY_{EXEC,WRITE,READ,APPEND} are used by -+ * kernel, other values are used locally only. -+ */ -+ if ((mode & mask) == mask) { -+ SD_DEBUG("MATCH! %s=0x%x [total mode=0x%x]\n", -+ name, mask, mode); -+ -+ goto done; -+ } -+ } -+ } -+ } -+ -+ /* return permissions not satisfied */ -+ error = mask & ~mode; -+ -+done: -+ return error; -+} -+ -+/** -+ * sd_link_perm - test permission to link to a file -+ * @sd: current subdomain -+ * @link: name of link being created -+ * @target: name of target to be linked to -+ * -+ * Look up permission mode on both @link and @target. @link must have same -+ * permission mode as @target. At least @link must have the link bit enabled. -+ * Return 0 on success, error otherwise. -+ */ -+static int sd_link_perm(struct subdomain *sd, -+ const char *link, const char *target) -+{ -+ int l_mode, t_mode, ret; -+ struct sdprofile *profile = sd->active; -+ -+ l_mode = sd_file_mode(profile, link); -+ if (l_mode & SD_MAY_LINK) { -+ /* mask off link bit */ -+ l_mode &= ~SD_MAY_LINK; -+ -+ t_mode = sd_file_mode(profile, target); -+ t_mode &= ~SD_MAY_LINK; -+ -+ ret = (l_mode == t_mode); -+ } else { -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+/** -+ * _sd_perm_dentry -+ * @sd: current subdomain -+ * @dentry: requested dentry -+ * @mask: mask of requested operations -+ * @pname: pointer to hold matched pathname (if any) -+ * -+ * Helper function. Obtain pathname for specified dentry. Verify if profile -+ * authorizes mask operations on pathname (due to lack of vfsmnt it is sadly -+ * necessary to search mountpoints in namespace -- when nameidata is passed -+ * more fully, this code can go away). If more than one mountpoint matches -+ * but none satisfy the profile, only the first pathname (mountpoint) is -+ * returned for subsequent logging. -+ * -+ * Return 0 (success), +ve (mask of permissions not satisfied) or -ve (system -+ * error, most likely -ENOMEM). -+ */ -+static int _sd_perm_dentry(struct subdomain *sd, struct dentry *dentry, -+ int mask, const char **pname) -+{ -+ char *name = NULL, *failed_name = NULL; -+ struct sd_path_data data; -+ int error = 0, failed_error = 0, sdpath_error, -+ sdcomplain = SUBDOMAIN_COMPLAIN(sd); -+ -+ /* search all paths to dentry */ -+ -+ sd_path_begin(dentry, &data); -+ do { -+ name = sd_path_getname(&data); -+ if (name) { -+ /* error here is 0 (success) or +ve (mask of perms) */ -+ error = sd_file_perm(sd, name, mask); -+ -+ /* access via any path is enough */ -+ if (sdcomplain || error == 0) -+ break; /* Caller must free name */ -+ -+ /* Already have an path that failed? */ -+ if (failed_name) { -+ sd_put_name(name); -+ } else { -+ failed_name = name; -+ failed_error = error; -+ } -+ } -+ } while (name); -+ -+ if ((sdpath_error = sd_path_end(&data)) != 0) { -+ SD_ERROR("%s: An error occured while translating dentry %p " -+ "inode# %lu to a pathname. Error %d\n", -+ __FUNCTION__, -+ dentry, -+ dentry->d_inode->i_ino, -+ sdpath_error); -+ -+ WARN_ON(name); /* name should not be set if error */ -+ error = sdpath_error; -+ name = NULL; -+ } else if (name) { -+ if (failed_name) -+ sd_put_name(failed_name); -+ } else { -+ name = failed_name; -+ error = failed_error; -+ } -+ -+ *pname = name; -+ -+ return error; -+} -+ -+/************************** -+ * GLOBAL UTILITY FUNCTIONS -+ *************************/ -+ -+/** -+ * alloc_nullprofiles - Allocate null profiles -+ */ -+int alloc_nullprofiles(void) -+{ -+ null_profile = alloc_sdprofile(); -+ null_complain_profile = alloc_sdprofile(); -+ -+ if (!null_profile || !null_complain_profile) -+ goto fail; -+ -+ null_profile->name = kstrdup("null-profile", GFP_KERNEL); -+ null_complain_profile->name = -+ kstrdup("null-complain-profile", GFP_KERNEL); -+ -+ if (!null_profile->name || -+ !null_complain_profile->name) -+ goto fail; -+ -+ get_sdprofile(null_profile); -+ get_sdprofile(null_complain_profile); -+ null_complain_profile->flags.complain = 1; -+ -+ return 1; -+ -+fail: -+ /* free_sdprofile is safe for freeing partially constructed objects */ -+ free_sdprofile(null_profile); -+ free_sdprofile(null_complain_profile); -+ null_profile = null_complain_profile = NULL; -+ return 0; -+} -+ -+/** -+ * free_nullprofiles - Free null profiles -+ */ -+void free_nullprofiles(void) -+{ -+ put_sdprofile(null_complain_profile); -+ put_sdprofile(null_profile); -+ null_profile = null_complain_profile = NULL; -+} -+ -+/** -+ * sd_audit_message - Log a message to the audit subsystem -+ * @sd: current subdomain -+ * @gfp: allocation flags -+ * @flags: audit flags -+ * @fmt: varargs fmt -+ */ -+int sd_audit_message(struct subdomain *sd, unsigned int gfp, int flags, -+ const char *fmt, ...) -+{ -+ int ret; -+ struct sd_audit sa; -+ -+ sa.type = SD_AUDITTYPE_MSG; -+ sa.name = fmt; -+ va_start(sa.vaval, fmt); -+ sa.flags = flags; -+ sa.gfp_mask = gfp; -+ sa.errorcode = 0; -+ sa.result = 0; /* fake failure: force message to be logged */ -+ -+ ret = sd_audit(sd, &sa); -+ -+ va_end(sa.vaval); -+ -+ return ret; -+} -+ -+/** -+ * sd_audit_syscallreject - Log a syscall rejection to the audit subsystem -+ * @sd: current subdomain -+ * @msg: string describing syscall being rejected -+ * @gfp: memory allocation flags -+ */ -+int sd_audit_syscallreject(struct subdomain *sd, unsigned int gfp, -+ const char *msg) -+{ -+ struct sd_audit sa; -+ -+ sa.type = SD_AUDITTYPE_SYSCALL; -+ sa.name = msg; -+ sa.flags = 0; -+ sa.gfp_mask = gfp; -+ sa.errorcode = 0; -+ sa.result = 0; /* failure */ -+ -+ return sd_audit(sd, &sa); -+} -+ -+/** -+ * sd_audit - Log an audit event to the audit subsystem -+ * @sd: current subdomain -+ * @sa: audit event -+ */ -+int sd_audit(struct subdomain *sd, const struct sd_audit *sa) -+{ -+ struct audit_buffer *ab = NULL; -+ struct audit_context *ctx; -+ -+ const char *logcls; -+ unsigned int flags; -+ int sdaudit = 0, -+ sdcomplain = 0, -+ error = -EINVAL, -+ opspec_error = -EACCES; -+ -+ const unsigned int gfp_mask = sa->gfp_mask; -+ -+ WARN_ON(sa->type >= SD_AUDITTYPE__END); -+ -+ /* -+ * sa->result: 1 success, 0 failure -+ * sa->errorcode: success: 0 -+ * failure: +ve mask of failed permissions or -ve -+ * system error -+ */ -+ -+ if (likely(sa->result)) { -+ if (likely(!SUBDOMAIN_AUDIT(sd))) { -+ /* nothing to log */ -+ error = 0; -+ goto out; -+ } else { -+ sdaudit = 1; -+ logcls = "AUDITING"; -+ } -+ } else if (sa->errorcode < 0) { -+ audit_log(current->audit_context, gfp_mask, AUDIT_SD, -+ "Internal error auditing event type %d (error %d)\n", -+ sa->type, sa->errorcode); -+ SD_ERROR("Internal error auditing event type %d (error %d)\n", -+ sa->type, sa->errorcode); -+ error = sa->errorcode; -+ goto out; -+ } else if (sa->type == SD_AUDITTYPE_SYSCALL) { -+ /* Currently SD_AUDITTYPE_SYSCALL is for rejects only. -+ * Values set by sd_audit_syscallreject will get us here. -+ */ -+ logcls = "REJECTING"; -+ } else { -+ sdcomplain = SUBDOMAIN_COMPLAIN(sd); -+ logcls = sdcomplain ? "PERMITTING" : "REJECTING"; -+ } -+ -+ /* In future extend w/ per-profile flags -+ * (flags |= sa->active->flags) -+ */ -+ flags = sa->flags; -+ if (subdomain_logsyscall) -+ flags |= SD_AUDITFLAG_AUDITSS_SYSCALL; -+ -+ -+ /* Force full audit syscall logging regardless of global setting if -+ * we are rejecting a syscall -+ */ -+ if (sa->type == SD_AUDITTYPE_SYSCALL) { -+ ctx = current->audit_context; -+ } else { -+ ctx = (flags & SD_AUDITFLAG_AUDITSS_SYSCALL) ? -+ current->audit_context : NULL; -+ } -+ -+ ab = audit_log_start(ctx, gfp_mask, AUDIT_SD); -+ -+ if (!ab) { -+ SD_ERROR("Unable to log event (%d) to audit subsys\n", -+ sa->type); -+ if (sdcomplain) -+ error = 0; -+ goto out; -+ } -+ -+ /* messages get special handling */ -+ if (sa->type == SD_AUDITTYPE_MSG) { -+ audit_log_vformat(ab, sa->name, sa->vaval); -+ audit_log_end(ab); -+ error = 0; -+ goto out; -+ } -+ -+ /* log operation */ -+ -+ audit_log_format(ab, "%s ", logcls); /* REJECTING/ALLOWING/etc */ -+ -+ if (sa->type == SD_AUDITTYPE_FILE) { -+ int perm = sdaudit ? sa->ival : sa->errorcode; -+ -+ audit_log_format(ab, "%s%s%s%s access to %s ", -+ perm & SD_MAY_READ ? "r" : "", -+ perm & SD_MAY_WRITE ? "w" : "", -+ perm & SD_MAY_EXEC ? "x" : "", -+ perm & SD_MAY_LINK ? "l" : "", -+ sa->name); -+ -+ opspec_error = -EPERM; -+ -+ } else if (sa->type == SD_AUDITTYPE_DIR) { -+ audit_log_format(ab, "%s on %s ", -+ sa->ival == SD_DIR_MKDIR ? "mkdir" : "rmdir", -+ sa->name); -+ -+ } else if (sa->type == SD_AUDITTYPE_ATTR) { -+ struct iattr *iattr = (struct iattr*)sa->pval; -+ -+ audit_log_format(ab, -+ "attribute (%s%s%s%s%s%s%s) change to %s ", -+ iattr->ia_valid & ATTR_MODE ? "mode," : "", -+ iattr->ia_valid & ATTR_UID ? "uid," : "", -+ iattr->ia_valid & ATTR_GID ? "gid," : "", -+ iattr->ia_valid & ATTR_SIZE ? "size," : "", -+ ((iattr->ia_valid & ATTR_ATIME_SET) || -+ (iattr->ia_valid & ATTR_ATIME)) ? "atime," : "", -+ ((iattr->ia_valid & ATTR_MTIME_SET) || -+ (iattr->ia_valid & ATTR_MTIME)) ? "mtime," : "", -+ iattr->ia_valid & ATTR_CTIME ? "ctime," : "", -+ sa->name); -+ -+ } else if (sa->type == SD_AUDITTYPE_XATTR) { -+ const char *fmt; -+ switch (sa->ival) { -+ case SD_XATTR_GET: -+ fmt = "xattr get"; -+ break; -+ case SD_XATTR_SET: -+ fmt = "xattr set"; -+ break; -+ case SD_XATTR_LIST: -+ fmt = "xattr list"; -+ break; -+ case SD_XATTR_REMOVE: -+ fmt = "xattr remove"; -+ break; -+ default: -+ fmt = "xattr "; -+ break; -+ } -+ -+ audit_log_format(ab, "%s on %s ", fmt, sa->name); -+ -+ } else if (sa->type == SD_AUDITTYPE_LINK) { -+ audit_log_format(ab, -+ "link access from %s to %s ", -+ sa->name, -+ (char*)sa->pval); -+ -+ } else if (sa->type == SD_AUDITTYPE_CAP) { -+ audit_log_format(ab, -+ "access to capability '%s' ", -+ capability_to_name(sa->ival)); -+ -+ opspec_error = -EPERM; -+ } else if (sa->type == SD_AUDITTYPE_SYSCALL) { -+ audit_log_format(ab, "access to syscall '%s' ", sa->name); -+ -+ opspec_error = -EPERM; -+ } else { -+ /* -EINVAL -- will WARN_ON above */ -+ goto out; -+ } -+ -+ audit_log_format(ab, "(%s(%d) ", current->comm, current->pid); -+ -+ if (0) -+ audit_log_format(ab, "[global deny])\n"); -+ else -+ audit_log_format(ab, "profile %s active %s)\n", -+ sd->profile->name, sd->active->name); -+ -+ audit_log_end(ab); -+ -+ if (sdcomplain) -+ error = 0; -+ else -+ error = sa->result ? 0 : opspec_error; -+ -+out: -+ return error; -+} -+ -+/** -+ * sd_get_name - retrieve fully qualified path name -+ * @dentry: relative path element -+ * @mnt: where in tree -+ * -+ * Returns fully qualified path name on sucess, NULL on failure. -+ * sd_put_name must be used to free allocated buffer. -+ */ -+char *sd_get_name(struct dentry *dentry, struct vfsmount *mnt) -+{ -+ char *page, *name = NULL; -+ -+ page = (char *)__get_free_page(GFP_KERNEL); -+ if (!page) -+ goto out; -+ -+ name = d_path(dentry, mnt, page, PAGE_SIZE); -+ -+ /* check for (deleted) that d_path appends to pathnames if the dentry -+ * has been removed from the cache. -+ * The size > deleted_size and strcmp checks are redundant safe guards. -+ */ -+ if (name) { -+ const char deleted_str[] = " (deleted)"; -+ const size_t deleted_size = sizeof(deleted_str) - 1; -+ size_t size; -+ size = strlen(name); -+ if (!IS_ROOT(dentry) && d_unhashed(dentry) && -+ size > deleted_size && -+ strcmp(name + size - deleted_size, deleted_str) == 0) -+ name[size - deleted_size] = '\0'; -+ } -+ SD_DEBUG("%s: full_path=%s\n", __FUNCTION__, name); -+out: -+ return name; -+} -+ -+/*********************************** -+ * GLOBAL PERMISSION CHECK FUNCTIONS -+ ***********************************/ -+ -+/** -+ * sd_attr - check whether attribute change allowed -+ * @sd: subdomain to check against to check against -+ * @dentry: file to check -+ * @iattr: attribute changes requested -+ */ -+int sd_attr(struct subdomain *sd, struct dentry *dentry, struct iattr *iattr) -+{ -+ int error = 0, permerror; -+ struct sd_audit sa; -+ -+ if (!__sd_is_confined(sd)) -+ goto out; -+ -+ sa.type = SD_AUDITTYPE_ATTR; -+ sa.pval = iattr; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = _sd_perm_dentry(sd, dentry, MAY_WRITE, &sa.name); -+ sd_permerror2result(permerror, &sa); -+ -+ error = sd_audit(sd, &sa); -+ -+ sd_put_name(sa.name); -+ -+out: -+ return error; -+} -+ -+int sd_xattr(struct subdomain *sd, struct dentry *dentry, const char *xattr, -+ int xattroptype) -+{ -+ int error = 0, permerror, mask = 0; -+ struct sd_audit sa; -+ -+ /* if not confined or empty mask permission granted */ -+ if (!__sd_is_confined(sd)) -+ goto out; -+ -+ if (xattroptype == SD_XATTR_GET || xattroptype == SD_XATTR_LIST) -+ mask = MAY_READ; -+ else if (xattroptype == SD_XATTR_SET || xattroptype == SD_XATTR_REMOVE) -+ mask = MAY_WRITE; -+ -+ sa.type = SD_AUDITTYPE_XATTR; -+ sa.ival = xattroptype; -+ sa.pval = xattr; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = _sd_perm_dentry(sd, dentry, mask, &sa.name); -+ sd_permerror2result(permerror, &sa); -+ -+ error = sd_audit(sd, &sa); -+ -+ sd_put_name(sa.name); -+ -+out: -+ return error; -+} -+ -+/** -+ * sd_perm - basic subdomain permissions check -+ * @sd: subdomain to check against -+ * @dentry: dentry -+ * @mnt: mountpoint -+ * @mask: access mode requested -+ * -+ * Determine if access (mask) for dentry is authorized by subdomain sd. -+ * Result, 0 (success), -ve (error) -+ */ -+int sd_perm(struct subdomain *sd, struct dentry *dentry, struct vfsmount *mnt, -+ int mask) -+{ -+ int error = 0, permerror; -+ struct sd_audit sa; -+ -+ if (!__sd_is_confined(sd)) -+ goto out; -+ -+ if ((mask = sd_filter_mask(mask, dentry->d_inode)) == 0) -+ goto out; -+ -+ sa.type = SD_AUDITTYPE_FILE; -+ sa.name = sd_get_name(dentry, mnt); -+ sa.ival = mask; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = (sa.name ? sd_file_perm(sd, sa.name, mask) : -ENOMEM); -+ -+ sd_permerror2result(permerror, &sa); -+ -+ error = sd_audit(sd, &sa); -+ -+ sd_put_name(sa.name); -+ -+out: -+ return error; -+} -+ -+/** -+ * sd_perm_nameidata: interface to sd_perm accepting nameidata -+ * @sd: subdomain to check against -+ * @nd: namespace data (for vfsmnt and dentry) -+ * @mask: access mode requested -+ */ -+int sd_perm_nameidata(struct subdomain *sd, struct nameidata *nd, int mask) -+{ -+ int error = 0; -+ -+ if (nd) -+ error = sd_perm(sd, nd->dentry, nd->mnt, mask); -+ -+ return error; -+} -+ -+/** -+ * sd_perm_dentry - file permissions interface when no vfsmnt available -+ * @sd: current subdomain -+ * @dentry: requested dentry -+ * @mask: access mode requested -+ * -+ * Determine if access (mask) for dentry is authorized by subdomain sd. -+ * Result, 0 (success), -ve (error) -+ */ -+int sd_perm_dentry(struct subdomain *sd, struct dentry *dentry, int mask) -+{ -+ int error = 0, permerror; -+ struct sd_audit sa; -+ -+ if (!__sd_is_confined(sd)) -+ goto out; -+ -+ if ((mask = sd_filter_mask(mask, dentry->d_inode)) == 0) -+ goto out; -+ -+ sa.type = SD_AUDITTYPE_FILE; -+ sa.ival = mask; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = _sd_perm_dentry(sd, dentry, mask, &sa.name); -+ sd_permerror2result(permerror, &sa); -+ -+ error = sd_audit(sd, &sa); -+ -+ sd_put_name(sa.name); -+ -+out: -+ return error; -+} -+ -+/** -+ * sd_perm_dir -+ * @sd: current subdomain -+ * @dentry: requested dentry -+ * @mode: SD_DIR_MKDIR or SD_DIR_RMDIR -+ * -+ * Determine if directory operation (make/remove) for dentry is authorized -+ * by subdomain sd. -+ * Result, 0 (success), -ve (error) -+ */ -+int sd_perm_dir(struct subdomain *sd, struct dentry *dentry, int diroptype) -+{ -+ int error = 0, permerror, mask; -+ struct sd_audit sa; -+ -+ BUG_ON(diroptype != SD_DIR_MKDIR && diroptype != SD_DIR_RMDIR); -+ -+ if (!__sd_is_confined(sd)) -+ goto out; -+ -+ mask = MAY_WRITE; -+ -+ sa.type = SD_AUDITTYPE_DIR; -+ sa.ival = diroptype; -+ sa.flags = 0; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ permerror = _sd_perm_dentry(sd, dentry, mask, &sa.name); -+ sd_permerror2result(permerror, &sa); -+ -+ error = sd_audit(sd, &sa); -+ -+ sd_put_name(sa.name); -+ -+out: -+ return error; -+} -+ -+/** -+ * sd_capability - test permission to use capability -+ * @sd: subdomain to check against -+ * @cap: capability to be tested -+ * -+ * Look up capability in active profile capability set. -+ * Return 0 (success), -EPERM (error) -+ */ -+int sd_capability(struct subdomain *sd, int cap) -+{ -+ int error = 0; -+ -+ if (__sd_is_confined(sd)) { -+ struct sd_audit sa; -+ -+ sa.type = SD_AUDITTYPE_CAP; -+ sa.name = NULL; -+ sa.ival = cap; -+ sa.flags = 0; -+ sa.errorcode = 0; -+ sa.result = cap_raised(sd->active->capabilities, cap); -+ sa.gfp_mask = GFP_ATOMIC; -+ -+ error = sd_audit(sd, &sa); -+ } -+ -+ return error; -+} -+ -+/** -+ * sd_link - hard link check -+ * @link: dentry for link being created -+ * @target: dentry for link target -+ * @sd: subdomain to check against -+ * -+ * Checks link permissions for all possible name combinations. This is -+ * particularly ugly. Returns 0 on sucess, error otherwise. -+ */ -+int sd_link(struct subdomain *sd, struct dentry *link, struct dentry *target) -+{ -+ char *iname = NULL, *oname = NULL, -+ *failed_iname = NULL, *failed_oname = NULL; -+ unsigned int result = 0; -+ int error, sdpath_error, errorcode = 0, match = 0, -+ sdcomplain = SUBDOMAIN_COMPLAIN(sd); -+ struct sd_path_data idata, odata; -+ struct sd_audit sa; -+ -+ if (!__sd_is_confined(sd)) -+ return 0; -+ -+ /* Perform nested lookup for names. -+ * This is necessary in the case where /dev/block is mounted -+ * multiple times, i.e /dev/block->/a and /dev/block->/b -+ * This allows us to detect links where src/dest are on different -+ * mounts. N.B no support yet for links across bind mounts of -+ * the form mount -bind /mnt/subpath /mnt2 -+ * -+ * Getting direct access to vfsmounts (via nameidata) for link and -+ * target would allow all this uglyness to go away. -+ * -+ * If more than one mountpoint matches but none satisfy the profile, -+ * only the first pathname (mountpoint) is logged. -+ */ -+ -+ sd_path_begin2(target, link, &odata); -+ do { -+ oname = sd_path_getname(&odata); -+ if (oname) { -+ sd_path_begin(target, &idata); -+ do { -+ iname = sd_path_getname(&idata); -+ if (iname) { -+ result = sd_link_perm(sd, oname, iname); -+ -+ /* access via any path is enough */ -+ if (result || sdcomplain) { -+ match = 1; -+ break; -+ } -+ -+ /* Already have an path that failed? */ -+ if (failed_iname) { -+ sd_put_name(iname); -+ } else { -+ failed_iname = iname; -+ failed_oname = oname; -+ } -+ } -+ } while (iname && !match); -+ -+ /* should not be possible if we matched */ -+ if ((sdpath_error = sd_path_end(&idata)) != 0) { -+ SD_ERROR("%s: An error occured while " -+ "translating inner dentry %p " -+ "inode %lu to a pathname. Error %d\n", -+ __FUNCTION__, -+ target, -+ target->d_inode->i_ino, -+ sdpath_error); -+ -+ /* name should not be set if error */ -+ WARN_ON(iname); -+ -+ errorcode = sdpath_error; -+ } -+ -+ /* don't release if we're saving it */ -+ if (!match && failed_oname != oname) -+ sd_put_name(oname); -+ } -+ } while (oname && !match); -+ -+ if (errorcode != 0) { -+ /* inner error */ -+ (void)sd_path_end(&odata); -+ } else if ((sdpath_error = sd_path_end(&odata)) != 0) { -+ SD_ERROR("%s: An error occured while translating outer " -+ "dentry %p inode %lu to a pathname. Error %d\n", -+ __FUNCTION__, -+ link, -+ link->d_inode->i_ino, -+ sdpath_error); -+ -+ errorcode = sdpath_error; -+ } -+ -+ if (errorcode != 0) { -+ /* inner or outer error */ -+ result = 0; -+ } else if (match) { -+ result = 1; -+ } else { -+ /* failed to match */ -+ WARN_ON(iname); -+ WARN_ON(oname); -+ -+ result = 0; -+ iname = failed_iname; -+ oname = failed_oname; -+ } -+ -+ sa.type = SD_AUDITTYPE_LINK; -+ sa.name = oname; /* link */ -+ sa.pval = iname; /* target */ -+ sa.flags = 0; -+ sa.errorcode = errorcode; -+ sa.result = result; -+ sa.gfp_mask = GFP_KERNEL; -+ -+ error = sd_audit(sd, &sa); -+ -+ if (failed_oname != oname) -+ sd_put_name(failed_oname); -+ if (failed_iname != iname) -+ sd_put_name(failed_iname); -+ -+ sd_put_name(oname); -+ sd_put_name(iname); -+ -+ return error; -+} -+ -+/********************************** -+ * GLOBAL PROCESS RELATED FUNCTIONS -+ *********************************/ -+ -+/** -+ * sd_fork - create a new subdomain -+ * @p: new process -+ * -+ * Create a new subdomain struct for the newly created process @p. -+ * Copy parent info to child. If parent has no subdomain, child -+ * will get one with NULL values. Return 0 on sucess. -+ */ -+ -+int sd_fork(struct task_struct *p) -+{ -+ struct subdomain *sd = SD_SUBDOMAIN(current->security); -+ struct subdomain *newsd = alloc_subdomain(p); -+ -+ SD_DEBUG("%s\n", __FUNCTION__); -+ -+ if (!newsd) -+ return -ENOMEM; -+ -+ if (sd) { -+ unsigned long flags; -+ -+ /* Can get away with a read rather than write lock here -+ * as we just allocated newsd above, so we can guarantee -+ * that it's active/profile are null and therefore a replace -+ * cannot happen. -+ */ -+ read_lock_irqsave(&sd_lock, flags); -+ sd_switch(newsd, sd->profile, sd->active); -+ newsd->sd_hat_magic = sd->sd_hat_magic; -+ read_unlock_irqrestore(&sd_lock, flags); -+ -+ if (SUBDOMAIN_COMPLAIN(sd) && -+ sd->active == null_complain_profile) -+ LOG_HINT(sd, GFP_KERNEL, HINT_FORK, -+ "pid=%d child=%d\n", -+ current->pid, p->pid); -+ } -+ p->security = newsd; -+ return 0; -+} -+ -+/** -+ * sd_register - register a new program -+ * @filp: file of program being registered -+ * -+ * Try to register a new program during execve(). This should give the -+ * new program a valid subdomain. -+ * -+ * This _used_ to be a really simple piece of code :-( -+ * -+ */ -+int sd_register(struct file *filp) -+{ -+ char *filename; -+ struct subdomain *sd, sdcopy; -+ struct sdprofile *newprofile = NULL, unconstrained_flag; -+ int error = -ENOMEM, -+ exec_mode = 0, -+ findprofile = 0, -+ findprofile_mandatory = 0, -+ issdcopy = 1, -+ complain = 0; -+ -+ SD_DEBUG("%s\n", __FUNCTION__); -+ -+ sd = get_sdcopy(&sdcopy); -+ -+ if (sd) { -+ complain = SUBDOMAIN_COMPLAIN(sd); -+ } else { -+ /* task has no subdomain. This can happen when a task is -+ * created when subdomain is not loaded. Allocate and -+ * attach a subdomain to the task -+ */ -+ issdcopy = 0; -+ -+ sd = alloc_subdomain(current); -+ if (!sd) { -+ SD_WARN("%s: Failed to allocate subdomain\n", -+ __FUNCTION__); -+ goto out; -+ } -+ -+ current->security = sd; -+ } -+ -+ filename = sd_get_name(filp->f_dentry, filp->f_vfsmnt); -+ if (!filename) { -+ SD_WARN("%s: Failed to get filename\n", __FUNCTION__); -+ goto out; -+ } -+ -+ error = 0; -+ -+ if (!__sd_is_confined(sd)) { -+ /* Unconfined task, load profile if it exists */ -+ findprofile = 1; -+ goto find_profile; -+ } -+ -+ /* Confined task, determine what mode inherit, unconstrained or -+ * mandatory to load new profile -+ */ -+ if (sd_get_execmode(sd, filename, &exec_mode)) { -+ switch (exec_mode) { -+ case SD_EXEC_INHERIT: -+ /* do nothing - setting of profile -+ * already handed in sd_fork -+ */ -+ SD_DEBUG("%s: INHERIT %s\n", -+ __FUNCTION__, -+ filename); -+ break; -+ -+ case SD_EXEC_UNCONSTRAINED: -+ SD_DEBUG("%s: UNCONSTRAINED %s\n", -+ __FUNCTION__, -+ filename); -+ -+ /* unload profile */ -+ newprofile = &unconstrained_flag; -+ break; -+ -+ case SD_EXEC_PROFILE: -+ SD_DEBUG("%s: PROFILE %s\n", -+ __FUNCTION__, -+ filename); -+ -+ findprofile = 1; -+ findprofile_mandatory = 1; -+ break; -+ -+ case SD_MAY_EXEC: -+ /* this should not happen, entries -+ * with just EXEC only should be -+ * rejected at profile load time -+ */ -+ SD_ERROR("%s: Rejecting exec(2) of image '%s'. " -+ "SD_MAY_EXEC without exec qualifier invalid " -+ "(%s(%d) profile %s active %s\n", -+ __FUNCTION__, -+ filename, -+ current->comm, current->pid, -+ sd->profile->name, sd->active->name); -+ error = -EPERM; -+ break; -+ -+ default: -+ SD_ERROR("%s: Rejecting exec(2) of image '%s'. " -+ "Unknown exec qualifier %x " -+ "(%s (pid %d) profile %s active %s)\n", -+ __FUNCTION__, -+ filename, -+ exec_mode, -+ current->comm, current->pid, -+ sd->profile->name, sd->active->name); -+ error = -EPERM; -+ break; -+ } -+ -+ } else if (complain) { -+ /* There was no entry in calling profile -+ * describing mode to execute image in. -+ * Drop into null-profile -+ */ -+ newprofile = get_sdprofile(null_complain_profile); -+ } else { -+ SD_WARN("%s: Rejecting exec(2) of image '%s'. " -+ "Unable to determine exec qualifier " -+ "(%s (pid %d) profile %s active %s)\n", -+ __FUNCTION__, -+ filename, -+ current->comm, current->pid, -+ sd->profile->name, sd->active->name); -+ error = -EPERM; -+ } -+ -+ -+find_profile: -+ if (!findprofile) -+ goto apply_profile; -+ -+ /* Locate new profile */ -+ newprofile = sd_profilelist_find(filename); -+ if (newprofile) { -+ SD_DEBUG("%s: setting profile %s\n", -+ __FUNCTION__, newprofile->name); -+ } else if (findprofile_mandatory) { -+ /* Profile (mandatory) could not be found */ -+ -+ if (complain) { -+ LOG_HINT(sd, GFP_KERNEL, HINT_MANDPROF, -+ "image=%s pid=%d profile=%s active=%s\n", -+ filename, -+ current->pid, -+ sd->profile->name, -+ sd->active->name); -+ -+ newprofile = get_sdprofile(null_complain_profile); -+ } else { -+ SD_WARN("REJECTING exec(2) of image '%s'. " -+ "Profile mandatory and not found " -+ "(%s(%d) profile %s active %s)\n", -+ filename, -+ current->comm, current->pid, -+ sd->profile->name, sd->active->name); -+ error = -EPERM; -+ } -+ } else { -+ /* Profile (non-mandatory) could not be found */ -+ -+ /* Only way we can get into this code is if task -+ * is unconstrained. -+ */ -+ -+ BUG_ON(__sd_is_confined(sd)); -+ -+ SD_DEBUG("%s: No profile found for exec image %s\n", -+ __FUNCTION__, -+ filename); -+ } /* newprofile */ -+ -+ -+apply_profile: -+ /* Apply profile if necessary */ -+ if (newprofile) { -+ struct subdomain *latest_sd; -+ unsigned long flags; -+ -+ if (newprofile == &unconstrained_flag) -+ newprofile = NULL; -+ -+ /* grab a write lock -+ * -+ * Several things may have changed since the code above -+ * -+ * - If we are a confined process, sd is a refcounted copy of -+ * the subdomain (get_sdcopy) and not the actual subdomain. -+ * This allows us to not have to hold a read lock around -+ * all this code. However, we need to change the actual -+ * subdomain, not the copy. Also, if profile replacement -+ * has taken place, our sd->profile may be inaccurate -+ * so we need to undo the copy and reverse the refcounting. -+ * -+ * - If newprofile points to an actual profile (result of -+ * sd_profilelist_find above), this profile may have been -+ * replaced. We need to fix it up. Doing this to avoid -+ * having to hold a write lock around all this code. -+ */ -+ -+ write_lock_irqsave(&sd_lock, flags); -+ -+ /* task is guaranteed to have a subdomain (->security) -+ * by this point -+ */ -+ latest_sd = SD_SUBDOMAIN(current->security); -+ -+ /* Determine if profile we found earlier is stale. -+ * If so, reobtain it. N.B stale flag should never be -+ * set on null_complain profile. -+ */ -+ if (newprofile && unlikely(newprofile->isstale)) { -+ BUG_ON(newprofile == null_complain_profile); -+ -+ /* drop refcnt obtained from earlier get_sdprofile */ -+ put_sdprofile(newprofile); -+ -+ newprofile = sd_profilelist_find(filename); -+ -+ if (!newprofile) { -+ /* Race, profile was removed, not replaced. -+ * Redo with error checking -+ */ -+ write_unlock_irqrestore(&sd_lock, flags); -+ goto find_profile; -+ } -+ } -+ -+ /* need to drop reference counts we obtained in get_sdcopy -+ * above. Need to do it before overwriting latest_sd, in -+ * case latest_sd == sd (no async replacement has taken place). -+ */ -+ if (issdcopy) { -+ put_sdcopy(sd); -+ issdcopy = 0; -+ } -+ -+ sd_switch(latest_sd, newprofile, newprofile); -+ put_sdprofile(newprofile); -+ -+ if (complain && newprofile == null_complain_profile) -+ LOG_HINT(latest_sd, GFP_ATOMIC, HINT_CHGPROF, -+ "pid=%d\n", -+ current->pid); -+ -+ write_unlock_irqrestore(&sd_lock, flags); -+ } -+ -+ sd_put_name(filename); -+ -+ if (issdcopy) -+ put_sdcopy(sd); -+ -+out: -+ return error; -+} -+ -+/** -+ * sd_release - release the task's subdomain -+ * @p: task being released -+ * -+ * This is called after a task has exited and the parent has reaped it. -+ * @p->security blob is freed. -+ */ -+void sd_release(struct task_struct *p) -+{ -+ struct subdomain *sd = SD_SUBDOMAIN(p->security); -+ if (sd) { -+ p->security = NULL; -+ -+ sd_subdomainlist_remove(sd); -+ -+ /* release profiles */ -+ put_sdprofile(sd->profile); -+ put_sdprofile(sd->active); -+ -+ kfree(sd); -+ } -+} -+ -+/***************************** -+ * GLOBAL SUBPROFILE FUNCTIONS -+ ****************************/ -+ -+/** -+ * do_change_hat - actually switch hats -+ * @name: name of hat to swtich to -+ * @sd: current subdomain -+ * -+ * Switch to a new hat. Return 0 on success, error otherwise. -+ */ -+static inline int do_change_hat(const char *hat_name, struct subdomain *sd) -+{ -+ struct sdprofile *sub; -+ struct sdprofile *p = sd->active; -+ int error = 0; -+ -+ sub = __sd_find_profile(hat_name, &sd->profile->sub); -+ -+ if (sub) { -+ /* change hat */ -+ sd->active = sub; -+ } else { -+ /* There is no such subprofile change to a NULL profile. -+ * The NULL profile grants no file access. -+ * -+ * This feature is used by changehat_apache. -+ * -+ * N.B from the null-profile the task can still changehat back -+ * out to the parent profile (assuming magic != NULL) -+ */ -+ if (SUBDOMAIN_COMPLAIN(sd)) { -+ LOG_HINT(sd, GFP_ATOMIC, HINT_UNKNOWN_HAT, -+ "%s pid=%d " -+ "profile=%s active=%s\n", -+ hat_name, -+ current->pid, -+ sd->profile->name, -+ sd->active->name); -+ sd->active = get_sdprofile(null_complain_profile); -+ } else { -+ SD_DEBUG("%s: Unknown hatname '%s'. " -+ "Changing to NULL profile " -+ "(%s(%d) profile %s active %s)\n", -+ __FUNCTION__, -+ hat_name, -+ current->comm, current->pid, -+ sd->profile->name, sd->active->name); -+ -+ sd->active = get_sdprofile(null_profile); -+ error = -EACCES; -+ } -+ } -+ put_sdprofile(p); -+ -+ return error; -+} -+ -+/** -+ * sd_change_hat - change hat to/from subprofile -+ * @hat_name: specifies hat to change to -+ * @hat_magic: token to validate hat change -+ * -+ * Change to new @hat_name when current hat is top level profile, and store -+ * the @hat_magic in the current subdomain. If the new @hat_name is -+ * NULL, and the @hat_magic matches that stored in the current subdomain -+ * return to original top level profile. Returns 0 on success, error -+ * otherwise. -+ */ -+#define IN_SUBPROFILE(sd) ((sd)->profile != (sd)->active) -+int sd_change_hat(const char *hat_name, __u32 hat_magic) -+{ -+ struct subdomain *sd = SD_SUBDOMAIN(current->security); -+ int error = 0; -+ -+ SD_DEBUG("%s: %p, 0x%x (pid %d)\n", -+ __FUNCTION__, -+ hat_name, hat_magic, -+ current->pid); -+ -+ /* Dump out above debugging in WARN mode if we are in AUDIT mode */ -+ if (SUBDOMAIN_AUDIT(sd)) { -+ SD_WARN("%s: %s, 0x%x (pid %d)\n", -+ __FUNCTION__, hat_name ? hat_name : "NULL", -+ hat_magic, current->pid); -+ } -+ -+ /* no subdomain: changehat into the null_profile, since the process -+ has no subdomain do_change_hat won't find a match which will cause -+ a changehat to null_profile. We could short circuit this but since -+ the subdprofile (hat) list is empty we would save very little. */ -+ -+ /* check to see if an unconfined process is doing a changehat. */ -+ if (!__sd_is_confined(sd)) { -+ error = -EACCES; -+ goto out; -+ } -+ -+ /* Check whether current domain is parent -+ * or one of the sibling children -+ */ -+ if (sd->profile == sd->active) { -+ /* -+ * parent -+ */ -+ if (hat_name) { -+ SD_DEBUG("%s: switching to %s, 0x%x\n", -+ __FUNCTION__, -+ hat_name, -+ hat_magic); -+ -+ /* -+ * N.B hat_magic == 0 has a special meaning -+ * this indicates that the task may never changehat -+ * back to it's parent, it will stay in this subhat -+ * (or null-profile, if the hat doesn't exist) until -+ * the task terminates -+ */ -+ sd->sd_hat_magic = hat_magic; -+ error = do_change_hat(hat_name, sd); -+ } else { -+ /* Got here via changehat(NULL, magic) -+ * -+ * We used to simply update the magic cookie. -+ * That's an odd behaviour, so just do nothing. -+ */ -+ } -+ } else { -+ /* -+ * child -- check to make sure magic is same as what was -+ * passed when we switched into this profile, -+ * Handle special casing of NULL magic which confines task -+ * to subprofile and prohibits further changehats -+ */ -+ if (hat_magic == sd->sd_hat_magic && sd->sd_hat_magic) { -+ if (!hat_name) { -+ /* -+ * Got here via changehat(NULL, magic) -+ * Return from subprofile, back to parent -+ */ -+ put_sdprofile(sd->active); -+ sd->active = get_sdprofile(sd->profile); -+ -+ /* Reset hat_magic to zero. -+ * New value will be passed on next changehat -+ */ -+ sd->sd_hat_magic = 0; -+ } else { -+ /* change to another (sibling) profile */ -+ error = do_change_hat(hat_name, sd); -+ } -+ } else if (sd->sd_hat_magic) { -+ SD_ERROR("KILLING process %s(%d) " -+ "Invalid change_hat() magic# 0x%x " -+ "(hatname %s profile %s active %s)\n", -+ current->comm, current->pid, -+ hat_magic, -+ hat_name ? hat_name : "NULL", -+ sd->profile->name, sd->active->name); -+ -+ /* terminate current process */ -+ (void)send_sig_info(SIGKILL, NULL, current); -+ } else { /* sd->sd_hat_magic == NULL */ -+ SD_ERROR("KILLING process %s(%d) " -+ "Task was confined to current subprofile " -+ "(profile %s active %s)\n", -+ current->comm, current->pid, -+ sd->profile->name, sd->active->name); -+ -+ /* terminate current process */ -+ (void)send_sig_info(SIGKILL, NULL, current); -+ } -+ -+ } -+ -+out: -+ return error; -+} ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/module_interface.c -@@ -0,0 +1,720 @@ -+/* -+ * Copyright (C) 1998-2005 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 userspace policy interface -+ */ -+ -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+#include "module_interface.h" -+#include "aamatch/match.h" -+ -+/* sd_code defined in module_interface.h */ -+ -+const int sdcode_datasize[] = { 1, 2, 4, 8, 2, 2, 4, 0, 0, 0, 0, 0, 0 }; -+ -+struct sd_taskreplace_data { -+ struct sdprofile *old_profile; -+ struct sdprofile *new_profile; -+}; -+ -+/* inlines must be forward of there use in newer version of gcc, -+ just forward declaring with a prototype won't work anymore */ -+ -+static inline void free_sd_entry(struct sd_entry *entry) -+{ -+ if (entry) { -+ kfree(entry->filename); -+ sdmatch_free(entry->extradata); -+ kfree(entry); -+ } -+} -+ -+/** -+ * alloc_sd_entry - create new empty sd_entry -+ * -+ * This routine allocates, initializes, and returns a new subdomain -+ * file entry structure. Structure is zeroed. Returns new structure on -+ * success, NULL on failure. -+ */ -+static inline struct sd_entry *alloc_sd_entry(void) -+{ -+ struct sd_entry *entry; -+ -+ SD_DEBUG("%s\n", __FUNCTION__); -+ entry = kmalloc(sizeof(struct sd_entry), GFP_KERNEL); -+ if (entry) { -+ int i; -+ memset(entry, 0, sizeof(struct sd_entry)); -+ INIT_LIST_HEAD(&entry->list); -+ for (i = 0; i <= POS_SD_FILE_MAX; i++) { -+ INIT_LIST_HEAD(&entry->listp[i]); -+ } -+ } -+ return entry; -+} -+ -+/** -+ * free_sdprofile - free sdprofile structure -+ */ -+void free_sdprofile(struct sdprofile *profile) -+{ -+ struct sd_entry *sdent, *tmp; -+ struct sdprofile *p, *ptmp; -+ -+ SD_DEBUG("%s(%p)\n", __FUNCTION__, profile); -+ -+ if (!profile) -+ return; -+ -+ /* profile is still on global profile list -- invalid */ -+ if (!list_empty(&profile->list)) { -+ SD_ERROR("%s: internal error, " -+ "profile '%s' still on global list\n", -+ __FUNCTION__, -+ profile->name); -+ BUG(); -+ } -+ -+ list_for_each_entry_safe(sdent, tmp, &profile->file_entry, list) { -+ if (sdent->filename) -+ SD_DEBUG("freeing sd_entry: %p %s\n", -+ sdent->filename, sdent->filename); -+ list_del_init(&sdent->list); -+ free_sd_entry(sdent); -+ } -+ -+ list_for_each_entry_safe(p, ptmp, &profile->sub, list) { -+ list_del_init(&p->list); -+ put_sdprofile(p); -+ } -+ -+ if (profile->name) { -+ SD_DEBUG("%s: %s\n", __FUNCTION__, profile->name); -+ kfree(profile->name); -+ } -+ -+ kfree(profile); -+} -+ -+/** task_remove -+ * -+ * remove profile in a task's subdomain leaving the task unconfined -+ * -+ * @sd: task's subdomain -+ */ -+static inline void task_remove(struct subdomain *sd) -+{ -+ /* write_lock(&sd_lock) held here */ -+ SD_DEBUG("%s: removing profile from task %s(%d) profile %s active %s\n", -+ __FUNCTION__, -+ sd->task->comm, -+ sd->task->pid, -+ sd->profile->name, -+ sd->active->name); -+ -+ sd_switch_unconfined(sd); -+} -+ -+/** taskremove_iter -+ * -+ * Iterate over all subdomains. -+ * -+ * If any matches old_profile, then call task_remove to remove it. -+ * This leaves the task (subdomain) unconfined. -+ */ -+static int taskremove_iter(struct subdomain *sd, void *cookie) -+{ -+ struct sdprofile *old_profile = (struct sdprofile *)cookie; -+ int remove = 0; -+ unsigned long flags; -+ -+ write_lock_irqsave(&sd_lock, flags); -+ -+ if (__sd_is_confined(sd) && sd->profile == old_profile) { -+ remove = 1; /* remove item from list */ -+ task_remove(sd); -+ } -+ -+ write_unlock_irqrestore(&sd_lock, flags); -+ -+ return remove; -+} -+ -+/** task_replace -+ * -+ * replace profile in a task's subdomain with newly loaded profile -+ * -+ * @sd: task's subdomain -+ * @new: old profile -+ */ -+static inline void task_replace(struct subdomain *sd, struct sdprofile *new) -+{ -+ struct sdprofile *nactive = NULL; -+ -+ SD_DEBUG("%s: replacing profile for task %s(%d) " -+ "profile=%s (%p) active=%s (%p)\n", -+ __FUNCTION__, -+ sd->task->comm, sd->task->pid, -+ sd->profile->name, sd->profile, -+ sd->active->name, sd->active); -+ -+ if (sd->profile == sd->active) -+ nactive = get_sdprofile(new); -+ else if (sd->active) { -+ /* old in hat, new profile has hats */ -+ nactive = __sd_find_profile(sd->active->name, &new->sub); -+ -+ if (!nactive) { -+ if (new->flags.complain) -+ nactive = get_sdprofile(null_complain_profile); -+ else -+ nactive = get_sdprofile(null_profile); -+ } -+ } -+ sd_switch(sd, new, nactive); -+ -+ put_sdprofile(nactive); -+} -+ -+/** taskreplace_iter -+ * -+ * Iterate over all subdomains. -+ * -+ * If any matches old_profile, then call task_replace to replace with -+ * new_profile -+ */ -+static int taskreplace_iter(struct subdomain *sd, void *cookie) -+{ -+ struct sd_taskreplace_data *data = (struct sd_taskreplace_data *)cookie; -+ unsigned long flags; -+ -+ write_lock_irqsave(&sd_lock, flags); -+ -+ if (__sd_is_confined(sd) && sd->profile == data->old_profile) -+ task_replace(sd, data->new_profile); -+ -+ write_unlock_irqrestore(&sd_lock, flags); -+ -+ return 0; -+} -+ -+static inline int sd_inbounds(struct sd_ext *e, size_t size) -+{ -+ return (e->pos + size <= e->end); -+} -+ -+/** -+ * sdconvert - for codes that have a trailing value, convert that value -+ * and put it in dest. -+ * if a code does not have a trailing value nop -+ * @code: type code -+ * @dest: pointer to object to receive the converted value -+ * @src: pointer to value to convert -+ */ -+static void sdconvert(enum sd_code code, void *dest, void *src) -+{ -+ switch (code) { -+ case SD_U8: -+ *(u8 *)dest = *(u8 *) src; -+ break; -+ case SD_U16: -+ case SD_NAME: -+ case SD_DYN_STRING: -+ *(u16 *)dest = le16_to_cpu(get_unaligned((u16 *)src)); -+ break; -+ case SD_U32: -+ case SD_STATIC_BLOB: -+ *(u32 *)dest = le32_to_cpu(get_unaligned((u32 *)src)); -+ break; -+ case SD_U64: -+ *(u64 *)dest = le64_to_cpu(get_unaligned((u64 *)src)); -+ break; -+ default: -+ /* nop - all other type codes do not have a trailing value */ -+ ; -+ } -+} -+ -+/** -+ * sd_is_X - check if the next element is of type X and if it is within -+ * bounds. If it is put the associated value in data. -+ * @e: extent information -+ * @code: type code -+ * @data: object located at @e->pos (of type @code) is written into @data -+ * if @data is non-null. if data is null it means skip this -+ * entry -+ * return the size of bytes associated with the returned data -+ * for complex object like blob and string a pointer to the allocated -+ * data is returned in data, but the size of the blob or string is -+ * returned. -+ */ -+static u32 sd_is_X(struct sd_ext *e, enum sd_code code, void *data) -+{ -+ void *pos = e->pos; -+ int ret = 0; -+ if (!sd_inbounds(e, SD_CODE_BYTE + sdcode_datasize[code])) -+ goto fail; -+ if (code != *(u8 *)e->pos) -+ goto out; -+ e->pos += SD_CODE_BYTE; -+ if (code == SD_NAME) { -+ u16 size; -+ /* name codes are followed by X bytes */ -+ size = le16_to_cpu(get_unaligned((u16 *)e->pos)); -+ if (!sd_inbounds(e, (size_t) size)) -+ goto fail; -+ if (data) -+ *(u16 *)data = size; -+ e->pos += sdcode_datasize[code]; -+ ret = 1 + sdcode_datasize[code]; -+ } else if (code == SD_DYN_STRING) { -+ u16 size; -+ char *str; -+ /* strings codes are followed by X bytes */ -+ size = le16_to_cpu(get_unaligned((u16 *)e->pos)); -+ e->pos += sdcode_datasize[code]; -+ if (!sd_inbounds(e, (size_t) size)) -+ goto fail; -+ if (data) { -+ * (char **)data = NULL; -+ str = kmalloc(size, GFP_KERNEL); -+ if (!str) -+ goto fail; -+ memcpy(str, e->pos, (size_t) size); -+ str[size-1] = '\0'; -+ * (char **)data = str; -+ } -+ e->pos += size; -+ ret = size; -+ } else if (code == SD_STATIC_BLOB) { -+ u32 size; -+ /* blobs are followed by X bytes, that can be 2^32 */ -+ size = le32_to_cpu(get_unaligned((u32 *)e->pos)); -+ e->pos += sdcode_datasize[code]; -+ if (!sd_inbounds(e, (size_t) size)) -+ goto fail; -+ if (data) -+ memcpy(data, e->pos, (size_t) size); -+ e->pos += size; -+ ret = size; -+ } else { -+ if (data) -+ sdconvert(code, data, e->pos); -+ e->pos += sdcode_datasize[code]; -+ ret = 1 + sdcode_datasize[code]; -+ } -+out: -+ return ret; -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+/* sd_is_nameX - check is the next element is X, and its tag is name. -+ * if the code matches and name (if specified) matches then the packed data -+ * is unpacked into *data. (Note for strings this is the size, and the next -+ * data in the stream is the string data) -+ * returns 0 if either match failes -+ */ -+static int sd_is_nameX(struct sd_ext *e, enum sd_code code, void *data, -+ const char *name) -+{ -+ void *pos = e->pos; -+ u16 size; -+ u32 ret; -+ /* check for presence of a tagname, and if present name size -+ * SD_NAME tag value is a u16 */ -+ if (sd_is_X(e, SD_NAME, &size)) { -+ /* if a name is specified it must match. otherwise skip tag */ -+ if (name && ((strlen(name) != size-1) || -+ strncmp(name, (char *)e->pos, (size_t)size-1))) -+ goto fail; -+ e->pos += size; -+ } -+ /* now check if data actually matches */ -+ ret = sd_is_X(e, code, data); -+ if (!ret) -+ goto fail; -+ return ret; -+ -+fail: -+ e->pos = pos; -+ return 0; -+} -+ -+/* macro to wrap error case to make a block of reads look nicer */ -+#define SD_READ_X(E, C, D, N) \ -+ do { \ -+ u32 __ret; \ -+ __ret = sd_is_nameX((E), (C), (D), (N)); \ -+ if (!__ret) \ -+ goto fail; \ -+ } while (0) -+ -+/** -+ * sd_activate_net_entry - ignores/skips net entries if the they are present -+ * in the data stream. -+ * @e: extent information -+ */ -+static inline int sd_activate_net_entry(struct sd_ext *e) -+{ -+ SD_READ_X(e, SD_STRUCT, NULL, "ne"); -+ SD_READ_X(e, SD_U32, NULL, NULL); -+ SD_READ_X(e, SD_U32, NULL, NULL); -+ SD_READ_X(e, SD_U32, NULL, NULL); -+ SD_READ_X(e, SD_U16, NULL, NULL); -+ SD_READ_X(e, SD_U16, NULL, NULL); -+ SD_READ_X(e, SD_U32, NULL, NULL); -+ SD_READ_X(e, SD_U32, NULL, NULL); -+ SD_READ_X(e, SD_U16, NULL, NULL); -+ SD_READ_X(e, SD_U16, NULL, NULL); -+ /* interface name is optional so just ignore return code */ -+ sd_is_nameX(e, SD_DYN_STRING, NULL, NULL); -+ SD_READ_X(e, SD_STRUCTEND, NULL, NULL); -+ -+ return 1; -+fail: -+ return 0; -+} -+ -+static inline struct sd_entry *sd_activate_file_entry(struct sd_ext *e) -+{ -+ struct sd_entry *entry = NULL; -+ -+ if (!(entry = alloc_sd_entry())) -+ goto fail; -+ -+ SD_READ_X(e, SD_STRUCT, NULL, "fe"); -+ SD_READ_X(e, SD_DYN_STRING, &entry->filename, NULL); -+ SD_READ_X(e, SD_U32, &entry->mode, "file.mode"); -+ SD_READ_X(e, SD_U32, &entry->entry_type, "file.pattern_type"); -+ -+ entry->extradata = sdmatch_alloc(entry->entry_type); -+ if (IS_ERR(entry->extradata)) { -+ entry->extradata = NULL; -+ goto fail; -+ } -+ -+ if (entry->extradata && -+ sdmatch_serialize(entry->extradata, e, sd_is_nameX) != 0) { -+ goto fail; -+ } -+ SD_READ_X(e, SD_STRUCTEND, NULL, NULL); -+ -+ switch (entry->entry_type) { -+ case sd_entry_literal: -+ SD_DEBUG("%s: %s [no pattern] mode=0x%x\n", -+ __FUNCTION__, -+ entry->filename, -+ entry->mode); -+ break; -+ case sd_entry_tailglob: -+ SD_DEBUG("%s: %s [tailglob] mode=0x%x\n", -+ __FUNCTION__, -+ entry->filename, -+ entry->mode); -+ break; -+ case sd_entry_pattern: -+ SD_DEBUG("%s: %s mode=0x%x\n", -+ __FUNCTION__, -+ entry->filename, -+ entry->mode); -+ break; -+ default: -+ SD_WARN("%s: INVALID entry_type %d\n", -+ __FUNCTION__, -+ (int)entry->entry_type); -+ goto fail; -+ } -+ -+ return entry; -+ -+fail: -+ sdmatch_free(entry->extradata); -+ free_sd_entry(entry); -+ return NULL; -+} -+ -+static inline int check_rule_and_add(struct sd_entry *file_entry, -+ struct sdprofile *profile, -+ const char **message) -+{ -+ /* verify consistency of x, px, ix, ux for entry against -+ possible duplicates for this entry */ -+ int mode = SD_EXEC_MODIFIER_MASK(file_entry->mode); -+ int i; -+ -+ if (mode && !(SD_MAY_EXEC & file_entry->mode)) { -+ *message = "inconsistent rule, x modifiers without x"; -+ goto out; -+ } -+ -+ /* check that only 1 of the modifiers is set */ -+ if (mode && (mode & (mode - 1))) { -+ *message = "inconsistent rule, multiple x modifiers"; -+ goto out; -+ } -+ -+ list_add(&file_entry->list, &profile->file_entry); -+ profile->num_file_entries++; -+ -+ mode = file_entry->mode; -+ -+ /* Handle partitioned lists -+ * Chain entries onto sublists based on individual -+ * permission bits. This allows more rapid searching. -+ */ -+ for (i = 0; i <= POS_SD_FILE_MAX; i++) { -+ if (mode & (1 << i)) -+ /* profile->file_entryp[i] initially set to -+ * NULL in alloc_sdprofile() */ -+ list_add(&file_entry->listp[i], -+ &profile->file_entryp[i]); -+ } -+ -+ return 1; -+ -+out: -+ free_sd_entry(file_entry); -+ return 0; -+} -+ -+#define SD_ENTRY_LIST(NAME) \ -+ do { \ -+ if (sd_is_nameX(e, SD_LIST, NULL, (NAME))) { \ -+ rulename = ""; \ -+ error_string = "Invalid file entry"; \ -+ while (!sd_is_nameX(e, SD_LISTEND, NULL, NULL)) { \ -+ struct sd_entry *file_entry; \ -+ file_entry = sd_activate_file_entry(e); \ -+ if (!file_entry) \ -+ goto fail; \ -+ if (!check_rule_and_add(file_entry, profile, \ -+ &error_string)) { \ -+ rulename = file_entry->filename; \ -+ goto fail; \ -+ } \ -+ } \ -+ } \ -+ } while (0) -+ -+struct sdprofile *sd_activate_profile(struct sd_ext *e, ssize_t *error) -+{ -+ struct sdprofile *profile = NULL; -+ const char *rulename = ""; -+ const char *error_string = "Invalid Profile"; -+ -+ *error = -EPROTO; -+ -+ profile = alloc_sdprofile(); -+ if (!profile) { -+ error_string = "Could not allocate profile"; -+ *error = -ENOMEM; -+ goto fail; -+ } -+ -+ /* check that we have the right struct being passed */ -+ SD_READ_X(e, SD_STRUCT, NULL, "profile"); -+ SD_READ_X(e, SD_DYN_STRING, &profile->name, NULL); -+ -+ error_string = "Invalid flags"; -+ /* per profile debug flags (debug, complain, audit) */ -+ SD_READ_X(e, SD_STRUCT, NULL, "flags"); -+ SD_READ_X(e, SD_U32, &(profile->flags.debug), "profile.flags.debug"); -+ SD_READ_X(e, SD_U32, &(profile->flags.complain), -+ "profile.flags.complain"); -+ SD_READ_X(e, SD_U32, &(profile->flags.audit), "profile.flags.audit"); -+ SD_READ_X(e, SD_STRUCTEND, NULL, NULL); -+ -+ error_string = "Invalid capabilities"; -+ SD_READ_X(e, SD_U32, &(profile->capabilities), "profile.capabilities"); -+ -+ /* get the file entries. */ -+ SD_ENTRY_LIST("pgent"); /* pcre rules */ -+ SD_ENTRY_LIST("sgent"); /* simple globs */ -+ SD_ENTRY_LIST("fent"); /* regular file entries */ -+ -+ /* get the net entries */ -+ if (sd_is_nameX(e, SD_LIST, NULL, "net")) { -+ error_string = "Invalid net entry"; -+ while (!sd_is_nameX(e, SD_LISTEND, NULL, NULL)) { -+ if (!sd_activate_net_entry(e)) -+ goto fail; -+ } -+ } -+ rulename = ""; -+ -+ /* get subprofiles */ -+ if (sd_is_nameX(e, SD_LIST, NULL, "hats")) { -+ error_string = "Invalid profile hat"; -+ while (!sd_is_nameX(e, SD_LISTEND, NULL, NULL)) { -+ struct sdprofile *subprofile; -+ subprofile = sd_activate_profile(e, error); -+ if (!subprofile) -+ goto fail; -+ get_sdprofile(subprofile); -+ list_add(&subprofile->list, &profile->sub); -+ } -+ } -+ -+ error_string = "Invalid end of profile"; -+ SD_READ_X(e, SD_STRUCTEND, NULL, NULL); -+ -+ return profile; -+ -+fail: -+ SD_WARN("%s: %s %s in profile %s\n", INTERFACE_ID, rulename, -+ error_string, profile && profile->name ? profile->name -+ : "unknown"); -+ -+ if (profile) { -+ free_sdprofile(profile); -+ profile = NULL; -+ } -+ -+ return NULL; -+} -+ -+void *sd_activate_top_profile(struct sd_ext *e, ssize_t *error) -+{ -+ /* get the interface version */ -+ if (!sd_is_nameX(e, SD_U32, &e->version, "version")) { -+ SD_WARN("%s: version missing\n", INTERFACE_ID); -+ *error = -EPROTONOSUPPORT; -+ goto out; -+ } -+ -+ /* check that the interface version is currently supported */ -+ if (e->version != 2) { -+ SD_WARN("%s: unsupported interface version (%d)\n", -+ INTERFACE_ID, e->version); -+ *error = -EPROTONOSUPPORT; -+ goto out; -+ } -+ -+ return sd_activate_profile(e, error); -+out: -+ return NULL; -+} -+ -+ssize_t sd_file_prof_add(void *data, size_t size) -+{ -+ struct sdprofile *profile = NULL; -+ -+ struct sd_ext e = { data, data + size, data }; -+ ssize_t error; -+ -+ profile = sd_activate_top_profile(&e, &error); -+ if (!profile) { -+ SD_DEBUG("couldn't activate profile\n"); -+ return error; -+ } -+ -+ if (!sd_profilelist_add(profile)) { -+ SD_WARN("trying to add profile (%s) that already exists.\n", -+ profile->name); -+ free_sdprofile(profile); -+ return -EEXIST; -+ } -+ -+ return size; -+} -+ -+ssize_t sd_file_prof_repl(void *udata, size_t size) -+{ -+ struct sd_taskreplace_data data; -+ struct sd_ext e = { udata, udata + size, udata }; -+ ssize_t error; -+ -+ data.new_profile = sd_activate_top_profile(&e, &error); -+ if (!data.new_profile) { -+ SD_DEBUG("couldn't activate profile\n"); -+ return error; -+ } -+ /* Grab reference to close race window (see comment below) */ -+ get_sdprofile(data.new_profile); -+ -+ /* Replace the profile on the global profile list. -+ * This list is used by all new exec's to find the correct profile. -+ * If there was a previous profile, it is returned, else NULL. -+ * -+ * N.B sd_profilelist_replace does not drop the refcnt on -+ * old_profile when removing it from the global list, otherwise it -+ * could reach zero and be automatically free'd. We nust manually -+ * drop it at the end of this function when we are finished with it. -+ */ -+ data.old_profile = sd_profilelist_replace(data.new_profile); -+ -+ /* RACE window here. -+ * At this point another task could preempt us trying to replace -+ * the SAME profile. If it makes it to this point, it has removed -+ * the original tasks new_profile from the global list and holds a -+ * reference of 1 to it in it's old_profile. If the new task -+ * reaches the end of the function it will put old_profile causing -+ * the profile to be deleted. -+ * When the original task is rescheduled it will continue calling -+ * sd_subdomainlist_iterate relabelling tasks with a profile -+ * which points to free'd memory. -+ */ -+ -+ /* If there was an old profile, find all currently executing tasks -+ * using this profile and replace the old profile with the new. -+ */ -+ if (data.old_profile) { -+ SD_DEBUG("%s: try to replace profile (%p)%s\n", -+ __FUNCTION__, -+ data.old_profile, -+ data.old_profile->name); -+ -+ sd_subdomainlist_iterate(taskreplace_iter, (void *)&data); -+ -+ /* mark old profile as stale */ -+ data.old_profile->isstale = 1; -+ -+ /* it's off global list, and we are done replacing */ -+ put_sdprofile(data.old_profile); -+ } -+ -+ /* Free reference obtained above */ -+ put_sdprofile(data.new_profile); -+ -+ return size; -+} -+ -+ssize_t sd_file_prof_remove(const char *name, size_t size) -+{ -+ struct sdprofile *old_profile; -+ -+ /* Do this step to get a guaranteed reference to profile -+ * as sd_profilelist_remove may drop it to zero which would -+ * made subsequent attempt to iterate using it unsafe -+ */ -+ old_profile = sd_profilelist_find(name); -+ -+ if (old_profile) { -+ if (sd_profilelist_remove(name) != 0) -+ SD_WARN("%s: race trying to remove profile (%s)\n", -+ __FUNCTION__, name); -+ -+ /* remove profile from any tasks using it */ -+ sd_subdomainlist_iterateremove(taskremove_iter, -+ (void *)old_profile); -+ -+ /* drop reference obtained by sd_profilelist_find */ -+ put_sdprofile(old_profile); -+ } else { -+ SD_WARN("%s: trying to remove profile (%s) that " -+ "doesn't exist - skipping.\n", __FUNCTION__, name); -+ return -ENOENT; -+ } -+ -+ return size; -+} ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/module_interface.h -@@ -0,0 +1,37 @@ -+#ifndef __MODULEINTERFACE_H -+#define __MODULEINTERFACE_H -+ -+/* Codes of the types of basic structures that are understood */ -+#define SD_CODE_BYTE (sizeof(u8)) -+#define INTERFACE_ID "INTERFACE" -+ -+#define SUBDOMAIN_INTERFACE_VERSION 2 -+ -+enum sd_code { -+ SD_U8, -+ SD_U16, -+ SD_U32, -+ SD_U64, -+ SD_NAME, /* same as string except it is items name */ -+ SD_DYN_STRING, -+ SD_STATIC_BLOB, -+ SD_STRUCT, -+ SD_STRUCTEND, -+ SD_LIST, -+ SD_LISTEND, -+ SD_OFFSET, -+ SD_BAD -+}; -+ -+/* sd_ext tracks the kernel buffer and read position in it. The interface -+ * data is copied into a kernel buffer in subdomainfs and then handed off to -+ * the activate routines. -+ */ -+struct sd_ext { -+ void *start; -+ void *end; -+ void *pos; /* pointer to current position in the buffer */ -+ u32 version; -+}; -+ -+#endif /* __MODULEINTERFACE_H */ ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/procattr.c -@@ -0,0 +1,310 @@ -+/* -+ * Copyright (C) 2005 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 /proc/pid/attr handling -+ */ -+ -+/* for isspace */ -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+ -+size_t sd_getprocattr(struct subdomain *sd, char *str, size_t size) -+{ -+ int error = -EACCES; /* default to a perm denied */ -+ size_t len; -+ -+ if (__sd_is_confined(sd)) { -+ size_t lena, lenm, lenp = 0; -+ const char *enforce_str = " (enforce)"; -+ const char *complain_str = " (complain)"; -+ const char *mode_str = -+ SUBDOMAIN_COMPLAIN(sd) ? complain_str : enforce_str; -+ -+ lenm = strlen(mode_str); -+ -+ lena = strlen(sd->active->name); -+ -+ len = lena; -+ if (sd->active != sd->profile) { -+ lenp = strlen(sd->profile->name); -+ len += (lenp + 1); /* +1 for ^ */ -+ } -+ /* DONT null terminate strings we output via proc */ -+ len += (lenm + 1); /* for \n */ -+ -+ if (len <= size) { -+ if (lenp) { -+ memcpy(str, sd->profile->name, lenp); -+ str += lenp; -+ *str++ = '^'; -+ } -+ -+ memcpy(str, sd->active->name, lena); -+ str += lena; -+ memcpy(str, mode_str, lenm); -+ str += lenm; -+ *str++ = '\n'; -+ error = len; -+ } else { -+ error = -ERANGE; -+ } -+ } else { -+ const char *unconstrained_str = SD_UNCONSTRAINED "\n"; -+ len = strlen(unconstrained_str); -+ -+ /* DONT null terminate strings we output via proc */ -+ if (len <= size) { -+ memcpy(str, unconstrained_str, len); -+ error = len; -+ } else { -+ error = -ERANGE; -+ } -+ } -+ -+ return error; -+ -+} -+int sd_setprocattr_changehat(char *hatinfo, size_t infosize) -+{ -+ int error = -EINVAL; -+ char *token = NULL, *hat, *smagic, *tmp; -+ __u32 magic; -+ int rc, len, consumed; -+ unsigned long flags; -+ -+ SD_DEBUG("%s: %p %zd\n", __FUNCTION__, hatinfo, infosize); -+ -+ /* strip leading white space */ -+ while (infosize && isspace(*hatinfo)) { -+ hatinfo++; -+ infosize--; -+ } -+ -+ if (infosize == 0) -+ goto out; -+ -+ /* -+ * Copy string to a new buffer so we can play with it -+ * It may be zero terminated but we add a trailing 0 -+ * for 100% safety -+ */ -+ token = kmalloc(infosize + 1, GFP_KERNEL); -+ -+ if (!token) { -+ error = -ENOMEM; -+ goto out; -+ } -+ -+ memcpy(token, hatinfo, infosize); -+ token[infosize] = 0; -+ -+ /* error is INVAL until we have at least parsed something */ -+ error = -EINVAL; -+ -+ tmp = token; -+ while (*tmp && *tmp != '^') { -+ tmp++; -+ } -+ -+ if (!*tmp || tmp == token) { -+ SD_WARN("%s: Invalid input '%s'\n", __FUNCTION__, token); -+ goto out; -+ } -+ -+ /* split magic and hat into two strings */ -+ *tmp = 0; -+ smagic = token; -+ -+ /* -+ * Initially set consumed=strlen(magic), as if sscanf -+ * consumes all input via the %x it will not process the %n -+ * directive. Otherwise, if sscanf does not consume all the -+ * input it will process the %n and update consumed. -+ */ -+ consumed = len = strlen(smagic); -+ -+ rc = sscanf(smagic, "%x%n", &magic, &consumed); -+ -+ if (rc != 1 || consumed != len) { -+ SD_WARN("%s: Invalid hex magic %s\n", -+ __FUNCTION__, -+ smagic); -+ goto out; -+ } -+ -+ hat = tmp + 1; -+ -+ if (!*hat) -+ hat = NULL; -+ -+ if (!hat && !magic) { -+ SD_WARN("%s: Invalid input, NULL hat and NULL magic\n", -+ __FUNCTION__); -+ goto out; -+ } -+ -+ SD_DEBUG("%s: Magic 0x%x Hat '%s'\n", -+ __FUNCTION__, magic, hat ? hat : NULL); -+ -+ write_lock_irqsave(&sd_lock, flags); -+ error = sd_change_hat(hat, magic); -+ write_unlock_irqrestore(&sd_lock, flags); -+ -+out: -+ if (token) { -+ memset(token, 0, infosize); -+ kfree(token); -+ } -+ -+ return error; -+} -+ -+int sd_setprocattr_setprofile(struct task_struct *p, char *profilename, -+ size_t profilesize) -+{ -+ int error = -EINVAL; -+ struct sdprofile *profile; -+ struct subdomain *sd; -+ char *name = NULL; -+ unsigned long flags; -+ -+ SD_DEBUG("%s: current %s(%d)\n", -+ __FUNCTION__, current->comm, current->pid); -+ -+ /* strip leading white space */ -+ while (profilesize && isspace(*profilename)) { -+ profilename++; -+ profilesize--; -+ } -+ -+ if (profilesize == 0) -+ goto out; -+ -+ /* -+ * Copy string to a new buffer so we guarantee it is zero -+ * terminated -+ */ -+ name = kmalloc(profilesize + 1, GFP_KERNEL); -+ -+ if (!name) { -+ error = -ENOMEM; -+ goto out; -+ } -+ -+ strncpy(name, profilename, profilesize); -+ name[profilesize] = 0; -+ -+ if (strcmp(name, SD_UNCONSTRAINED) == 0) -+ profile = null_profile; -+ else -+ profile = sd_profilelist_find(name); -+ -+ if (!profile) { -+ SD_WARN("%s: Unable to switch task %s(%d) to profile '%s'. " -+ "No such profile.\n", -+ __FUNCTION__, -+ p->comm, p->pid, -+ name); -+ -+ error = -EINVAL; -+ goto out; -+ } -+ -+ -+ write_lock_irqsave(&sd_lock, flags); -+ -+ sd = SD_SUBDOMAIN(p->security); -+ -+ /* switch to unconstrained */ -+ if (profile == null_profile) { -+ if (__sd_is_confined(sd)) { -+ SD_WARN("%s: Unconstraining task %s(%d) " -+ "profile %s active %s\n", -+ __FUNCTION__, -+ p->comm, p->pid, -+ sd->profile->name, -+ sd->active->name); -+ -+ sd_switch_unconfined(sd); -+ } else { -+ SD_WARN("%s: task %s(%d) " -+ "is already unconstrained\n", -+ __FUNCTION__, p->comm, p->pid); -+ } -+ } else { -+ if (!sd) { -+ /* this task was created before module was -+ * loaded, allocate a subdomain -+ */ -+ SD_WARN("%s: task %s(%d) has no subdomain\n", -+ __FUNCTION__, p->comm, p->pid); -+ -+ /* unlock so we can safely GFP_KERNEL */ -+ write_unlock_irqrestore(&sd_lock, flags); -+ -+ sd = alloc_subdomain(p); -+ if (!sd) { -+ SD_WARN("%s: Unable to allocate subdomain for " -+ "task %s(%d). Cannot confine task to " -+ "profile %s\n", -+ __FUNCTION__, -+ p->comm, p->pid, -+ name); -+ -+ error = -ENOMEM; -+ put_sdprofile(profile); -+ -+ goto out; -+ } -+ -+ write_lock_irqsave(&sd_lock, flags); -+ if (!SD_SUBDOMAIN(p->security)) { -+ p->security = sd; -+ } else { /* race */ -+ free_subdomain(sd); -+ sd = SD_SUBDOMAIN(p->security); -+ } -+ } -+ -+ /* we do not do a normal task replace since we are not -+ * replacing with the same profile. -+ * If existing process is in a hat, it will be moved -+ * into the new parent profile, even if this new -+ * profile has a identical named hat. -+ */ -+ -+ SD_WARN("%s: Switching task %s(%d) " -+ "profile %s active %s to new profile %s\n", -+ __FUNCTION__, -+ p->comm, p->pid, -+ sd->profile ? sd->profile->name : SD_UNCONSTRAINED, -+ sd->active ? sd->profile->name : SD_UNCONSTRAINED, -+ name); -+ -+ sd_switch(sd, profile, profile); -+ -+ put_sdprofile(profile); /* drop ref we obtained above -+ * from sd_profilelist_find -+ */ -+ -+ /* Reset magic in case we were in a subhat before -+ * This is the only case where we zero the magic after -+ * calling sd_switch -+ */ -+ sd->sd_hat_magic = 0; -+ } -+ -+ write_unlock_irqrestore(&sd_lock, flags); -+ -+out: -+ kfree(name); -+ -+ return error; -+} ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/aamatch/match.h -@@ -0,0 +1,137 @@ -+/* -+ * Copyright (C) 2002-2005 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 submodule (match) prototypes -+ */ -+ -+#ifndef __MATCH_H -+#define __MATCH_H -+ -+#include "../module_interface.h" -+#include "../apparmor.h" -+ -+/* The following functions implement an interface used by the primary -+ * AppArmor module to perform name matching (n.b. "AppArmor" was previously -+ * called "SubDomain"). -+ -+ * sdmatch_alloc -+ * sdmatch_free -+ * sdmatch_features -+ * sdmatch_serialize -+ * sdmatch_match -+ * -+ * The intent is for the primary module to export (via virtual fs entries) -+ * the features provided by the submodule (sdmatch_features) so that the -+ * parser may only load policy that can be supported. -+ * -+ * The primary module will call sdmatch_serialize to allow the submodule -+ * to consume submodule specific data from parser data stream and will call -+ * sdmatch_match to determine if a pathname matches an sd_entry. -+ */ -+ -+typedef int (*sdmatch_serializecb) -+ (struct sd_ext *, enum sd_code, void *, const char *); -+ -+/** -+ * sdmatch_alloc: allocate extradata (if necessary) -+ * @entry_type: type of entry being allocated -+ * Return value: NULL indicates no data was allocated (ERR_PTR(x) on error) -+ */ -+extern void* sdmatch_alloc(enum entry_t entry_type); -+ -+/** -+ * sdmatch_free: release data allocated by sdmatch_alloc -+ * @entry_extradata: data previously allocated by sdmatch_alloc -+ */ -+extern void sdmatch_free(void *entry_extradata); -+ -+/** -+ * sdmatch_features: return match types supported -+ * Return value: space seperated string (of types supported - use type=value -+ * to indicate variants of a type) -+ */ -+extern const char* sdmatch_features(void); -+ -+/** -+ * sdmatch_serialize: serialize extradata -+ * @entry_extradata: data previously allocated by sdmatch_alloc -+ * @e: input stream -+ * @cb: callback fn (consume incoming data stream) -+ * Return value: 0 success, -ve error -+ */ -+extern int sdmatch_serialize(void *entry_extradata, struct sd_ext *e, -+ sdmatch_serializecb cb); -+ -+/** -+ * sdmatch_match: determine if pathname matches entry -+ * @pathname: pathname to verify -+ * @entry_name: entry name -+ * @entry_type: type of entry -+ * @entry_extradata: data previously allocated by sdmatch_alloc -+ * Return value: 1 match, 0 othersise -+ */ -+extern unsigned int sdmatch_match(const char *pathname, const char *entry_name, -+ enum entry_t entry_type, -+ void *entry_extradata); -+ -+ -+/** -+ * sd_getentry_type - return string representation of entry_t -+ * @etype: entry type -+ */ -+static inline const char *sd_getentry_type(enum entry_t etype) -+{ -+ const char *etype_names[] = { -+ "sd_entry_literal", -+ "sd_entry_tailglob", -+ "sd_entry_pattern", -+ "sd_entry_invalid" -+ }; -+ -+ if (etype >= sd_entry_invalid) { -+ etype = sd_entry_invalid; -+ } -+ -+ return etype_names[etype]; -+} -+ -+/** -+ * sdmatch_match_common - helper function to check if a pathname matches -+ * a literal/tailglob -+ * @path: path requested to search for -+ * @entry_name: name from sd_entry -+ * @etype: type of entry -+ */ -+static inline int sdmatch_match_common(const char *path, -+ const char *entry_name, -+ enum entry_t etype) -+{ -+ int retval; -+ -+ /* literal, no pattern matching characters */ -+ if (etype == sd_entry_literal) { -+ retval = (strcmp(entry_name, path) == 0); -+ /* trailing ** glob pattern */ -+ } else if (etype == sd_entry_tailglob) { -+ retval = (strncmp(entry_name, path, -+ strlen(entry_name) - 2) == 0); -+ } else { -+ SD_WARN("%s: Invalid entry_t %d\n", __FUNCTION__, etype); -+ retval = 0; -+ } -+ -+#if 0 -+ SD_DEBUG("%s(%d): %s %s [%s]\n", -+ __FUNCTION__, retval, path, entry_name, -+ sd_getentry_type(etype)); -+#endif -+ -+ return retval; -+} -+ -+#endif /* __MATCH_H */ ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/aamatch/match_pcre.c -@@ -0,0 +1,169 @@ -+/* -+ * Copyright (C) 2002-2005 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. -+ * -+ * http://forge.novell.com/modules/xfmod/project/?apparmor -+ * -+ * AppArmor aamatch submodule (w/ pattern expansion). -+ * -+ * This module makes use of a slightly modified version of the PCRE -+ * library developed by Philip Hazel . See the files -+ * pcre_* in this directory. -+ */ -+ -+#include -+#include "match.h" -+#include "pcre_exec.h" -+#include "pcre_tables.h" -+ -+static const char *features="literal tailglob pattern=pcre"; -+ -+struct sdmatch_entry -+{ -+ char *pattern; -+ pcre *compiled; -+}; -+ -+void* sdmatch_alloc(enum entry_t entry_type) -+{ -+void *ptr=NULL; -+ -+ if (entry_type == sd_entry_pattern) { -+ ptr = kmalloc(sizeof(struct sdmatch_entry), GFP_KERNEL); -+ if (ptr) -+ memset(ptr, 0, sizeof(struct sdmatch_entry)); -+ else -+ ptr=ERR_PTR(-ENOMEM); -+ } else if (entry_type != sd_entry_literal && -+ entry_type != sd_entry_tailglob) { -+ ptr = ERR_PTR(-EINVAL); -+ } -+ -+ return ptr; -+} -+ -+void sdmatch_free(void *ptr) -+{ -+ if (ptr) { -+ struct sdmatch_entry *ed = (struct sdmatch_entry *) ptr; -+ kfree(ed->pattern); -+ kfree(ed->compiled); /* allocated by SD_READ_X */ -+ } -+ kfree(ptr); -+} -+ -+const char *sdmatch_features(void) -+{ -+ return features; -+} -+ -+int sdmatch_serialize(void *entry_extradata, struct sd_ext *e, -+ sdmatch_serializecb cb) -+{ -+#define SD_READ_X(E, C, D, N) \ -+ do { \ -+ if (!cb((E), (C), (D), (N))) { \ -+ error = -EINVAL; \ -+ goto done; \ -+ }\ -+ } while (0) -+ -+ int error = 0; -+ u32 size, magic, opts; -+ u8 t_char; -+ struct sdmatch_entry *ed = (struct sdmatch_entry *) entry_extradata; -+ -+ if (ed == NULL) -+ goto done; -+ -+ SD_READ_X(e, SD_DYN_STRING, &ed->pattern, NULL); -+ -+ /* size determines the real size of the pcre struct, -+ it is size_t - sizeof(pcre) on user side. -+ uschar must be the same in user and kernel space */ -+ /* check that we are processing the correct structure */ -+ SD_READ_X(e, SD_STRUCT, NULL, "pcre"); -+ SD_READ_X(e, SD_U32, &size, "pattern.size"); -+ SD_READ_X(e, SD_U32, &magic, "pattern.magic"); -+ -+ /* the allocation of pcre is delayed because it depends on the size -+ * of the pattern */ -+ ed->compiled = (pcre *) kmalloc(size + sizeof(pcre), GFP_KERNEL); -+ if (!ed->compiled) { -+ error = -ENOMEM; -+ goto done; -+ } -+ -+ memset(ed->compiled, 0, size + sizeof(pcre)); -+ ed->compiled->magic_number = magic; -+ ed->compiled->size = size + sizeof(pcre); -+ -+ SD_READ_X(e, SD_U32, &opts, "pattern.options"); -+ ed->compiled->options = opts; -+ SD_READ_X(e, SD_U16, &ed->compiled->top_bracket, "pattern.top_bracket"); -+ SD_READ_X(e, SD_U16, &ed->compiled->top_backref, "pattern.top_backref"); -+ SD_READ_X(e, SD_U8, &t_char, "pattern.first_char"); -+ ed->compiled->first_char = t_char; -+ SD_READ_X(e, SD_U8, &t_char, "pattern.req_char"); -+ ed->compiled->req_char = t_char; -+ SD_READ_X(e, SD_U8, &t_char, "pattern.code[0]"); -+ ed->compiled->code[0] = t_char; -+ -+ SD_READ_X(e, SD_STATIC_BLOB, &ed->compiled->code[1], NULL); -+ -+ SD_READ_X(e, SD_STRUCTEND, NULL, NULL); -+ -+ /* stitch in pcre patterns, it was NULLed out by parser -+ * pcre_default_tables defined in pcre_tables.h */ -+ ed->compiled->tables = pcre_default_tables; -+ -+done: -+ if (error != 0 && ed) { -+ kfree(ed->pattern); /* allocated by SD_READ_X */ -+ kfree(ed->compiled); -+ ed->pattern = NULL; -+ ed->compiled = NULL; -+ } -+ -+ return error; -+} -+ -+unsigned int sdmatch_match(const char *pathname, const char *entry_name, -+ enum entry_t entry_type, void *entry_extradata) -+{ -+ int ret; -+ -+ if (entry_type == sd_entry_pattern) { -+ int pcreret; -+ struct sdmatch_entry *ed = -+ (struct sdmatch_entry *) entry_extradata; -+ -+ pcreret = pcre_exec(ed->compiled, NULL, -+ pathname, strlen(pathname), -+ 0, 0, NULL, 0); -+ -+ ret = (pcreret >= 0); -+ -+ // XXX - this needs access to subdomain_debug, hmmm -+ //SD_DEBUG("%s(%d): %s %s %d\n", __FUNCTION__, -+ // ret, pathname, ed->pattern, pcreret); -+ } else { -+ ret = sdmatch_match_common(pathname, entry_name, entry_type); -+ } -+ -+ return ret; -+} -+ -+EXPORT_SYMBOL_GPL(sdmatch_alloc); -+EXPORT_SYMBOL_GPL(sdmatch_free); -+EXPORT_SYMBOL_GPL(sdmatch_features); -+EXPORT_SYMBOL_GPL(sdmatch_serialize); -+EXPORT_SYMBOL_GPL(sdmatch_match); -+ -+MODULE_DESCRIPTION("AppArmor aa_match module [pcre]"); -+MODULE_AUTHOR("Tony Jones "); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/aamatch/pcre_exec.c -@@ -0,0 +1,1945 @@ -+/* -+ * This is a modified version of pcre.c containing only the code/data -+ * required to support pcre_exec() -+ */ -+ -+ -+/************************************************* -+* Perl-Compatible Regular Expressions * -+*************************************************/ -+ -+/* -+This is a library of functions to support regular expressions whose syntax -+and semantics are as close as possible to those of the Perl 5 language. See -+the file Tech.Notes for some information on the internals. -+ -+Written by: Philip Hazel -+ -+ Copyright (c) 1997-2001 University of Cambridge -+ -+----------------------------------------------------------------------------- -+Permission is granted to anyone to use this software for any purpose on any -+computer system, and to redistribute it freely, subject to the following -+restrictions: -+ -+1. This software 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. -+ -+2. The origin of this software must not be misrepresented, either by -+ explicit claim or by omission. -+ -+3. Altered versions must be plainly marked as such, and must not be -+ misrepresented as being the original software. -+ -+4. If PCRE is embedded in any software that is released under the GNU -+ General Purpose Licence (GPL), then the terms of that licence shall -+ supersede any condition above with which it is incompatible. -+----------------------------------------------------------------------------- -+*/ -+ -+ -+/* Define DEBUG to get debugging output on stdout. */ -+ -+/* #define DEBUG */ -+ -+/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef -+inline, and there are *still* stupid compilers about that don't like indented -+pre-processor statements. I suppose it's only been 10 years... */ -+ -+#ifdef DEBUG -+#define DPRINTF(p) PCRE_PRINTF p -+#else -+#define DPRINTF(p) /*nothing*/ -+#endif -+ -+/* Include the internals header, which itself includes Standard C headers plus -+the external pcre header. */ -+ -+#include "pcre_exec.h" -+ -+ -+/* ---- CODE DELETED ---- */ -+ -+ -+/* Min and max values for the common repeats; for the maxima, 0 => infinity */ -+ -+static const char rep_min[] = { 0, 0, 1, 1, 0, 0 }; -+static const char rep_max[] = { 0, 0, 0, 0, 1, 1 }; -+ -+ -+/* ---- CODE DELETED ---- */ -+ -+ -+/* Structure for building a chain of data that actually lives on the -+ * stack, for holding the values of the subject pointer at the start of each -+ * subpattern, so as to detect when an empty string has been matched by a -+ * subpattern - to break infinite loops. */ -+ -+typedef struct eptrblock { -+ struct eptrblock *prev; -+ const uschar *saved_eptr; -+} eptrblock; -+ -+/* Flag bits for the match() function */ -+ -+#define match_condassert 0x01 /* Called to check a condition assertion */ -+#define match_isgroup 0x02 /* Set if start of bracketed group */ -+ -+ -+/* ---- CODE DELETED ---- */ -+ -+ -+/************************************************* -+ * * Global variables * -+ * *************************************************/ -+ -+/* PCRE is thread-clean and doesn't use any global variables in the normal -+ * sense. However, it calls memory allocation and free functions via the two -+ * indirections below, which are can be changed by the caller, but are shared -+ * between all threads. */ -+ -+#ifdef __KERNEL__ -+static void *kern_malloc(size_t sz) -+{ -+ return kmalloc(sz, GFP_KERNEL); -+} -+void *(*pcre_malloc)(size_t) = kern_malloc; -+void (*pcre_free)(const void *) = kfree; -+#else -+void *(*pcre_malloc)(size_t) = malloc; -+void (*pcre_free)(const void *) = free; -+#endif -+ -+ -+/************************************************* -+ * * Macros and tables for character handling * -+ * *************************************************/ -+ -+/* When UTF-8 encoding is being used, a character is no longer just a single -+ * byte. The macros for character handling generate simple sequences when used in -+ * byte-mode, and more complicated ones for UTF-8 characters. */ -+ -+#ifndef SUPPORT_UTF8 -+#define GETCHARINC(c, eptr) c = *eptr++; -+#define GETCHARLEN(c, eptr, len) c = *eptr; -+#define BACKCHAR(eptr) -+#endif -+ -+/* ---- CODE DELETED ---- */ -+ -+#ifdef DEBUG -+/************************************************* -+* Debugging function to print chars * -+*************************************************/ -+ -+/* Print a sequence of chars in printable format, stopping at the end of the -+subject if the requested. -+ -+Arguments: -+ p points to characters -+ length number to print -+ is_subject TRUE if printing from within md->start_subject -+ md pointer to matching data block, if is_subject is TRUE -+ -+Returns: nothing -+*/ -+ -+static void -+pchars(const uschar *p, int length, BOOL is_subject, match_data *md) -+{ -+int c; -+if (is_subject && length > md->end_subject - p) length = md->end_subject - p; -+while (length-- > 0) -+ if (isprint(c = *(p++))) PCRE_PRINTF("%c", c); else PCRE_PRINTF("\\x%02x", c); -+} -+#endif /* DEBUG */ -+ -+/* ---- CODE DELETED ---- */ -+ -+ -+/************************************************* -+* Match a back-reference * -+*************************************************/ -+ -+/* If a back reference hasn't been set, the length that is passed is greater -+than the number of characters left in the string, so the match fails. -+ -+Arguments: -+ offset index into the offset vector -+ eptr points into the subject -+ length length to be matched -+ md points to match data block -+ ims the ims flags -+ -+Returns: TRUE if matched -+*/ -+ -+static BOOL -+match_ref(int offset, register const uschar *eptr, int length, match_data *md, -+ unsigned long int ims) -+{ -+const uschar *p = md->start_subject + md->offset_vector[offset]; -+ -+#ifdef DEBUG -+if (eptr >= md->end_subject) -+ PCRE_PRINTF("matching subject "); -+else -+ { -+ PCRE_PRINTF("matching subject "); -+ pchars(eptr, length, TRUE, md); -+ } -+PCRE_PRINTF(" against backref "); -+pchars(p, length, FALSE, md); -+PCRE_PRINTF("\n"); -+#endif -+ -+/* Always fail if not enough characters left */ -+ -+if (length > md->end_subject - eptr) return FALSE; -+ -+/* Separate the caselesss case for speed */ -+ -+if ((ims & PCRE_CASELESS) != 0) -+ { -+ while (length-- > 0) -+ if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; -+ } -+else -+ { while (length-- > 0) if (*p++ != *eptr++) return FALSE; } -+ -+return TRUE; -+} -+ -+ -+/************************************************* -+* Match from current position * -+*************************************************/ -+ -+/* On entry ecode points to the first opcode, and eptr to the first character -+in the subject string, while eptrb holds the value of eptr at the start of the -+last bracketed group - used for breaking infinite loops matching zero-length -+strings. -+ -+Arguments: -+ eptr pointer in subject -+ ecode position in code -+ offset_top current top pointer -+ md pointer to "static" info for the match -+ ims current /i, /m, and /s options -+ eptrb pointer to chain of blocks containing eptr at start of -+ brackets - for testing for empty matches -+ flags can contain -+ match_condassert - this is an assertion condition -+ match_isgroup - this is the start of a bracketed group -+ -+Returns: TRUE if matched -+*/ -+ -+static BOOL -+match(register const uschar *eptr, register const uschar *ecode, -+ int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb, -+ int flags) -+{ -+unsigned long int original_ims = ims; /* Save for resetting on ')' */ -+eptrblock newptrb; -+ -+/* At the start of a bracketed group, add the current subject pointer to the -+stack of such pointers, to be re-instated at the end of the group when we hit -+the closing ket. When match() is called in other circumstances, we don't add to -+the stack. */ -+ -+if ((flags & match_isgroup) != 0) -+ { -+ newptrb.prev = eptrb; -+ newptrb.saved_eptr = eptr; -+ eptrb = &newptrb; -+ } -+ -+/* Now start processing the operations. */ -+ -+for (;;) -+ { -+ int op = (int)*ecode; -+ int min, max, ctype; -+ register int i; -+ register int c; -+ BOOL minimize = FALSE; -+ -+ /* Opening capturing bracket. If there is space in the offset vector, save -+ the current subject position in the working slot at the top of the vector. We -+ mustn't change the current values of the data slot, because they may be set -+ from a previous iteration of this group, and be referred to by a reference -+ inside the group. -+ -+ If the bracket fails to match, we need to restore this value and also the -+ values of the final offsets, in case they were set by a previous iteration of -+ the same bracket. -+ -+ If there isn't enough space in the offset vector, treat this as if it were a -+ non-capturing bracket. Don't worry about setting the flag for the error case -+ here; that is handled in the code for KET. */ -+ -+ if (op > OP_BRA) -+ { -+ int offset; -+ int number = op - OP_BRA; -+ -+ /* For extended extraction brackets (large number), we have to fish out the -+ number from a dummy opcode at the start. */ -+ -+ if (number > EXTRACT_BASIC_MAX) number = (ecode[4] << 8) | ecode[5]; -+ offset = number << 1; -+ -+#ifdef DEBUG -+ PCRE_PRINTF("start bracket %d subject=", number); -+ pchars(eptr, 16, TRUE, md); -+ PCRE_PRINTF("\n"); -+#endif -+ -+ if (offset < md->offset_max) -+ { -+ int save_offset1 = md->offset_vector[offset]; -+ int save_offset2 = md->offset_vector[offset+1]; -+ int save_offset3 = md->offset_vector[md->offset_end - number]; -+ -+ DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); -+ md->offset_vector[md->offset_end - number] = eptr - md->start_subject; -+ -+ do -+ { -+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup)) -+ return TRUE; -+ ecode += (ecode[1] << 8) + ecode[2]; -+ } -+ while (*ecode == OP_ALT); -+ -+ DPRINTF(("bracket %d failed\n", number)); -+ -+ md->offset_vector[offset] = save_offset1; -+ md->offset_vector[offset+1] = save_offset2; -+ md->offset_vector[md->offset_end - number] = save_offset3; -+ -+ return FALSE; -+ } -+ -+ /* Insufficient room for saving captured contents */ -+ -+ else op = OP_BRA; -+ } -+ -+ /* Other types of node can be handled by a switch */ -+ -+ switch(op) -+ { -+ case OP_BRA: /* Non-capturing bracket: optimized */ -+ DPRINTF(("start bracket 0\n")); -+ do -+ { -+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup)) -+ return TRUE; -+ ecode += (ecode[1] << 8) + ecode[2]; -+ } -+ while (*ecode == OP_ALT); -+ DPRINTF(("bracket 0 failed\n")); -+ return FALSE; -+ -+ /* Conditional group: compilation checked that there are no more than -+ two branches. If the condition is false, skipping the first branch takes us -+ past the end if there is only one branch, but that's OK because that is -+ exactly what going to the ket would do. */ -+ -+ case OP_COND: -+ if (ecode[3] == OP_CREF) /* Condition is extraction test */ -+ { -+ int offset = (ecode[4] << 9) | (ecode[5] << 1); /* Doubled ref number */ -+ return match(eptr, -+ ecode + ((offset < offset_top && md->offset_vector[offset] >= 0)? -+ 6 : 3 + (ecode[1] << 8) + ecode[2]), -+ offset_top, md, ims, eptrb, match_isgroup); -+ } -+ -+ /* The condition is an assertion. Call match() to evaluate it - setting -+ the final argument TRUE causes it to stop at the end of an assertion. */ -+ -+ else -+ { -+ if (match(eptr, ecode+3, offset_top, md, ims, NULL, -+ match_condassert | match_isgroup)) -+ { -+ ecode += 3 + (ecode[4] << 8) + ecode[5]; -+ while (*ecode == OP_ALT) ecode += (ecode[1] << 8) + ecode[2]; -+ } -+ else ecode += (ecode[1] << 8) + ecode[2]; -+ return match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup); -+ } -+ /* Control never reaches here */ -+ -+ /* Skip over conditional reference or large extraction number data if -+ encountered. */ -+ -+ case OP_CREF: -+ case OP_BRANUMBER: -+ ecode += 3; -+ break; -+ -+ /* End of the pattern. If PCRE_NOTEMPTY is set, fail if we have matched -+ an empty string - recursion will then try other alternatives, if any. */ -+ -+ case OP_END: -+ if (md->notempty && eptr == md->start_match) return FALSE; -+ md->end_match_ptr = eptr; /* Record where we ended */ -+ md->end_offset_top = offset_top; /* and how many extracts were taken */ -+ return TRUE; -+ -+ /* Change option settings */ -+ -+ case OP_OPT: -+ ims = ecode[1]; -+ ecode += 2; -+ DPRINTF(("ims set to %02lx\n", ims)); -+ break; -+ -+ /* Assertion brackets. Check the alternative branches in turn - the -+ matching won't pass the KET for an assertion. If any one branch matches, -+ the assertion is true. Lookbehind assertions have an OP_REVERSE item at the -+ start of each branch to move the current point backwards, so the code at -+ this level is identical to the lookahead case. */ -+ -+ case OP_ASSERT: -+ case OP_ASSERTBACK: -+ do -+ { -+ if (match(eptr, ecode+3, offset_top, md, ims, NULL, match_isgroup)) break; -+ ecode += (ecode[1] << 8) + ecode[2]; -+ } -+ while (*ecode == OP_ALT); -+ if (*ecode == OP_KET) return FALSE; -+ -+ /* If checking an assertion for a condition, return TRUE. */ -+ -+ if ((flags & match_condassert) != 0) return TRUE; -+ -+ /* Continue from after the assertion, updating the offsets high water -+ mark, since extracts may have been taken during the assertion. */ -+ -+ do ecode += (ecode[1] << 8) + ecode[2]; while (*ecode == OP_ALT); -+ ecode += 3; -+ offset_top = md->end_offset_top; -+ continue; -+ -+ /* Negative assertion: all branches must fail to match */ -+ -+ case OP_ASSERT_NOT: -+ case OP_ASSERTBACK_NOT: -+ do -+ { -+ if (match(eptr, ecode+3, offset_top, md, ims, NULL, match_isgroup)) -+ return FALSE; -+ ecode += (ecode[1] << 8) + ecode[2]; -+ } -+ while (*ecode == OP_ALT); -+ -+ if ((flags & match_condassert) != 0) return TRUE; -+ -+ ecode += 3; -+ continue; -+ -+ /* Move the subject pointer back. This occurs only at the start of -+ each branch of a lookbehind assertion. If we are too close to the start to -+ move back, this match function fails. When working with UTF-8 we move -+ back a number of characters, not bytes. */ -+ -+ case OP_REVERSE: -+#ifdef SUPPORT_UTF8 -+ c = (ecode[1] << 8) + ecode[2]; -+ for (i = 0; i < c; i++) -+ { -+ eptr--; -+ BACKCHAR(eptr) -+ } -+#else -+ eptr -= (ecode[1] << 8) + ecode[2]; -+#endif -+ -+ if (eptr < md->start_subject) return FALSE; -+ ecode += 3; -+ break; -+ -+ /* Recursion matches the current regex, nested. If there are any capturing -+ brackets started but not finished, we have to save their starting points -+ and reinstate them after the recursion. However, we don't know how many -+ such there are (offset_top records the completed total) so we just have -+ to save all the potential data. There may be up to 99 such values, which -+ is a bit large to put on the stack, but using malloc for small numbers -+ seems expensive. As a compromise, the stack is used when there are fewer -+ than 16 values to store; otherwise malloc is used. A problem is what to do -+ if the malloc fails ... there is no way of returning to the top level with -+ an error. Save the top 15 values on the stack, and accept that the rest -+ may be wrong. */ -+ -+ case OP_RECURSE: -+ { -+ BOOL rc; -+ int *save; -+ int stacksave[15]; -+ -+ c = md->offset_max; -+ -+ if (c < 16) save = stacksave; else -+ { -+ save = (int *)(pcre_malloc)((c+1) * sizeof(int)); -+ if (save == NULL) -+ { -+ save = stacksave; -+ c = 15; -+ } -+ } -+ -+ for (i = 1; i <= c; i++) -+ save[i] = md->offset_vector[md->offset_end - i]; -+ rc = match(eptr, md->start_pattern, offset_top, md, ims, eptrb, -+ match_isgroup); -+ for (i = 1; i <= c; i++) -+ md->offset_vector[md->offset_end - i] = save[i]; -+ if (save != stacksave) (pcre_free)(save); -+ if (!rc) return FALSE; -+ -+ /* In case the recursion has set more capturing values, save the final -+ number, then move along the subject till after the recursive match, -+ and advance one byte in the pattern code. */ -+ -+ offset_top = md->end_offset_top; -+ eptr = md->end_match_ptr; -+ ecode++; -+ } -+ break; -+ -+ /* "Once" brackets are like assertion brackets except that after a match, -+ the point in the subject string is not moved back. Thus there can never be -+ a move back into the brackets. Check the alternative branches in turn - the -+ matching won't pass the KET for this kind of subpattern. If any one branch -+ matches, we carry on as at the end of a normal bracket, leaving the subject -+ pointer. */ -+ -+ case OP_ONCE: -+ { -+ const uschar *prev = ecode; -+ const uschar *saved_eptr = eptr; -+ -+ do -+ { -+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup)) -+ break; -+ ecode += (ecode[1] << 8) + ecode[2]; -+ } -+ while (*ecode == OP_ALT); -+ -+ /* If hit the end of the group (which could be repeated), fail */ -+ -+ if (*ecode != OP_ONCE && *ecode != OP_ALT) return FALSE; -+ -+ /* Continue as from after the assertion, updating the offsets high water -+ mark, since extracts may have been taken. */ -+ -+ do ecode += (ecode[1] << 8) + ecode[2]; while (*ecode == OP_ALT); -+ -+ offset_top = md->end_offset_top; -+ eptr = md->end_match_ptr; -+ -+ /* For a non-repeating ket, just continue at this level. This also -+ happens for a repeating ket if no characters were matched in the group. -+ This is the forcible breaking of infinite loops as implemented in Perl -+ 5.005. If there is an options reset, it will get obeyed in the normal -+ course of events. */ -+ -+ if (*ecode == OP_KET || eptr == saved_eptr) -+ { -+ ecode += 3; -+ break; -+ } -+ -+ /* The repeating kets try the rest of the pattern or restart from the -+ preceding bracket, in the appropriate order. We need to reset any options -+ that changed within the bracket before re-running it, so check the next -+ opcode. */ -+ -+ if (ecode[3] == OP_OPT) -+ { -+ ims = (ims & ~PCRE_IMS) | ecode[4]; -+ DPRINTF(("ims set to %02lx at group repeat\n", ims)); -+ } -+ -+ if (*ecode == OP_KETRMIN) -+ { -+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, 0) || -+ match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup)) -+ return TRUE; -+ } -+ else /* OP_KETRMAX */ -+ { -+ if (match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup) || -+ match(eptr, ecode+3, offset_top, md, ims, eptrb, 0)) return TRUE; -+ } -+ } -+ return FALSE; -+ -+ /* An alternation is the end of a branch; scan along to find the end of the -+ bracketed group and go to there. */ -+ -+ case OP_ALT: -+ do ecode += (ecode[1] << 8) + ecode[2]; while (*ecode == OP_ALT); -+ break; -+ -+ /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating -+ that it may occur zero times. It may repeat infinitely, or not at all - -+ i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper -+ repeat limits are compiled as a number of copies, with the optional ones -+ preceded by BRAZERO or BRAMINZERO. */ -+ -+ case OP_BRAZERO: -+ { -+ const uschar *next = ecode+1; -+ if (match(eptr, next, offset_top, md, ims, eptrb, match_isgroup)) -+ return TRUE; -+ do next += (next[1] << 8) + next[2]; while (*next == OP_ALT); -+ ecode = next + 3; -+ } -+ break; -+ -+ case OP_BRAMINZERO: -+ { -+ const uschar *next = ecode+1; -+ do next += (next[1] << 8) + next[2]; while (*next == OP_ALT); -+ if (match(eptr, next+3, offset_top, md, ims, eptrb, match_isgroup)) -+ return TRUE; -+ ecode++; -+ } -+ break; -+ -+ /* End of a group, repeated or non-repeating. If we are at the end of -+ an assertion "group", stop matching and return TRUE, but record the -+ current high water mark for use by positive assertions. Do this also -+ for the "once" (not-backup up) groups. */ -+ -+ case OP_KET: -+ case OP_KETRMIN: -+ case OP_KETRMAX: -+ { -+ const uschar *prev = ecode - (ecode[1] << 8) - ecode[2]; -+ const uschar *saved_eptr = eptrb->saved_eptr; -+ -+ eptrb = eptrb->prev; /* Back up the stack of bracket start pointers */ -+ -+ if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT || -+ *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT || -+ *prev == OP_ONCE) -+ { -+ md->end_match_ptr = eptr; /* For ONCE */ -+ md->end_offset_top = offset_top; -+ return TRUE; -+ } -+ -+ /* In all other cases except a conditional group we have to check the -+ group number back at the start and if necessary complete handling an -+ extraction by setting the offsets and bumping the high water mark. */ -+ -+ if (*prev != OP_COND) -+ { -+ int offset; -+ int number = *prev - OP_BRA; -+ -+ /* For extended extraction brackets (large number), we have to fish out -+ the number from a dummy opcode at the start. */ -+ -+ if (number > EXTRACT_BASIC_MAX) number = (prev[4] << 8) | prev[5]; -+ offset = number << 1; -+ -+#ifdef DEBUG -+ PCRE_PRINTF("end bracket %d", number); -+ PCRE_PRINTF("\n"); -+#endif -+ -+ if (number > 0) -+ { -+ if (offset >= md->offset_max) md->offset_overflow = TRUE; else -+ { -+ md->offset_vector[offset] = -+ md->offset_vector[md->offset_end - number]; -+ md->offset_vector[offset+1] = eptr - md->start_subject; -+ if (offset_top <= offset) offset_top = offset + 2; -+ } -+ } -+ } -+ -+ /* Reset the value of the ims flags, in case they got changed during -+ the group. */ -+ -+ ims = original_ims; -+ DPRINTF(("ims reset to %02lx\n", ims)); -+ -+ /* For a non-repeating ket, just continue at this level. This also -+ happens for a repeating ket if no characters were matched in the group. -+ This is the forcible breaking of infinite loops as implemented in Perl -+ 5.005. If there is an options reset, it will get obeyed in the normal -+ course of events. */ -+ -+ if (*ecode == OP_KET || eptr == saved_eptr) -+ { -+ ecode += 3; -+ break; -+ } -+ -+ /* The repeating kets try the rest of the pattern or restart from the -+ preceding bracket, in the appropriate order. */ -+ -+ if (*ecode == OP_KETRMIN) -+ { -+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, 0) || -+ match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup)) -+ return TRUE; -+ } -+ else /* OP_KETRMAX */ -+ { -+ if (match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup) || -+ match(eptr, ecode+3, offset_top, md, ims, eptrb, 0)) return TRUE; -+ } -+ } -+ return FALSE; -+ -+ /* Start of subject unless notbol, or after internal newline if multiline */ -+ -+ case OP_CIRC: -+ if (md->notbol && eptr == md->start_subject) return FALSE; -+ if ((ims & PCRE_MULTILINE) != 0) -+ { -+ if (eptr != md->start_subject && eptr[-1] != NEWLINE) return FALSE; -+ ecode++; -+ break; -+ } -+ /* ... else fall through */ -+ -+ /* Start of subject assertion */ -+ -+ case OP_SOD: -+ if (eptr != md->start_subject) return FALSE; -+ ecode++; -+ break; -+ -+ /* Assert before internal newline if multiline, or before a terminating -+ newline unless endonly is set, else end of subject unless noteol is set. */ -+ -+ case OP_DOLL: -+ if ((ims & PCRE_MULTILINE) != 0) -+ { -+ if (eptr < md->end_subject) { if (*eptr != NEWLINE) return FALSE; } -+ else { if (md->noteol) return FALSE; } -+ ecode++; -+ break; -+ } -+ else -+ { -+ if (md->noteol) return FALSE; -+ if (!md->endonly) -+ { -+ if (eptr < md->end_subject - 1 || -+ (eptr == md->end_subject - 1 && *eptr != NEWLINE)) return FALSE; -+ -+ ecode++; -+ break; -+ } -+ } -+ /* ... else fall through */ -+ -+ /* End of subject assertion (\z) */ -+ -+ case OP_EOD: -+ if (eptr < md->end_subject) return FALSE; -+ ecode++; -+ break; -+ -+ /* End of subject or ending \n assertion (\Z) */ -+ -+ case OP_EODN: -+ if (eptr < md->end_subject - 1 || -+ (eptr == md->end_subject - 1 && *eptr != NEWLINE)) return FALSE; -+ ecode++; -+ break; -+ -+ /* Word boundary assertions */ -+ -+ case OP_NOT_WORD_BOUNDARY: -+ case OP_WORD_BOUNDARY: -+ { -+ BOOL prev_is_word = (eptr != md->start_subject) && -+ ((md->ctypes[eptr[-1]] & ctype_word) != 0); -+ BOOL cur_is_word = (eptr < md->end_subject) && -+ ((md->ctypes[*eptr] & ctype_word) != 0); -+ if ((*ecode++ == OP_WORD_BOUNDARY)? -+ cur_is_word == prev_is_word : cur_is_word != prev_is_word) -+ return FALSE; -+ } -+ break; -+ -+ /* Match a single character type; inline for speed */ -+ -+ case OP_ANY: -+ if ((ims & PCRE_DOTALL) == 0 && eptr < md->end_subject && *eptr == NEWLINE) -+ return FALSE; -+ if (eptr++ >= md->end_subject) return FALSE; -+#ifdef SUPPORT_UTF8 -+ if (md->utf8) -+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; -+#endif -+ ecode++; -+ break; -+ -+ case OP_NOT_DIGIT: -+ if (eptr >= md->end_subject || -+ (md->ctypes[*eptr++] & ctype_digit) != 0) -+ return FALSE; -+ ecode++; -+ break; -+ -+ case OP_DIGIT: -+ if (eptr >= md->end_subject || -+ (md->ctypes[*eptr++] & ctype_digit) == 0) -+ return FALSE; -+ ecode++; -+ break; -+ -+ case OP_NOT_WHITESPACE: -+ if (eptr >= md->end_subject || -+ (md->ctypes[*eptr++] & ctype_space) != 0) -+ return FALSE; -+ ecode++; -+ break; -+ -+ case OP_WHITESPACE: -+ if (eptr >= md->end_subject || -+ (md->ctypes[*eptr++] & ctype_space) == 0) -+ return FALSE; -+ ecode++; -+ break; -+ -+ case OP_NOT_WORDCHAR: -+ if (eptr >= md->end_subject || -+ (md->ctypes[*eptr++] & ctype_word) != 0) -+ return FALSE; -+ ecode++; -+ break; -+ -+ case OP_WORDCHAR: -+ if (eptr >= md->end_subject || -+ (md->ctypes[*eptr++] & ctype_word) == 0) -+ return FALSE; -+ ecode++; -+ break; -+ -+ /* Match a back reference, possibly repeatedly. Look past the end of the -+ item to see if there is repeat information following. The code is similar -+ to that for character classes, but repeated for efficiency. Then obey -+ similar code to character type repeats - written out again for speed. -+ However, if the referenced string is the empty string, always treat -+ it as matched, any number of times (otherwise there could be infinite -+ loops). */ -+ -+ case OP_REF: -+ { -+ int length; -+ int offset = (ecode[1] << 9) | (ecode[2] << 1); /* Doubled ref number */ -+ ecode += 3; /* Advance past item */ -+ -+ /* If the reference is unset, set the length to be longer than the amount -+ of subject left; this ensures that every attempt at a match fails. We -+ can't just fail here, because of the possibility of quantifiers with zero -+ minima. */ -+ -+ length = (offset >= offset_top || md->offset_vector[offset] < 0)? -+ md->end_subject - eptr + 1 : -+ md->offset_vector[offset+1] - md->offset_vector[offset]; -+ -+ /* Set up for repetition, or handle the non-repeated case */ -+ -+ switch (*ecode) -+ { -+ case OP_CRSTAR: -+ case OP_CRMINSTAR: -+ case OP_CRPLUS: -+ case OP_CRMINPLUS: -+ case OP_CRQUERY: -+ case OP_CRMINQUERY: -+ c = *ecode++ - OP_CRSTAR; -+ minimize = (c & 1) != 0; -+ min = rep_min[c]; /* Pick up values from tables; */ -+ max = rep_max[c]; /* zero for max => infinity */ -+ if (max == 0) max = INT_MAX; -+ break; -+ -+ case OP_CRRANGE: -+ case OP_CRMINRANGE: -+ minimize = (*ecode == OP_CRMINRANGE); -+ min = (ecode[1] << 8) + ecode[2]; -+ max = (ecode[3] << 8) + ecode[4]; -+ if (max == 0) max = INT_MAX; -+ ecode += 5; -+ break; -+ -+ default: /* No repeat follows */ -+ if (!match_ref(offset, eptr, length, md, ims)) return FALSE; -+ eptr += length; -+ continue; /* With the main loop */ -+ } -+ -+ /* If the length of the reference is zero, just continue with the -+ main loop. */ -+ -+ if (length == 0) continue; -+ -+ /* First, ensure the minimum number of matches are present. We get back -+ the length of the reference string explicitly rather than passing the -+ address of eptr, so that eptr can be a register variable. */ -+ -+ for (i = 1; i <= min; i++) -+ { -+ if (!match_ref(offset, eptr, length, md, ims)) return FALSE; -+ eptr += length; -+ } -+ -+ /* If min = max, continue at the same level without recursion. -+ They are not both allowed to be zero. */ -+ -+ if (min == max) continue; -+ -+ /* If minimizing, keep trying and advancing the pointer */ -+ -+ if (minimize) -+ { -+ for (i = min;; i++) -+ { -+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ if (i >= max || !match_ref(offset, eptr, length, md, ims)) -+ return FALSE; -+ eptr += length; -+ } -+ /* Control never gets here */ -+ } -+ -+ /* If maximizing, find the longest string and work backwards */ -+ -+ else -+ { -+ const uschar *pp = eptr; -+ for (i = min; i < max; i++) -+ { -+ if (!match_ref(offset, eptr, length, md, ims)) break; -+ eptr += length; -+ } -+ while (eptr >= pp) -+ { -+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ eptr -= length; -+ } -+ return FALSE; -+ } -+ } -+ /* Control never gets here */ -+ -+ -+ -+ /* Match a character class, possibly repeatedly. Look past the end of the -+ item to see if there is repeat information following. Then obey similar -+ code to character type repeats - written out again for speed. */ -+ -+ case OP_CLASS: -+ { -+ const uschar *data = ecode + 1; /* Save for matching */ -+ ecode += 33; /* Advance past the item */ -+ -+ switch (*ecode) -+ { -+ case OP_CRSTAR: -+ case OP_CRMINSTAR: -+ case OP_CRPLUS: -+ case OP_CRMINPLUS: -+ case OP_CRQUERY: -+ case OP_CRMINQUERY: -+ c = *ecode++ - OP_CRSTAR; -+ minimize = (c & 1) != 0; -+ min = rep_min[c]; /* Pick up values from tables; */ -+ max = rep_max[c]; /* zero for max => infinity */ -+ if (max == 0) max = INT_MAX; -+ break; -+ -+ case OP_CRRANGE: -+ case OP_CRMINRANGE: -+ minimize = (*ecode == OP_CRMINRANGE); -+ min = (ecode[1] << 8) + ecode[2]; -+ max = (ecode[3] << 8) + ecode[4]; -+ if (max == 0) max = INT_MAX; -+ ecode += 5; -+ break; -+ -+ default: /* No repeat follows */ -+ min = max = 1; -+ break; -+ } -+ -+ /* First, ensure the minimum number of matches are present. */ -+ -+ for (i = 1; i <= min; i++) -+ { -+ if (eptr >= md->end_subject) return FALSE; -+ GETCHARINC(c, eptr) /* Get character; increment eptr */ -+ -+#ifdef SUPPORT_UTF8 -+ /* We do not yet support class members > 255 */ -+ if (c > 255) return FALSE; -+#endif -+ -+ if ((data[c/8] & (1 << (c&7))) != 0) continue; -+ return FALSE; -+ } -+ -+ /* If max == min we can continue with the main loop without the -+ need to recurse. */ -+ -+ if (min == max) continue; -+ -+ /* If minimizing, keep testing the rest of the expression and advancing -+ the pointer while it matches the class. */ -+ -+ if (minimize) -+ { -+ for (i = min;; i++) -+ { -+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ if (i >= max || eptr >= md->end_subject) return FALSE; -+ GETCHARINC(c, eptr) /* Get character; increment eptr */ -+ -+#ifdef SUPPORT_UTF8 -+ /* We do not yet support class members > 255 */ -+ if (c > 255) return FALSE; -+#endif -+ if ((data[c/8] & (1 << (c&7))) != 0) continue; -+ return FALSE; -+ } -+ /* Control never gets here */ -+ } -+ -+ /* If maximizing, find the longest possible run, then work backwards. */ -+ -+ else -+ { -+ const uschar *pp = eptr; -+ int len = 1; -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject) break; -+ GETCHARLEN(c, eptr, len) /* Get character, set length if UTF-8 */ -+ -+#ifdef SUPPORT_UTF8 -+ /* We do not yet support class members > 255 */ -+ if (c > 255) break; -+#endif -+ if ((data[c/8] & (1 << (c&7))) == 0) break; -+ eptr += len; -+ } -+ -+ while (eptr >= pp) -+ { -+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ -+#ifdef SUPPORT_UTF8 -+ BACKCHAR(eptr) -+#endif -+ } -+ return FALSE; -+ } -+ } -+ /* Control never gets here */ -+ -+ /* Match a run of characters */ -+ -+ case OP_CHARS: -+ { -+ register int length = ecode[1]; -+ ecode += 2; -+ -+#ifdef DEBUG /* Sigh. Some compilers never learn. */ -+ if (eptr >= md->end_subject) -+ PCRE_PRINTF("matching subject against pattern "); -+ else -+ { -+ PCRE_PRINTF("matching subject "); -+ pchars(eptr, length, TRUE, md); -+ PCRE_PRINTF(" against pattern "); -+ } -+ pchars(ecode, length, FALSE, md); -+ PCRE_PRINTF("\n"); -+#endif -+ -+ if (length > md->end_subject - eptr) return FALSE; -+ if ((ims & PCRE_CASELESS) != 0) -+ { -+ while (length-- > 0) -+ if (md->lcc[*ecode++] != md->lcc[*eptr++]) -+ return FALSE; -+ } -+ else -+ { -+ while (length-- > 0) if (*ecode++ != *eptr++) return FALSE; -+ } -+ } -+ break; -+ -+ /* Match a single character repeatedly; different opcodes share code. */ -+ -+ case OP_EXACT: -+ min = max = (ecode[1] << 8) + ecode[2]; -+ ecode += 3; -+ goto REPEATCHAR; -+ -+ case OP_UPTO: -+ case OP_MINUPTO: -+ min = 0; -+ max = (ecode[1] << 8) + ecode[2]; -+ minimize = *ecode == OP_MINUPTO; -+ ecode += 3; -+ goto REPEATCHAR; -+ -+ case OP_STAR: -+ case OP_MINSTAR: -+ case OP_PLUS: -+ case OP_MINPLUS: -+ case OP_QUERY: -+ case OP_MINQUERY: -+ c = *ecode++ - OP_STAR; -+ minimize = (c & 1) != 0; -+ min = rep_min[c]; /* Pick up values from tables; */ -+ max = rep_max[c]; /* zero for max => infinity */ -+ if (max == 0) max = INT_MAX; -+ -+ /* Common code for all repeated single-character matches. We can give -+ up quickly if there are fewer than the minimum number of characters left in -+ the subject. */ -+ -+ REPEATCHAR: -+ if (min > md->end_subject - eptr) return FALSE; -+ c = *ecode++; -+ -+ /* The code is duplicated for the caseless and caseful cases, for speed, -+ since matching characters is likely to be quite common. First, ensure the -+ minimum number of matches are present. If min = max, continue at the same -+ level without recursing. Otherwise, if minimizing, keep trying the rest of -+ the expression and advancing one matching character if failing, up to the -+ maximum. Alternatively, if maximizing, find the maximum number of -+ characters and work backwards. */ -+ -+ DPRINTF(("matching %c{%d,%d} against subject %.*s\n", c, min, max, -+ max, eptr)); -+ -+ if ((ims & PCRE_CASELESS) != 0) -+ { -+ c = md->lcc[c]; -+ for (i = 1; i <= min; i++) -+ if (c != md->lcc[*eptr++]) return FALSE; -+ if (min == max) continue; -+ if (minimize) -+ { -+ for (i = min;; i++) -+ { -+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ if (i >= max || eptr >= md->end_subject || -+ c != md->lcc[*eptr++]) -+ return FALSE; -+ } -+ /* Control never gets here */ -+ } -+ else -+ { -+ const uschar *pp = eptr; -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || c != md->lcc[*eptr]) break; -+ eptr++; -+ } -+ while (eptr >= pp) -+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ return FALSE; -+ } -+ /* Control never gets here */ -+ } -+ -+ /* Caseful comparisons */ -+ -+ else -+ { -+ for (i = 1; i <= min; i++) if (c != *eptr++) return FALSE; -+ if (min == max) continue; -+ if (minimize) -+ { -+ for (i = min;; i++) -+ { -+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ if (i >= max || eptr >= md->end_subject || c != *eptr++) return FALSE; -+ } -+ /* Control never gets here */ -+ } -+ else -+ { -+ const uschar *pp = eptr; -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || c != *eptr) break; -+ eptr++; -+ } -+ while (eptr >= pp) -+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ return FALSE; -+ } -+ } -+ /* Control never gets here */ -+ -+ /* Match a negated single character */ -+ -+ case OP_NOT: -+ if (eptr >= md->end_subject) return FALSE; -+ ecode++; -+ if ((ims & PCRE_CASELESS) != 0) -+ { -+ if (md->lcc[*ecode++] == md->lcc[*eptr++]) return FALSE; -+ } -+ else -+ { -+ if (*ecode++ == *eptr++) return FALSE; -+ } -+ break; -+ -+ /* Match a negated single character repeatedly. This is almost a repeat of -+ the code for a repeated single character, but I haven't found a nice way of -+ commoning these up that doesn't require a test of the positive/negative -+ option for each character match. Maybe that wouldn't add very much to the -+ time taken, but character matching *is* what this is all about... */ -+ -+ case OP_NOTEXACT: -+ min = max = (ecode[1] << 8) + ecode[2]; -+ ecode += 3; -+ goto REPEATNOTCHAR; -+ -+ case OP_NOTUPTO: -+ case OP_NOTMINUPTO: -+ min = 0; -+ max = (ecode[1] << 8) + ecode[2]; -+ minimize = *ecode == OP_NOTMINUPTO; -+ ecode += 3; -+ goto REPEATNOTCHAR; -+ -+ case OP_NOTSTAR: -+ case OP_NOTMINSTAR: -+ case OP_NOTPLUS: -+ case OP_NOTMINPLUS: -+ case OP_NOTQUERY: -+ case OP_NOTMINQUERY: -+ c = *ecode++ - OP_NOTSTAR; -+ minimize = (c & 1) != 0; -+ min = rep_min[c]; /* Pick up values from tables; */ -+ max = rep_max[c]; /* zero for max => infinity */ -+ if (max == 0) max = INT_MAX; -+ -+ /* Common code for all repeated single-character matches. We can give -+ up quickly if there are fewer than the minimum number of characters left in -+ the subject. */ -+ -+ REPEATNOTCHAR: -+ if (min > md->end_subject - eptr) return FALSE; -+ c = *ecode++; -+ -+ /* The code is duplicated for the caseless and caseful cases, for speed, -+ since matching characters is likely to be quite common. First, ensure the -+ minimum number of matches are present. If min = max, continue at the same -+ level without recursing. Otherwise, if minimizing, keep trying the rest of -+ the expression and advancing one matching character if failing, up to the -+ maximum. Alternatively, if maximizing, find the maximum number of -+ characters and work backwards. */ -+ -+ DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", c, min, max, -+ max, eptr)); -+ -+ if ((ims & PCRE_CASELESS) != 0) -+ { -+ c = md->lcc[c]; -+ for (i = 1; i <= min; i++) -+ if (c == md->lcc[*eptr++]) return FALSE; -+ if (min == max) continue; -+ if (minimize) -+ { -+ for (i = min;; i++) -+ { -+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ if (i >= max || eptr >= md->end_subject || -+ c == md->lcc[*eptr++]) -+ return FALSE; -+ } -+ /* Control never gets here */ -+ } -+ else -+ { -+ const uschar *pp = eptr; -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || c == md->lcc[*eptr]) break; -+ eptr++; -+ } -+ while (eptr >= pp) -+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ return FALSE; -+ } -+ /* Control never gets here */ -+ } -+ -+ /* Caseful comparisons */ -+ -+ else -+ { -+ for (i = 1; i <= min; i++) if (c == *eptr++) return FALSE; -+ if (min == max) continue; -+ if (minimize) -+ { -+ for (i = min;; i++) -+ { -+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ if (i >= max || eptr >= md->end_subject || c == *eptr++) return FALSE; -+ } -+ /* Control never gets here */ -+ } -+ else -+ { -+ const uschar *pp = eptr; -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || c == *eptr) break; -+ eptr++; -+ } -+ while (eptr >= pp) -+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+ return FALSE; -+ } -+ } -+ /* Control never gets here */ -+ -+ /* Match a single character type repeatedly; several different opcodes -+ share code. This is very similar to the code for single characters, but we -+ repeat it in the interests of efficiency. */ -+ -+ case OP_TYPEEXACT: -+ min = max = (ecode[1] << 8) + ecode[2]; -+ minimize = TRUE; -+ ecode += 3; -+ goto REPEATTYPE; -+ -+ case OP_TYPEUPTO: -+ case OP_TYPEMINUPTO: -+ min = 0; -+ max = (ecode[1] << 8) + ecode[2]; -+ minimize = *ecode == OP_TYPEMINUPTO; -+ ecode += 3; -+ goto REPEATTYPE; -+ -+ case OP_TYPESTAR: -+ case OP_TYPEMINSTAR: -+ case OP_TYPEPLUS: -+ case OP_TYPEMINPLUS: -+ case OP_TYPEQUERY: -+ case OP_TYPEMINQUERY: -+ c = *ecode++ - OP_TYPESTAR; -+ minimize = (c & 1) != 0; -+ min = rep_min[c]; /* Pick up values from tables; */ -+ max = rep_max[c]; /* zero for max => infinity */ -+ if (max == 0) max = INT_MAX; -+ -+ /* Common code for all repeated single character type matches */ -+ -+ REPEATTYPE: -+ ctype = *ecode++; /* Code for the character type */ -+ -+ /* First, ensure the minimum number of matches are present. Use inline -+ code for maximizing the speed, and do the type test once at the start -+ (i.e. keep it out of the loop). Also we can test that there are at least -+ the minimum number of bytes before we start, except when doing '.' in -+ UTF8 mode. Leave the test in in all cases; in the special case we have -+ to test after each character. */ -+ -+ if (min > md->end_subject - eptr) return FALSE; -+ if (min > 0) switch(ctype) -+ { -+ case OP_ANY: -+#ifdef SUPPORT_UTF8 -+ if (md->utf8) -+ { -+ for (i = 1; i <= min; i++) -+ { -+ if (eptr >= md->end_subject || -+ (*eptr++ == NEWLINE && (ims & PCRE_DOTALL) == 0)) -+ return FALSE; -+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; -+ } -+ break; -+ } -+#endif -+ /* Non-UTF8 can be faster */ -+ if ((ims & PCRE_DOTALL) == 0) -+ { for (i = 1; i <= min; i++) if (*eptr++ == NEWLINE) return FALSE; } -+ else eptr += min; -+ break; -+ -+ case OP_NOT_DIGIT: -+ for (i = 1; i <= min; i++) -+ if ((md->ctypes[*eptr++] & ctype_digit) != 0) return FALSE; -+ break; -+ -+ case OP_DIGIT: -+ for (i = 1; i <= min; i++) -+ if ((md->ctypes[*eptr++] & ctype_digit) == 0) return FALSE; -+ break; -+ -+ case OP_NOT_WHITESPACE: -+ for (i = 1; i <= min; i++) -+ if ((md->ctypes[*eptr++] & ctype_space) != 0) return FALSE; -+ break; -+ -+ case OP_WHITESPACE: -+ for (i = 1; i <= min; i++) -+ if ((md->ctypes[*eptr++] & ctype_space) == 0) return FALSE; -+ break; -+ -+ case OP_NOT_WORDCHAR: -+ for (i = 1; i <= min; i++) -+ if ((md->ctypes[*eptr++] & ctype_word) != 0) -+ return FALSE; -+ break; -+ -+ case OP_WORDCHAR: -+ for (i = 1; i <= min; i++) -+ if ((md->ctypes[*eptr++] & ctype_word) == 0) -+ return FALSE; -+ break; -+ } -+ -+ /* If min = max, continue at the same level without recursing */ -+ -+ if (min == max) continue; -+ -+ /* If minimizing, we have to test the rest of the pattern before each -+ subsequent match. */ -+ -+ if (minimize) -+ { -+ for (i = min;; i++) -+ { -+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) return TRUE; -+ if (i >= max || eptr >= md->end_subject) return FALSE; -+ -+ c = *eptr++; -+ switch(ctype) -+ { -+ case OP_ANY: -+ if ((ims & PCRE_DOTALL) == 0 && c == NEWLINE) return FALSE; -+#ifdef SUPPORT_UTF8 -+ if (md->utf8) -+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; -+#endif -+ break; -+ -+ case OP_NOT_DIGIT: -+ if ((md->ctypes[c] & ctype_digit) != 0) return FALSE; -+ break; -+ -+ case OP_DIGIT: -+ if ((md->ctypes[c] & ctype_digit) == 0) return FALSE; -+ break; -+ -+ case OP_NOT_WHITESPACE: -+ if ((md->ctypes[c] & ctype_space) != 0) return FALSE; -+ break; -+ -+ case OP_WHITESPACE: -+ if ((md->ctypes[c] & ctype_space) == 0) return FALSE; -+ break; -+ -+ case OP_NOT_WORDCHAR: -+ if ((md->ctypes[c] & ctype_word) != 0) return FALSE; -+ break; -+ -+ case OP_WORDCHAR: -+ if ((md->ctypes[c] & ctype_word) == 0) return FALSE; -+ break; -+ } -+ } -+ /* Control never gets here */ -+ } -+ -+ /* If maximizing it is worth using inline code for speed, doing the type -+ test once at the start (i.e. keep it out of the loop). */ -+ -+ else -+ { -+ const uschar *pp = eptr; -+ switch(ctype) -+ { -+ case OP_ANY: -+ -+ /* Special code is required for UTF8, but when the maximum is unlimited -+ we don't need it. */ -+ -+#ifdef SUPPORT_UTF8 -+ if (md->utf8 && max < INT_MAX) -+ { -+ if ((ims & PCRE_DOTALL) == 0) -+ { -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || *eptr++ == NEWLINE) break; -+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; -+ } -+ } -+ else -+ { -+ for (i = min; i < max; i++) -+ { -+ eptr++; -+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; -+ } -+ } -+ break; -+ } -+#endif -+ /* Non-UTF8 can be faster */ -+ if ((ims & PCRE_DOTALL) == 0) -+ { -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || *eptr == NEWLINE) break; -+ eptr++; -+ } -+ } -+ else -+ { -+ c = max - min; -+ if (c > md->end_subject - eptr) c = md->end_subject - eptr; -+ eptr += c; -+ } -+ break; -+ -+ case OP_NOT_DIGIT: -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0) -+ break; -+ eptr++; -+ } -+ break; -+ -+ case OP_DIGIT: -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0) -+ break; -+ eptr++; -+ } -+ break; -+ -+ case OP_NOT_WHITESPACE: -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0) -+ break; -+ eptr++; -+ } -+ break; -+ -+ case OP_WHITESPACE: -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0) -+ break; -+ eptr++; -+ } -+ break; -+ -+ case OP_NOT_WORDCHAR: -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0) -+ break; -+ eptr++; -+ } -+ break; -+ -+ case OP_WORDCHAR: -+ for (i = min; i < max; i++) -+ { -+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0) -+ break; -+ eptr++; -+ } -+ break; -+ } -+ -+ while (eptr >= pp) -+ { -+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0)) -+ return TRUE; -+#ifdef SUPPORT_UTF8 -+ if (md->utf8) -+ while (eptr > pp && (*eptr & 0xc0) == 0x80) eptr--; -+#endif -+ } -+ return FALSE; -+ } -+ /* Control never gets here */ -+ -+ /* There's been some horrible disaster. */ -+ -+ default: -+ DPRINTF(("Unknown opcode %d\n", *ecode)); -+ md->errorcode = PCRE_ERROR_UNKNOWN_NODE; -+ return FALSE; -+ } -+ -+ /* Do not stick any code in here without much thought; it is assumed -+ that "continue" in the code above comes out to here to repeat the main -+ loop. */ -+ -+ } /* End of main loop */ -+/* Control never reaches here */ -+} -+ -+ -+/************************************************* -+* Execute a Regular Expression * -+*************************************************/ -+ -+/* This function applies a compiled re to a subject string and picks out -+portions of the string if it matches. Two elements in the vector are set for -+each substring: the offsets to the start and end of the substring. -+ -+Arguments: -+ external_re points to the compiled expression -+ external_extra points to "hints" from pcre_study() or is NULL -+ subject points to the subject string -+ length length of subject string (may contain binary zeros) -+ start_offset where to start in the subject string -+ options option bits -+ offsets points to a vector of ints to be filled in with offsets -+ offsetcount the number of elements in the vector -+ -+Returns: > 0 => success; value is the number of elements filled in -+ = 0 => success, but offsets is not big enough -+ -1 => failed to match -+ < -1 => some kind of unexpected problem -+*/ -+ -+int -+pcre_exec(const pcre *external_re, const pcre_extra *external_extra, -+ const char *subject, int length, int start_offset, int options, int *offsets, -+ int offsetcount) -+{ -+int resetcount, ocount; -+int first_char = -1; -+int req_char = -1; -+int req_char2 = -1; -+unsigned long int ims = 0; -+match_data match_block; -+const uschar *start_bits = NULL; -+const uschar *start_match = (const uschar *)subject + start_offset; -+const uschar *end_subject; -+const uschar *req_char_ptr = start_match - 1; -+const real_pcre *re = (const real_pcre *)external_re; -+const real_pcre_extra *extra = (const real_pcre_extra *)external_extra; -+BOOL using_temporary_offsets = FALSE; -+BOOL anchored; -+BOOL startline; -+ -+if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; -+ -+if (re == NULL || subject == NULL || -+ (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; -+if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC; -+ -+anchored = ((re->options | options) & PCRE_ANCHORED) != 0; -+startline = (re->options & PCRE_STARTLINE) != 0; -+ -+match_block.start_pattern = re->code; -+match_block.start_subject = (const uschar *)subject; -+match_block.end_subject = match_block.start_subject + length; -+end_subject = match_block.end_subject; -+ -+match_block.endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; -+match_block.utf8 = (re->options & PCRE_UTF8) != 0; -+ -+match_block.notbol = (options & PCRE_NOTBOL) != 0; -+match_block.noteol = (options & PCRE_NOTEOL) != 0; -+match_block.notempty = (options & PCRE_NOTEMPTY) != 0; -+ -+match_block.errorcode = PCRE_ERROR_NOMATCH; /* Default error */ -+ -+match_block.lcc = re->tables + lcc_offset; -+match_block.ctypes = re->tables + ctypes_offset; -+ -+/* The ims options can vary during the matching as a result of the presence -+of (?ims) items in the pattern. They are kept in a local variable so that -+restoring at the exit of a group is easy. */ -+ -+ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL); -+ -+/* If the expression has got more back references than the offsets supplied can -+hold, we get a temporary bit of working store to use during the matching. -+Otherwise, we can use the vector supplied, rounding down its size to a multiple -+of 3. */ -+ -+ocount = offsetcount - (offsetcount % 3); -+ -+if (re->top_backref > 0 && re->top_backref >= ocount/3) -+ { -+ ocount = re->top_backref * 3 + 3; -+ match_block.offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int)); -+ if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY; -+ using_temporary_offsets = TRUE; -+ DPRINTF(("Got memory to hold back references\n")); -+ } -+else match_block.offset_vector = offsets; -+ -+match_block.offset_end = ocount; -+match_block.offset_max = (2*ocount)/3; -+match_block.offset_overflow = FALSE; -+ -+/* Compute the minimum number of offsets that we need to reset each time. Doing -+this makes a huge difference to execution time when there aren't many brackets -+in the pattern. */ -+ -+resetcount = 2 + re->top_bracket * 2; -+if (resetcount > offsetcount) resetcount = ocount; -+ -+/* Reset the working variable associated with each extraction. These should -+never be used unless previously set, but they get saved and restored, and so we -+initialize them to avoid reading uninitialized locations. */ -+ -+if (match_block.offset_vector != NULL) -+ { -+ register int *iptr = match_block.offset_vector + ocount; -+ register int *iend = iptr - resetcount/2 + 1; -+ while (--iptr >= iend) *iptr = -1; -+ } -+ -+/* Set up the first character to match, if available. The first_char value is -+never set for an anchored regular expression, but the anchoring may be forced -+at run time, so we have to test for anchoring. The first char may be unset for -+an unanchored pattern, of course. If there's no first char and the pattern was -+studied, there may be a bitmap of possible first characters. */ -+ -+if (!anchored) -+ { -+ if ((re->options & PCRE_FIRSTSET) != 0) -+ { -+ first_char = re->first_char; -+ if ((ims & PCRE_CASELESS) != 0) first_char = match_block.lcc[first_char]; -+ } -+ else -+ if (!startline && extra != NULL && -+ (extra->options & PCRE_STUDY_MAPPED) != 0) -+ start_bits = extra->start_bits; -+ } -+ -+/* For anchored or unanchored matches, there may be a "last known required -+character" set. If the PCRE_CASELESS is set, implying that the match starts -+caselessly, or if there are any changes of this flag within the regex, set up -+both cases of the character. Otherwise set the two values the same, which will -+avoid duplicate testing (which takes significant time). This covers the vast -+majority of cases. It will be suboptimal when the case flag changes in a regex -+and the required character in fact is caseful. */ -+ -+if ((re->options & PCRE_REQCHSET) != 0) -+ { -+ req_char = re->req_char; -+ req_char2 = ((re->options & (PCRE_CASELESS | PCRE_ICHANGED)) != 0)? -+ (re->tables + fcc_offset)[req_char] : req_char; -+ } -+ -+/* Loop for handling unanchored repeated matching attempts; for anchored regexs -+the loop runs just once. */ -+ -+do -+ { -+ int rc; -+ register int *iptr = match_block.offset_vector; -+ register int *iend = iptr + resetcount; -+ -+ /* Reset the maximum number of extractions we might see. */ -+ -+ while (iptr < iend) *iptr++ = -1; -+ -+ /* Advance to a unique first char if possible */ -+ -+ if (first_char >= 0) -+ { -+ if ((ims & PCRE_CASELESS) != 0) -+ while (start_match < end_subject && -+ match_block.lcc[*start_match] != first_char) -+ start_match++; -+ else -+ while (start_match < end_subject && *start_match != first_char) -+ start_match++; -+ } -+ -+ /* Or to just after \n for a multiline match if possible */ -+ -+ else if (startline) -+ { -+ if (start_match > match_block.start_subject + start_offset) -+ { -+ while (start_match < end_subject && start_match[-1] != NEWLINE) -+ start_match++; -+ } -+ } -+ -+ /* Or to a non-unique first char after study */ -+ -+ else if (start_bits != NULL) -+ { -+ while (start_match < end_subject) -+ { -+ register int c = *start_match; -+ if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++; else break; -+ } -+ } -+ -+#ifdef DEBUG /* Sigh. Some compilers never learn. */ -+ PCRE_PRINTF(">>>> Match against: "); -+ pchars(start_match, end_subject - start_match, TRUE, &match_block); -+ PCRE_PRINTF("\n"); -+#endif -+ -+ /* If req_char is set, we know that that character must appear in the subject -+ for the match to succeed. If the first character is set, req_char must be -+ later in the subject; otherwise the test starts at the match point. This -+ optimization can save a huge amount of backtracking in patterns with nested -+ unlimited repeats that aren't going to match. We don't know what the state of -+ case matching may be when this character is hit, so test for it in both its -+ cases if necessary. However, the different cased versions will not be set up -+ unless PCRE_CASELESS was given or the casing state changes within the regex. -+ Writing separate code makes it go faster, as does using an autoincrement and -+ backing off on a match. */ -+ -+ if (req_char >= 0) -+ { -+ register const uschar *p = start_match + ((first_char >= 0)? 1 : 0); -+ -+ /* We don't need to repeat the search if we haven't yet reached the -+ place we found it at last time. */ -+ -+ if (p > req_char_ptr) -+ { -+ /* Do a single test if no case difference is set up */ -+ -+ if (req_char == req_char2) -+ { -+ while (p < end_subject) -+ { -+ if (*p++ == req_char) { p--; break; } -+ } -+ } -+ -+ /* Otherwise test for either case */ -+ -+ else -+ { -+ while (p < end_subject) -+ { -+ register int pp = *p++; -+ if (pp == req_char || pp == req_char2) { p--; break; } -+ } -+ } -+ -+ /* If we can't find the required character, break the matching loop */ -+ -+ if (p >= end_subject) break; -+ -+ /* If we have found the required character, save the point where we -+ found it, so that we don't search again next time round the loop if -+ the start hasn't passed this character yet. */ -+ -+ req_char_ptr = p; -+ } -+ } -+ -+ /* When a match occurs, substrings will be set for all internal extractions; -+ we just need to set up the whole thing as substring 0 before returning. If -+ there were too many extractions, set the return code to zero. In the case -+ where we had to get some local store to hold offsets for backreferences, copy -+ those back references that we can. In this case there need not be overflow -+ if certain parts of the pattern were not used. */ -+ -+ match_block.start_match = start_match; -+ if (!match(start_match, re->code, 2, &match_block, ims, NULL, match_isgroup)) -+ continue; -+ -+ /* Copy the offset information from temporary store if necessary */ -+ -+ if (using_temporary_offsets) -+ { -+ if (offsetcount >= 4) -+ { -+ memcpy(offsets + 2, match_block.offset_vector + 2, -+ (offsetcount - 2) * sizeof(int)); -+ DPRINTF(("Copied offsets from temporary memory\n")); -+ } -+ if (match_block.end_offset_top > offsetcount) -+ match_block.offset_overflow = TRUE; -+ -+ DPRINTF(("Freeing temporary memory\n")); -+ (pcre_free)(match_block.offset_vector); -+ } -+ -+ rc = match_block.offset_overflow? 0 : match_block.end_offset_top/2; -+ -+ if (offsetcount < 2) rc = 0; else -+ { -+ offsets[0] = start_match - match_block.start_subject; -+ offsets[1] = match_block.end_match_ptr - match_block.start_subject; -+ } -+ -+ DPRINTF((">>>> returning %d\n", rc)); -+ return rc; -+ } -+ -+/* This "while" is the end of the "do" above */ -+ -+while (!anchored && -+ match_block.errorcode == PCRE_ERROR_NOMATCH && -+ start_match++ < end_subject); -+ -+if (using_temporary_offsets) -+ { -+ DPRINTF(("Freeing temporary memory\n")); -+ (pcre_free)(match_block.offset_vector); -+ } -+ -+DPRINTF((">>>> returning %d\n", match_block.errorcode)); -+ -+return match_block.errorcode; -+} -+ -+/* End of pcre.c */ ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/aamatch/pcre_exec.h -@@ -0,0 +1,308 @@ -+/* -+ * This is a modified header file containing the definitions from -+ * pcre.h and internal.h required to support pcre_exec() -+ */ -+ -+ -+/************************************************* -+* Perl-Compatible Regular Expressions * -+*************************************************/ -+ -+/* Copyright (c) 1997-2001 University of Cambridge */ -+ -+#ifndef _PCRE_H -+#define _PCRE_H -+ -+/* ----- CODE ADDED ---- */ -+ -+#ifdef __KERNEL__ -+#include // for kmalloc/kfree -+#endif -+ -+#ifdef __KERNEL__ -+#define PCRE_PRINTF printk -+#define isprint(x) ((unsigned char)(x) >= 128 && (unsigned char)(x) <= 255) -+#else -+#define PCRE_PRINTF printf -+#endif -+ -+/* The value of NEWLINE determines the newline character. The default is to -+ * leave it up to the compiler, but some sites want to force a particular value. -+ * On Unix systems, "configure" can be used to override this default. */ -+ -+#ifndef NEWLINE -+#define NEWLINE '\n' -+#endif -+ -+/* ---- CODE DELETED ---- */ -+ -+/* Options */ -+ -+#define PCRE_CASELESS 0x0001 -+#define PCRE_MULTILINE 0x0002 -+#define PCRE_DOTALL 0x0004 -+#define PCRE_EXTENDED 0x0008 -+#define PCRE_ANCHORED 0x0010 -+#define PCRE_DOLLAR_ENDONLY 0x0020 -+#define PCRE_EXTRA 0x0040 -+#define PCRE_NOTBOL 0x0080 -+#define PCRE_NOTEOL 0x0100 -+#define PCRE_UNGREEDY 0x0200 -+#define PCRE_NOTEMPTY 0x0400 -+#define PCRE_UTF8 0x0800 -+ -+/* Exec-time and get-time error codes */ -+ -+#define PCRE_ERROR_NOMATCH (-1) -+#define PCRE_ERROR_NULL (-2) -+#define PCRE_ERROR_BADOPTION (-3) -+#define PCRE_ERROR_BADMAGIC (-4) -+#define PCRE_ERROR_UNKNOWN_NODE (-5) -+#define PCRE_ERROR_NOMEMORY (-6) -+#define PCRE_ERROR_NOSUBSTRING (-7) -+ -+/* ---- CODE DELETED ---- */ -+ -+/* Types */ -+ -+struct real_pcre; /* declaration; the definition is private */ -+struct real_pcre_extra; /* declaration; the definition is private */ -+ -+typedef struct real_pcre pcre; -+typedef struct real_pcre_extra pcre_extra; -+ -+/* ---- CODE DELETED ---- */ -+ -+extern int pcre_exec(const pcre *, const pcre_extra *, -+ const char *, int, int, int, int *, -+ int); -+ -+/* ---- CODE ADDED (from internal.h) ---- */ -+ -+/* These are the public options that can change during matching. */ -+ -+#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL) -+ -+/* Private options flags start at the most significant end of the four bytes, -+but skip the top bit so we can use ints for convenience without getting tangled -+with negative values. The public options defined in pcre.h start at the least -+significant end. Make sure they don't overlap, though now that we have expanded -+to four bytes there is plenty of space. */ -+ -+#define PCRE_FIRSTSET 0x40000000 /* first_char is set */ -+#define PCRE_REQCHSET 0x20000000 /* req_char is set */ -+#define PCRE_STARTLINE 0x10000000 /* start after \n for multiline */ -+#define PCRE_ICHANGED 0x04000000 /* i option changes within regex */ -+ -+/* Options for the "extra" block produced by pcre_study(). */ -+ -+#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */ -+ -+/* Masks for identifying the public options which are permitted at compile -+time, run time or study time, respectively. */ -+ -+#define PUBLIC_EXEC_OPTIONS \ -+ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY) -+ -+/* Magic number to provide a small check against being handed junk. */ -+ -+#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ -+ -+typedef int BOOL; -+ -+#define FALSE 0 -+#define TRUE 1 -+ -+/* Opcode table: OP_BRA must be last, as all values >= it are used for brackets -+that extract substrings. Starting from 1 (i.e. after OP_END), the values up to -+OP_EOD must correspond in order to the list of escapes immediately above. */ -+ -+enum { -+ OP_END, /* End of pattern */ -+ -+ /* Values corresponding to backslashed metacharacters */ -+ -+ OP_SOD, /* Start of data: \A */ -+ OP_NOT_WORD_BOUNDARY, /* \B */ -+ OP_WORD_BOUNDARY, /* \b */ -+ OP_NOT_DIGIT, /* \D */ -+ OP_DIGIT, /* \d */ -+ OP_NOT_WHITESPACE, /* \S */ -+ OP_WHITESPACE, /* \s */ -+ OP_NOT_WORDCHAR, /* \W */ -+ OP_WORDCHAR, /* \w */ -+ OP_EODN, /* End of data or \n at end of data: \Z. */ -+ OP_EOD, /* End of data: \z */ -+ -+ OP_OPT, /* Set runtime options */ -+ OP_CIRC, /* Start of line - varies with multiline switch */ -+ OP_DOLL, /* End of line - varies with multiline switch */ -+ OP_ANY, /* Match any character */ -+ OP_CHARS, /* Match string of characters */ -+ OP_NOT, /* Match anything but the following char */ -+ -+ OP_STAR, /* The maximizing and minimizing versions of */ -+ OP_MINSTAR, /* all these opcodes must come in pairs, with */ -+ OP_PLUS, /* the minimizing one second. */ -+ OP_MINPLUS, /* This first set applies to single characters */ -+ OP_QUERY, -+ OP_MINQUERY, -+ OP_UPTO, /* From 0 to n matches */ -+ OP_MINUPTO, -+ OP_EXACT, /* Exactly n matches */ -+ -+ OP_NOTSTAR, /* The maximizing and minimizing versions of */ -+ OP_NOTMINSTAR, /* all these opcodes must come in pairs, with */ -+ OP_NOTPLUS, /* the minimizing one second. */ -+ OP_NOTMINPLUS, /* This first set applies to "not" single characters */ -+ OP_NOTQUERY, -+ OP_NOTMINQUERY, -+ OP_NOTUPTO, /* From 0 to n matches */ -+ OP_NOTMINUPTO, -+ OP_NOTEXACT, /* Exactly n matches */ -+ -+ OP_TYPESTAR, /* The maximizing and minimizing versions of */ -+ OP_TYPEMINSTAR, /* all these opcodes must come in pairs, with */ -+ OP_TYPEPLUS, /* the minimizing one second. These codes must */ -+ OP_TYPEMINPLUS, /* be in exactly the same order as those above. */ -+ OP_TYPEQUERY, /* This set applies to character types such as \d */ -+ OP_TYPEMINQUERY, -+ OP_TYPEUPTO, /* From 0 to n matches */ -+ OP_TYPEMINUPTO, -+ OP_TYPEEXACT, /* Exactly n matches */ -+ -+ OP_CRSTAR, /* The maximizing and minimizing versions of */ -+ OP_CRMINSTAR, /* all these opcodes must come in pairs, with */ -+ OP_CRPLUS, /* the minimizing one second. These codes must */ -+ OP_CRMINPLUS, /* be in exactly the same order as those above. */ -+ OP_CRQUERY, /* These are for character classes and back refs */ -+ OP_CRMINQUERY, -+ OP_CRRANGE, /* These are different to the three seta above. */ -+ OP_CRMINRANGE, -+ -+ OP_CLASS, /* Match a character class */ -+ OP_REF, /* Match a back reference */ -+ OP_RECURSE, /* Match this pattern recursively */ -+ -+ OP_ALT, /* Start of alternation */ -+ OP_KET, /* End of group that doesn't have an unbounded repeat */ -+ OP_KETRMAX, /* These two must remain together and in this */ -+ OP_KETRMIN, /* order. They are for groups the repeat for ever. */ -+ -+ /* The assertions must come before ONCE and COND */ -+ -+ OP_ASSERT, /* Positive lookahead */ -+ OP_ASSERT_NOT, /* Negative lookahead */ -+ OP_ASSERTBACK, /* Positive lookbehind */ -+ OP_ASSERTBACK_NOT, /* Negative lookbehind */ -+ OP_REVERSE, /* Move pointer back - used in lookbehind assertions */ -+ -+ /* ONCE and COND must come after the assertions, with ONCE first, as there's -+ a test for >= ONCE for a subpattern that isn't an assertion. */ -+ -+ OP_ONCE, /* Once matched, don't back up into the subpattern */ -+ OP_COND, /* Conditional group */ -+ OP_CREF, /* Used to hold an extraction string number (cond ref) */ -+ -+ OP_BRAZERO, /* These two must remain together and in this */ -+ OP_BRAMINZERO, /* order. */ -+ -+ OP_BRANUMBER, /* Used for extracting brackets whose number is greater -+ than can fit into an opcode. */ -+ -+ OP_BRA /* This and greater values are used for brackets that -+ extract substrings up to a basic limit. After that, -+ use is made of OP_BRANUMBER. */ -+}; -+ -+/* The highest extraction number before we have to start using additional -+bytes. (Originally PCRE didn't have support for extraction counts highter than -+this number.) The value is limited by the number of opcodes left after OP_BRA, -+i.e. 255 - OP_BRA. We actually set it a bit lower to leave room for additional -+opcodes. */ -+ -+#define EXTRACT_BASIC_MAX 150 -+ -+/* All character handling must be done as unsigned characters. Otherwise there -+are problems with top-bit-set characters and functions such as isspace(). -+However, we leave the interface to the outside world as char *, because that -+should make things easier for callers. We define a short type for unsigned char -+to save lots of typing. I tried "uchar", but it causes problems on Digital -+Unix, where it is defined in sys/types, so use "uschar" instead. */ -+ -+typedef unsigned char uschar; -+ -+/* The real format of the start of the pcre block; the actual code vector -+runs on as long as necessary after the end. */ -+ -+typedef struct real_pcre { -+ unsigned long int magic_number; -+ size_t size; -+ const unsigned char *tables; -+ unsigned long int options; -+ unsigned short int top_bracket; -+ unsigned short int top_backref; -+ uschar first_char; -+ uschar req_char; -+ uschar code[1]; -+} real_pcre; -+ -+/* The real format of the extra block returned by pcre_study(). */ -+ -+typedef struct real_pcre_extra { -+ uschar options; -+ uschar start_bits[32]; -+} real_pcre_extra; -+ -+/* Structure for passing "static" information around between the functions -+doing the matching, so that they are thread-safe. */ -+ -+typedef struct match_data { -+ int errorcode; /* As it says */ -+ int *offset_vector; /* Offset vector */ -+ int offset_end; /* One past the end */ -+ int offset_max; /* The maximum usable for return data */ -+ const uschar *lcc; /* Points to lower casing table */ -+ const uschar *ctypes; /* Points to table of type maps */ -+ BOOL offset_overflow; /* Set if too many extractions */ -+ BOOL notbol; /* NOTBOL flag */ -+ BOOL noteol; /* NOTEOL flag */ -+ BOOL utf8; /* UTF8 flag */ -+ BOOL endonly; /* Dollar not before final \n */ -+ BOOL notempty; /* Empty string match not wanted */ -+ const uschar *start_pattern; /* For use when recursing */ -+ const uschar *start_subject; /* Start of the subject string */ -+ const uschar *end_subject; /* End of the subject string */ -+ const uschar *start_match; /* Start of this match attempt */ -+ const uschar *end_match_ptr; /* Subject position at end match */ -+ int end_offset_top; /* Highwater mark at end of match */ -+} match_data; -+ -+/* Bit definitions for entries in the pcre_ctypes table. */ -+ -+#define ctype_space 0x01 -+#define ctype_letter 0x02 -+#define ctype_digit 0x04 -+#define ctype_xdigit 0x08 -+#define ctype_word 0x10 /* alphameric or '_' */ -+#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ -+ -+/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set -+of bits for a class map. Some classes are built by combining these tables. */ -+ -+#define cbit_length 320 /* Length of the cbits table */ -+ -+/* Offsets of the various tables from the base tables pointer, and -+total length. */ -+ -+#define lcc_offset 0 -+#define fcc_offset 256 -+ -+#define fcc_offset 256 -+#define cbits_offset 512 -+#define ctypes_offset (cbits_offset + cbit_length) -+ -+/* ----- CODE ADDED ---- */ -+ -+#endif // _PCRE_H -+ /* End of pcre.h */ ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/aamatch/pcre_tables.h -@@ -0,0 +1,184 @@ -+ -+/************************************************* -+* Perl-Compatible Regular Expressions * -+*************************************************/ -+ -+/* This file is automatically written by the dftables auxiliary -+program. If you edit it by hand, you might like to edit the Makefile to -+prevent its ever being regenerated. -+ -+This file is #included in the compilation of pcre.c to build the default -+character tables which are used when no tables are passed to the compile -+function. */ -+ -+static unsigned char pcre_default_tables[] = { -+ -+/* This table is a lower casing table. */ -+ -+ 0, 1, 2, 3, 4, 5, 6, 7, -+ 8, 9, 10, 11, 12, 13, 14, 15, -+ 16, 17, 18, 19, 20, 21, 22, 23, -+ 24, 25, 26, 27, 28, 29, 30, 31, -+ 32, 33, 34, 35, 36, 37, 38, 39, -+ 40, 41, 42, 43, 44, 45, 46, 47, -+ 48, 49, 50, 51, 52, 53, 54, 55, -+ 56, 57, 58, 59, 60, 61, 62, 63, -+ 64, 97, 98, 99,100,101,102,103, -+ 104,105,106,107,108,109,110,111, -+ 112,113,114,115,116,117,118,119, -+ 120,121,122, 91, 92, 93, 94, 95, -+ 96, 97, 98, 99,100,101,102,103, -+ 104,105,106,107,108,109,110,111, -+ 112,113,114,115,116,117,118,119, -+ 120,121,122,123,124,125,126,127, -+ 128,129,130,131,132,133,134,135, -+ 136,137,138,139,140,141,142,143, -+ 144,145,146,147,148,149,150,151, -+ 152,153,154,155,156,157,158,159, -+ 160,161,162,163,164,165,166,167, -+ 168,169,170,171,172,173,174,175, -+ 176,177,178,179,180,181,182,183, -+ 184,185,186,187,188,189,190,191, -+ 192,193,194,195,196,197,198,199, -+ 200,201,202,203,204,205,206,207, -+ 208,209,210,211,212,213,214,215, -+ 216,217,218,219,220,221,222,223, -+ 224,225,226,227,228,229,230,231, -+ 232,233,234,235,236,237,238,239, -+ 240,241,242,243,244,245,246,247, -+ 248,249,250,251,252,253,254,255, -+ -+/* This table is a case flipping table. */ -+ -+ 0, 1, 2, 3, 4, 5, 6, 7, -+ 8, 9, 10, 11, 12, 13, 14, 15, -+ 16, 17, 18, 19, 20, 21, 22, 23, -+ 24, 25, 26, 27, 28, 29, 30, 31, -+ 32, 33, 34, 35, 36, 37, 38, 39, -+ 40, 41, 42, 43, 44, 45, 46, 47, -+ 48, 49, 50, 51, 52, 53, 54, 55, -+ 56, 57, 58, 59, 60, 61, 62, 63, -+ 64, 97, 98, 99,100,101,102,103, -+ 104,105,106,107,108,109,110,111, -+ 112,113,114,115,116,117,118,119, -+ 120,121,122, 91, 92, 93, 94, 95, -+ 96, 65, 66, 67, 68, 69, 70, 71, -+ 72, 73, 74, 75, 76, 77, 78, 79, -+ 80, 81, 82, 83, 84, 85, 86, 87, -+ 88, 89, 90,123,124,125,126,127, -+ 128,129,130,131,132,133,134,135, -+ 136,137,138,139,140,141,142,143, -+ 144,145,146,147,148,149,150,151, -+ 152,153,154,155,156,157,158,159, -+ 160,161,162,163,164,165,166,167, -+ 168,169,170,171,172,173,174,175, -+ 176,177,178,179,180,181,182,183, -+ 184,185,186,187,188,189,190,191, -+ 192,193,194,195,196,197,198,199, -+ 200,201,202,203,204,205,206,207, -+ 208,209,210,211,212,213,214,215, -+ 216,217,218,219,220,221,222,223, -+ 224,225,226,227,228,229,230,231, -+ 232,233,234,235,236,237,238,239, -+ 240,241,242,243,244,245,246,247, -+ 248,249,250,251,252,253,254,255, -+ -+/* This table contains bit maps for various character classes. -+Each map is 32 bytes long and the bits run from the least -+significant end of each byte. The classes that have their own -+maps are: space, xdigit, digit, upper, lower, word, graph -+print, punct, and cntrl. Other classes are built from combinations. */ -+ -+ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, -+ 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, -+ 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, -+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, -+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+ 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, -+ 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -+ -+/* This table identifies various classes of character by individual bits: -+ 0x01 white space character -+ 0x02 letter -+ 0x04 decimal digit -+ 0x08 hexadecimal digit -+ 0x10 alphanumeric or '_' -+ 0x80 regular expression metacharacter or binary zero -+*/ -+ -+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ -+ 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ -+ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ -+ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ -+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ -+ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ -+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ -+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ -+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ -+ 0x12,0x12,0x12,0x80,0x00,0x00,0x80,0x10, /* X - _ */ -+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ -+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ -+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ -+ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ -+ -+/* End of chartables.c */ ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/Kconfig -@@ -0,0 +1,9 @@ -+config SECURITY_APPARMOR -+ tristate "AppArmor support" -+ depends on SECURITY!=n -+ help -+ This enables the Novell AppArmor security module. -+ Required userspace tools (if they are not included in your -+ distribution) and further information may be found at -+ -+ If you are unsure how to answer this question, answer N. ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/aamatch/Makefile -@@ -0,0 +1,5 @@ -+# Makefile for AppArmor aamatch submodule -+# -+obj-$(CONFIG_SECURITY_APPARMOR) += aamatch_pcre.o -+ -+aamatch_pcre-y := match_pcre.o pcre_exec.o ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/apparmor.h -@@ -0,0 +1,283 @@ -+/* -+ * Copyright (C) 1998-2005 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 internal prototypes -+ */ -+ -+#ifndef __SUBDOMAIN_H -+#define __SUBDOMAIN_H -+ -+/* defn of iattr */ -+#include -+ -+#include "shared.h" -+ -+/* Control parameters (0 or 1), settable thru module/boot flags or -+ * via /sys/kernel/security/subdomain/control */ -+extern int subdomain_complain; -+extern int subdomain_debug; -+extern int subdomain_audit; -+extern int subdomain_logsyscall; -+ -+#define SD_UNCONSTRAINED "unconstrained" -+ -+/* $ echo -n subdomain.o | md5sum | cut -c -8 */ -+#define SD_ID_MAGIC 0x8c235e38 -+ -+#define PROFILE_COMPLAIN(_profile) \ -+ (subdomain_complain == 1 || ((_profile) && (_profile)->flags.complain)) -+ -+#define SUBDOMAIN_COMPLAIN(_sd) \ -+ (subdomain_complain == 1 || \ -+ ((_sd) && (_sd)->active && (_sd)->active->flags.complain)) -+ -+#define SUBDOMAIN_AUDIT(_sd) \ -+ (subdomain_audit == 1 || \ -+ ((_sd) && (_sd)->active && (_sd)->active->flags.audit)) -+ -+/* -+ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl -+ * which is not related to profile accesses. -+ */ -+ -+#define SD_DEBUG(fmt, args...) \ -+ do { \ -+ if (subdomain_debug) \ -+ printk(KERN_DEBUG "AppArmor: " fmt, ##args); \ -+ } while (0) -+#define SD_INFO(fmt, args...) printk(KERN_INFO "AppArmor: " fmt, ##args) -+#define SD_WARN(fmt, args...) printk(KERN_WARNING "AppArmor: " fmt, ##args) -+#define SD_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args) -+ -+/* basic AppArmor data structures */ -+ -+struct flagval { -+ int debug; -+ int complain; -+ int audit; -+}; -+ -+enum entry_t { -+ sd_entry_literal, -+ sd_entry_tailglob, -+ sd_entry_pattern, -+ sd_entry_invalid -+}; -+ -+/** -+ * sd_entry - file ACL * -+ * Each entry describes a file and an allowed access mode. -+ */ -+struct sd_entry { -+ char *filename; -+ int mode; /* mode is 'or' of READ, WRITE, EXECUTE, -+ * INHERIT, UNCONSTRAINED, and LIBRARY -+ * (meaning don't prefetch). */ -+ -+ enum entry_t entry_type; -+ void *extradata; -+ -+ struct list_head list; -+ struct list_head listp[POS_SD_FILE_MAX + 1]; -+}; -+ -+#define SD_EXEC_MODIFIER_MASK(mask) ((mask) & (SD_EXEC_UNCONSTRAINED |\ -+ SD_EXEC_INHERIT |\ -+ SD_EXEC_PROFILE)) -+ -+#define SD_EXEC_MASK(mask) ((mask) & (SD_MAY_EXEC |\ -+ SD_EXEC_UNCONSTRAINED |\ -+ SD_EXEC_INHERIT |\ -+ SD_EXEC_PROFILE)) -+ -+/** -+ * sdprofile - basic confinement data -+ * -+ * The AppArmor profile contains the basic confinement data. Each profile -+ * has a name and potentially a list of subdomain entries. The profiles are -+ * connected in a list -+ */ -+struct sdprofile { -+ char *name; /* profile name */ -+ -+ struct list_head file_entry; /* file ACL */ -+ struct list_head file_entryp[POS_SD_FILE_MAX + 1]; -+ struct list_head list; /* list of profiles */ -+ struct list_head sub; /* sub profiles, for change_hat */ -+ struct flagval flags; /* per profile debug flags */ -+ -+ int isstale; /* is profile stale */ -+ -+ int num_file_entries; -+ int num_file_pentries[POS_SD_FILE_MAX + 1]; -+ -+ kernel_cap_t capabilities; -+ -+ atomic_t count; /* reference count */ -+}; -+ -+/** -+ * subdomain - a task's subdomain -+ * -+ * Contains the original profile obtained from execve() as well as the -+ * current active profile (which could change due to change_hat). Plus -+ * the hat_magic needed during change_hat. -+ */ -+struct subdomain { -+ __u32 sd_magic; /* magic value to distinguish blobs */ -+ struct sdprofile *profile; /* The profile obtained from execve() */ -+ struct sdprofile *active; /* The current active profile */ -+ __u32 sd_hat_magic; /* used with change_hat */ -+ struct list_head list; /* list of subdomains */ -+ struct task_struct *task; -+}; -+ -+typedef int (*sd_iter) (struct subdomain *, void *); -+ -+/* sd_path_data -+ * temp (cookie) data used by sd_path_* functions, see inline.h -+ */ -+struct sd_path_data { -+ struct dentry *root, *dentry; -+ struct namespace *namespace; -+ struct list_head *head, *pos; -+ int errno; -+}; -+ -+#define SD_SUBDOMAIN(sec) ((struct subdomain*)(sec)) -+#define SD_PROFILE(sec) ((struct sdprofile*)(sec)) -+ -+/* Lock protecting access to 'struct subdomain' accesses */ -+extern rwlock_t sd_lock; -+ -+extern struct sdprofile *null_profile; -+extern struct sdprofile *null_complain_profile; -+ -+/** sd_audit -+ * -+ * Auditing structure -+ */ -+ -+struct sd_audit { -+ unsigned short type, flags; -+ unsigned int result; -+ unsigned int gfp_mask; -+ int errorcode; -+ -+ const char *name; -+ unsigned int ival; -+ union{ -+ const void *pval; -+ va_list vaval; -+ }; -+}; -+ -+/* audit types */ -+#define SD_AUDITTYPE_FILE 1 -+#define SD_AUDITTYPE_DIR 2 -+#define SD_AUDITTYPE_ATTR 3 -+#define SD_AUDITTYPE_XATTR 4 -+#define SD_AUDITTYPE_LINK 5 -+#define SD_AUDITTYPE_CAP 6 -+#define SD_AUDITTYPE_MSG 7 -+#define SD_AUDITTYPE_SYSCALL 8 -+#define SD_AUDITTYPE__END 9 -+ -+/* audit flags */ -+#define SD_AUDITFLAG_AUDITSS_SYSCALL 1 /* log syscall context */ -+#define SD_AUDITFLAG_LOGERR 2 /* log operations that failed due to -+ non permission errors */ -+ -+#define HINT_UNKNOWN_HAT "unknown_hat" -+#define HINT_FORK "fork" -+#define HINT_MANDPROF "missing_mandatory_profile" -+#define HINT_CHGPROF "changing_profile" -+ -+#define LOG_HINT(sd, gfp, hint, fmt, args...) \ -+ do {\ -+ sd_audit_message(sd, gfp, 0, \ -+ "LOGPROF-HINT " hint " " fmt, ##args);\ -+ } while(0) -+ -+/* diroptype */ -+#define SD_DIR_MKDIR 0 -+#define SD_DIR_RMDIR 1 -+ -+/* xattroptype */ -+#define SD_XATTR_GET 0 -+#define SD_XATTR_SET 1 -+#define SD_XATTR_LIST 2 -+#define SD_XATTR_REMOVE 3 -+ -+/* main.c */ -+extern int alloc_nullprofiles(void); -+extern void free_nullprofiles(void); -+extern int sd_audit_message(struct subdomain *, unsigned int gfp, int, -+ const char *, ...); -+extern int sd_audit_syscallreject(struct subdomain *, unsigned int gfp, -+ const char *); -+extern int sd_audit(struct subdomain *, const struct sd_audit *); -+extern char *sd_get_name(struct dentry *dentry, struct vfsmount *mnt); -+ -+extern int sd_attr(struct subdomain *sd, struct dentry *dentry, -+ struct iattr *iattr); -+extern int sd_xattr(struct subdomain *sd, struct dentry *dentry, -+ const char *xattr, int xattroptype); -+extern int sd_capability(struct subdomain *sd, int cap); -+extern int sd_perm(struct subdomain *sd, struct dentry *dentry, -+ struct vfsmount *mnt, int mask); -+extern int sd_perm_nameidata(struct subdomain *sd, struct nameidata *nd, -+ int mask); -+extern int sd_perm_dentry(struct subdomain *sd, struct dentry *dentry, -+ int mask); -+extern int sd_perm_dir(struct subdomain *sd, struct dentry *dentry, -+ int diroptype); -+extern int sd_link(struct subdomain *sd, -+ struct dentry *link, struct dentry *target); -+extern int sd_fork(struct task_struct *p); -+extern int sd_register(struct file *file); -+extern void sd_release(struct task_struct *p); -+extern int sd_change_hat(const char *id, __u32 hat_magic); -+extern int sd_associate_filp(struct file *filp); -+ -+/* list.c */ -+extern struct sdprofile *sd_profilelist_find(const char *name); -+extern int sd_profilelist_add(struct sdprofile *profile); -+extern int sd_profilelist_remove(const char *name); -+extern void sd_profilelist_release(void); -+extern struct sdprofile *sd_profilelist_replace(struct sdprofile *profile); -+extern void sd_profile_dump(struct sdprofile *); -+extern void sd_profilelist_dump(void); -+extern void sd_subdomainlist_add(struct subdomain *); -+extern void sd_subdomainlist_remove(struct subdomain *); -+extern void sd_subdomainlist_iterate(sd_iter, void *); -+extern void sd_subdomainlist_iterateremove(sd_iter, void *); -+extern void sd_subdomainlist_release(void); -+ -+/* subdomain_interface.c */ -+extern void free_sdprofile(struct sdprofile *profile); -+extern int sd_sys_security(unsigned int id, unsigned call, unsigned long *args); -+ -+/* procattr.c */ -+extern size_t sd_getprocattr(struct subdomain *sd, char *str, size_t size); -+extern int sd_setprocattr_changehat(char *hatinfo, size_t infosize); -+extern int sd_setprocattr_setprofile(struct task_struct *p, char *profilename, -+ size_t profilesize); -+ -+/* apparmorfs.c */ -+extern int create_subdomainfs(void); -+extern int destroy_subdomainfs(void); -+ -+/* capabilities.c */ -+extern const char *capability_to_name(unsigned int cap); -+ -+/* apparmor_version.c */ -+extern const char *apparmor_version(void); -+extern const char *apparmor_version_nl(void); -+ -+#endif /* __SUBDOMAIN_H */ ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/apparmor_version.c -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (C) 2005 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 version definition -+ */ -+ -+#ifndef APPARMOR_VERSION -+#error "-DAPPARMOR_VERSION must be specified when compiling this file" -+#endif -+ -+#define APPARMOR_VERSION_STR_PFX "APPARMOR_VERSION=" -+ -+#include -+MODULE_VERSION(APPARMOR_VERSION); -+ -+/* apparmor_version_str exists to allow a strings on module to -+ * see APPARMOR_VERSION= prefix -+ */ -+static const char *apparmor_version_str = -+ APPARMOR_VERSION_STR_PFX APPARMOR_VERSION; -+ -+/* apparmor_version_str_nl exists to allow an easy way to get a newline -+ * terminated string without having to do dynamic memory allocation -+ */ -+static const char *apparmor_version_str_nl = APPARMOR_VERSION "\n"; -+ -+const char *apparmor_version(void) -+{ -+ const int len = sizeof(APPARMOR_VERSION_STR_PFX) - 1; -+ -+ return apparmor_version_str + len; -+} -+ -+const char *apparmor_version_nl(void) -+{ -+ return apparmor_version_str_nl; -+} ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/apparmorfs.c -@@ -0,0 +1,417 @@ -+/* -+ * Copyright (C) 2005 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 filesystem (part of securityfs) -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "apparmor.h" -+#include "inline.h" -+ -+#define SECFS_SD "apparmor" -+static struct dentry *sdfs_dentry = NULL; -+ -+/* profile */ -+extern struct seq_operations subdomainfs_profiles_op; -+static int sd_prof_open(struct inode *inode, struct file *file); -+static int sd_prof_release(struct inode *inode, struct file *file); -+ -+static struct file_operations subdomainfs_profiles_fops = { -+ .open = sd_prof_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = sd_prof_release, -+}; -+ -+/* version */ -+static ssize_t sd_version_read(struct file *file, char __user *buf, -+ size_t size, loff_t *ppos); -+ -+static struct file_operations subdomainfs_version_fops = { -+ .read = sd_version_read, -+}; -+ -+/* interface */ -+extern ssize_t sd_file_prof_add(void *, size_t); -+extern ssize_t sd_file_prof_repl(void *, size_t); -+extern ssize_t sd_file_prof_remove(const char *, int); -+ -+static ssize_t sd_profile_load(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos); -+static ssize_t sd_profile_replace(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos); -+static ssize_t sd_profile_remove(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos); -+ -+static struct file_operations subdomainfs_profile_load = { -+ .write = sd_profile_load -+}; -+ -+static struct file_operations subdomainfs_profile_replace = { -+ .write = sd_profile_replace -+}; -+ -+static struct file_operations subdomainfs_profile_remove = { -+ .write = sd_profile_remove -+}; -+ -+ -+/* control */ -+static u64 sd_control_get(void *data); -+static void sd_control_set(void *data, u64 val); -+ -+DEFINE_SIMPLE_ATTRIBUTE(subdomainfs_control_fops, sd_control_get, -+ sd_control_set, "%lld\n"); -+ -+ -+ -+/* table of static entries */ -+ -+static struct root_entry { -+ const char *name; -+ int mode; -+ int access; -+ struct file_operations *fops; -+ void *data; -+ -+ /* internal fields */ -+ struct dentry *dentry; -+ int parent_index; -+} root_entries[] = { -+ /* our root, normally /sys/kernel/security/subdomain */ -+ {SECFS_SD, S_IFDIR, 0550}, /* DO NOT EDIT/MOVE */ -+ -+ /* interface for obtaining list of profiles currently loaded */ -+ {"profiles", S_IFREG, 0440, &subdomainfs_profiles_fops, -+ NULL}, -+ -+ /* interface for obtaining version# of subdomain */ -+ {"version", S_IFREG, 0440, &subdomainfs_version_fops, -+ NULL}, -+ -+ /* interface for loading/removing/replacing profiles */ -+ {".load", S_IFREG, 0640, &subdomainfs_profile_load, -+ NULL}, -+ {".replace", S_IFREG, 0640, &subdomainfs_profile_replace, -+ NULL}, -+ {".remove", S_IFREG, 0640, &subdomainfs_profile_remove, -+ NULL}, -+ -+ /* interface for setting binary config values */ -+ {"control", S_IFDIR, 0550}, -+ {"complain", S_IFREG, 0640, &subdomainfs_control_fops, -+ &subdomain_complain}, -+ {"audit", S_IFREG, 0640, &subdomainfs_control_fops, -+ &subdomain_audit}, -+ {"debug", S_IFREG, 0640, &subdomainfs_control_fops, -+ &subdomain_debug}, -+ {"logsyscall", S_IFREG, 0640, &subdomainfs_control_fops, -+ &subdomain_logsyscall}, -+ {NULL, S_IFDIR, 0}, -+ -+ /* root end */ -+ {NULL, S_IFDIR, 0} -+}; -+ -+#define SDFS_DENTRY root_entries[0].dentry -+ -+static const unsigned int num_entries = -+ sizeof(root_entries) / sizeof(struct root_entry); -+ -+ -+ -+static int sd_prof_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &subdomainfs_profiles_op); -+} -+ -+ -+static int sd_prof_release(struct inode *inode, struct file *file) -+{ -+ return seq_release(inode, file); -+} -+ -+static ssize_t sd_version_read(struct file *file, char __user *buf, -+ size_t size, loff_t *ppos) -+{ -+ const char *version = apparmor_version_nl(); -+ -+ return simple_read_from_buffer(buf, size, ppos, version, -+ strlen(version)); -+} -+ -+static char *sd_simple_write_to_buffer(const char __user *userbuf, -+ size_t alloc_size, size_t copy_size, -+ loff_t *pos, const char *msg) -+{ -+ char *data; -+ -+ if (*pos != 0) { -+ /* only writes from pos 0, that is complete writes */ -+ data = ERR_PTR(-ESPIPE); -+ goto out; -+ } -+ -+ /* Don't allow confined processes to load/replace/remove profiles. -+ * No sane person would add rules allowing this to a profile -+ * but we enforce the restriction anyways. -+ */ -+ if (sd_is_confined()) { -+ struct subdomain *sd = SD_SUBDOMAIN(current->security); -+ -+ SD_WARN("REJECTING access to profile %s (%s(%d) " -+ "profile %s active %s)\n", -+ msg, current->comm, current->pid, -+ sd->profile->name, sd->active->name); -+ -+ data = ERR_PTR(-EPERM); -+ goto out; -+ } -+ -+ data = vmalloc(alloc_size); -+ if (data == NULL) { -+ data = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ if (copy_from_user(data, userbuf, copy_size)) { -+ vfree(data); -+ data = ERR_PTR(-EFAULT); -+ goto out; -+ } -+ -+out: -+ return data; -+} -+ -+static ssize_t sd_profile_load(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos) -+{ -+ char *data; -+ ssize_t error; -+ -+ data = sd_simple_write_to_buffer(buf, size, size, pos, "load"); -+ -+ if (!IS_ERR(data)) { -+ error = sd_file_prof_add(data, size); -+ vfree(data); -+ } else { -+ error = PTR_ERR(data); -+ } -+ -+ return error; -+} -+ -+static ssize_t sd_profile_replace(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos) -+{ -+ char *data; -+ ssize_t error; -+ -+ data = sd_simple_write_to_buffer(buf, size, size, pos, "replacement"); -+ -+ if (!IS_ERR(data)) { -+ error = sd_file_prof_repl(data, size); -+ vfree(data); -+ } else { -+ error = PTR_ERR(data); -+ } -+ -+ return error; -+} -+ -+static ssize_t sd_profile_remove(struct file *f, const char __user *buf, -+ size_t size, loff_t *pos) -+{ -+ char *data; -+ ssize_t error; -+ -+ /* sd_file_prof_remove needs a null terminated string so 1 extra -+ * byte is allocated and null the copied data is then null terminated -+ */ -+ data = sd_simple_write_to_buffer(buf, size+1, size, pos, "removal"); -+ -+ if (!IS_ERR(data)) { -+ data[size] = 0; -+ error = sd_file_prof_remove(data, size); -+ vfree(data); -+ } else { -+ error = PTR_ERR(data); -+ } -+ -+ return error; -+} -+ -+static u64 sd_control_get(void *data) -+{ -+ return *(int *)data; -+} -+ -+static void sd_control_set(void *data, u64 val) -+{ -+ if (val > 1) -+ val = 1; -+ -+ *(int*)data = (int)val; -+} -+ -+static void clear_subdomainfs(void) -+{ -+ unsigned int i; -+ -+ for (i=0; i < num_entries;i++) { -+ unsigned int index; -+ -+ if (root_entries[i].mode == S_IFDIR) { -+ if (root_entries[i].name) -+ /* defer dir free till all sub-entries freed */ -+ continue; -+ else -+ /* cleanup parent */ -+ index = root_entries[i].parent_index; -+ } else { -+ index = i; -+ } -+ -+ if (root_entries[index].dentry) { -+ securityfs_remove(root_entries[index].dentry); -+ -+ SD_DEBUG("%s: deleted subdomainfs entry name=%s " -+ "dentry=%p\n", -+ __FUNCTION__, -+ root_entries[index].name, -+ root_entries[index].dentry); -+ -+ root_entries[index].dentry = NULL; -+ root_entries[index].parent_index = 0; -+ } -+ } -+} -+ -+static int populate_subdomainfs(struct dentry *root) -+{ -+ unsigned int i, parent_index, depth; -+ -+#define ENT root_entries[i] -+ -+ for (i = 0; i < num_entries; i++) { -+ root_entries[i].dentry = NULL; -+ root_entries[i].parent_index = 0; -+ } -+ -+ /* 1. Verify entry 0 is valid [sanity check] */ -+ if (num_entries == 0 || -+ !root_entries[0].name || -+ strcmp(root_entries[0].name, SECFS_SD) != 0 || -+ root_entries[0].mode != S_IFDIR) { -+ SD_ERROR("%s: root entry 0 is not SECFS_SD/dir\n", -+ __FUNCTION__); -+ goto error; -+ } -+ -+ /* 2. Verify table structure */ -+ parent_index = 0; -+ depth = 1; -+ -+ for (i = 1; i < num_entries; i++) { -+ ENT.parent_index = parent_index; -+ -+ if (ENT.name && ENT.mode == S_IFDIR) { -+ depth++; -+ parent_index = i; -+ } else if (!ENT.name) { -+ if (ENT.mode != S_IFDIR || depth == 0) { -+ SD_ERROR("%s: root_entry %d invalid (%u %d)", -+ __FUNCTION__, i, -+ ENT.mode, ENT.parent_index); -+ goto error; -+ } -+ -+ depth--; -+ parent_index = root_entries[parent_index].parent_index; -+ } -+ } -+ -+ if (depth != 0) { -+ SD_ERROR("%s: root_entry table not correctly terminated\n", -+ __FUNCTION__); -+ goto error; -+ } -+ -+ /* 3. Create root (parent=NULL) */ -+ i=0; -+ -+ ENT.dentry = securityfs_create_file(ENT.name, -+ ENT.mode | ENT.access, -+ NULL, NULL, NULL); -+ -+ if (ENT.dentry) -+ SD_DEBUG("%s: created securityfs/subdomain [dentry=%p]\n", -+ __FUNCTION__, ENT.dentry); -+ else -+ goto error; -+ -+ -+ /* 4. create remaining nodes */ -+ for (i = 1; i < num_entries; i++) { -+ struct dentry *parent; -+ -+ /* end of directory ? */ -+ if (!ENT.name) -+ continue; -+ -+ parent = root_entries[ENT.parent_index].dentry; -+ -+ ENT.dentry = securityfs_create_file(ENT.name, -+ ENT.mode | ENT.access, -+ parent, -+ ENT.mode != S_IFDIR ? ENT.data : NULL, -+ ENT.mode != S_IFDIR ? ENT.fops : NULL); -+ -+ if (!ENT.dentry) -+ goto cleanup_error; -+ -+ SD_DEBUG("%s: added subdomainfs entry " -+ "name=%s mode=%x dentry=%p [parent %p]\n", -+ __FUNCTION__, ENT.name, ENT.mode|ENT.access, -+ ENT.dentry, parent); -+ } -+ -+ return 1; -+ -+cleanup_error: -+ clear_subdomainfs(); -+ -+error: -+ return 0; -+} -+ -+int create_subdomainfs(void) -+{ -+ if (SDFS_DENTRY) -+ SD_ERROR("%s: Subdomain securityfs already exists\n", -+ __FUNCTION__); -+ else if (!populate_subdomainfs(sdfs_dentry)) -+ SD_ERROR("%s: Error populating Subdomain securityfs\n", -+ __FUNCTION__); -+ -+ return (SDFS_DENTRY != NULL); -+} -+ -+int destroy_subdomainfs(void) -+{ -+ if (SDFS_DENTRY) -+ clear_subdomainfs(); -+ -+ return 1; -+} ---- /dev/null -+++ linux-2.6.16-SL101_BRANCH/security/apparmor/shared.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (C) 2000, 2001, 2004, 2005 Novell/SUSE -+ * -+ * Immunix AppArmor LSM -+ * -+ * 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. -+ */ -+ -+#ifndef _SHARED_H -+#define _SHARED_H -+ -+/* start of system offsets */ -+#define POS_SD_FILE_MIN 0 -+#define POS_SD_MAY_EXEC POS_SD_FILE_MIN -+#define POS_SD_MAY_WRITE (POS_SD_MAY_EXEC + 1) -+#define POS_SD_MAY_READ (POS_SD_MAY_WRITE + 1) -+/* not used by Subdomain */ -+#define POS_SD_MAY_APPEND (POS_SD_MAY_READ + 1) -+/* end of system offsets */ -+ -+#define POS_SD_MAY_LINK (POS_SD_MAY_APPEND + 1) -+#define POS_SD_EXEC_INHERIT (POS_SD_MAY_LINK + 1) -+#define POS_SD_EXEC_UNCONSTRAINED (POS_SD_EXEC_INHERIT + 1) -+#define POS_SD_EXEC_PROFILE (POS_SD_EXEC_UNCONSTRAINED + 1) -+#define POS_SD_FILE_MAX POS_SD_EXEC_PROFILE -+ -+/* Modeled after MAY_READ, MAY_WRITE, MAY_EXEC def'ns */ -+#define SD_MAY_EXEC (0x01 << POS_SD_MAY_EXEC) -+#define SD_MAY_WRITE (0x01 << POS_SD_MAY_WRITE) -+#define SD_MAY_READ (0x01 << POS_SD_MAY_READ) -+#define SD_MAY_LINK (0x01 << POS_SD_MAY_LINK) -+#define SD_EXEC_INHERIT (0x01 << POS_SD_EXEC_INHERIT) -+#define SD_EXEC_UNCONSTRAINED (0x01 << POS_SD_EXEC_UNCONSTRAINED) -+#define SD_EXEC_PROFILE (0x01 << POS_SD_EXEC_PROFILE) -+#define SD_EXEC_MODIFIERS(X) (X & (SD_EXEC_INHERIT | \ -+ SD_EXEC_UNCONSTRAINED | \ -+ SD_EXEC_PROFILE)) -+ -+#endif /* _SHARED_H */ diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_namespacesem.patch b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_namespacesem.patch deleted file mode 100644 index 1dd1f544..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/apparmor-sources-2.6.17-r1-apparmor_namespacesem.patch +++ /dev/null @@ -1,36 +0,0 @@ -Subject: Export namespace semaphore -Patch-mainline: no - -Export global namespace_sem (this used to be a per namespace semaphore). -Alas, this isn't going to win _any_ points for style. -Patch is not in mainline -- pending AppArmor code submission to lkml - -Index: linux-2.6.17/fs/namespace.c -=================================================================== ---- linux-2.6.17.orig/fs/namespace.c -+++ linux-2.6.17/fs/namespace.c -@@ -46,7 +46,8 @@ - static struct list_head *mount_hashtable __read_mostly; - static int hash_mask __read_mostly, hash_bits __read_mostly; - static kmem_cache_t *mnt_cache __read_mostly; --static struct rw_semaphore namespace_sem; -+struct rw_semaphore namespace_sem; -+EXPORT_SYMBOL_GPL(namespace_sem); - - /* /sys/fs */ - decl_subsys(fs, NULL, NULL); - -Index: linux-2.6.17/include/linux/namespace.h -=================================================================== ---- linux-2.6.17.orig/include/linux/namespace.h -+++ linux-2.6.17/include/linux/namespace.h -@@ -5,6 +5,9 @@ - #include - #include - -+/* exported for AppArmor (SubDomain) */ -+extern struct rw_semaphore namespace_sem; -+ - struct namespace { - atomic_t count; - struct vfsmount * root; diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.17 b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.17 deleted file mode 100644 index 5fb45997..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.17 +++ /dev/null @@ -1,12 +0,0 @@ -MD5 a6a5ccde0c291921c155a74da36463a2 apparmor-kernel-patches-2.6.17.9.tar.gz 231231 -RMD160 762d4b59aa508cfd82ebbeba4822ffb0551f5888 apparmor-kernel-patches-2.6.17.9.tar.gz 231231 -SHA256 0884cd7bfdff4505fd5271ca68b72f74b352d209321ef60dc81620b0539f0ec7 apparmor-kernel-patches-2.6.17.9.tar.gz 231231 -MD5 cd5d67dc1d3514ec240497efff0f8726 genpatches-2.6.17-1.base.tar.bz2 3337 -RMD160 f9b5621fed8fcfee7da697d89097842287b41b24 genpatches-2.6.17-1.base.tar.bz2 3337 -SHA256 2208b72729dce6daef7dc5700192aec0ae17327c794681621d2123f0c483ae21 genpatches-2.6.17-1.base.tar.bz2 3337 -MD5 0b6385904bccbd9d6c5508565e5c76ff genpatches-2.6.17-1.extras.tar.bz2 138704 -RMD160 14b17e02b7893e6b023bee9e1b40f4bc85a30f05 genpatches-2.6.17-1.extras.tar.bz2 138704 -SHA256 fa10ec7d3d74c8bf57fb3bd01c33f83dcca3c1e4cd4601937cc2ef904cce1dfe genpatches-2.6.17-1.extras.tar.bz2 138704 -MD5 37ddefe96625502161f075b9d907f21e linux-2.6.17.tar.bz2 41272919 -RMD160 26aad30c9a6610665c6c7d62401d79bf56a6a699 linux-2.6.17.tar.bz2 41272919 -SHA256 ab0f647d52f124958439517df9e1ae0efda90cdb851f59f522fa1749f1d87d58 linux-2.6.17.tar.bz2 41272919 diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.17-r1 b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.17-r1 deleted file mode 100644 index 0d2fbf99..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.17-r1 +++ /dev/null @@ -1,9 +0,0 @@ -MD5 cd5d67dc1d3514ec240497efff0f8726 genpatches-2.6.17-1.base.tar.bz2 3337 -RMD160 f9b5621fed8fcfee7da697d89097842287b41b24 genpatches-2.6.17-1.base.tar.bz2 3337 -SHA256 2208b72729dce6daef7dc5700192aec0ae17327c794681621d2123f0c483ae21 genpatches-2.6.17-1.base.tar.bz2 3337 -MD5 0b6385904bccbd9d6c5508565e5c76ff genpatches-2.6.17-1.extras.tar.bz2 138704 -RMD160 14b17e02b7893e6b023bee9e1b40f4bc85a30f05 genpatches-2.6.17-1.extras.tar.bz2 138704 -SHA256 fa10ec7d3d74c8bf57fb3bd01c33f83dcca3c1e4cd4601937cc2ef904cce1dfe genpatches-2.6.17-1.extras.tar.bz2 138704 -MD5 37ddefe96625502161f075b9d907f21e linux-2.6.17.tar.bz2 41272919 -RMD160 26aad30c9a6610665c6c7d62401d79bf56a6a699 linux-2.6.17.tar.bz2 41272919 -SHA256 ab0f647d52f124958439517df9e1ae0efda90cdb851f59f522fa1749f1d87d58 linux-2.6.17.tar.bz2 41272919 diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.18 b/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.18 deleted file mode 100644 index fed15c63..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/files/digest-apparmor-sources-2.6.18 +++ /dev/null @@ -1,12 +0,0 @@ -MD5 523e91619920dea824a35bf813db1b67 apparmor-kernel-patches-2.6.18.tar.gz 231072 -RMD160 f734125d986dcb3aec371f0e24126a5473d5637f apparmor-kernel-patches-2.6.18.tar.gz 231072 -SHA256 91224ff1f45de306c0720a5680a8f883888b52f296b0de24c63ec02668782b63 apparmor-kernel-patches-2.6.18.tar.gz 231072 -MD5 0c1cd82748c5d2207fa034e32686bca7 genpatches-2.6.18-1.base.tar.bz2 2397 -RMD160 1b02d9e5adba7a9a17f85691f312ee2c870c9a48 genpatches-2.6.18-1.base.tar.bz2 2397 -SHA256 e87db440591d48f74b8d50f47bde55a1652c969626befa94aba48cee57aa5da8 genpatches-2.6.18-1.base.tar.bz2 2397 -MD5 f565ec95a1f2ac1b675f9a126c27c3c1 genpatches-2.6.18-1.extras.tar.bz2 147040 -RMD160 f62b371d522fa8978cee4e809baea364ed8e804a genpatches-2.6.18-1.extras.tar.bz2 147040 -SHA256 080b19f98ffa8f5edbccabfa9dd4ac845ecc1b21c7fba761ad3d011893117b01 genpatches-2.6.18-1.extras.tar.bz2 147040 -MD5 296a6d150d260144639c3664d127d174 linux-2.6.18.tar.bz2 41863580 -RMD160 f92283f956880676bfb1f1d5288325461e4e02e7 linux-2.6.18.tar.bz2 41863580 -SHA256 c95280ff6c5d2a17788f7cc582d23ae8a9a7ba3f202ec6e4238eaadfce7c163d linux-2.6.18.tar.bz2 41863580 diff --git a/trunk/novell4gentoo/sys-kernel/apparmor-sources/metadata.xml b/trunk/novell4gentoo/sys-kernel/apparmor-sources/metadata.xml deleted file mode 100644 index e43ec030..00000000 --- a/trunk/novell4gentoo/sys-kernel/apparmor-sources/metadata.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - -apparmor - - zepher@sigalrm.com - Matthew Snelham - Primary Maintainer - -Patched kernel sources containing the proper symbol exports, and the full apparmor module suite. Based on gentoo-sources kernel. - diff --git a/trunk/novell4gentoo/sys-libs/libapparmor/ChangeLog b/trunk/novell4gentoo/sys-libs/libapparmor/ChangeLog deleted file mode 100644 index 183ffe01..00000000 --- a/trunk/novell4gentoo/sys-libs/libapparmor/ChangeLog +++ /dev/null @@ -1,10 +0,0 @@ -# ChangeLog for sys-libs/libapparmor -# Copyright 1999-2006 Gentoo Foundation; Distributed under the GPL v2 -# $Header: $ - - 13 Aug 2006; Mario Fetka - +libapparmor-2.0_p6288.ebuild: - Initial Import of - Matthew Snelham - Apparmor ebuilds - diff --git a/trunk/novell4gentoo/sys-libs/libapparmor/Manifest b/trunk/novell4gentoo/sys-libs/libapparmor/Manifest deleted file mode 100644 index c9777027..00000000 --- a/trunk/novell4gentoo/sys-libs/libapparmor/Manifest +++ /dev/null @@ -1,24 +0,0 @@ -DIST libapparmor-2.0-132.tar.gz 16744 RMD160 c174a530fadb8c33f2858160f2cdcf5b76289940 SHA1 953851b4079ff864bd9679c2f62b18c424662cb8 SHA256 b4ac4f208b1db08339effaf3362da0e3b240e1b6126b8a367d54006b23ae1b17 -DIST libapparmor-2.0-6288.tar.gz 20725 RMD160 5f4b8a443a23d4cd4a16b35ae8ebf65647683b2e SHA1 cd75d8631bdddb9e873cee5c6b3b45d12d94d416 SHA256 0aebaae48f1917a65c43683ad8f332301fcf46d4dcb392177a4750b245f42882 -EBUILD libapparmor-2.0_p132.ebuild 832 RMD160 b0dc473a86806f47adb4f7d18ad2b084764f2971 SHA1 a322be109eeb3bb78333b59183704b20c54c0960 SHA256 69087039002aa33d329eb1dbeab51b3fb638dde18afc1c3bf0683cd261b5df51 -MD5 29b073603effc975e61720b86b04644f libapparmor-2.0_p132.ebuild 832 -RMD160 b0dc473a86806f47adb4f7d18ad2b084764f2971 libapparmor-2.0_p132.ebuild 832 -SHA256 69087039002aa33d329eb1dbeab51b3fb638dde18afc1c3bf0683cd261b5df51 libapparmor-2.0_p132.ebuild 832 -EBUILD libapparmor-2.0_p6288.ebuild 833 RMD160 2cb68e615d17cb3a8d2dec04eb3e7591ff0b7b0c SHA1 a532c94dad06f14345b10056425eb7a83f86fede SHA256 62b95ca2859d69d52a6c61953323a436445de006e99f696bac2372652c805a62 -MD5 3211838fc17b65a3c9802623a6c7bf26 libapparmor-2.0_p6288.ebuild 833 -RMD160 2cb68e615d17cb3a8d2dec04eb3e7591ff0b7b0c libapparmor-2.0_p6288.ebuild 833 -SHA256 62b95ca2859d69d52a6c61953323a436445de006e99f696bac2372652c805a62 libapparmor-2.0_p6288.ebuild 833 -MISC ChangeLog 284 RMD160 1553535ff05f46ae92828147a583f2f0d5402eee SHA1 343d3606e800346037da0a81e214300916e46917 SHA256 5353c6e36136b7e1b35a257611658d4d61e38f6c534b66d4eeb32bbef767c72a -MD5 ab9f8c5f4d1aa1b4e3591adb277b2b63 ChangeLog 284 -RMD160 1553535ff05f46ae92828147a583f2f0d5402eee ChangeLog 284 -SHA256 5353c6e36136b7e1b35a257611658d4d61e38f6c534b66d4eeb32bbef767c72a ChangeLog 284 -MISC metadata.xml 450 RMD160 d535fe106e302ca44b57bb84c908879597d95391 SHA1 d1ab915420fa81974724847d4e1dbbcb4b6a2cd6 SHA256 ee835dc483681371f197a3a46241f0fc7ce54869b2578132c268a4dc171cf015 -MD5 61f0a7a9d59cc054a3542313d1515744 metadata.xml 450 -RMD160 d535fe106e302ca44b57bb84c908879597d95391 metadata.xml 450 -SHA256 ee835dc483681371f197a3a46241f0fc7ce54869b2578132c268a4dc171cf015 metadata.xml 450 -MD5 9913e4e3a663787501f86fe85c989cc6 files/digest-libapparmor-2.0_p132 256 -RMD160 efca71ce6079f9be02ca6bec4d0a3edea523f00a files/digest-libapparmor-2.0_p132 256 -SHA256 4d5fbabd865d64ab586b53e90f1fb7ad0ca8ac03dcb69e93fa6a105b7bdf8a9a files/digest-libapparmor-2.0_p132 256 -MD5 b2a797f50971ce7df339c695782874b2 files/digest-libapparmor-2.0_p6288 259 -RMD160 7088ab92b7dc5c741357ca3184eb79575a0832de files/digest-libapparmor-2.0_p6288 259 -SHA256 ae7d5dd76d792a1ff7ee7817846dff1402573c7fee7b19a45120086dac49e898 files/digest-libapparmor-2.0_p6288 259 diff --git a/trunk/novell4gentoo/sys-libs/libapparmor/files/digest-libapparmor-2.0_p132 b/trunk/novell4gentoo/sys-libs/libapparmor/files/digest-libapparmor-2.0_p132 deleted file mode 100644 index 20a2b08a..00000000 --- a/trunk/novell4gentoo/sys-libs/libapparmor/files/digest-libapparmor-2.0_p132 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 6f62215d4e8d54ac1f79fd8d39c3bbd3 libapparmor-2.0-132.tar.gz 16744 -RMD160 c174a530fadb8c33f2858160f2cdcf5b76289940 libapparmor-2.0-132.tar.gz 16744 -SHA256 b4ac4f208b1db08339effaf3362da0e3b240e1b6126b8a367d54006b23ae1b17 libapparmor-2.0-132.tar.gz 16744 diff --git a/trunk/novell4gentoo/sys-libs/libapparmor/files/digest-libapparmor-2.0_p6288 b/trunk/novell4gentoo/sys-libs/libapparmor/files/digest-libapparmor-2.0_p6288 deleted file mode 100644 index 74898c70..00000000 --- a/trunk/novell4gentoo/sys-libs/libapparmor/files/digest-libapparmor-2.0_p6288 +++ /dev/null @@ -1,3 +0,0 @@ -MD5 e7f5e6f8663919d5998469e842442509 libapparmor-2.0-6288.tar.gz 20725 -RMD160 5f4b8a443a23d4cd4a16b35ae8ebf65647683b2e libapparmor-2.0-6288.tar.gz 20725 -SHA256 0aebaae48f1917a65c43683ad8f332301fcf46d4dcb392177a4750b245f42882 libapparmor-2.0-6288.tar.gz 20725 diff --git a/trunk/novell4gentoo/sys-libs/libapparmor/libapparmor-2.0_p132.ebuild b/trunk/novell4gentoo/sys-libs/libapparmor/libapparmor-2.0_p132.ebuild deleted file mode 100644 index fdd52858..00000000 --- a/trunk/novell4gentoo/sys-libs/libapparmor/libapparmor-2.0_p132.ebuild +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit eutils toolchain-funcs - -MY_P="${P/_p/-}" -MONTH="October" -DESCRIPTION="Primary support library and headers for AppArmor userspace" -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -SRC_URI="http://forgeftp.novell.com/apparmor/Development%20-%20${MONTH}%20Snapshot/${MY_P}.tar.gz" - -LICENSE="LGPL-2.1" -SLOT="0" -KEYWORDS="~x86 ~amd64" -IUSE="" - -DEPEND="virtual/libc" -RDEPEND="${DEPEND}" - -MY_S=${WORKDIR}/${P/_*/} - -src_unpack() { - unpack ${A} - - cd ${MY_S} - # the Make.rules isn't needed for Gentoo - sed -i "s/^include Make.rules//g" Makefile -} - -src_compile() { - cd ${MY_S} - emake CC="$(tc-getCC)" CFLAGS="${CFLAGS}" || die -} - -src_install() { - cd ${MY_S} - make DESTDIR="${D}" install || die -} diff --git a/trunk/novell4gentoo/sys-libs/libapparmor/libapparmor-2.0_p6288.ebuild b/trunk/novell4gentoo/sys-libs/libapparmor/libapparmor-2.0_p6288.ebuild deleted file mode 100644 index 379dd1b7..00000000 --- a/trunk/novell4gentoo/sys-libs/libapparmor/libapparmor-2.0_p6288.ebuild +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 1999-2006 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit eutils toolchain-funcs - -MY_P="${P/_p/-}" -DESCRIPTION="Primary support library and headers for AppArmor userspace" -HOMEPAGE="http://forge.novell.com/modules/xfmod/project/?apparmor" -SRC_URI="http://forge.novell.com/modules/xfcontent/private.php/apparmor/Development%20-%20April%20Snapshot/${MY_P}.tar.gz" - -LICENSE="LGPL-2.1" -SLOT="0" -KEYWORDS="~x86" -IUSE="" - -DEPEND="virtual/libc" -RDEPEND="${DEPEND}" - -MY_S=${WORKDIR}/${P/_*/} - -src_unpack() { - unpack ${A} - - cd ${MY_S} - # the Make.rules isn't needed for Gentoo - sed -i "s/^include Make.rules//g" Makefile -} - -src_compile() { - cd ${MY_S} - emake CC="$(tc-getCC)" CFLAGS="${CFLAGS}" || die -} - -src_install() { - cd ${MY_S} - make DESTDIR="${D}" install || die -} diff --git a/trunk/novell4gentoo/sys-libs/libapparmor/metadata.xml b/trunk/novell4gentoo/sys-libs/libapparmor/metadata.xml deleted file mode 100644 index 35e8e28a..00000000 --- a/trunk/novell4gentoo/sys-libs/libapparmor/metadata.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - -apparmor - - zepher@sigalrm.com - Matthew Snelham - Primary Maintainer - -Apparmor shared libraries. Packaged separately due to license difference from primary apparmor code. -