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:
parent
bda571d643
commit
adf6076d85
@ -24,13 +24,13 @@
|
||||
|
||||
=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
|
||||
|
||||
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.
|
||||
|
||||
@ -39,13 +39,13 @@ Link with B<-lapparmor> when compiling.
|
||||
An AppArmor profile applies to an executable program; if a portion of
|
||||
the program needs different access permissions than other portions,
|
||||
the program can "change hats" to a different role, also known as a
|
||||
subprofile. To change into a new hat, it calls the change_hat() function
|
||||
to do so. It passes in a pointer to the I<subprofile> which it wants to
|
||||
change into, and a 32bit I<magic_token>. The I<magic_token> is used to
|
||||
return out of the subprofile at a later time.
|
||||
subprofile. To change into a new hat, it calls the aa_change_hat()
|
||||
function to do so. It passes in a pointer to the I<subprofile> which it
|
||||
wants to change into, and a 64bit I<magic_token>. The I<magic_token>
|
||||
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
|
||||
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
|
||||
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
|
||||
@ -54,7 +54,7 @@ If the I<magic_token> matches the original token, then the process will
|
||||
change back to the original profile.
|
||||
|
||||
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>.
|
||||
|
||||
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
|
||||
|
||||
The following code examples shows simple, if contrived, uses of
|
||||
change_hat(); a typical use of change_hat() will separate privileged
|
||||
portions of a process from unprivileged portions of a process, such as
|
||||
keeping unauthenticated network traffic handling separate from
|
||||
authenticated network traffic handling in OpenSSH or executing
|
||||
aa_change_hat(); a typical use of aa_change_hat() will separate
|
||||
privileged portions of a process from unprivileged portions of a process,
|
||||
such as keeping unauthenticated network traffic handling separate
|
||||
from authenticated network traffic handling in OpenSSH or executing
|
||||
user-supplied CGI scripts in apache.
|
||||
|
||||
The use of random(3) is simply illustrative. Use of F</dev/urandom> is
|
||||
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) {
|
||||
int magic_token;
|
||||
unsigned long magic_token;
|
||||
|
||||
/* get a random magic token value
|
||||
from our huge entropy pool */
|
||||
@ -117,7 +117,7 @@ First, a simple high-level overview of change_hat() use:
|
||||
|
||||
/* change into the subprofile while
|
||||
* 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
|
||||
* 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);
|
||||
|
||||
/* 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
|
||||
("hat") aren't accessible after a change_hat() call:
|
||||
Second, an example to show that files not listed in a subprofile ("hat")
|
||||
aren't accessible after an aa_change_hat() call:
|
||||
|
||||
#include <stdlib.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 fd;
|
||||
int tok;
|
||||
unsigned long tok;
|
||||
char buf[10];
|
||||
|
||||
/* 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
|
||||
* read access to /etc/passwd -- even though we have a valid
|
||||
* file descriptor at the time of the change_hat() call. */
|
||||
if (change_hat("hat", tok)) {
|
||||
* file descriptor at the time of the aa_change_hat() call. */
|
||||
if (aa_change_hat("hat", tok)) {
|
||||
perror("Failure changing hat -- aborting");
|
||||
_exit(1);
|
||||
}
|
||||
@ -221,7 +221,7 @@ The output when run:
|
||||
=head1 BUGS
|
||||
|
||||
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
|
||||
separation is required, then separate processes should be used.
|
||||
|
||||
|
@ -58,10 +58,10 @@ mkdir ${RPM_BUILD_ROOT}/%{_lib}
|
||||
# this is really hacky
|
||||
rm ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.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}/libimmunix.so.1.0.0 ${RPM_BUILD_ROOT}/%{_lib}
|
||||
ln -s /%{_lib}/libapparmor.so.1.0.0 ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.so
|
||||
ln -s /%{_lib}/libimmunix.so.1.0.0 ${RPM_BUILD_ROOT}/%{_libdir}/libimmunix.so
|
||||
cp ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.so.1.0.1 ${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.1 ${RPM_BUILD_ROOT}/%{_libdir}/libapparmor.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 perllocal.pod -exec rm -f {} \;
|
||||
@ -77,8 +77,8 @@ rm -rf "$RPM_BUILD_ROOT"
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
/%{_lib}/libapparmor.so.1.0.0
|
||||
/%{_lib}/libimmunix.so.1.0.0
|
||||
/%{_lib}/libapparmor.so.*
|
||||
/%{_lib}/libimmunix.so.*
|
||||
|
||||
%files -n libapparmor-devel
|
||||
%defattr(-,root,root)
|
||||
@ -103,5 +103,6 @@ rm -rf "$RPM_BUILD_ROOT"
|
||||
* Wed Aug 15 2007 - sbeattie@suse.de
|
||||
- fix braindead symbol versioning issue with old version name
|
||||
- re-enable CFLAGS=RPM_OPT_FLAGS for build
|
||||
|
||||
- convert change_hat(2) to aa_change_hat(2)
|
||||
- use 64bit magic token
|
||||
|
||||
|
@ -16,10 +16,10 @@ lib_LTLIBRARIES = libapparmor.la libimmunix.la
|
||||
noinst_HEADERS = grammar.h parser.h scanner.h
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
@ -16,7 +16,10 @@ __BEGIN_DECLS
|
||||
<http://forge.novell.com/modules/xfmod/project/?apparmor>
|
||||
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
|
||||
|
||||
|
@ -26,28 +26,28 @@
|
||||
#define default_symbol_version(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 fd, ret, len = 0, ctlerr = 0;
|
||||
char *buf = NULL;
|
||||
const char *cmd = "changehat";
|
||||
const char *fmt = "%s %016x^%s";
|
||||
char *ctl = NULL;
|
||||
pid_t tid = syscall(SYS_gettid);
|
||||
|
||||
/* both may not be null */
|
||||
if (!(token || subprofile)) {
|
||||
if (!(token || name)) {
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (subprofile && strnlen(subprofile, PATH_MAX + 1) > PATH_MAX) {
|
||||
if (name && strnlen(name, PATH_MAX + 1) > PATH_MAX) {
|
||||
errno = EPROTO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = asprintf(&buf, "%s %08x^%s", cmd, token,
|
||||
subprofile ? subprofile : "");
|
||||
len = asprintf(&buf, fmt, cmd, token,
|
||||
name ? name : "");
|
||||
if (len < 0) {
|
||||
goto out;
|
||||
}
|
||||
@ -89,6 +89,17 @@ out:
|
||||
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 */
|
||||
extern typeof((__change_hat)) __old_change_hat __attribute__((alias ("__change_hat")));
|
||||
symbol_version(__old_change_hat, change_hat, IMMUNIX_1.0);
|
||||
|
@ -13,3 +13,12 @@ APPARMOR_1.0 {
|
||||
local:
|
||||
*;
|
||||
} IMMUNIX_1.0;
|
||||
|
||||
APPARMOR_1.1 {
|
||||
global:
|
||||
aa_change_hat;
|
||||
parse_record;
|
||||
free_record;
|
||||
local:
|
||||
*;
|
||||
} APPARMOR_1.0;
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
%{
|
||||
#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 "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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user