aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2014-12-12 20:19:19 -0500
committerCasey Schaufler <casey@schaufler-ca.com>2015-01-20 19:32:17 -0500
commit5e7270a6dd14fa6e3bb10128f200305b4a75f350 (patch)
tree586640992a1e76584e85a73f6651c018dffc8843 /security
parent96be7b5424948ae39d29d5149eaec0bd6edd7404 (diff)
Smack: Rework file hooks
This is one of those cases where you look at code you did years ago and wonder what you might have been thinking. There are a number of LSM hooks that work off of file pointers, and most of them really want the security data from the inode. Some, however, really want the security context that the process had when the file was opened. The difference went undetected in Smack until it started getting used in a real system with real testing. At that point it was clear that something was amiss. This patch corrects the misuse of the f_security value in several of the hooks. The behavior will not usually be any different, as the process had to be able to open the file in the first place, and the old check almost always succeeded, as will the new, but for different reasons. Thanks to the Samsung Tizen development team that identified this. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security')
-rw-r--r--security/smack/smack_lsm.c40
1 files changed, 19 insertions, 21 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 654345de62e7..1fa72317bbec 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -160,7 +160,7 @@ static int smk_bu_file(struct file *file, int mode, int rc)
160{ 160{
161 struct task_smack *tsp = current_security(); 161 struct task_smack *tsp = current_security();
162 struct smack_known *sskp = tsp->smk_task; 162 struct smack_known *sskp = tsp->smk_task;
163 struct inode *inode = file->f_inode; 163 struct inode *inode = file_inode(file);
164 char acc[SMK_NUM_ACCESS_TYPE + 1]; 164 char acc[SMK_NUM_ACCESS_TYPE + 1];
165 165
166 if (rc <= 0) 166 if (rc <= 0)
@@ -168,7 +168,7 @@ static int smk_bu_file(struct file *file, int mode, int rc)
168 168
169 smk_bu_mode(mode, acc); 169 smk_bu_mode(mode, acc);
170 pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", 170 pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n",
171 sskp->smk_known, (char *)file->f_security, acc, 171 sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
172 inode->i_sb->s_id, inode->i_ino, file, 172 inode->i_sb->s_id, inode->i_ino, file,
173 current->comm); 173 current->comm);
174 return 0; 174 return 0;
@@ -1347,6 +1347,9 @@ static int smack_file_permission(struct file *file, int mask)
1347 * The security blob for a file is a pointer to the master 1347 * The security blob for a file is a pointer to the master
1348 * label list, so no allocation is done. 1348 * label list, so no allocation is done.
1349 * 1349 *
1350 * f_security is the owner security information. It
1351 * isn't used on file access checks, it's for send_sigio.
1352 *
1350 * Returns 0 1353 * Returns 0
1351 */ 1354 */
1352static int smack_file_alloc_security(struct file *file) 1355static int smack_file_alloc_security(struct file *file)
@@ -1384,17 +1387,18 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
1384{ 1387{
1385 int rc = 0; 1388 int rc = 0;
1386 struct smk_audit_info ad; 1389 struct smk_audit_info ad;
1390 struct inode *inode = file_inode(file);
1387 1391
1388 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 1392 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1389 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1393 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1390 1394
1391 if (_IOC_DIR(cmd) & _IOC_WRITE) { 1395 if (_IOC_DIR(cmd) & _IOC_WRITE) {
1392 rc = smk_curacc(file->f_security, MAY_WRITE, &ad); 1396 rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
1393 rc = smk_bu_file(file, MAY_WRITE, rc); 1397 rc = smk_bu_file(file, MAY_WRITE, rc);
1394 } 1398 }
1395 1399
1396 if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) { 1400 if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) {
1397 rc = smk_curacc(file->f_security, MAY_READ, &ad); 1401 rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad);
1398 rc = smk_bu_file(file, MAY_READ, rc); 1402 rc = smk_bu_file(file, MAY_READ, rc);
1399 } 1403 }
1400 1404
@@ -1412,10 +1416,11 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
1412{ 1416{
1413 struct smk_audit_info ad; 1417 struct smk_audit_info ad;
1414 int rc; 1418 int rc;
1419 struct inode *inode = file_inode(file);
1415 1420
1416 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 1421 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1417 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1422 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1418 rc = smk_curacc(file->f_security, MAY_LOCK, &ad); 1423 rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
1419 rc = smk_bu_file(file, MAY_LOCK, rc); 1424 rc = smk_bu_file(file, MAY_LOCK, rc);
1420 return rc; 1425 return rc;
1421} 1426}
@@ -1437,7 +1442,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
1437{ 1442{
1438 struct smk_audit_info ad; 1443 struct smk_audit_info ad;
1439 int rc = 0; 1444 int rc = 0;
1440 1445 struct inode *inode = file_inode(file);
1441 1446
1442 switch (cmd) { 1447 switch (cmd) {
1443 case F_GETLK: 1448 case F_GETLK:
@@ -1446,14 +1451,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
1446 case F_SETLKW: 1451 case F_SETLKW:
1447 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 1452 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1448 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1453 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1449 rc = smk_curacc(file->f_security, MAY_LOCK, &ad); 1454 rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
1450 rc = smk_bu_file(file, MAY_LOCK, rc); 1455 rc = smk_bu_file(file, MAY_LOCK, rc);
1451 break; 1456 break;
1452 case F_SETOWN: 1457 case F_SETOWN:
1453 case F_SETSIG: 1458 case F_SETSIG:
1454 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 1459 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1455 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1460 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1456 rc = smk_curacc(file->f_security, MAY_WRITE, &ad); 1461 rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
1457 rc = smk_bu_file(file, MAY_WRITE, rc); 1462 rc = smk_bu_file(file, MAY_WRITE, rc);
1458 break; 1463 break;
1459 default: 1464 default:
@@ -1571,14 +1576,10 @@ static int smack_mmap_file(struct file *file,
1571 * smack_file_set_fowner - set the file security blob value 1576 * smack_file_set_fowner - set the file security blob value
1572 * @file: object in question 1577 * @file: object in question
1573 * 1578 *
1574 * Returns 0
1575 * Further research may be required on this one.
1576 */ 1579 */
1577static void smack_file_set_fowner(struct file *file) 1580static void smack_file_set_fowner(struct file *file)
1578{ 1581{
1579 struct smack_known *skp = smk_of_current(); 1582 file->f_security = smk_of_current();
1580
1581 file->f_security = skp;
1582} 1583}
1583 1584
1584/** 1585/**
@@ -1630,6 +1631,7 @@ static int smack_file_receive(struct file *file)
1630 int rc; 1631 int rc;
1631 int may = 0; 1632 int may = 0;
1632 struct smk_audit_info ad; 1633 struct smk_audit_info ad;
1634 struct inode *inode = file_inode(file);
1633 1635
1634 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 1636 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1635 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1637 smk_ad_setfield_u_fs_path(&ad, file->f_path);
@@ -1641,7 +1643,7 @@ static int smack_file_receive(struct file *file)
1641 if (file->f_mode & FMODE_WRITE) 1643 if (file->f_mode & FMODE_WRITE)
1642 may |= MAY_WRITE; 1644 may |= MAY_WRITE;
1643 1645
1644 rc = smk_curacc(file->f_security, may, &ad); 1646 rc = smk_curacc(smk_of_inode(inode), may, &ad);
1645 rc = smk_bu_file(file, may, rc); 1647 rc = smk_bu_file(file, may, rc);
1646 return rc; 1648 return rc;
1647} 1649}
@@ -1661,21 +1663,17 @@ static int smack_file_receive(struct file *file)
1661static int smack_file_open(struct file *file, const struct cred *cred) 1663static int smack_file_open(struct file *file, const struct cred *cred)
1662{ 1664{
1663 struct task_smack *tsp = cred->security; 1665 struct task_smack *tsp = cred->security;
1664 struct inode_smack *isp = file_inode(file)->i_security; 1666 struct inode *inode = file_inode(file);
1665 struct smk_audit_info ad; 1667 struct smk_audit_info ad;
1666 int rc; 1668 int rc;
1667 1669
1668 if (smack_privileged(CAP_MAC_OVERRIDE)) { 1670 if (smack_privileged(CAP_MAC_OVERRIDE))
1669 file->f_security = isp->smk_inode;
1670 return 0; 1671 return 0;
1671 }
1672 1672
1673 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); 1673 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1674 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1674 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1675 rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad); 1675 rc = smk_access(tsp->smk_task, smk_of_inode(inode), MAY_READ, &ad);
1676 rc = smk_bu_credfile(cred, file, MAY_READ, rc); 1676 rc = smk_bu_credfile(cred, file, MAY_READ, rc);
1677 if (rc == 0)
1678 file->f_security = isp->smk_inode;
1679 1677
1680 return rc; 1678 return rc;
1681} 1679}