2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-30 13:58:22 +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
#include <linux/fs.h> /* Include for defn of iattr */
#include <linux/binfmts.h> /* defn of linux_binprm */
#include <linux/rcupdate.h>
#include "shared.h"
@@ -101,15 +102,12 @@ struct aa_entry {
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))
#define AA_SECURE_EXEC_NEEDED 0x00000001
#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
* @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,
struct dentry *link, struct dentry *target);
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 int aa_change_hat(const char *id, u32 hat_magic);
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 */
if (bprm->sh_bang)
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,
@@ -748,6 +762,7 @@ struct security_operations apparmor_ops = {
.bprm_apply_creds = apparmor_bprm_apply_creds,
.bprm_set_security = apparmor_bprm_set_security,
.bprm_secureexec = apparmor_bprm_secureexec,
.sb_mount = apparmor_sb_mount,
.sb_umount = apparmor_umount,

View File

@@ -119,22 +119,22 @@ out:
* %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.
*
* @unsafe: true if secure_exec should be overriden
* Returns %0 (false):
* if unable to find profile or there are conflicting pattern matches.
* *xmod - is not modified
* *unsafe - 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
* unsafe = presence of unsage flag
*/
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 *match = NULL;
@@ -158,8 +158,8 @@ static inline int aa_get_execmode(struct aaprofile *active, const char *name,
aamatch_match(name, entry->filename,
entry->type, entry->extradata)) {
if (match &&
AA_EXEC_MASK(entry->mode) !=
AA_EXEC_MASK(match->mode))
AA_EXEC_UNSAFE_MASK(entry->mode) !=
AA_EXEC_UNSAFE_MASK(match->mode))
pattern_match_invalid = 1;
else
/* keep searching for an exact match */
@@ -179,8 +179,8 @@ static inline int aa_get_execmode(struct aaprofile *active, const char *name,
break;
} else {
if (match &&
AA_EXEC_MASK(entry->mode) !=
AA_EXEC_MASK(match->mode))
AA_EXEC_UNSAFE_MASK(entry->mode) !=
AA_EXEC_UNSAFE_MASK(match->mode))
pattern_match_invalid = 1;
else
/* 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;
*xmod = mode;
*unsafe = (match->mode & AA_EXEC_UNSAFE);
} else if (!match) {
AA_DEBUG("%s: Unable to find execute entry in profile "
"for image '%s'\n",
@@ -219,9 +220,6 @@ static inline int aa_get_execmode(struct aaprofile *active, const char *name,
}
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
* @filp: file of program being registered
* @bprm: binprm 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)
int aa_register(struct linux_binprm *bprm)
{
char *filename;
struct file *filp = bprm->file;
struct subdomain *sd;
struct aaprofile *active;
struct aaprofile *newprofile = NULL, unconstrained_flag;
@@ -1218,6 +1217,7 @@ int aa_register(struct file *filp)
exec_mode = 0,
find_profile = 0,
find_profile_mandatory = 0,
unsafe_exec = 0,
complain = 0;
AA_DEBUG("%s\n", __FUNCTION__);
@@ -1260,7 +1260,7 @@ int aa_register(struct file *filp)
/* Confined task, determine what mode inherit, unconstrained or
* 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) {
case AA_EXEC_INHERIT:
/* do nothing - setting of profile
@@ -1320,9 +1320,10 @@ int aa_register(struct file *filp)
} else if (complain) {
/* There was no entry in calling profile
* describing mode to execute image in.
* Drop into null-profile
* Drop into null-profile (disabling secure exec).
*/
newprofile = get_aaprofile(null_complain_profile);
unsafe_exec = 1;
} else {
AA_WARN("%s: Rejecting exec(2) of image '%s'. "
"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);
put_aaprofile(newprofile);

View File

@@ -25,7 +25,8 @@
#define POS_AA_EXEC_UNCONSTRAINED (POS_AA_EXEC_INHERIT + 1)
#define POS_AA_EXEC_PROFILE (POS_AA_EXEC_UNCONSTRAINED + 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 */
#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_PROFILE (0x01 << POS_AA_EXEC_PROFILE)
#define AA_EXEC_MMAP (0x01 << POS_AA_EXEC_MMAP)
#define AA_EXEC_MODIFIERS(X) (X & (AA_EXEC_INHERIT | \
A_EXEC_UNCONSTRAINED | \
AA_EXEC_PROFILE))
#define AA_EXEC_UNSAFE (0x01 << POS_AA_EXEC_UNSAFE)
#define AA_EXEC_MODIFIERS (AA_EXEC_INHERIT | \
AA_EXEC_UNCONSTRAINED | \
AA_EXEC_PROFILE)
#endif /* _SHARED_H */