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:
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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 */
|
||||
|
Reference in New Issue
Block a user