2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-29 13:28:19 +00:00

Rename change_hat(2) to aa_change_hat(2) (a backwards compatibility

macro is in place) and support 64 bit magic tokens.
This commit is contained in:
Steve Beattie 2007-08-16 04:26:19 +00:00
parent bda571d643
commit adf6076d85
7 changed files with 64 additions and 40 deletions

View File

@ -24,13 +24,13 @@
=head1 NAME =head1 NAME
change_hat - change to or from a "hat" within a AppArmor profile aa_change_hat - change to or from a "hat" within a AppArmor profile
=head1 SYNOPSIS =head1 SYNOPSIS
B<#include E<lt>sys/apparmor.hE<gt>> B<#include E<lt>sys/apparmor.hE<gt>>
B<int change_hat (char *subprofile, unsigned int magic_token);> B<int aa_change_hat (char *subprofile, unsigned long magic_token);>
Link with B<-lapparmor> when compiling. Link with B<-lapparmor> when compiling.
@ -39,13 +39,13 @@ Link with B<-lapparmor> when compiling.
An AppArmor profile applies to an executable program; if a portion of An AppArmor profile applies to an executable program; if a portion of
the program needs different access permissions than other portions, the program needs different access permissions than other portions,
the program can "change hats" to a different role, also known as a the program can "change hats" to a different role, also known as a
subprofile. To change into a new hat, it calls the change_hat() function subprofile. To change into a new hat, it calls the aa_change_hat()
to do so. It passes in a pointer to the I<subprofile> which it wants to function to do so. It passes in a pointer to the I<subprofile> which it
change into, and a 32bit I<magic_token>. The I<magic_token> is used to wants to change into, and a 64bit I<magic_token>. The I<magic_token>
return out of the subprofile at a later time. is used to return out of the subprofile at a later time.
If a program wants to return out of the current subprofile to the If a program wants to return out of the current subprofile to the
original profile, it calls change_hat() with a pointer to NULL as original profile, it calls aa_change_hat() with a pointer to NULL as
the I<subprofile>, and the original I<magic_token> value. If the the I<subprofile>, and the original I<magic_token> value. If the
I<magic_token> does not match the original I<magic_token> passed into the I<magic_token> does not match the original I<magic_token> passed into the
kernel when the program entered the subprofile, the change back to the kernel when the program entered the subprofile, the change back to the
@ -54,7 +54,7 @@ If the I<magic_token> matches the original token, then the process will
change back to the original profile. change back to the original profile.
If the program wants to change to a subprofile that it can never If the program wants to change to a subprofile that it can never
change back out of, the application should call change_hat() with a change back out of, the application should call aa_change_hat() with a
I<magic_token> of I<0>. I<magic_token> of I<0>.
As both read(2) and write(2) are mediated, a file must be listed in a As both read(2) and write(2) are mediated, a file must be listed in a
@ -97,19 +97,19 @@ process tried to change another process's domain.
=head1 EXAMPLE =head1 EXAMPLE
The following code examples shows simple, if contrived, uses of The following code examples shows simple, if contrived, uses of
change_hat(); a typical use of change_hat() will separate privileged aa_change_hat(); a typical use of aa_change_hat() will separate
portions of a process from unprivileged portions of a process, such as privileged portions of a process from unprivileged portions of a process,
keeping unauthenticated network traffic handling separate from such as keeping unauthenticated network traffic handling separate
authenticated network traffic handling in OpenSSH or executing from authenticated network traffic handling in OpenSSH or executing
user-supplied CGI scripts in apache. user-supplied CGI scripts in apache.
The use of random(3) is simply illustrative. Use of F</dev/urandom> is The use of random(3) is simply illustrative. Use of F</dev/urandom> is
recommended. recommended.
First, a simple high-level overview of change_hat() use: First, a simple high-level overview of aa_change_hat() use:
void foo (void) { void foo (void) {
int magic_token; unsigned long magic_token;
/* get a random magic token value /* get a random magic token value
from our huge entropy pool */ from our huge entropy pool */
@ -117,7 +117,7 @@ First, a simple high-level overview of change_hat() use:
/* change into the subprofile while /* change into the subprofile while
* we do stuff we don't trust */ * we do stuff we don't trust */
change_hat ("stuff_we_dont_trust", magic_token); aa_change_hat("stuff_we_dont_trust", magic_token);
/* Go do stuff we don't trust -- this is all /* Go do stuff we don't trust -- this is all
* done in *this* process space, no separate * done in *this* process space, no separate
@ -125,11 +125,11 @@ First, a simple high-level overview of change_hat() use:
interpret_perl_stuff(stuff_from_user); interpret_perl_stuff(stuff_from_user);
/* now change back to our original profile */ /* now change back to our original profile */
change_hat (NULL, magic_token); aa_change_hat(NULL, magic_token);
} }
Second, an example to show that files not listed in a subprofile Second, an example to show that files not listed in a subprofile ("hat")
("hat") aren't accessible after a change_hat() call: aren't accessible after an aa_change_hat() call:
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -143,7 +143,7 @@ Second, an example to show that files not listed in a subprofile
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int fd; int fd;
int tok; unsigned long tok;
char buf[10]; char buf[10];
/* random() is a poor choice */ /* random() is a poor choice */
@ -164,8 +164,8 @@ Second, an example to show that files not listed in a subprofile
/* change hat to the "hat" subprofile, which should not have /* change hat to the "hat" subprofile, which should not have
* read access to /etc/passwd -- even though we have a valid * read access to /etc/passwd -- even though we have a valid
* file descriptor at the time of the change_hat() call. */ * file descriptor at the time of the aa_change_hat() call. */
if (change_hat("hat", tok)) { if (aa_change_hat("hat", tok)) {
perror("Failure changing hat -- aborting"); perror("Failure changing hat -- aborting");
_exit(1); _exit(1);
} }
@ -221,7 +221,7 @@ The output when run:
=head1 BUGS =head1 BUGS
None known. If you find any, please report them to bugzilla at None known. If you find any, please report them to bugzilla at
L<http://bugzilla.novell.com>. Note that change_hat(2) provides no L<http://bugzilla.novell.com>. Note that aa_change_hat(2) provides no
memory barriers between different areas of a program; if address space memory barriers between different areas of a program; if address space
separation is required, then separate processes should be used. separation is required, then separate processes should be used.

