Skip to content

Commit

Permalink
Subject: [PATCH] Smack: mmap controls for library containment
Browse files Browse the repository at this point in the history
  In the embedded world there are often situations
  where libraries are updated from a variety of sources,
  for a variety of reasons, and with any number of
  security characteristics. These differences
  might include privilege required for a given library
  provided interface to function properly, as occurs
  from time to time in graphics libraries. There are
  also cases where it is important to limit use of
  libraries based on the provider of the library and
  the security aware application may make choices
  based on that criteria.

  These issues are addressed by providing an additional
  Smack label that may optionally be assigned to an object,
  the SMACK64MMAP attribute. An mmap operation is allowed
  if there is no such attribute.

  If there is a SMACK64MMAP attribute the mmap is permitted
  only if a subject with that label has all of the access
  permitted a subject with the current task label.

  Security aware applications may from time to time
  wish to reduce their "privilege" to avoid accidental use
  of privilege. One case where this arises is the
  environment in which multiple sources provide libraries
  to perform the same functions. An application may know
  that it should eschew services made available from a
  particular vendor, or of a particular version.

  In support of this a secondary list of Smack rules has
  been added that is local to the task. This list is
  consulted only in the case where the global list has
  approved access. It can only further restrict access.
  Unlike the global last, if no entry is found on the
  local list access is granted. An application can add
  entries to its own list by writing to /smack/load-self.

  The changes appear large as they involve refactoring
  the list handling to accomodate there being more
  than one rule list.

Signed-off-by: Casey Schaufler <[email protected]>
  • Loading branch information
cschaufler committed Jan 17, 2011
1 parent aeda4ac commit 7898e1f
Show file tree
Hide file tree
Showing 5 changed files with 524 additions and 178 deletions.
2 changes: 2 additions & 0 deletions include/linux/xattr.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@
#define XATTR_SMACK_IPOUT "SMACK64IPOUT"
#define XATTR_SMACK_EXEC "SMACK64EXEC"
#define XATTR_SMACK_TRANSMUTE "SMACK64TRANSMUTE"
#define XATTR_SMACK_MMAP "SMACK64MMAP"
#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX
#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
#define XATTR_NAME_SMACKEXEC XATTR_SECURITY_PREFIX XATTR_SMACK_EXEC
#define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE
#define XATTR_NAME_SMACKMMAP XATTR_SECURITY_PREFIX XATTR_SMACK_MMAP

#define XATTR_CAPS_SUFFIX "capability"
#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
Expand Down
9 changes: 6 additions & 3 deletions security/smack/smack.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@ struct socket_smack {
struct inode_smack {
char *smk_inode; /* label of the fso */
char *smk_task; /* label of the task */
char *smk_mmap; /* label of the mmap domain */
struct mutex smk_lock; /* initialization lock */
int smk_flags; /* smack inode flags */
};

struct task_smack {
char *smk_task; /* label used for access control */
char *smk_forked; /* label when forked */
char *smk_task; /* label for access control */
char *smk_forked; /* label when forked */
struct list_head smk_rules; /* per task access rules */
struct mutex smk_rules_lock; /* lock for the rules */
};

#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
Expand Down Expand Up @@ -202,7 +205,7 @@ struct inode_smack *new_inode_smack(char *);
/*
* These functions are in smack_access.c
*/
int smk_access_entry(char *, char *);
int smk_access_entry(char *, char *, struct list_head *);
int smk_access(char *, char *, int, struct smk_audit_info *);
int smk_curacc(char *, u32, struct smk_audit_info *);
int smack_to_cipso(const char *, struct smack_cipso *);
Expand Down
52 changes: 34 additions & 18 deletions security/smack/smack_access.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ int log_policy = SMACK_AUDIT_DENIED;
* smk_access_entry - look up matching access rule
* @subject_label: a pointer to the subject's Smack label
* @object_label: a pointer to the object's Smack label
* @rule_list: the list of rules to search
*
* This function looks up the subject/object pair in the
* access rule list and returns pointer to the matching rule if found,
* NULL otherwise.
* access rule list and returns the access mode. If no
* entry is found returns -ENOENT.
*
* NOTE:
* Even though Smack labels are usually shared on smack_list
Expand All @@ -85,13 +86,13 @@ int log_policy = SMACK_AUDIT_DENIED;
* will be on the list, so checking the pointers may be a worthwhile
* optimization.
*/
int smk_access_entry(char *subject_label, char *object_label)
int smk_access_entry(char *subject_label, char *object_label,
struct list_head *rule_list)
{
u32 may = MAY_NOT;
int may = -ENOENT;
struct smack_rule *srp;

rcu_read_lock();
list_for_each_entry_rcu(srp, &smack_rule_list, list) {
list_for_each_entry_rcu(srp, rule_list, list) {
if (srp->smk_subject == subject_label ||
strcmp(srp->smk_subject, subject_label) == 0) {
if (srp->smk_object == object_label ||
Expand All @@ -101,7 +102,6 @@ int smk_access_entry(char *subject_label, char *object_label)
}
}
}
rcu_read_unlock();

return may;
}
Expand Down Expand Up @@ -129,7 +129,7 @@ int smk_access_entry(char *subject_label, char *object_label)
int smk_access(char *subject_label, char *object_label, int request,
struct smk_audit_info *a)
{
u32 may = MAY_NOT;
int may = MAY_NOT;
int rc = 0;

/*
Expand Down Expand Up @@ -181,13 +181,14 @@ int smk_access(char *subject_label, char *object_label, int request,
* Beyond here an explicit relationship is required.
* If the requested access is contained in the available
* access (e.g. read is included in readwrite) it's
* good.
*/
may = smk_access_entry(subject_label, object_label);
/*
* This is a bit map operation.
* good. A negative response from smk_access_entry()
* indicates there is no entry for this pair.
*/
if ((request & may) == request)
rcu_read_lock();
may = smk_access_entry(subject_label, object_label, &smack_rule_list);
rcu_read_unlock();

if (may > 0 && (request & may) == request)
goto out_audit;

rc = -EACCES;
Expand All @@ -212,12 +213,27 @@ int smk_access(char *subject_label, char *object_label, int request,
*/
int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
{
struct task_smack *tsp = current_security();
char *sp = smk_of_task(tsp);
int may;
int rc;
char *sp = smk_of_current();

/*
* Check the global rule list
*/
rc = smk_access(sp, obj_label, mode, NULL);
if (rc == 0)
goto out_audit;
if (rc == 0) {
/*
* If there is an entry in the task's rule list
* it can further restrict access.
*/
may = smk_access_entry(sp, obj_label, &tsp->smk_rules);
if (may < 0)
goto out_audit;
if ((mode & may) == mode)
goto out_audit;
rc = -EACCES;
}

/*
* Return if a specific label has been designated as the
Expand All @@ -228,7 +244,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
goto out_audit;

if (capable(CAP_MAC_OVERRIDE))
return 0;
rc = 0;

out_audit:
#ifdef CONFIG_AUDIT
Expand Down
Loading

0 comments on commit 7898e1f

Please sign in to comment.