2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-01 14:55:10 +00:00

Add the unsafe exec flag and change exec to handle both safe (environment scrubbed by loader) and unsafe execs.

This commit is contained in:
John Johansen
2006-08-30 00:42:09 +00:00
parent 802ba1fad1
commit acb8945d38
4 changed files with 63 additions and 29 deletions

View File

@@ -13,6 +13,7 @@
#define __APPARMOR_H #define __APPARMOR_H
#include <linux/fs.h> /* Include for defn of iattr */ #include <linux/fs.h> /* Include for defn of iattr */
#include <linux/binfmts.h> /* defn of linux_binprm */
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include "shared.h" #include "shared.h"
@@ -101,15 +102,12 @@ struct aa_entry {
struct list_head listp[POS_AA_FILE_MAX + 1]; struct list_head listp[POS_AA_FILE_MAX + 1];
}; };
#define AA_EXEC_MODIFIER_MASK(mask) ((mask) & (AA_EXEC_UNCONSTRAINED |\ #define AA_SECURE_EXEC_NEEDED 0x00000001
AA_EXEC_INHERIT |\
AA_EXEC_PROFILE))
#define AA_EXEC_MASK(mask) ((mask) & (AA_MAY_EXEC |\
AA_EXEC_UNCONSTRAINED |\
AA_EXEC_INHERIT |\
AA_EXEC_PROFILE))
#define AA_EXEC_MODIFIER_MASK(mask) ((mask) & AA_EXEC_MODIFIERS)
#define AA_EXEC_MASK(mask) ((mask) & (AA_MAY_EXEC | AA_EXEC_MODIFIERS))
#define AA_EXEC_UNSAFE_MASK(mask) ((mask) & (AA_MAY_EXEC | AA_EXEC_MODIFIERS |\
AA_EXEC_UNSAFE))
/* struct aaprofile - basic confinement data /* struct aaprofile - basic confinement data
* @parent: non refcounted pointer to parent profile * @parent: non refcounted pointer to parent profile
@@ -298,7 +296,7 @@ extern int aa_perm_dir(struct aaprofile *active, struct dentry *dentry,
extern int aa_link(struct aaprofile *active, extern int aa_link(struct aaprofile *active,
struct dentry *link, struct dentry *target); struct dentry *link, struct dentry *target);
extern int aa_fork(struct task_struct *p); extern int aa_fork(struct task_struct *p);
extern int aa_register(struct file *file); extern int aa_register(struct linux_binprm *bprm);
extern void aa_release(struct task_struct *p); extern void aa_release(struct task_struct *p);
extern int aa_change_hat(const char *id, u32 hat_magic); extern int aa_change_hat(const char *id, u32 hat_magic);
extern int aa_associate_filp(struct file *filp); extern int aa_associate_filp(struct file *filp);

View File

@@ -194,7 +194,21 @@ static int apparmor_bprm_set_security(struct linux_binprm *bprm)
/* already set based on script name */ /* already set based on script name */
if (bprm->sh_bang) if (bprm->sh_bang)
return 0; return 0;
return aa_register(bprm->file); return aa_register(bprm);
}
static int apparmor_bprm_secureexec(struct linux_binprm *bprm)
{
int ret = cap_bprm_secureexec(bprm);
if (ret == 0 &&
(unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) {
AA_DEBUG("%s: secureexec required for %s\n",
__FUNCTION__, bprm->filename);
ret = 1;
}
return ret;
} }
static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type, static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type,
@@ -748,6 +762,7 @@ struct security_operations apparmor_ops = {
.bprm_apply_creds = apparmor_bprm_apply_creds, .bprm_apply_creds = apparmor_bprm_apply_creds,
.bprm_set_security = apparmor_bprm_set_security, .bprm_set_security = apparmor_bprm_set_security,
.bprm_secureexec = apparmor_bprm_secureexec,
.sb_mount = apparmor_sb_mount, .sb_mount = apparmor_sb_mount,
.sb_umount = apparmor_umount, .sb_umount = apparmor_umount,

View File

@@ -119,22 +119,22 @@ out:
* %AA_MAY_EXEC is returned indicating a naked x * %AA_MAY_EXEC is returned indicating a naked x
* if the has an exec qualifier then only the qualifier bit {pui} * if the has an exec qualifier then only the qualifier bit {pui}
* is returned (%AA_MAY_EXEC) is not set. * is returned (%AA_MAY_EXEC) is not set.
* * @unsafe: true if secure_exec should be overriden
* Returns %0 (false): * Returns %0 (false):
* if unable to find profile or there are conflicting pattern matches. * if unable to find profile or there are conflicting pattern matches.
* *xmod - is not modified * *xmod - is not modified
* *unsafe - is not modified
* *
* Returns %1 (true): * Returns %1 (true):
* if not confined
* *xmod = %AA_MAY_EXEC
* if exec rule matched * if exec rule matched
* if the rule has an execution mode qualifier {pui} then * if the rule has an execution mode qualifier {pui} then
* *xmod = the execution qualifier of the rule {pui} * *xmod = the execution qualifier of the rule {pui}
* else * else
* *xmod = %AA_MAY_EXEC * *xmod = %AA_MAY_EXEC
* unsafe = presence of unsage flag
*/ */
static inline int aa_get_execmode(struct aaprofile *active, const char *name, static inline int aa_get_execmode(struct aaprofile *active, const char *name,
int *xmod) int *xmod, int *unsafe)
{ {
struct aa_entry *entry; struct aa_entry *entry;
struct aa_entry *match = NULL; struct aa_entry *match = NULL;
@@ -158,8 +158,8 @@ static inline int aa_get_execmode(struct aaprofile *active, const char *name,
aamatch_match(name, entry->filename, aamatch_match(name, entry->filename,
entry->type, entry->extradata)) { entry->type, entry->extradata)) {
if (match && if (match &&
AA_EXEC_MASK(entry->mode) != AA_EXEC_UNSAFE_MASK(entry->mode) !=
AA_EXEC_MASK(match->mode)) AA_EXEC_UNSAFE_MASK(match->mode))
pattern_match_invalid = 1; pattern_match_invalid = 1;
else else
/* keep searching for an exact match */ /* keep searching for an exact match */
@@ -179,8 +179,8 @@ static inline int aa_get_execmode(struct aaprofile *active, const char *name,
break; break;
} else { } else {
if (match && if (match &&
AA_EXEC_MASK(entry->mode) != AA_EXEC_UNSAFE_MASK(entry->mode) !=
AA_EXEC_MASK(match->mode)) AA_EXEC_UNSAFE_MASK(match->mode))
pattern_match_invalid = 1; pattern_match_invalid = 1;
else else
/* got a tailglob match, keep searching /* got a tailglob match, keep searching
@@ -204,6 +204,7 @@ static inline int aa_get_execmode(struct aaprofile *active, const char *name,
mode = mode & ~AA_MAY_EXEC; mode = mode & ~AA_MAY_EXEC;
*xmod = mode; *xmod = mode;
*unsafe = (match->mode & AA_EXEC_UNSAFE);
} else if (!match) { } else if (!match) {
AA_DEBUG("%s: Unable to find execute entry in profile " AA_DEBUG("%s: Unable to find execute entry in profile "
"for image '%s'\n", "for image '%s'\n",
@@ -219,9 +220,6 @@ static inline int aa_get_execmode(struct aaprofile *active, const char *name,
} }
return rc; return rc;
*xmod = AA_MAY_EXEC;
return 1;
} }
/** /**
@@ -1203,14 +1201,15 @@ int aa_fork(struct task_struct *p)
/** /**
* aa_register - register a new program * aa_register - register a new program
* @filp: file of program being registered * @bprm: binprm of program being registered
* *
* Try to register a new program during execve(). This should give the * Try to register a new program during execve(). This should give the
* new program a valid subdomain. * new program a valid subdomain.
*/ */
int aa_register(struct file *filp) int aa_register(struct linux_binprm *bprm)
{ {
char *filename; char *filename;
struct file *filp = bprm->file;
struct subdomain *sd; struct subdomain *sd;
struct aaprofile *active; struct aaprofile *active;
struct aaprofile *newprofile = NULL, unconstrained_flag; struct aaprofile *newprofile = NULL, unconstrained_flag;
@@ -1218,6 +1217,7 @@ int aa_register(struct file *filp)
exec_mode = 0, exec_mode = 0,
find_profile = 0, find_profile = 0,
find_profile_mandatory = 0, find_profile_mandatory = 0,
unsafe_exec = 0,
complain = 0; complain = 0;
AA_DEBUG("%s\n", __FUNCTION__); AA_DEBUG("%s\n", __FUNCTION__);
@@ -1260,7 +1260,7 @@ int aa_register(struct file *filp)
/* Confined task, determine what mode inherit, unconstrained or /* Confined task, determine what mode inherit, unconstrained or
* mandatory to load new profile * mandatory to load new profile
*/ */
if (aa_get_execmode(active, filename, &exec_mode)) { if (aa_get_execmode(active, filename, &exec_mode, &unsafe_exec)) {
switch (exec_mode) { switch (exec_mode) {
case AA_EXEC_INHERIT: case AA_EXEC_INHERIT:
/* do nothing - setting of profile /* do nothing - setting of profile
@@ -1320,9 +1320,10 @@ int aa_register(struct file *filp)
} else if (complain) { } else if (complain) {
/* There was no entry in calling profile /* There was no entry in calling profile
* describing mode to execute image in. * describing mode to execute image in.
* Drop into null-profile * Drop into null-profile (disabling secure exec).
*/ */
newprofile = get_aaprofile(null_complain_profile); newprofile = get_aaprofile(null_complain_profile);
unsafe_exec = 1;
} else { } else {
AA_WARN("%s: Rejecting exec(2) of image '%s'. " AA_WARN("%s: Rejecting exec(2) of image '%s'. "
"Unable to determine exec qualifier " "Unable to determine exec qualifier "
@@ -1429,6 +1430,23 @@ apply_profile:
} }
} }
/* Handle confined exec.
* Can be at this point for the following reasons:
* 1. unconfined switching to confined
* 2. confined switching to different confinement
* 3. confined switching to unconfined
*
* Cases 2 and 3 are marked as requiring secure exec
* (unless policy specified "unsafe exec")
*/
if (__aa_is_confined(sd) && !unsafe_exec) {
unsigned long bprm_flags;
bprm_flags = AA_SECURE_EXEC_NEEDED;
bprm->security = (void*)
((unsigned long)bprm->security | bprm_flags);
}
aa_switch(sd, newprofile); aa_switch(sd, newprofile);
put_aaprofile(newprofile); put_aaprofile(newprofile);

View File

@@ -25,7 +25,8 @@
#define POS_AA_EXEC_UNCONSTRAINED (POS_AA_EXEC_INHERIT + 1) #define POS_AA_EXEC_UNCONSTRAINED (POS_AA_EXEC_INHERIT + 1)
#define POS_AA_EXEC_PROFILE (POS_AA_EXEC_UNCONSTRAINED + 1) #define POS_AA_EXEC_PROFILE (POS_AA_EXEC_UNCONSTRAINED + 1)
#define POS_AA_EXEC_MMAP (POS_AA_EXEC_PROFILE + 1) #define POS_AA_EXEC_MMAP (POS_AA_EXEC_PROFILE + 1)
#define POS_AA_FILE_MAX POS_AA_EXEC_MMAP #define POS_AA_EXEC_UNSAFE (POS_AA_EXEC_MMAP + 1)
#define POS_AA_FILE_MAX POS_AA_EXEC_UNSAFE
/* Modeled after MAY_READ, MAY_WRITE, MAY_EXEC def'ns */ /* Modeled after MAY_READ, MAY_WRITE, MAY_EXEC def'ns */
#define AA_MAY_EXEC (0x01 << POS_AA_MAY_EXEC) #define AA_MAY_EXEC (0x01 << POS_AA_MAY_EXEC)
@@ -36,8 +37,10 @@
#define AA_EXEC_UNCONSTRAINED (0x01 << POS_AA_EXEC_UNCONSTRAINED) #define AA_EXEC_UNCONSTRAINED (0x01 << POS_AA_EXEC_UNCONSTRAINED)
#define AA_EXEC_PROFILE (0x01 << POS_AA_EXEC_PROFILE) #define AA_EXEC_PROFILE (0x01 << POS_AA_EXEC_PROFILE)
#define AA_EXEC_MMAP (0x01 << POS_AA_EXEC_MMAP) #define AA_EXEC_MMAP (0x01 << POS_AA_EXEC_MMAP)
#define AA_EXEC_MODIFIERS(X) (X & (AA_EXEC_INHERIT | \ #define AA_EXEC_UNSAFE (0x01 << POS_AA_EXEC_UNSAFE)
A_EXEC_UNCONSTRAINED | \
AA_EXEC_PROFILE)) #define AA_EXEC_MODIFIERS (AA_EXEC_INHERIT | \
AA_EXEC_UNCONSTRAINED | \
AA_EXEC_PROFILE)
#endif /* _SHARED_H */ #endif /* _SHARED_H */