aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack_lsm.c
diff options
context:
space:
mode:
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();