View File

@ -58,10 +58,10 @@ mkdir ${RPM_BUILD_ROOT}/%{_lib}
# this is really hacky # this is really hacky
rm ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.so rm ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.so
rm ${RPM_BUILD_ROOT}/%{_libdir}/libimmunix.so rm ${RPM_BUILD_ROOT}/%{_libdir}/libimmunix.so
cp ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.so.1.0.0 ${RPM_BUILD_ROOT}/%{_lib} cp ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.so.1.0.1 ${RPM_BUILD_ROOT}/%{_lib}
cp ${RPM_BUILD_ROOT}/%{_libdir}/libimmunix.so.1.0.0 ${RPM_BUILD_ROOT}/%{_lib} cp ${RPM_BUILD_ROOT}/%{_libdir}/libimmunix.so.1.0.1 ${RPM_BUILD_ROOT}/%{_lib}
ln -s /%{_lib}/libapparmor.so.1.0.0 ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.so ln -s /%{_lib}/libapparmor.so.1.0.1 ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.so
ln -s /%{_lib}/libimmunix.so.1.0.0 ${RPM_BUILD_ROOT}/%{_libdir}/libimmunix.so ln -s /%{_lib}/libimmunix.so.1.0.1 ${RPM_BUILD_ROOT}/%{_libdir}/libimmunix.so
find $RPM_BUILD_ROOT -name .packlist -exec rm -f {} \; find $RPM_BUILD_ROOT -name .packlist -exec rm -f {} \;
find $RPM_BUILD_ROOT -name perllocal.pod -exec rm -f {} \; find $RPM_BUILD_ROOT -name perllocal.pod -exec rm -f {} \;
@ -77,8 +77,8 @@ rm -rf "$RPM_BUILD_ROOT"
%files %files
%defattr(-,root,root) %defattr(-,root,root)
/%{_lib}/libapparmor.so.1.0.0 /%{_lib}/libapparmor.so.*
/%{_lib}/libimmunix.so.1.0.0 /%{_lib}/libimmunix.so.*
%files -n libapparmor-devel %files -n libapparmor-devel
%defattr(-,root,root) %defattr(-,root,root)
@ -103,5 +103,6 @@ rm -rf "$RPM_BUILD_ROOT"
* Wed Aug 15 2007 - sbeattie@suse.de * Wed Aug 15 2007 - sbeattie@suse.de
- fix braindead symbol versioning issue with old version name - fix braindead symbol versioning issue with old version name
- re-enable CFLAGS=RPM_OPT_FLAGS for build - re-enable CFLAGS=RPM_OPT_FLAGS for build
- convert change_hat(2) to aa_change_hat(2)
- use 64bit magic token

View File

