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 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