aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack_lsm.c
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2011-02-08 19:36:24 -0500
committerJames Morris <jmorris@namei.org>2011-02-09 02:50:23 -0500
commit0e0a070d3a47d279de66e08244769556deae2eee (patch)
tree8d9c07464833076a40c1d95dd2f8f33716509290 /security/smack/smack_lsm.c
parent821404434f3324bf23f545050ff64055a149766e (diff)
Smack: correct behavior in the mmap hook
The mmap policy enforcement was not properly handling the interaction between the global and local rule lists. Instead of going through one and then the other, which missed the important case where a rule specified that there should be no access, combine the access limitations where there is a rule in each list. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r--security/smack/smack_lsm.c85
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 */
1121static 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();