@ -16,10 +16,10 @@ lib_LTLIBRARIES = libapparmor.la libimmunix.la
noinst_HEADERS = grammar.h parser.h scanner.h noinst_HEADERS = grammar.h parser.h scanner.h
libapparmor_la_SOURCES = grammar.y libaalogparse.c change_hat.c scanner.c libapparmor_la_SOURCES = grammar.y libaalogparse.c change_hat.c scanner.c
libapparmor_la_LDFLAGS = -version-info 1:0:0 -XCClinker -dynamic \ libapparmor_la_LDFLAGS = -version-info 1:1:0 -XCClinker -dynamic \
-Wl,--version-script=libapparmor.map -Wl,-soname=libapparmor.so.1 -Wl,--version-script=libapparmor.map -Wl,-soname=libapparmor.so.1
libimmunix_la_SOURCES = change_hat.c libimmunix_warning.c libimmunix_la_SOURCES = change_hat.c libimmunix_warning.c
libimmunix_la_LDFLAGS = -version-info 1:0:0 -Wl,--version-script=libapparmor.map -Wl,-soname=libimmunix.so.1 libimmunix_la_LDFLAGS = -version-info 1:1:0 -Wl,--version-script=libapparmor.map -Wl,-soname=libimmunix.so.1
EXTRA_DIST = grammar.y scanner.l libapparmor.map EXTRA_DIST = grammar.y scanner.l libapparmor.map

View File

@ -16,7 +16,10 @@ __BEGIN_DECLS
<http://forge.novell.com/modules/xfmod/project/?apparmor> <http://forge.novell.com/modules/xfmod/project/?apparmor>
Please see the change_hat(2) manpage for information. */ Please see the change_hat(2) manpage for information. */
extern int change_hat (const char *subprofile, unsigned int magic_token); extern int (change_hat)(const char *subprofile, unsigned int magic_token);
extern int aa_change_hat(const char *subprofile, unsigned long magic_token);
#define change_hat(X, Y) aa_change_hat((X), (Y))
__END_DECLS __END_DECLS

View File

@ -26,28 +26,28 @@
#define default_symbol_version(real, name, version) \ #define default_symbol_version(real, name, version) \
__asm__ (".symver " #real "," #name "@@" #version) __asm__ (".symver " #real "," #name "@@" #version)
int __change_hat(char *subprofile, unsigned int token) static int do_change_x(const char *cmd, const char *name, unsigned long token)
{ {
int rc = -1; int rc = -1;
int fd, ret, len = 0, ctlerr = 0; int fd, ret, len = 0, ctlerr = 0;
char *buf = NULL; char *buf = NULL;
const char *cmd = "changehat"; const char *fmt = "%s %016x^%s";
char *ctl = NULL; char *ctl = NULL;
pid_t tid = syscall(SYS_gettid); pid_t tid = syscall(SYS_gettid);
/* both may not be null */ /* both may not be null */
if (!(token || subprofile)) { if (!(token || name)) {
errno = EINVAL; errno = EINVAL;
goto out; goto out;
} }
if (subprofile && strnlen(subprofile, PATH_MAX + 1) > PATH_MAX) { if (name && strnlen(name, PATH_MAX + 1) > PATH_MAX) {
errno = EPROTO; errno = EPROTO;
goto out; goto out;
} }
len = asprintf(&buf, "%s %08x^%s", cmd, token, len = asprintf(&buf, fmt, cmd, token,
subprofile ? subprofile : ""); name ? name : "");
if (len < 0) { if (len < 0) {
goto out; goto out;
} }
@ -89,6 +89,17 @@ out:
return rc; return rc;
} }
int aa_change_hat(const char *subprofile, unsigned long token)
{
return do_change_x("changehat", subprofile, token);
}
/* original change_hat interface */
int __change_hat(char *subprofile, unsigned int token)
{
return aa_change_hat(subprofile, (unsigned long) token);
}
/* create an alias for the old change_hat@IMMUNIX_1.0 symbol */ /* create an alias for the old change_hat@IMMUNIX_1.0 symbol */
extern typeof((__change_hat)) __old_change_hat __attribute__((alias ("__change_hat"))); extern typeof((__change_hat)) __old_change_hat __attribute__((alias ("__change_hat")));
symbol_version(__old_change_hat, change_hat, IMMUNIX_1.0); symbol_version(__old_change_hat, change_hat, IMMUNIX_1.0);

View File

@ -13,3 +13,12 @@ APPARMOR_1.0 {
local: local:
*; *;
} IMMUNIX_1.0; } IMMUNIX_1.0;
APPARMOR_1.1 {
global:
aa_change_hat;
parse_record;
free_record;
local:
*;
} APPARMOR_1.0;

View File

@ -2,11 +2,11 @@
%{ %{
#include "aalogparse.h" #include "aalogparse.h"
extern int change_hat (const char *subprofile, unsigned int magic_token); extern int aa_change_hat(const char *subprofile, unsigned long magic_token);
%} %}
%include "typemaps.i" %include "typemaps.i"
%include "aalogparse.h" %include "aalogparse.h"
extern int change_hat (const char *subprofile, unsigned int magic_token); extern int aa_change_hat(const char *subprofile, unsigned long magic_token);