Loading security/smack/smack.h +62 −48 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -46,7 +78,7 @@ struct superblock_smack { }; struct socket_smack { char *smk_out; /* outbound label */ struct smack_known *smk_out; /* outbound label */ char *smk_in; /* inbound label */ char *smk_packet; /* TCP peer label */ }; Loading @@ -56,15 +88,15 @@ 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 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 */ }; Loading @@ -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; }; Loading @@ -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 smk_port_label { 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 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 */ }; /* Loading @@ -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" Loading Loading @@ -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); Loading @@ -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; Loading Loading @@ -254,17 +266,17 @@ 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; } Loading @@ -272,7 +284,7 @@ static inline char *smk_of_forked(const struct task_smack *tsp) /* * 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()); } Loading @@ -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; } Loading security/smack/smack_access.c +23 −20 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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 Loading @@ -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; Loading @@ -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; } Loading @@ -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. Loading @@ -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. Loading @@ -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; } /* Loading @@ -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) Loading @@ -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; } Loading @@ -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) Loading @@ -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; } Loading Loading @@ -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++) Loading Loading @@ -513,10 +516,10 @@ 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; Loading @@ -524,7 +527,7 @@ char *smack_from_secid(const u32 secid) list_for_each_entry_rcu(skp, &smack_known_list, list) { if (skp->smk_secid == secid) { rcu_read_unlock(); return skp->smk_known; return skp; } } Loading @@ -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; } /** Loading security/smack/smack_lsm.c +498 −186 File changed.Preview size limit exceeded, changes collapsed. Show changes security/smack/smackfs.c +27 −26 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock); * If it isn't somehow marked, use this. * It can be reset via smackfs/ambient */ char *smack_net_ambient; struct smack_known *smack_net_ambient; /* * This is the level in a CIPSO header that indicates a Loading Loading @@ -112,7 +112,7 @@ struct smack_master_list { LIST_HEAD(smack_rule_list); struct smack_parsed_rule { char *smk_subject; struct smack_known *smk_subject; char *smk_object; int smk_access1; int smk_access2; Loading Loading @@ -163,9 +163,11 @@ static inline void smack_catset_bit(unsigned int cat, char *catsetp) */ static void smk_netlabel_audit_set(struct netlbl_audit *nap) { struct smack_known *skp = smk_of_current(); nap->loginuid = audit_get_loginuid(current); nap->sessionid = audit_get_sessionid(current); nap->secid = smack_to_secid(smk_of_current()); nap->secid = skp->smk_secid; } /* Loading Loading @@ -306,7 +308,7 @@ static int smk_fill_rule(const char *subject, const char *object, struct smack_known *skp; if (import) { rule->smk_subject = smk_import(subject, len); rule->smk_subject = smk_import_entry(subject, len); if (rule->smk_subject == NULL) return -1; Loading @@ -321,7 +323,7 @@ static int smk_fill_rule(const char *subject, const char *object, kfree(cp); if (skp == NULL) return -1; rule->smk_subject = skp->smk_known; rule->smk_subject = skp; cp = smk_parse_smack(object, len); if (cp == NULL) Loading Loading @@ -445,7 +447,6 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, struct list_head *rule_list, struct mutex *rule_lock, int format) { struct smack_known *skp; struct smack_parsed_rule *rule; char *data; int datalen; Loading Loading @@ -505,12 +506,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, goto out_free_rule; } if (rule_list == NULL) { load = 1; skp = smk_find_entry(rule->smk_subject); rule_list = &skp->smk_rules; rule_lock = &skp->smk_rules_lock; rule_list = &rule->smk_subject->smk_rules; rule_lock = &rule->smk_subject->smk_rules_lock; } rc = smk_set_access(rule, rule_list, rule_lock, load); Loading Loading @@ -579,13 +578,14 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) * because you should expect to be able to write * anything you read back. */ if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) if (strlen(srp->smk_subject->smk_known) >= max || strlen(srp->smk_object) >= max) return; if (srp->smk_access == 0) return; seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object); seq_putc(s, ' '); Loading Loading @@ -738,9 +738,9 @@ static void smk_unlbl_ambient(char *oldambient) __func__, __LINE__, rc); } if (smack_net_ambient == NULL) smack_net_ambient = smack_known_floor.smk_known; smack_net_ambient = &smack_known_floor; rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET, NULL, NULL, &nai); if (rc != 0) printk(KERN_WARNING "%s:%d add rc = %d\n", Loading Loading @@ -881,7 +881,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, if (format == SMK_FIXED24_FMT) rule += SMK_LABELLEN; else rule += strlen(skp->smk_known); rule += strlen(skp->smk_known) + 1; ret = sscanf(rule, "%d", &maplevel); if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) Loading Loading @@ -1535,11 +1535,12 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, */ mutex_lock(&smack_ambient_lock); asize = strlen(smack_net_ambient) + 1; asize = strlen(smack_net_ambient->smk_known) + 1; if (cn >= asize) rc = simple_read_from_buffer(buf, cn, ppos, smack_net_ambient, asize); smack_net_ambient->smk_known, asize); else rc = -EINVAL; Loading @@ -1560,8 +1561,8 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, static ssize_t smk_write_ambient(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct smack_known *skp; char *oldambient; char *smack = NULL; char *data; int rc = count; Loading @@ -1577,16 +1578,16 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, goto out; } smack = smk_import(data, count); if (smack == NULL) { skp = smk_import_entry(data, count); if (skp == NULL) { rc = -EINVAL; goto out; } mutex_lock(&smack_ambient_lock); oldambient = smack_net_ambient; smack_net_ambient = smack; oldambient = smack_net_ambient->smk_known; smack_net_ambient = skp; smk_unlbl_ambient(oldambient); mutex_unlock(&smack_ambient_lock); Loading Loading @@ -1645,7 +1646,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char *data; char *sp = smk_of_task(current->cred->security); struct smack_known *skp = smk_of_task(current->cred->security); int rc = count; if (!smack_privileged(CAP_MAC_ADMIN)) Loading @@ -1656,7 +1657,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, * explicitly for clarity. The smk_access() implementation * would use smk_access(smack_onlycap, MAY_WRITE) */ if (smack_onlycap != NULL && smack_onlycap != sp) if (smack_onlycap != NULL && smack_onlycap != skp->smk_known) return -EPERM; data = kzalloc(count, GFP_KERNEL); Loading Loading @@ -1866,8 +1867,8 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, if (res) return -EINVAL; res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1, NULL); res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1, NULL); data[0] = res == 0 ? '1' : '0'; data[1] = '\0'; Loading Loading
security/smack/smack.h +62 −48 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -46,7 +78,7 @@ struct superblock_smack { }; struct socket_smack { char *smk_out; /* outbound label */ struct smack_known *smk_out; /* outbound label */ char *smk_in; /* inbound label */ char *smk_packet; /* TCP peer label */ }; Loading @@ -56,15 +88,15 @@ 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 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 */ }; Loading @@ -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; }; Loading @@ -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 smk_port_label { 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 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 */ }; /* Loading @@ -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" Loading Loading @@ -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); Loading @@ -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; Loading Loading @@ -254,17 +266,17 @@ 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; } Loading @@ -272,7 +284,7 @@ static inline char *smk_of_forked(const struct task_smack *tsp) /* * 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()); } Loading @@ -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; } Loading
security/smack/smack_access.c +23 −20 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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 Loading @@ -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; Loading @@ -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; } Loading @@ -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. Loading @@ -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. Loading @@ -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; } /* Loading @@ -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) Loading @@ -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; } Loading @@ -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) Loading @@ -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; } Loading Loading @@ -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++) Loading Loading @@ -513,10 +516,10 @@ 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; Loading @@ -524,7 +527,7 @@ char *smack_from_secid(const u32 secid) list_for_each_entry_rcu(skp, &smack_known_list, list) { if (skp->smk_secid == secid) { rcu_read_unlock(); return skp->smk_known; return skp; } } Loading @@ -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; } /** Loading
security/smack/smack_lsm.c +498 −186 File changed.Preview size limit exceeded, changes collapsed. Show changes
security/smack/smackfs.c +27 −26 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock); * If it isn't somehow marked, use this. * It can be reset via smackfs/ambient */ char *smack_net_ambient; struct smack_known *smack_net_ambient; /* * This is the level in a CIPSO header that indicates a Loading Loading @@ -112,7 +112,7 @@ struct smack_master_list { LIST_HEAD(smack_rule_list); struct smack_parsed_rule { char *smk_subject; struct smack_known *smk_subject; char *smk_object; int smk_access1; int smk_access2; Loading Loading @@ -163,9 +163,11 @@ static inline void smack_catset_bit(unsigned int cat, char *catsetp) */ static void smk_netlabel_audit_set(struct netlbl_audit *nap) { struct smack_known *skp = smk_of_current(); nap->loginuid = audit_get_loginuid(current); nap->sessionid = audit_get_sessionid(current); nap->secid = smack_to_secid(smk_of_current()); nap->secid = skp->smk_secid; } /* Loading Loading @@ -306,7 +308,7 @@ static int smk_fill_rule(const char *subject, const char *object, struct smack_known *skp; if (import) { rule->smk_subject = smk_import(subject, len); rule->smk_subject = smk_import_entry(subject, len); if (rule->smk_subject == NULL) return -1; Loading @@ -321,7 +323,7 @@ static int smk_fill_rule(const char *subject, const char *object, kfree(cp); if (skp == NULL) return -1; rule->smk_subject = skp->smk_known; rule->smk_subject = skp; cp = smk_parse_smack(object, len); if (cp == NULL) Loading Loading @@ -445,7 +447,6 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, struct list_head *rule_list, struct mutex *rule_lock, int format) { struct smack_known *skp; struct smack_parsed_rule *rule; char *data; int datalen; Loading Loading @@ -505,12 +506,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, goto out_free_rule; } if (rule_list == NULL) { load = 1; skp = smk_find_entry(rule->smk_subject); rule_list = &skp->smk_rules; rule_lock = &skp->smk_rules_lock; rule_list = &rule->smk_subject->smk_rules; rule_lock = &rule->smk_subject->smk_rules_lock; } rc = smk_set_access(rule, rule_list, rule_lock, load); Loading Loading @@ -579,13 +578,14 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) * because you should expect to be able to write * anything you read back. */ if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) if (strlen(srp->smk_subject->smk_known) >= max || strlen(srp->smk_object) >= max) return; if (srp->smk_access == 0) return; seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object); seq_putc(s, ' '); Loading Loading @@ -738,9 +738,9 @@ static void smk_unlbl_ambient(char *oldambient) __func__, __LINE__, rc); } if (smack_net_ambient == NULL) smack_net_ambient = smack_known_floor.smk_known; smack_net_ambient = &smack_known_floor; rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET, NULL, NULL, &nai); if (rc != 0) printk(KERN_WARNING "%s:%d add rc = %d\n", Loading Loading @@ -881,7 +881,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, if (format == SMK_FIXED24_FMT) rule += SMK_LABELLEN; else rule += strlen(skp->smk_known); rule += strlen(skp->smk_known) + 1; ret = sscanf(rule, "%d", &maplevel); if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) Loading Loading @@ -1535,11 +1535,12 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, */ mutex_lock(&smack_ambient_lock); asize = strlen(smack_net_ambient) + 1; asize = strlen(smack_net_ambient->smk_known) + 1; if (cn >= asize) rc = simple_read_from_buffer(buf, cn, ppos, smack_net_ambient, asize); smack_net_ambient->smk_known, asize); else rc = -EINVAL; Loading @@ -1560,8 +1561,8 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, static ssize_t smk_write_ambient(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct smack_known *skp; char *oldambient; char *smack = NULL; char *data; int rc = count; Loading @@ -1577,16 +1578,16 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, goto out; } smack = smk_import(data, count); if (smack == NULL) { skp = smk_import_entry(data, count); if (skp == NULL) { rc = -EINVAL; goto out; } mutex_lock(&smack_ambient_lock); oldambient = smack_net_ambient; smack_net_ambient = smack; oldambient = smack_net_ambient->smk_known; smack_net_ambient = skp; smk_unlbl_ambient(oldambient); mutex_unlock(&smack_ambient_lock); Loading Loading @@ -1645,7 +1646,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char *data; char *sp = smk_of_task(current->cred->security); struct smack_known *skp = smk_of_task(current->cred->security); int rc = count; if (!smack_privileged(CAP_MAC_ADMIN)) Loading @@ -1656,7 +1657,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, * explicitly for clarity. The smk_access() implementation * would use smk_access(smack_onlycap, MAY_WRITE) */ if (smack_onlycap != NULL && smack_onlycap != sp) if (smack_onlycap != NULL && smack_onlycap != skp->smk_known) return -EPERM; data = kzalloc(count, GFP_KERNEL); Loading Loading @@ -1866,8 +1867,8 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, if (res) return -EINVAL; res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1, NULL); res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1, NULL); data[0] = res == 0 ? '1' : '0'; data[1] = '\0'; Loading