Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'selinux-pr-20180629' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux fix from Paul Moore:
"One fairly straightforward patch to fix a longstanding issue where a
process could stall while accessing files in selinuxfs and block
everyone else due to a held mutex.

The patch passes all our tests and looks to apply cleanly to your
current tree"

* tag 'selinux-pr-20180629' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
selinux: move user accesses in selinuxfs out of locked regions

+33 -45
+33 -45
security/selinux/selinuxfs.c
··· 441 441 static ssize_t sel_read_policy(struct file *filp, char __user *buf, 442 442 size_t count, loff_t *ppos) 443 443 { 444 - struct selinux_fs_info *fsi = file_inode(filp)->i_sb->s_fs_info; 445 444 struct policy_load_memory *plm = filp->private_data; 446 445 int ret; 447 - 448 - mutex_lock(&fsi->mutex); 449 446 450 447 ret = avc_has_perm(&selinux_state, 451 448 current_sid(), SECINITSID_SECURITY, 452 449 SECCLASS_SECURITY, SECURITY__READ_POLICY, NULL); 453 450 if (ret) 454 - goto out; 451 + return ret; 455 452 456 - ret = simple_read_from_buffer(buf, count, ppos, plm->data, plm->len); 457 - out: 458 - mutex_unlock(&fsi->mutex); 459 - return ret; 453 + return simple_read_from_buffer(buf, count, ppos, plm->data, plm->len); 460 454 } 461 455 462 456 static vm_fault_t sel_mmap_policy_fault(struct vm_fault *vmf) ··· 1182 1188 ret = -EINVAL; 1183 1189 if (index >= fsi->bool_num || strcmp(name, 1184 1190 fsi->bool_pending_names[index])) 1185 - goto out; 1191 + goto out_unlock; 1186 1192 1187 1193 ret = -ENOMEM; 1188 1194 page = (char *)get_zeroed_page(GFP_KERNEL); 1189 1195 if (!page) 1190 - goto out; 1196 + goto out_unlock; 1191 1197 1192 1198 cur_enforcing = security_get_bool_value(fsi->state, index); 1193 1199 if (cur_enforcing < 0) { 1194 1200 ret = cur_enforcing; 1195 - goto out; 1201 + goto out_unlock; 1196 1202 } 1197 1203 length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, 1198 1204 fsi->bool_pending_values[index]); 1199 - ret = simple_read_from_buffer(buf, count, ppos, page, length); 1200 - out: 1201 1205 mutex_unlock(&fsi->mutex); 1206 + ret = simple_read_from_buffer(buf, count, ppos, page, length); 1207 + out_free: 1202 1208 free_page((unsigned long)page); 1203 1209 return ret; 1210 + 1211 + out_unlock: 1212 + mutex_unlock(&fsi->mutex); 1213 + goto out_free; 1204 1214 } 1205 1215 1206 1216 static ssize_t sel_write_bool(struct file *filep, const char __user *buf, ··· 1216 1218 int new_value; 1217 1219 unsigned index = file_inode(filep)->i_ino & SEL_INO_MASK; 1218 1220 const char *name = filep->f_path.dentry->d_name.name; 1221 + 1222 + if (count >= PAGE_SIZE) 1223 + return -ENOMEM; 1224 + 1225 + /* No partial writes. */ 1226 + if (*ppos != 0) 1227 + return -EINVAL; 1228 + 1229 + page = memdup_user_nul(buf, count); 1230 + if (IS_ERR(page)) 1231 + return PTR_ERR(page); 1219 1232 1220 1233 mutex_lock(&fsi->mutex); 1221 1234 ··· 1241 1232 if (index >= fsi->bool_num || strcmp(name, 1242 1233 fsi->bool_pending_names[index])) 1243 1234 goto out; 1244 - 1245 - length = -ENOMEM; 1246 - if (count >= PAGE_SIZE) 1247 - goto out; 1248 - 1249 - /* No partial writes. */ 1250 - length = -EINVAL; 1251 - if (*ppos != 0) 1252 - goto out; 1253 - 1254 - page = memdup_user_nul(buf, count); 1255 - if (IS_ERR(page)) { 1256 - length = PTR_ERR(page); 1257 - page = NULL; 1258 - goto out; 1259 - } 1260 1235 1261 1236 length = -EINVAL; 1262 1237 if (sscanf(page, "%d", &new_value) != 1) ··· 1273 1280 ssize_t length; 1274 1281 int new_value; 1275 1282 1283 + if (count >= PAGE_SIZE) 1284 + return -ENOMEM; 1285 + 1286 + /* No partial writes. */ 1287 + if (*ppos != 0) 1288 + return -EINVAL; 1289 + 1290 + page = memdup_user_nul(buf, count); 1291 + if (IS_ERR(page)) 1292 + return PTR_ERR(page); 1293 + 1276 1294 mutex_lock(&fsi->mutex); 1277 1295 1278 1296 length = avc_has_perm(&selinux_state, ··· 1292 1288 NULL); 1293 1289 if (length) 1294 1290 goto out; 1295 - 1296 - length = -ENOMEM; 1297 - if (count >= PAGE_SIZE) 1298 - goto out; 1299 - 1300 - /* No partial writes. */ 1301 - length = -EINVAL; 1302 - if (*ppos != 0) 1303 - goto out; 1304 - 1305 - page = memdup_user_nul(buf, count); 1306 - if (IS_ERR(page)) { 1307 - length = PTR_ERR(page); 1308 - page = NULL; 1309 - goto out; 1310 - } 1311 1291 1312 1292 length = -EINVAL; 1313 1293 if (sscanf(page, "%d", &new_value) != 1)