diff options
author | Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com> | 2010-12-07 06:34:01 -0500 |
---|---|---|
committer | Casey Schaufler <casey@schaufler-ca.com> | 2010-12-07 17:04:02 -0500 |
commit | 5c6d1125f8dbd1bfef39e38fbc2837003be78a59 (patch) | |
tree | 368d34e800bc5478442679323270d776b79501e8 /security/smack/smack_access.c | |
parent | fe27d4b012273640e033be80f143bdc54daa8e16 (diff) |
Smack: Transmute labels on specified directories
In a situation where Smack access rules allow processes
with multiple labels to write to a directory it is easy
to get into a situation where the directory gets cluttered
with files that the owner can't deal with because while
they could be written to the directory a process at the
label of the directory can't write them. This is generally
the desired behavior, but when it isn't it is a real
issue.
This patch introduces a new attribute SMACK64TRANSMUTE that
instructs Smack to create the file with the label of the directory
under certain circumstances.
A new access mode, "t" for transmute, is made available to
Smack access rules, which are expanded from "rwxa" to "rwxat".
If a file is created in a directory marked as transmutable
and if access was granted to perform the operation by a rule
that included the transmute mode, then the file gets the
Smack label of the directory instead of the Smack label of the
creating process.
Note that this is equivalent to creating an empty file at the
label of the directory and then having the other process write
to it. The transmute scheme requires that both the access rule
allows transmutation and that the directory be explicitly marked.
Signed-off-by: Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security/smack/smack_access.c')
-rw-r--r-- | security/smack/smack_access.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 42becbc1ce33..7ba8478f599e 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
@@ -67,6 +67,46 @@ static u32 smack_next_secid = 10; | |||
67 | int log_policy = SMACK_AUDIT_DENIED; | 67 | int log_policy = SMACK_AUDIT_DENIED; |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * smk_access_entry - look up matching access rule | ||
71 | * @subject_label: a pointer to the subject's Smack label | ||
72 | * @object_label: a pointer to the object's Smack label | ||
73 | * | ||
74 | * This function looks up the subject/object pair in the | ||
75 | * access rule list and returns pointer to the matching rule if found, | ||
76 | * NULL otherwise. | ||
77 | * | ||
78 | * NOTE: | ||
79 | * Even though Smack labels are usually shared on smack_list | ||
80 | * labels that come in off the network can't be imported | ||
81 | * and added to the list for locking reasons. | ||
82 | * | ||
83 | * Therefore, it is necessary to check the contents of the labels, | ||
84 | * not just the pointer values. Of course, in most cases the labels | ||
85 | * will be on the list, so checking the pointers may be a worthwhile | ||
86 | * optimization. | ||
87 | */ | ||
88 | int smk_access_entry(char *subject_label, char *object_label) | ||
89 | { | ||
90 | u32 may = MAY_NOT; | ||
91 | struct smack_rule *srp; | ||
92 | |||
93 | rcu_read_lock(); | ||
94 | list_for_each_entry_rcu(srp, &smack_rule_list, list) { | ||
95 | if (srp->smk_subject == subject_label || | ||
96 | strcmp(srp->smk_subject, subject_label) == 0) { | ||
97 | if (srp->smk_object == object_label || | ||
98 | strcmp(srp->smk_object, object_label) == 0) { | ||
99 | may = srp->smk_access; | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | rcu_read_unlock(); | ||
105 | |||
106 | return may; | ||
107 | } | ||
108 | |||
109 | /** | ||
70 | * smk_access - determine if a subject has a specific access to an object | 110 | * smk_access - determine if a subject has a specific access to an object |
71 | * @subject_label: a pointer to the subject's Smack label | 111 | * @subject_label: a pointer to the subject's Smack label |
72 | * @object_label: a pointer to the object's Smack label | 112 | * @object_label: a pointer to the object's Smack label |
@@ -90,7 +130,6 @@ int smk_access(char *subject_label, char *object_label, int request, | |||
90 | struct smk_audit_info *a) | 130 | struct smk_audit_info *a) |
91 | { | 131 | { |
92 | u32 may = MAY_NOT; | 132 | u32 may = MAY_NOT; |
93 | struct smack_rule *srp; | ||
94 | int rc = 0; | 133 | int rc = 0; |
95 | 134 | ||
96 | /* | 135 | /* |
@@ -144,18 +183,7 @@ int smk_access(char *subject_label, char *object_label, int request, | |||
144 | * access (e.g. read is included in readwrite) it's | 183 | * access (e.g. read is included in readwrite) it's |
145 | * good. | 184 | * good. |
146 | */ | 185 | */ |
147 | rcu_read_lock(); | 186 | may = smk_access_entry(subject_label, object_label); |
148 | list_for_each_entry_rcu(srp, &smack_rule_list, list) { | ||
149 | if (srp->smk_subject == subject_label || | ||
150 | strcmp(srp->smk_subject, subject_label) == 0) { | ||
151 | if (srp->smk_object == object_label || | ||
152 | strcmp(srp->smk_object, object_label) == 0) { | ||
153 | may = srp->smk_access; | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | rcu_read_unlock(); | ||
159 | /* | 187 | /* |
160 | * This is a bit map operation. | 188 | * This is a bit map operation. |
161 | */ | 189 | */ |