diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index e5ed07510309..75c2e99bfb81 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -1272,12 +1272,18 @@ static int task_has_perm(struct task_struct *tsk1, | |||
| 1272 | SECCLASS_PROCESS, perms, NULL); | 1272 | SECCLASS_PROCESS, perms, NULL); |
| 1273 | } | 1273 | } |
| 1274 | 1274 | ||
| 1275 | #if CAP_LAST_CAP > 63 | ||
| 1276 | #error Fix SELinux to handle capabilities > 63. | ||
| 1277 | #endif | ||
| 1278 | |||
| 1275 | /* Check whether a task is allowed to use a capability. */ | 1279 | /* Check whether a task is allowed to use a capability. */ |
| 1276 | static int task_has_capability(struct task_struct *tsk, | 1280 | static int task_has_capability(struct task_struct *tsk, |
| 1277 | int cap) | 1281 | int cap) |
| 1278 | { | 1282 | { |
| 1279 | struct task_security_struct *tsec; | 1283 | struct task_security_struct *tsec; |
| 1280 | struct avc_audit_data ad; | 1284 | struct avc_audit_data ad; |
| 1285 | u16 sclass; | ||
| 1286 | u32 av = CAP_TO_MASK(cap); | ||
| 1281 | 1287 | ||
| 1282 | tsec = tsk->security; | 1288 | tsec = tsk->security; |
| 1283 | 1289 | ||
| @@ -1285,8 +1291,19 @@ static int task_has_capability(struct task_struct *tsk, | |||
| 1285 | ad.tsk = tsk; | 1291 | ad.tsk = tsk; |
| 1286 | ad.u.cap = cap; | 1292 | ad.u.cap = cap; |
| 1287 | 1293 | ||
| 1288 | return avc_has_perm(tsec->sid, tsec->sid, | 1294 | switch (CAP_TO_INDEX(cap)) { |
| 1289 | SECCLASS_CAPABILITY, CAP_TO_MASK(cap), &ad); | 1295 | case 0: |
| 1296 | sclass = SECCLASS_CAPABILITY; | ||
| 1297 | break; | ||
| 1298 | case 1: | ||
| 1299 | sclass = SECCLASS_CAPABILITY2; | ||
| 1300 | break; | ||
| 1301 | default: | ||
| 1302 | printk(KERN_ERR | ||
| 1303 | "SELinux: out of range capability %d\n", cap); | ||
| 1304 | BUG(); | ||
| 1305 | } | ||
| 1306 | return avc_has_perm(tsec->sid, tsec->sid, sclass, av, &ad); | ||
| 1290 | } | 1307 | } |
| 1291 | 1308 | ||
| 1292 | /* Check whether a task is allowed to use a system operation. */ | 1309 | /* Check whether a task is allowed to use a system operation. */ |
| @@ -1339,8 +1356,8 @@ static inline int dentry_has_perm(struct task_struct *tsk, | |||
| 1339 | struct inode *inode = dentry->d_inode; | 1356 | struct inode *inode = dentry->d_inode; |
| 1340 | struct avc_audit_data ad; | 1357 | struct avc_audit_data ad; |
| 1341 | AVC_AUDIT_DATA_INIT(&ad,FS); | 1358 | AVC_AUDIT_DATA_INIT(&ad,FS); |
| 1342 | ad.u.fs.mnt = mnt; | 1359 | ad.u.fs.path.mnt = mnt; |
| 1343 | ad.u.fs.dentry = dentry; | 1360 | ad.u.fs.path.dentry = dentry; |
| 1344 | return inode_has_perm(tsk, inode, av, &ad); | 1361 | return inode_has_perm(tsk, inode, av, &ad); |
| 1345 | } | 1362 | } |
| 1346 | 1363 | ||
| @@ -1358,15 +1375,12 @@ static int file_has_perm(struct task_struct *tsk, | |||
| 1358 | { | 1375 | { |
| 1359 | struct task_security_struct *tsec = tsk->security; | 1376 | struct task_security_struct *tsec = tsk->security; |
| 1360 | struct file_security_struct *fsec = file->f_security; | 1377 | struct file_security_struct *fsec = file->f_security; |
| 1361 | struct vfsmount *mnt = file->f_path.mnt; | 1378 | struct inode *inode = file->f_path.dentry->d_inode; |
| 1362 | struct dentry *dentry = file->f_path.dentry; | ||
| 1363 | struct inode *inode = dentry->d_inode; | ||
| 1364 | struct avc_audit_data ad; | 1379 | struct avc_audit_data ad; |
| 1365 | int rc; | 1380 | int rc; |
| 1366 | 1381 | ||
| 1367 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1382 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 1368 | ad.u.fs.mnt = mnt; | 1383 | ad.u.fs.path = file->f_path; |
| 1369 | ad.u.fs.dentry = dentry; | ||
| 1370 | 1384 | ||
| 1371 | if (tsec->sid != fsec->sid) { | 1385 | if (tsec->sid != fsec->sid) { |
| 1372 | rc = avc_has_perm(tsec->sid, fsec->sid, | 1386 | rc = avc_has_perm(tsec->sid, fsec->sid, |
| @@ -1401,7 +1415,7 @@ static int may_create(struct inode *dir, | |||
| 1401 | sbsec = dir->i_sb->s_security; | 1415 | sbsec = dir->i_sb->s_security; |
| 1402 | 1416 | ||
| 1403 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1417 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 1404 | ad.u.fs.dentry = dentry; | 1418 | ad.u.fs.path.dentry = dentry; |
| 1405 | 1419 | ||
| 1406 | rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR, | 1420 | rc = avc_has_perm(tsec->sid, dsec->sid, SECCLASS_DIR, |
| 1407 | DIR__ADD_NAME | DIR__SEARCH, | 1421 | DIR__ADD_NAME | DIR__SEARCH, |
| @@ -1459,7 +1473,7 @@ static int may_link(struct inode *dir, | |||
| 1459 | isec = dentry->d_inode->i_security; | 1473 | isec = dentry->d_inode->i_security; |
| 1460 | 1474 | ||
| 1461 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1475 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 1462 | ad.u.fs.dentry = dentry; | 1476 | ad.u.fs.path.dentry = dentry; |
| 1463 | 1477 | ||
| 1464 | av = DIR__SEARCH; | 1478 | av = DIR__SEARCH; |
| 1465 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); | 1479 | av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); |
| @@ -1506,7 +1520,7 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1506 | 1520 | ||
| 1507 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1521 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 1508 | 1522 | ||
| 1509 | ad.u.fs.dentry = old_dentry; | 1523 | ad.u.fs.path.dentry = old_dentry; |
| 1510 | rc = avc_has_perm(tsec->sid, old_dsec->sid, SECCLASS_DIR, | 1524 | rc = avc_has_perm(tsec->sid, old_dsec->sid, SECCLASS_DIR, |
| 1511 | DIR__REMOVE_NAME | DIR__SEARCH, &ad); | 1525 | DIR__REMOVE_NAME | DIR__SEARCH, &ad); |
| 1512 | if (rc) | 1526 | if (rc) |
| @@ -1522,7 +1536,7 @@ static inline int may_rename(struct inode *old_dir, | |||
| 1522 | return rc; | 1536 | return rc; |
| 1523 | } | 1537 | } |
| 1524 | 1538 | ||
| 1525 | ad.u.fs.dentry = new_dentry; | 1539 | ad.u.fs.path.dentry = new_dentry; |
| 1526 | av = DIR__ADD_NAME | DIR__SEARCH; | 1540 | av = DIR__ADD_NAME | DIR__SEARCH; |
| 1527 | if (new_dentry->d_inode) | 1541 | if (new_dentry->d_inode) |
| 1528 | av |= DIR__REMOVE_NAME; | 1542 | av |= DIR__REMOVE_NAME; |
| @@ -1901,8 +1915,7 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm) | |||
| 1901 | } | 1915 | } |
| 1902 | 1916 | ||
| 1903 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1917 | AVC_AUDIT_DATA_INIT(&ad, FS); |
| 1904 | ad.u.fs.mnt = bprm->file->f_path.mnt; | 1918 | ad.u.fs.path = bprm->file->f_path; |
| 1905 | ad.u.fs.dentry = bprm->file->f_path.dentry; | ||
| 1906 | 1919 | ||
| 1907 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) | 1920 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) |
| 1908 | newsid = tsec->sid; | 1921 | newsid = tsec->sid; |
| @@ -2298,7 +2311,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, void *data) | |||
| 2298 | return rc; | 2311 | return rc; |
| 2299 | 2312 | ||
| 2300 | AVC_AUDIT_DATA_INIT(&ad,FS); | 2313 | AVC_AUDIT_DATA_INIT(&ad,FS); |
| 2301 | ad.u.fs.dentry = sb->s_root; | 2314 | ad.u.fs.path.dentry = sb->s_root; |
| 2302 | return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); | 2315 | return superblock_has_perm(current, sb, FILESYSTEM__MOUNT, &ad); |
| 2303 | } | 2316 | } |
| 2304 | 2317 | ||
| @@ -2307,7 +2320,7 @@ static int selinux_sb_statfs(struct dentry *dentry) | |||
| 2307 | struct avc_audit_data ad; | 2320 | struct avc_audit_data ad; |
| 2308 | 2321 | ||
| 2309 | AVC_AUDIT_DATA_INIT(&ad,FS); | 2322 | AVC_AUDIT_DATA_INIT(&ad,FS); |
| 2310 | ad.u.fs.dentry = dentry->d_sb->s_root; | 2323 | ad.u.fs.path.dentry = dentry->d_sb->s_root; |
| 2311 | return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad); | 2324 | return superblock_has_perm(current, dentry->d_sb, FILESYSTEM__GETATTR, &ad); |
| 2312 | } | 2325 | } |
| 2313 | 2326 | ||
| @@ -2324,10 +2337,10 @@ static int selinux_mount(char * dev_name, | |||
| 2324 | return rc; | 2337 | return rc; |
| 2325 | 2338 | ||
| 2326 | if (flags & MS_REMOUNT) | 2339 | if (flags & MS_REMOUNT) |
| 2327 | return superblock_has_perm(current, nd->mnt->mnt_sb, | 2340 | return superblock_has_perm(current, nd->path.mnt->mnt_sb, |
| 2328 | FILESYSTEM__REMOUNT, NULL); | 2341 | FILESYSTEM__REMOUNT, NULL); |
| 2329 | else | 2342 | else |
| 2330 | return dentry_has_perm(current, nd->mnt, nd->dentry, | 2343 | return dentry_has_perm(current, nd->path.mnt, nd->path.dentry, |
| 2331 | FILE__MOUNTON); | 2344 | FILE__MOUNTON); |
| 2332 | } | 2345 | } |
| 2333 | 2346 | ||
| @@ -2570,7 +2583,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value | |||
| 2570 | return -EPERM; | 2583 | return -EPERM; |
| 2571 | 2584 | ||
| 2572 | AVC_AUDIT_DATA_INIT(&ad,FS); | 2585 | AVC_AUDIT_DATA_INIT(&ad,FS); |
| 2573 | ad.u.fs.dentry = dentry; | 2586 | ad.u.fs.path.dentry = dentry; |
| 2574 | 2587 | ||
| 2575 | rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, | 2588 | rc = avc_has_perm(tsec->sid, isec->sid, isec->sclass, |
| 2576 | FILE__RELABELFROM, &ad); | 2589 | FILE__RELABELFROM, &ad); |
