diff options
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 123a499ded37..92cb71507f5b 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -1110,38 +1110,6 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, | |||
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | /** | 1112 | /** |
1113 | * smk_mmap_list_check - the mmap check | ||
1114 | * @sub: subject label | ||
1115 | * @obj: object label | ||
1116 | * @access: access mode | ||
1117 | * @local: the task specific rule list | ||
1118 | * | ||
1119 | * Returns 0 if acces is permitted, -EACCES otherwise | ||
1120 | */ | ||
1121 | static int smk_mmap_list_check(char *sub, char *obj, int access, | ||
1122 | struct list_head *local) | ||
1123 | { | ||
1124 | int may; | ||
1125 | |||
1126 | /* | ||
1127 | * If there is not a global rule that | ||
1128 | * allows access say no. | ||
1129 | */ | ||
1130 | may = smk_access_entry(sub, obj, &smack_rule_list); | ||
1131 | if (may == -ENOENT || (may & access) != access) | ||
1132 | return -EACCES; | ||
1133 | /* | ||
1134 | * If there is a task local rule that | ||
1135 | * denies access say no. | ||
1136 | */ | ||
1137 | may = smk_access_entry(sub, obj, local); | ||
1138 | if (may != -ENOENT && (may & access) != access) | ||
1139 | return -EACCES; | ||
1140 | |||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | /** | ||
1145 | * smack_file_mmap : | 1113 | * smack_file_mmap : |
1146 | * Check permissions for a mmap operation. The @file may be NULL, e.g. | 1114 | * Check permissions for a mmap operation. The @file may be NULL, e.g. |
1147 | * if mapping anonymous memory. | 1115 | * if mapping anonymous memory. |
@@ -1160,8 +1128,12 @@ static int smack_file_mmap(struct file *file, | |||
1160 | struct task_smack *tsp; | 1128 | struct task_smack *tsp; |
1161 | char *sp; | 1129 | char *sp; |
1162 | char *msmack; | 1130 | char *msmack; |
1131 | char *osmack; | ||
1163 | struct inode_smack *isp; | 1132 | struct inode_smack *isp; |
1164 | struct dentry *dp; | 1133 | struct dentry *dp; |
1134 | int may; | ||
1135 | int mmay; | ||
1136 | int tmay; | ||
1165 | int rc; | 1137 | int rc; |
1166 | 1138 | ||
1167 | /* do DAC check on address space usage */ | 1139 | /* do DAC check on address space usage */ |
@@ -1199,16 +1171,57 @@ static int smack_file_mmap(struct file *file, | |||
1199 | list_for_each_entry_rcu(srp, &smack_rule_list, list) { | 1171 | list_for_each_entry_rcu(srp, &smack_rule_list, list) { |
1200 | if (srp->smk_subject != sp) | 1172 | if (srp->smk_subject != sp) |
1201 | continue; | 1173 | continue; |
1174 | |||
1175 | osmack = srp->smk_object; | ||
1202 | /* | 1176 | /* |
1203 | * Matching labels always allows access. | 1177 | * Matching labels always allows access. |
1204 | */ | 1178 | */ |
1205 | if (msmack == srp->smk_object) | 1179 | if (msmack == osmack) |
1180 | continue; | ||
1181 | /* | ||
1182 | * If there is a matching local rule take | ||
1183 | * that into account as well. | ||
1184 | */ | ||
1185 | may = smk_access_entry(srp->smk_subject, osmack, | ||
1186 | &tsp->smk_rules); | ||
1187 | if (may == -ENOENT) | ||
1188 | may = srp->smk_access; | ||
1189 | else | ||
1190 | may &= srp->smk_access; | ||
1191 | /* | ||
1192 | * If may is zero the SMACK64MMAP subject can't | ||
1193 | * possibly have less access. | ||
1194 | */ | ||
1195 | if (may == 0) | ||
1206 | continue; | 1196 | continue; |
1207 | 1197 | ||
1208 | rc = smk_mmap_list_check(msmack, srp->smk_object, | 1198 | /* |
1209 | srp->smk_access, &tsp->smk_rules); | 1199 | * Fetch the global list entry. |
1210 | if (rc != 0) | 1200 | * If there isn't one a SMACK64MMAP subject |
1201 | * can't have as much access as current. | ||
1202 | */ | ||
1203 | mmay = smk_access_entry(msmack, osmack, &smack_rule_list); | ||
1204 | if (mmay == -ENOENT) { | ||
1205 | rc = -EACCES; | ||
1211 | break; | 1206 | break; |
1207 | } | ||
1208 | /* | ||
1209 | * If there is a local entry it modifies the | ||
1210 | * potential access, too. | ||
1211 | */ | ||
1212 | tmay = smk_access_entry(msmack, osmack, &tsp->smk_rules); | ||
1213 | if (tmay != -ENOENT) | ||
1214 | mmay &= tmay; | ||
1215 | |||
1216 | /* | ||
1217 | * If there is any access available to current that is | ||
1218 | * not available to a SMACK64MMAP subject | ||
1219 | * deny access. | ||
1220 | */ | ||
1221 | if ((may | mmay) != may) { | ||
1222 | rc = -EACCES; | ||
1223 | break; | ||
1224 | } | ||
1212 | } | 1225 | } |
1213 | 1226 | ||
1214 | rcu_read_unlock(); | 1227 | rcu_read_unlock(); |