Skip to content

Commit

Permalink
Merge branch 'smack-for-3.11' of git://git.gitorious.org/smack-next/k…
Browse files Browse the repository at this point in the history
…ernel into ra-next
  • Loading branch information
James Morris committed Jun 11, 2013
2 parents e2fa3d7 + 0fcfee6 commit 1ca0072
Show file tree
Hide file tree
Showing 4 changed files with 610 additions and 280 deletions.
110 changes: 62 additions & 48 deletions security/smack/smack.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,38 @@
#define SMK_LABELLEN 24
#define SMK_LONGLABEL 256

/*
* This is the repository for labels seen so that it is
* not necessary to keep allocating tiny chuncks of memory
* and so that they can be shared.
*
* Labels are never modified in place. Anytime a label
* is imported (e.g. xattrset on a file) the list is checked
* for it and it is added if it doesn't exist. The address
* is passed out in either case. Entries are added, but
* never deleted.
*
* Since labels are hanging around anyway it doesn't
* hurt to maintain a secid for those awkward situations
* where kernel components that ought to use LSM independent
* interfaces don't. The secid should go away when all of
* these components have been repaired.
*
* The cipso value associated with the label gets stored here, too.
*
* Keep the access rules for this subject label here so that
* the entire set of rules does not need to be examined every
* time.
*/
struct smack_known {
struct list_head list;
char *smk_known;
u32 smk_secid;
struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */
struct list_head smk_rules; /* access rules */
struct mutex smk_rules_lock; /* lock for rules */
};

/*
* Maximum number of bytes for the levels in a CIPSO IP option.
* Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
Expand All @@ -46,25 +78,25 @@ struct superblock_smack {
};

struct socket_smack {
char *smk_out; /* outbound label */
char *smk_in; /* inbound label */
char *smk_packet; /* TCP peer label */
struct smack_known *smk_out; /* outbound label */
char *smk_in; /* inbound label */
char *smk_packet; /* TCP peer label */
};

