Skip to content

Commit

Permalink
AppArmor: misc. base functions and defines
Browse files Browse the repository at this point in the history
Miscellaneous functions and defines needed by AppArmor, including
the base path resolution routines.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: James Morris <jmorris@namei.org>
  • Loading branch information
John Johansen authored and James Morris committed Aug 2, 2010
1 parent e6f6a4c commit cdff264
Show file tree
Hide file tree
Showing 4 changed files with 491 additions and 0 deletions.
92 changes: 92 additions & 0 deletions security/apparmor/include/apparmor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* AppArmor security module
*
* This file contains AppArmor basic global and lib definitions
*
* Copyright (C) 1998-2008 Novell/SUSE
* Copyright 2009-2010 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/

#ifndef __APPARMOR_H
#define __APPARMOR_H

#include <linux/fs.h>

#include "match.h"

/* Control parameters settable through module/boot flags */
extern enum audit_mode aa_g_audit;
extern int aa_g_audit_header;
extern int aa_g_debug;
extern int aa_g_lock_policy;
extern int aa_g_logsyscall;
extern int aa_g_paranoid_load;
extern unsigned int aa_g_path_max;

/*
* DEBUG remains global (no per profile flag) since it is mostly used in sysctl
* which is not related to profile accesses.
*/

#define AA_DEBUG(fmt, args...) \
do { \
if (aa_g_debug && printk_ratelimit()) \
printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
} while (0)

#define AA_ERROR(fmt, args...) \
do { \
if (printk_ratelimit()) \
printk(KERN_ERR "AppArmor: " fmt, ##args); \
} while (0)

/* Flag indicating whether initialization completed */
extern int apparmor_initialized __initdata;

/* fn's in lib */
char *aa_split_fqname(char *args, char **ns_name);
void aa_info_message(const char *str);
void *kvmalloc(size_t size);
void kvfree(void *buffer);


/**
* aa_strneq - compare null terminated @str to a non null terminated substring
* @str: a null terminated string
* @sub: a substring, not necessarily null terminated
* @len: length of @sub to compare
*
* The @str string must be full consumed for this to be considered a match
*/
static inline bool aa_strneq(const char *str, const char *sub, int len)
{
return !strncmp(str, sub, len) && !str[len];
}

/**
* aa_dfa_null_transition - step to next state after null character
* @dfa: the dfa to match against
* @start: the state of the dfa to start matching in
*
* aa_dfa_null_transition transitions to the next state after a null
* character which is not used in standard matching and is only
* used to separate pairs.
*/
static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa,
unsigned int start)
{
/* the null transition only needs the string's null terminator byte */
return aa_dfa_match_len(dfa, start, "", 1);
}

static inline bool mediated_filesystem(struct inode *inode)
{
return !(inode->i_sb->s_flags & MS_NOUSER);
}

#endif /* __APPARMOR_H */
31 changes: 31 additions & 0 deletions security/apparmor/include/path.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* AppArmor security module
*
* This file contains AppArmor basic path manipulation function definitions.
*
* Copyright (C) 1998-2008 Novell/SUSE
* Copyright 2009-2010 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/

#ifndef __AA_PATH_H
#define __AA_PATH_H


enum path_flags {
PATH_IS_DIR = 0x1, /* path is a directory */
PATH_CONNECT_PATH = 0x4, /* connect disconnected paths to / */
PATH_CHROOT_REL = 0x8, /* do path lookup relative to chroot */
PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */

PATH_DELEGATE_DELETED = 0x08000, /* delegate deleted files */
PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */
};

int aa_get_name(struct path *path, int flags, char **buffer, const char **name);

#endif /* __AA_PATH_H */
133 changes: 133 additions & 0 deletions security/apparmor/lib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* AppArmor security module
*
* This file contains basic common functions used in AppArmor
*
* Copyright (C) 1998-2008 Novell/SUSE
* Copyright 2009-2010 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/

#include <linux/slab.h>
#include <linux/string.h>
#include <linux/vmalloc.h>

#include "include/audit.h"


/**
* aa_split_fqname - split a fqname into a profile and namespace name
* @fqname: a full qualified name in namespace profile format (NOT NULL)
* @ns_name: pointer to portion of the string containing the ns name (NOT NULL)
*
* Returns: profile name or NULL if one is not specified
*
* Split a namespace name from a profile name (see policy.c for naming
* description). If a portion of the name is missing it returns NULL for
* that portion.
*
* NOTE: may modify the @fqname string. The pointers returned point
* into the @fqname string.
*/
char *aa_split_fqname(char *fqname, char **ns_name)
{
char *name = strim(fqname);

*ns_name = NULL;
if (name[0] == ':') {
char *split = strchr(&name[1], ':');
if (split) {
/* overwrite ':' with \0 */
*split = 0;
name = skip_spaces(split + 1);
} else
/* a ns name without a following profile is allowed */
name = NULL;
*ns_name = &name[1];
}
if (name && *name == 0)
name = NULL;

return name;
}

/**
* aa_info_message - log a none profile related status message
* @str: message to log
*/
void aa_info_message(const char *str)
{
if (audit_enabled) {
struct common_audit_data sa;
COMMON_AUDIT_DATA_INIT(&sa, NONE);
sa.aad.info = str;
aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
}
printk(KERN_INFO "AppArmor: %s\n", str);
}

/**
* kvmalloc - do allocation preferring kmalloc but falling back to vmalloc
* @size: size of allocation
*
* Return: allocated buffer or NULL if failed
*
* It is possible that policy being loaded from the user is larger than
* what can be allocated by kmalloc, in those cases fall back to vmalloc.
*/
void *kvmalloc(size_t size)
{
void *buffer = NULL;

if (size == 0)
return NULL;

/* do not attempt kmalloc if we need more than 16 pages at once */
if (size <= (16*PAGE_SIZE))
buffer = kmalloc(size, GFP_NOIO | __GFP_NOWARN);
if (!buffer) {
/* see kvfree for why size must be at least work_struct size
* when allocated via vmalloc
*/
if (size < sizeof(struct work_struct))
size = sizeof(struct work_struct);
buffer = vmalloc(size);
}
return buffer;
}

/**
* do_vfree - workqueue routine for freeing vmalloced memory
* @work: data to be freed
*
* The work_struct is overlaid to the data being freed, as at the point
* the work is scheduled the data is no longer valid, be its freeing
* needs to be delayed until safe.
*/
static void do_vfree(struct work_struct *work)
{
vfree(work);
}

/**
* kvfree - free an allocation do by kvmalloc
* @buffer: buffer to free (MAYBE_NULL)
*
* Free a buffer allocated by kvmalloc
*/
void kvfree(void *buffer)
{
if (is_vmalloc_addr(buffer)) {
/* Data is no longer valid so just use the allocated space
* as the work_struct
*/
struct work_struct *work = (struct work_struct *) buffer;
INIT_WORK(work, do_vfree);
schedule_work(work);
} else
kfree(buffer);
}
Loading

0 comments on commit cdff264

Please sign in to comment.