/*
* Inode smack data
*/
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 */
char *smk_inode; /* label of the fso */
struct smack_known *smk_task; /* label of the task */
struct smack_known *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 for access control */
char *smk_forked; /* label when forked */
struct smack_known *smk_task; /* label for access control */
struct smack_known *smk_forked; /* label when forked */
struct list_head smk_rules; /* per task access rules */
struct mutex smk_rules_lock; /* lock for the rules */
};
Expand All @@ -78,7 +110,7 @@ struct task_smack {
*/
struct smack_rule {
struct list_head list;
char *smk_subject;
struct smack_known *smk_subject;
char *smk_object;
int smk_access;
};
Expand All @@ -94,35 +126,14 @@ struct smk_netlbladdr {
};

/*
* This is the repository for labels seen so that it is
* not necessary to keep allocating tiny chuncks of memory
* and so that they can be shared.
*
* Labels are never modified in place. Anytime a label
* is imported (e.g. xattrset on a file) the list is checked
* for it and it is added if it doesn't exist. The address
* is passed out in either case. Entries are added, but
* never deleted.
*
* Since labels are hanging around anyway it doesn't
* hurt to maintain a secid for those awkward situations
* where kernel components that ought to use LSM independent
* interfaces don't. The secid should go away when all of
* these components have been repaired.
*
* The cipso value associated with the label gets stored here, too.
*
* Keep the access rules for this subject label here so that
* the entire set of rules does not need to be examined every
* time.
* An entry in the table identifying ports.
*/
struct smack_known {
struct list_head list;
char *smk_known;
u32 smk_secid;
struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */
struct list_head smk_rules; /* access rules */
struct mutex smk_rules_lock; /* lock for rules */
struct smk_port_label {
struct list_head list;
struct sock *smk_sock; /* socket initialized on */
unsigned short smk_port; /* the port number */
char *smk_in; /* incoming label */
struct smack_known *smk_out; /* outgoing label */
};

/*
Expand All @@ -132,6 +143,7 @@ struct smack_known {
#define SMK_FSFLOOR "smackfsfloor="
#define SMK_FSHAT "smackfshat="
#define SMK_FSROOT "smackfsroot="
#define SMK_FSTRANS "smackfstransmute="

#define SMACK_CIPSO_OPTION "-CIPSO"

Expand Down Expand Up @@ -203,9 +215,9 @@ struct inode_smack *new_inode_smack(char *);
* These functions are in smack_access.c
*/
int smk_access_entry(char *, char *, struct list_head *);
int smk_access(char *, char *, int, struct smk_audit_info *);
int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
int smk_curacc(char *, u32, struct smk_audit_info *);
char *smack_from_secid(const u32);
struct smack_known *smack_from_secid(const u32);
char *smk_parse_smack(const char *string, int len);
int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
char *smk_import(const char *, int);
Expand All @@ -218,7 +230,7 @@ u32 smack_to_secid(const char *);
*/
extern int smack_cipso_direct;
extern int smack_cipso_mapped;
extern char *smack_net_ambient;
extern struct smack_known *smack_net_ambient;
extern char *smack_onlycap;
extern const char *smack_cipso_option;

Expand Down Expand Up @@ -254,25 +266,25 @@ static inline char *smk_of_inode(const struct inode *isp)
}

/*
* Present a pointer to the smack label in an task blob.
* Present a pointer to the smack label entry in an task blob.
*/
static inline char *smk_of_task(const struct task_smack *tsp)
static inline struct smack_known *smk_of_task(const struct task_smack *tsp)
{
return tsp->smk_task;
}

/*
* Present a pointer to the forked smack label in an task blob.
* Present a pointer to the forked smack label entry in an task blob.
*/
static inline char *smk_of_forked(const struct task_smack *tsp)
static inline struct smack_known *smk_of_forked(const struct task_smack *tsp)
{
return tsp->smk_forked;
}

/*
* Present a pointer to the smack label in the current task blob.
*/
static inline char *smk_of_current(void)
static inline struct smack_known *smk_of_current(void)
{
return smk_of_task(current_security());
}
Expand All @@ -283,9 +295,11 @@ static inline char *smk_of_current(void)
*/
static inline int smack_privileged(int cap)
{
struct smack_known *skp = smk_of_current();

if (!capable(cap))
return 0;
if (smack_onlycap == NULL || smack_onlycap == smk_of_current())
if (smack_onlycap == NULL || smack_onlycap == skp->smk_known)
return 1;
return 0;
}
Expand Down
43 changes: 23 additions & 20 deletions security/smack/smack_access.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ int smk_access_entry(char *subject_label, char *object_label,

list_for_each_entry_rcu(srp, rule_list, list) {
if (srp->smk_object == object_label &&
srp->smk_subject == subject_label) {
srp->smk_subject->smk_known == subject_label) {
may = srp->smk_access;
break;
}
Expand All @@ -104,7 +104,7 @@ int smk_access_entry(char *subject_label, char *object_label,

/**
* smk_access - determine if a subject has a specific access to an object
* @subject_label: a pointer to the subject's Smack label
* @subject_known: a pointer to the subject's Smack label entry
* @object_label: a pointer to the object's Smack label
* @request: the access requested, in "MAY" format
* @a : a pointer to the audit data
Expand All @@ -115,10 +115,9 @@ int smk_access_entry(char *subject_label, char *object_label,
*
* Smack labels are shared on smack_list
*/
int smk_access(char *subject_label, char *object_label, int request,
struct smk_audit_info *a)
int smk_access(struct smack_known *subject_known, char *object_label,
int request, struct smk_audit_info *a)
{
struct smack_known *skp;
int may = MAY_NOT;
int rc = 0;

Expand All @@ -127,7 +126,7 @@ int smk_access(char *subject_label, char *object_label, int request,
*
* A star subject can't access any object.
*/
if (subject_label == smack_known_star.smk_known) {
if (subject_known == &smack_known_star) {
rc = -EACCES;
goto out_audit;
}
Expand All @@ -137,7 +136,7 @@ int smk_access(char *subject_label, char *object_label, int request,
* An internet subject can access any object.
*/
if (object_label == smack_known_web.smk_known ||
subject_label == smack_known_web.smk_known)
subject_known == &smack_known_web)
goto out_audit;
/*
* A star object can be accessed by any subject.
Expand All @@ -148,7 +147,7 @@ int smk_access(char *subject_label, char *object_label, int request,
* An object can be accessed in any way by a subject
* with the same label.
*/
if (subject_label == object_label)
if (subject_known->smk_known == object_label)
goto out_audit;
/*
* A hat subject can read any object.
Expand All @@ -157,7 +156,7 @@ int smk_access(char *subject_label, char *object_label, int request,
if ((request & MAY_ANYREAD) == request) {
if (object_label == smack_known_floor.smk_known)
goto out_audit;
if (subject_label == smack_known_hat.smk_known)
if (subject_known == &smack_known_hat)
goto out_audit;
}
/*
Expand All @@ -167,9 +166,9 @@ int smk_access(char *subject_label, char *object_label, int request,
* good. A negative response from smk_access_entry()
* indicates there is no entry for this pair.
*/
skp = smk_find_entry(subject_label);
rcu_read_lock();
may = smk_access_entry(subject_label, object_label, &skp->smk_rules);
may = smk_access_entry(subject_known->smk_known, object_label,
&subject_known->smk_rules);
rcu_read_unlock();

if (may > 0 && (request & may) == request)
Expand All @@ -179,7 +178,8 @@ int smk_access(char *subject_label, char *object_label, int request,
out_audit:
#ifdef CONFIG_AUDIT
if (a)
smack_log(subject_label, object_label, request, rc, a);
smack_log(subject_known->smk_known, object_label, request,
rc, a);
#endif
return rc;
}
Expand All @@ -198,20 +198,21 @@ 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);
struct smack_known *skp = smk_of_task(tsp);
int may;
int rc;

/*
* Check the global rule list
*/
rc = smk_access(sp, obj_label, mode, NULL);
rc = smk_access(skp, obj_label, mode, NULL);
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);
may = smk_access_entry(skp->smk_known, obj_label,
&tsp->smk_rules);
if (may < 0)
goto out_audit;
if ((mode & may) == mode)
Expand All @@ -228,7 +229,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
out_audit:
#ifdef CONFIG_AUDIT
if (a)
smack_log(sp, obj_label, mode, rc, a);
smack_log(skp->smk_known, obj_label, mode, rc, a);
#endif
return rc;
}
Expand Down Expand Up @@ -402,6 +403,8 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
sap->flags |= NETLBL_SECATTR_MLS_CAT;
sap->attr.mls.lvl = level;
sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
if (!sap->attr.mls.cat)
return -ENOMEM;
sap->attr.mls.cat->startbit = 0;

for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
Expand Down Expand Up @@ -513,18 +516,18 @@ char *smk_import(const char *string, int len)
* smack_from_secid - find the Smack label associated with a secid
* @secid: an integer that might be associated with a Smack label
*
* Returns a pointer to the appropriate Smack label if there is one,
* Returns a pointer to the appropriate Smack label entry if there is one,
* otherwise a pointer to the invalid Smack label.
*/
char *smack_from_secid(const u32 secid)
struct smack_known *smack_from_secid(const u32 secid)
{
struct smack_known *skp;

rcu_read_lock();
list_for_each_entry_rcu(skp, &smack_known_list, list) {
if (skp->smk_secid == secid) {
rcu_read_unlock();
return skp->smk_known;
return skp;
}
}

Expand All @@ -533,7 +536,7 @@ char *smack_from_secid(const u32 secid)
* of a secid that is not on the list.
*/
rcu_read_unlock();
return smack_known_invalid.smk_known;
return &smack_known_invalid;
}

/**
Expand Down
Loading

0 comments on commit 1ca0072

Please sign in to comment.