diff options
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 199 |
1 files changed, 147 insertions, 52 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index f1b17a476e12..a0ccce4e46f8 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -43,8 +43,6 @@ | |||
43 | #include <linux/binfmts.h> | 43 | #include <linux/binfmts.h> |
44 | #include "smack.h" | 44 | #include "smack.h" |
45 | 45 | ||
46 | #define task_security(task) (task_cred_xxx((task), security)) | ||
47 | |||
48 | #define TRANS_TRUE "TRUE" | 46 | #define TRANS_TRUE "TRUE" |
49 | #define TRANS_TRUE_SIZE 4 | 47 | #define TRANS_TRUE_SIZE 4 |
50 | 48 | ||
@@ -52,8 +50,11 @@ | |||
52 | #define SMK_RECEIVING 1 | 50 | #define SMK_RECEIVING 1 |
53 | #define SMK_SENDING 2 | 51 | #define SMK_SENDING 2 |
54 | 52 | ||
53 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
55 | LIST_HEAD(smk_ipv6_port_list); | 54 | LIST_HEAD(smk_ipv6_port_list); |
55 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
56 | static struct kmem_cache *smack_inode_cache; | 56 | static struct kmem_cache *smack_inode_cache; |
57 | int smack_enabled; | ||
57 | 58 | ||
58 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP | 59 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP |
59 | static void smk_bu_mode(int mode, char *s) | 60 | static void smk_bu_mode(int mode, char *s) |
@@ -120,7 +121,7 @@ static int smk_bu_current(char *note, struct smack_known *oskp, | |||
120 | static int smk_bu_task(struct task_struct *otp, int mode, int rc) | 121 | static int smk_bu_task(struct task_struct *otp, int mode, int rc) |
121 | { | 122 | { |
122 | struct task_smack *tsp = current_security(); | 123 | struct task_smack *tsp = current_security(); |
123 | struct task_smack *otsp = task_security(otp); | 124 | struct smack_known *smk_task = smk_of_task_struct(otp); |
124 | char acc[SMK_NUM_ACCESS_TYPE + 1]; | 125 | char acc[SMK_NUM_ACCESS_TYPE + 1]; |
125 | 126 | ||
126 | if (rc <= 0) | 127 | if (rc <= 0) |
@@ -128,7 +129,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc) | |||
128 | 129 | ||
129 | smk_bu_mode(mode, acc); | 130 | smk_bu_mode(mode, acc); |
130 | pr_info("Smack Bringup: (%s %s %s) %s to %s\n", | 131 | pr_info("Smack Bringup: (%s %s %s) %s to %s\n", |
131 | tsp->smk_task->smk_known, otsp->smk_task->smk_known, acc, | 132 | tsp->smk_task->smk_known, smk_task->smk_known, acc, |
132 | current->comm, otp->comm); | 133 | current->comm, otp->comm); |
133 | return 0; | 134 | return 0; |
134 | } | 135 | } |
@@ -160,7 +161,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) | |||
160 | { | 161 | { |
161 | struct task_smack *tsp = current_security(); | 162 | struct task_smack *tsp = current_security(); |
162 | struct smack_known *sskp = tsp->smk_task; | 163 | struct smack_known *sskp = tsp->smk_task; |
163 | struct inode *inode = file->f_inode; | 164 | struct inode *inode = file_inode(file); |
164 | char acc[SMK_NUM_ACCESS_TYPE + 1]; | 165 | char acc[SMK_NUM_ACCESS_TYPE + 1]; |
165 | 166 | ||
166 | if (rc <= 0) | 167 | if (rc <= 0) |
@@ -168,7 +169,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) | |||
168 | 169 | ||
169 | smk_bu_mode(mode, acc); | 170 | smk_bu_mode(mode, acc); |
170 | pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", | 171 | pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", |
171 | sskp->smk_known, (char *)file->f_security, acc, | 172 | sskp->smk_known, smk_of_inode(inode)->smk_known, acc, |
172 | inode->i_sb->s_id, inode->i_ino, file, | 173 | inode->i_sb->s_id, inode->i_ino, file, |
173 | current->comm); | 174 | current->comm); |
174 | return 0; | 175 | return 0; |
@@ -202,6 +203,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, | |||
202 | 203 | ||
203 | /** | 204 | /** |
204 | * smk_fetch - Fetch the smack label from a file. | 205 | * smk_fetch - Fetch the smack label from a file. |
206 | * @name: type of the label (attribute) | ||
205 | * @ip: a pointer to the inode | 207 | * @ip: a pointer to the inode |
206 | * @dp: a pointer to the dentry | 208 | * @dp: a pointer to the dentry |
207 | * | 209 | * |
@@ -254,7 +256,9 @@ struct inode_smack *new_inode_smack(struct smack_known *skp) | |||
254 | 256 | ||
255 | /** | 257 | /** |
256 | * new_task_smack - allocate a task security blob | 258 | * new_task_smack - allocate a task security blob |
257 | * @smack: a pointer to the Smack label to use in the blob | 259 | * @task: a pointer to the Smack label for the running task |
260 | * @forked: a pointer to the Smack label for the forked task | ||
261 | * @gfp: type of the memory for the allocation | ||
258 | * | 262 | * |
259 | * Returns the new blob or NULL if there's no memory available | 263 | * Returns the new blob or NULL if there's no memory available |
260 | */ | 264 | */ |
@@ -277,8 +281,9 @@ static struct task_smack *new_task_smack(struct smack_known *task, | |||
277 | 281 | ||
278 | /** | 282 | /** |
279 | * smk_copy_rules - copy a rule set | 283 | * smk_copy_rules - copy a rule set |
280 | * @nhead - new rules header pointer | 284 | * @nhead: new rules header pointer |
281 | * @ohead - old rules header pointer | 285 | * @ohead: old rules header pointer |
286 | * @gfp: type of the memory for the allocation | ||
282 | * | 287 | * |
283 | * Returns 0 on success, -ENOMEM on error | 288 | * Returns 0 on success, -ENOMEM on error |
284 | */ | 289 | */ |
@@ -345,7 +350,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, | |||
345 | saip = &ad; | 350 | saip = &ad; |
346 | } | 351 | } |
347 | 352 | ||
348 | tsp = task_security(tracer); | 353 | rcu_read_lock(); |
354 | tsp = __task_cred(tracer)->security; | ||
349 | tracer_known = smk_of_task(tsp); | 355 | tracer_known = smk_of_task(tsp); |
350 | 356 | ||
351 | if ((mode & PTRACE_MODE_ATTACH) && | 357 | if ((mode & PTRACE_MODE_ATTACH) && |
@@ -365,11 +371,14 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, | |||
365 | tracee_known->smk_known, | 371 | tracee_known->smk_known, |
366 | 0, rc, saip); | 372 | 0, rc, saip); |
367 | 373 | ||
374 | rcu_read_unlock(); | ||
368 | return rc; | 375 | return rc; |
369 | } | 376 | } |
370 | 377 | ||
371 | /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ | 378 | /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ |
372 | rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip); | 379 | rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip); |
380 | |||
381 | rcu_read_unlock(); | ||
373 | return rc; | 382 | return rc; |
374 | } | 383 | } |
375 | 384 | ||
@@ -396,7 +405,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) | |||
396 | if (rc != 0) | 405 | if (rc != 0) |
397 | return rc; | 406 | return rc; |
398 | 407 | ||
399 | skp = smk_of_task(task_security(ctp)); | 408 | skp = smk_of_task_struct(ctp); |
400 | 409 | ||
401 | rc = smk_ptrace_rule_check(current, skp, mode, __func__); | 410 | rc = smk_ptrace_rule_check(current, skp, mode, __func__); |
402 | return rc; | 411 | return rc; |
@@ -796,7 +805,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, | |||
796 | if (name) | 805 | if (name) |
797 | *name = XATTR_SMACK_SUFFIX; | 806 | *name = XATTR_SMACK_SUFFIX; |
798 | 807 | ||
799 | if (value) { | 808 | if (value && len) { |
800 | rcu_read_lock(); | 809 | rcu_read_lock(); |
801 | may = smk_access_entry(skp->smk_known, dsp->smk_known, | 810 | may = smk_access_entry(skp->smk_known, dsp->smk_known, |
802 | &skp->smk_rules); | 811 | &skp->smk_rules); |
@@ -817,10 +826,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, | |||
817 | *value = kstrdup(isp->smk_known, GFP_NOFS); | 826 | *value = kstrdup(isp->smk_known, GFP_NOFS); |
818 | if (*value == NULL) | 827 | if (*value == NULL) |
819 | return -ENOMEM; | 828 | return -ENOMEM; |
820 | } | ||
821 | 829 | ||
822 | if (len) | ||
823 | *len = strlen(isp->smk_known); | 830 | *len = strlen(isp->smk_known); |
831 | } | ||
824 | 832 | ||
825 | return 0; | 833 | return 0; |
826 | } | 834 | } |
@@ -1344,6 +1352,9 @@ static int smack_file_permission(struct file *file, int mask) | |||
1344 | * The security blob for a file is a pointer to the master | 1352 | * The security blob for a file is a pointer to the master |
1345 | * label list, so no allocation is done. | 1353 | * label list, so no allocation is done. |
1346 | * | 1354 | * |
1355 | * f_security is the owner security information. It | ||
1356 | * isn't used on file access checks, it's for send_sigio. | ||
1357 | * | ||
1347 | * Returns 0 | 1358 | * Returns 0 |
1348 | */ | 1359 | */ |
1349 | static int smack_file_alloc_security(struct file *file) | 1360 | static int smack_file_alloc_security(struct file *file) |
@@ -1381,17 +1392,18 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, | |||
1381 | { | 1392 | { |
1382 | int rc = 0; | 1393 | int rc = 0; |
1383 | struct smk_audit_info ad; | 1394 | struct smk_audit_info ad; |
1395 | struct inode *inode = file_inode(file); | ||
1384 | 1396 | ||
1385 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1397 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
1386 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | 1398 | smk_ad_setfield_u_fs_path(&ad, file->f_path); |
1387 | 1399 | ||
1388 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | 1400 | if (_IOC_DIR(cmd) & _IOC_WRITE) { |
1389 | rc = smk_curacc(file->f_security, MAY_WRITE, &ad); | 1401 | rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad); |
1390 | rc = smk_bu_file(file, MAY_WRITE, rc); | 1402 | rc = smk_bu_file(file, MAY_WRITE, rc); |
1391 | } | 1403 | } |
1392 | 1404 | ||
1393 | if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) { | 1405 | if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) { |
1394 | rc = smk_curacc(file->f_security, MAY_READ, &ad); | 1406 | rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad); |
1395 | rc = smk_bu_file(file, MAY_READ, rc); | 1407 | rc = smk_bu_file(file, MAY_READ, rc); |
1396 | } | 1408 | } |
1397 | 1409 | ||
@@ -1409,10 +1421,11 @@ static int smack_file_lock(struct file *file, unsigned int cmd) | |||
1409 | { | 1421 | { |
1410 | struct smk_audit_info ad; | 1422 | struct smk_audit_info ad; |
1411 | int rc; | 1423 | int rc; |
1424 | struct inode *inode = file_inode(file); | ||
1412 | 1425 | ||
1413 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1426 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
1414 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | 1427 | smk_ad_setfield_u_fs_path(&ad, file->f_path); |
1415 | rc = smk_curacc(file->f_security, MAY_LOCK, &ad); | 1428 | rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad); |
1416 | rc = smk_bu_file(file, MAY_LOCK, rc); | 1429 | rc = smk_bu_file(file, MAY_LOCK, rc); |
1417 | return rc; | 1430 | return rc; |
1418 | } | 1431 | } |
@@ -1434,7 +1447,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, | |||
1434 | { | 1447 | { |
1435 | struct smk_audit_info ad; | 1448 | struct smk_audit_info ad; |
1436 | int rc = 0; | 1449 | int rc = 0; |
1437 | 1450 | struct inode *inode = file_inode(file); | |
1438 | 1451 | ||
1439 | switch (cmd) { | 1452 | switch (cmd) { |
1440 | case F_GETLK: | 1453 | case F_GETLK: |
@@ -1443,14 +1456,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, | |||
1443 | case F_SETLKW: | 1456 | case F_SETLKW: |
1444 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1457 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
1445 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | 1458 | smk_ad_setfield_u_fs_path(&ad, file->f_path); |
1446 | rc = smk_curacc(file->f_security, MAY_LOCK, &ad); | 1459 | rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad); |
1447 | rc = smk_bu_file(file, MAY_LOCK, rc); | 1460 | rc = smk_bu_file(file, MAY_LOCK, rc); |
1448 | break; | 1461 | break; |
1449 | case F_SETOWN: | 1462 | case F_SETOWN: |
1450 | case F_SETSIG: | 1463 | case F_SETSIG: |
1451 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1464 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
1452 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | 1465 | smk_ad_setfield_u_fs_path(&ad, file->f_path); |
1453 | rc = smk_curacc(file->f_security, MAY_WRITE, &ad); | 1466 | rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad); |
1454 | rc = smk_bu_file(file, MAY_WRITE, rc); | 1467 | rc = smk_bu_file(file, MAY_WRITE, rc); |
1455 | break; | 1468 | break; |
1456 | default: | 1469 | default: |
@@ -1568,14 +1581,10 @@ static int smack_mmap_file(struct file *file, | |||
1568 | * smack_file_set_fowner - set the file security blob value | 1581 | * smack_file_set_fowner - set the file security blob value |
1569 | * @file: object in question | 1582 | * @file: object in question |
1570 | * | 1583 | * |
1571 | * Returns 0 | ||
1572 | * Further research may be required on this one. | ||
1573 | */ | 1584 | */ |
1574 | static void smack_file_set_fowner(struct file *file) | 1585 | static void smack_file_set_fowner(struct file *file) |
1575 | { | 1586 | { |
1576 | struct smack_known *skp = smk_of_current(); | 1587 | file->f_security = smk_of_current(); |
1577 | |||
1578 | file->f_security = skp; | ||
1579 | } | 1588 | } |
1580 | 1589 | ||
1581 | /** | 1590 | /** |
@@ -1627,6 +1636,7 @@ static int smack_file_receive(struct file *file) | |||
1627 | int rc; | 1636 | int rc; |
1628 | int may = 0; | 1637 | int may = 0; |
1629 | struct smk_audit_info ad; | 1638 | struct smk_audit_info ad; |
1639 | struct inode *inode = file_inode(file); | ||
1630 | 1640 | ||
1631 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1641 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
1632 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | 1642 | smk_ad_setfield_u_fs_path(&ad, file->f_path); |
@@ -1638,7 +1648,7 @@ static int smack_file_receive(struct file *file) | |||
1638 | if (file->f_mode & FMODE_WRITE) | 1648 | if (file->f_mode & FMODE_WRITE) |
1639 | may |= MAY_WRITE; | 1649 | may |= MAY_WRITE; |
1640 | 1650 | ||
1641 | rc = smk_curacc(file->f_security, may, &ad); | 1651 | rc = smk_curacc(smk_of_inode(inode), may, &ad); |
1642 | rc = smk_bu_file(file, may, rc); | 1652 | rc = smk_bu_file(file, may, rc); |
1643 | return rc; | 1653 | return rc; |
1644 | } | 1654 | } |
@@ -1658,21 +1668,17 @@ static int smack_file_receive(struct file *file) | |||
1658 | static int smack_file_open(struct file *file, const struct cred *cred) | 1668 | static int smack_file_open(struct file *file, const struct cred *cred) |
1659 | { | 1669 | { |
1660 | struct task_smack *tsp = cred->security; | 1670 | struct task_smack *tsp = cred->security; |
1661 | struct inode_smack *isp = file_inode(file)->i_security; | 1671 | struct inode *inode = file_inode(file); |
1662 | struct smk_audit_info ad; | 1672 | struct smk_audit_info ad; |
1663 | int rc; | 1673 | int rc; |
1664 | 1674 | ||
1665 | if (smack_privileged(CAP_MAC_OVERRIDE)) { | 1675 | if (smack_privileged(CAP_MAC_OVERRIDE)) |
1666 | file->f_security = isp->smk_inode; | ||
1667 | return 0; | 1676 | return 0; |
1668 | } | ||
1669 | 1677 | ||
1670 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); | 1678 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); |
1671 | smk_ad_setfield_u_fs_path(&ad, file->f_path); | 1679 | smk_ad_setfield_u_fs_path(&ad, file->f_path); |
1672 | rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad); | 1680 | rc = smk_access(tsp->smk_task, smk_of_inode(inode), MAY_READ, &ad); |
1673 | rc = smk_bu_credfile(cred, file, MAY_READ, rc); | 1681 | rc = smk_bu_credfile(cred, file, MAY_READ, rc); |
1674 | if (rc == 0) | ||
1675 | file->f_security = isp->smk_inode; | ||
1676 | 1682 | ||
1677 | return rc; | 1683 | return rc; |
1678 | } | 1684 | } |
@@ -1826,7 +1832,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access, | |||
1826 | const char *caller) | 1832 | const char *caller) |
1827 | { | 1833 | { |
1828 | struct smk_audit_info ad; | 1834 | struct smk_audit_info ad; |
1829 | struct smack_known *skp = smk_of_task(task_security(p)); | 1835 | struct smack_known *skp = smk_of_task_struct(p); |
1830 | int rc; | 1836 | int rc; |
1831 | 1837 | ||
1832 | smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); | 1838 | smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); |
@@ -1879,7 +1885,7 @@ static int smack_task_getsid(struct task_struct *p) | |||
1879 | */ | 1885 | */ |
1880 | static void smack_task_getsecid(struct task_struct *p, u32 *secid) | 1886 | static void smack_task_getsecid(struct task_struct *p, u32 *secid) |
1881 | { | 1887 | { |
1882 | struct smack_known *skp = smk_of_task(task_security(p)); | 1888 | struct smack_known *skp = smk_of_task_struct(p); |
1883 | 1889 | ||
1884 | *secid = skp->smk_secid; | 1890 | *secid = skp->smk_secid; |
1885 | } | 1891 | } |
@@ -1986,7 +1992,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, | |||
1986 | { | 1992 | { |
1987 | struct smk_audit_info ad; | 1993 | struct smk_audit_info ad; |
1988 | struct smack_known *skp; | 1994 | struct smack_known *skp; |
1989 | struct smack_known *tkp = smk_of_task(task_security(p)); | 1995 | struct smack_known *tkp = smk_of_task_struct(p); |
1990 | int rc; | 1996 | int rc; |
1991 | 1997 | ||
1992 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); | 1998 | smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); |
@@ -2040,7 +2046,7 @@ static int smack_task_wait(struct task_struct *p) | |||
2040 | static void smack_task_to_inode(struct task_struct *p, struct inode *inode) | 2046 | static void smack_task_to_inode(struct task_struct *p, struct inode *inode) |
2041 | { | 2047 | { |
2042 | struct inode_smack *isp = inode->i_security; | 2048 | struct inode_smack *isp = inode->i_security; |
2043 | struct smack_known *skp = smk_of_task(task_security(p)); | 2049 | struct smack_known *skp = smk_of_task_struct(p); |
2044 | 2050 | ||
2045 | isp->smk_inode = skp; | 2051 | isp->smk_inode = skp; |
2046 | } | 2052 | } |
@@ -2212,6 +2218,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) | |||
2212 | return smack_netlabel(sk, sk_lbl); | 2218 | return smack_netlabel(sk, sk_lbl); |
2213 | } | 2219 | } |
2214 | 2220 | ||
2221 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
2215 | /** | 2222 | /** |
2216 | * smk_ipv6_port_label - Smack port access table management | 2223 | * smk_ipv6_port_label - Smack port access table management |
2217 | * @sock: socket | 2224 | * @sock: socket |
@@ -2361,6 +2368,7 @@ auditout: | |||
2361 | rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); | 2368 | rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); |
2362 | return rc; | 2369 | return rc; |
2363 | } | 2370 | } |
2371 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
2364 | 2372 | ||
2365 | /** | 2373 | /** |
2366 | * smack_inode_setsecurity - set smack xattrs | 2374 | * smack_inode_setsecurity - set smack xattrs |
@@ -2421,8 +2429,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
2421 | } else | 2429 | } else |
2422 | return -EOPNOTSUPP; | 2430 | return -EOPNOTSUPP; |
2423 | 2431 | ||
2432 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
2424 | if (sock->sk->sk_family == PF_INET6) | 2433 | if (sock->sk->sk_family == PF_INET6) |
2425 | smk_ipv6_port_label(sock, NULL); | 2434 | smk_ipv6_port_label(sock, NULL); |
2435 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
2426 | 2436 | ||
2427 | return 0; | 2437 | return 0; |
2428 | } | 2438 | } |
@@ -2450,6 +2460,7 @@ static int smack_socket_post_create(struct socket *sock, int family, | |||
2450 | return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); | 2460 | return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); |
2451 | } | 2461 | } |
2452 | 2462 | ||
2463 | #ifndef CONFIG_SECURITY_SMACK_NETFILTER | ||
2453 | /** | 2464 | /** |
2454 | * smack_socket_bind - record port binding information. | 2465 | * smack_socket_bind - record port binding information. |
2455 | * @sock: the socket | 2466 | * @sock: the socket |
@@ -2463,11 +2474,14 @@ static int smack_socket_post_create(struct socket *sock, int family, | |||
2463 | static int smack_socket_bind(struct socket *sock, struct sockaddr *address, | 2474 | static int smack_socket_bind(struct socket *sock, struct sockaddr *address, |
2464 | int addrlen) | 2475 | int addrlen) |
2465 | { | 2476 | { |
2477 | #if IS_ENABLED(CONFIG_IPV6) | ||
2466 | if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) | 2478 | if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) |
2467 | smk_ipv6_port_label(sock, address); | 2479 | smk_ipv6_port_label(sock, address); |
2480 | #endif | ||
2468 | 2481 | ||
2469 | return 0; | 2482 | return 0; |
2470 | } | 2483 | } |
2484 | #endif /* !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
2471 | 2485 | ||
2472 | /** | 2486 | /** |
2473 | * smack_socket_connect - connect access check | 2487 | * smack_socket_connect - connect access check |
@@ -2496,8 +2510,10 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, | |||
2496 | case PF_INET6: | 2510 | case PF_INET6: |
2497 | if (addrlen < sizeof(struct sockaddr_in6)) | 2511 | if (addrlen < sizeof(struct sockaddr_in6)) |
2498 | return -EINVAL; | 2512 | return -EINVAL; |
2513 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
2499 | rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, | 2514 | rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, |
2500 | SMK_CONNECTING); | 2515 | SMK_CONNECTING); |
2516 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
2501 | break; | 2517 | break; |
2502 | } | 2518 | } |
2503 | return rc; | 2519 | return rc; |
@@ -3033,7 +3049,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
3033 | * of the superblock. | 3049 | * of the superblock. |
3034 | */ | 3050 | */ |
3035 | if (opt_dentry->d_parent == opt_dentry) { | 3051 | if (opt_dentry->d_parent == opt_dentry) { |
3036 | if (sbp->s_magic == CGROUP_SUPER_MAGIC) { | 3052 | switch (sbp->s_magic) { |
3053 | case CGROUP_SUPER_MAGIC: | ||
3037 | /* | 3054 | /* |
3038 | * The cgroup filesystem is never mounted, | 3055 | * The cgroup filesystem is never mounted, |
3039 | * so there's no opportunity to set the mount | 3056 | * so there's no opportunity to set the mount |
@@ -3041,8 +3058,19 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) | |||
3041 | */ | 3058 | */ |
3042 | sbsp->smk_root = &smack_known_star; | 3059 | sbsp->smk_root = &smack_known_star; |
3043 | sbsp->smk_default = &smack_known_star; | 3060 | sbsp->smk_default = &smack_known_star; |
3061 | isp->smk_inode = sbsp->smk_root; | ||
3062 | break; | ||
3063 | case TMPFS_MAGIC: | ||
3064 | /* | ||
3065 | * What about shmem/tmpfs anonymous files with dentry | ||
3066 | * obtained from d_alloc_pseudo()? | ||
3067 | */ | ||
3068 | isp->smk_inode = smk_of_current(); | ||
3069 | break; | ||
3070 | default: | ||
3071 | isp->smk_inode = sbsp->smk_root; | ||
3072 | break; | ||
3044 | } | 3073 | } |
3045 | isp->smk_inode = sbsp->smk_root; | ||
3046 | isp->smk_flags |= SMK_INODE_INSTANT; | 3074 | isp->smk_flags |= SMK_INODE_INSTANT; |
3047 | goto unlockandout; | 3075 | goto unlockandout; |
3048 | } | 3076 | } |
@@ -3200,7 +3228,7 @@ unlockandout: | |||
3200 | */ | 3228 | */ |
3201 | static int smack_getprocattr(struct task_struct *p, char *name, char **value) | 3229 | static int smack_getprocattr(struct task_struct *p, char *name, char **value) |
3202 | { | 3230 | { |
3203 | struct smack_known *skp = smk_of_task(task_security(p)); | 3231 | struct smack_known *skp = smk_of_task_struct(p); |
3204 | char *cp; | 3232 | char *cp; |
3205 | int slen; | 3233 | int slen; |
3206 | 3234 | ||
@@ -3297,7 +3325,7 @@ static int smack_unix_stream_connect(struct sock *sock, | |||
3297 | 3325 | ||
3298 | if (!smack_privileged(CAP_MAC_OVERRIDE)) { | 3326 | if (!smack_privileged(CAP_MAC_OVERRIDE)) { |
3299 | skp = ssp->smk_out; | 3327 | skp = ssp->smk_out; |
3300 | okp = osp->smk_out; | 3328 | okp = osp->smk_in; |
3301 | #ifdef CONFIG_AUDIT | 3329 | #ifdef CONFIG_AUDIT |
3302 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); | 3330 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); |
3303 | smk_ad_setfield_u_net_sk(&ad, other); | 3331 | smk_ad_setfield_u_net_sk(&ad, other); |
@@ -3305,7 +3333,9 @@ static int smack_unix_stream_connect(struct sock *sock, | |||
3305 | rc = smk_access(skp, okp, MAY_WRITE, &ad); | 3333 | rc = smk_access(skp, okp, MAY_WRITE, &ad); |
3306 | rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc); | 3334 | rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc); |
3307 | if (rc == 0) { | 3335 | if (rc == 0) { |
3308 | rc = smk_access(okp, skp, MAY_WRITE, NULL); | 3336 | okp = osp->smk_out; |
3337 | skp = ssp->smk_in; | ||
3338 | rc = smk_access(okp, skp, MAY_WRITE, &ad); | ||
3309 | rc = smk_bu_note("UDS connect", okp, skp, | 3339 | rc = smk_bu_note("UDS connect", okp, skp, |
3310 | MAY_WRITE, rc); | 3340 | MAY_WRITE, rc); |
3311 | } | 3341 | } |
@@ -3366,7 +3396,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, | |||
3366 | int size) | 3396 | int size) |
3367 | { | 3397 | { |
3368 | struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; | 3398 | struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; |
3399 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
3369 | struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; | 3400 | struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; |
3401 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3370 | int rc = 0; | 3402 | int rc = 0; |
3371 | 3403 | ||
3372 | /* | 3404 | /* |
@@ -3380,7 +3412,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, | |||
3380 | rc = smack_netlabel_send(sock->sk, sip); | 3412 | rc = smack_netlabel_send(sock->sk, sip); |
3381 | break; | 3413 | break; |
3382 | case AF_INET6: | 3414 | case AF_INET6: |
3415 | #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) | ||
3383 | rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); | 3416 | rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); |
3417 | #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3384 | break; | 3418 | break; |
3385 | } | 3419 | } |
3386 | return rc; | 3420 | return rc; |
@@ -3471,6 +3505,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, | |||
3471 | return smack_net_ambient; | 3505 | return smack_net_ambient; |
3472 | } | 3506 | } |
3473 | 3507 | ||
3508 | #if IS_ENABLED(CONFIG_IPV6) | ||
3474 | static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) | 3509 | static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) |
3475 | { | 3510 | { |
3476 | u8 nexthdr; | 3511 | u8 nexthdr; |
@@ -3517,6 +3552,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) | |||
3517 | } | 3552 | } |
3518 | return proto; | 3553 | return proto; |
3519 | } | 3554 | } |
3555 | #endif /* CONFIG_IPV6 */ | ||
3520 | 3556 | ||
3521 | /** | 3557 | /** |
3522 | * smack_socket_sock_rcv_skb - Smack packet delivery access check | 3558 | * smack_socket_sock_rcv_skb - Smack packet delivery access check |
@@ -3529,15 +3565,30 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3529 | { | 3565 | { |
3530 | struct netlbl_lsm_secattr secattr; | 3566 | struct netlbl_lsm_secattr secattr; |
3531 | struct socket_smack *ssp = sk->sk_security; | 3567 | struct socket_smack *ssp = sk->sk_security; |
3532 | struct smack_known *skp; | 3568 | struct smack_known *skp = NULL; |
3533 | struct sockaddr_in6 sadd; | ||
3534 | int rc = 0; | 3569 | int rc = 0; |
3535 | struct smk_audit_info ad; | 3570 | struct smk_audit_info ad; |
3536 | #ifdef CONFIG_AUDIT | 3571 | #ifdef CONFIG_AUDIT |
3537 | struct lsm_network_audit net; | 3572 | struct lsm_network_audit net; |
3538 | #endif | 3573 | #endif |
3574 | #if IS_ENABLED(CONFIG_IPV6) | ||
3575 | struct sockaddr_in6 sadd; | ||
3576 | int proto; | ||
3577 | #endif /* CONFIG_IPV6 */ | ||
3578 | |||
3539 | switch (sk->sk_family) { | 3579 | switch (sk->sk_family) { |
3540 | case PF_INET: | 3580 | case PF_INET: |
3581 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3582 | /* | ||
3583 | * If there is a secmark use it rather than the CIPSO label. | ||
3584 | * If there is no secmark fall back to CIPSO. | ||
3585 | * The secmark is assumed to reflect policy better. | ||
3586 | */ | ||
3587 | if (skb && skb->secmark != 0) { | ||
3588 | skp = smack_from_secid(skb->secmark); | ||
3589 | goto access_check; | ||
3590 | } | ||
3591 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3541 | /* | 3592 | /* |
3542 | * Translate what netlabel gave us. | 3593 | * Translate what netlabel gave us. |
3543 | */ | 3594 | */ |
@@ -3551,6 +3602,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3551 | 3602 | ||
3552 | netlbl_secattr_destroy(&secattr); | 3603 | netlbl_secattr_destroy(&secattr); |
3553 | 3604 | ||
3605 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3606 | access_check: | ||
3607 | #endif | ||
3554 | #ifdef CONFIG_AUDIT | 3608 | #ifdef CONFIG_AUDIT |
3555 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); | 3609 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); |
3556 | ad.a.u.net->family = sk->sk_family; | 3610 | ad.a.u.net->family = sk->sk_family; |
@@ -3569,14 +3623,32 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3569 | if (rc != 0) | 3623 | if (rc != 0) |
3570 | netlbl_skbuff_err(skb, rc, 0); | 3624 | netlbl_skbuff_err(skb, rc, 0); |
3571 | break; | 3625 | break; |
3626 | #if IS_ENABLED(CONFIG_IPV6) | ||
3572 | case PF_INET6: | 3627 | case PF_INET6: |
3573 | rc = smk_skb_to_addr_ipv6(skb, &sadd); | 3628 | proto = smk_skb_to_addr_ipv6(skb, &sadd); |
3574 | if (rc == IPPROTO_UDP || rc == IPPROTO_TCP) | 3629 | if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) |
3575 | rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); | 3630 | break; |
3631 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3632 | if (skb && skb->secmark != 0) | ||
3633 | skp = smack_from_secid(skb->secmark); | ||
3576 | else | 3634 | else |
3577 | rc = 0; | 3635 | skp = smack_net_ambient; |
3636 | #ifdef CONFIG_AUDIT | ||
3637 | smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); | ||
3638 | ad.a.u.net->family = sk->sk_family; | ||
3639 | ad.a.u.net->netif = skb->skb_iif; | ||
3640 | ipv6_skb_to_auditdata(skb, &ad.a, NULL); | ||
3641 | #endif /* CONFIG_AUDIT */ | ||
3642 | rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); | ||
3643 | rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in, | ||
3644 | MAY_WRITE, rc); | ||
3645 | #else /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3646 | rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); | ||
3647 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3578 | break; | 3648 | break; |
3649 | #endif /* CONFIG_IPV6 */ | ||
3579 | } | 3650 | } |
3651 | |||
3580 | return rc; | 3652 | return rc; |
3581 | } | 3653 | } |
3582 | 3654 | ||
@@ -3638,16 +3710,25 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, | |||
3638 | if (skb != NULL) { | 3710 | if (skb != NULL) { |
3639 | if (skb->protocol == htons(ETH_P_IP)) | 3711 | if (skb->protocol == htons(ETH_P_IP)) |
3640 | family = PF_INET; | 3712 | family = PF_INET; |
3713 | #if IS_ENABLED(CONFIG_IPV6) | ||
3641 | else if (skb->protocol == htons(ETH_P_IPV6)) | 3714 | else if (skb->protocol == htons(ETH_P_IPV6)) |
3642 | family = PF_INET6; | 3715 | family = PF_INET6; |
3716 | #endif /* CONFIG_IPV6 */ | ||
3643 | } | 3717 | } |
3644 | if (family == PF_UNSPEC && sock != NULL) | 3718 | if (family == PF_UNSPEC && sock != NULL) |
3645 | family = sock->sk->sk_family; | 3719 | family = sock->sk->sk_family; |
3646 | 3720 | ||
3647 | if (family == PF_UNIX) { | 3721 | switch (family) { |
3722 | case PF_UNIX: | ||
3648 | ssp = sock->sk->sk_security; | 3723 | ssp = sock->sk->sk_security; |
3649 | s = ssp->smk_out->smk_secid; | 3724 | s = ssp->smk_out->smk_secid; |
3650 | } else if (family == PF_INET || family == PF_INET6) { | 3725 | break; |
3726 | case PF_INET: | ||
3727 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3728 | s = skb->secmark; | ||
3729 | if (s != 0) | ||
3730 | break; | ||
3731 | #endif | ||
3651 | /* | 3732 | /* |
3652 | * Translate what netlabel gave us. | 3733 | * Translate what netlabel gave us. |
3653 | */ | 3734 | */ |
@@ -3660,6 +3741,14 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, | |||
3660 | s = skp->smk_secid; | 3741 | s = skp->smk_secid; |
3661 | } | 3742 | } |
3662 | netlbl_secattr_destroy(&secattr); | 3743 | netlbl_secattr_destroy(&secattr); |
3744 | break; | ||
3745 | #if IS_ENABLED(CONFIG_IPV6) | ||
3746 | case PF_INET6: | ||
3747 | #ifdef CONFIG_SECURITY_SMACK_NETFILTER | ||
3748 | s = skb->secmark; | ||
3749 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
3750 | break; | ||
3751 | #endif /* CONFIG_IPV6 */ | ||
3663 | } | 3752 | } |
3664 | *secid = s; | 3753 | *secid = s; |
3665 | if (s == 0) | 3754 | if (s == 0) |
@@ -3715,6 +3804,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
3715 | struct lsm_network_audit net; | 3804 | struct lsm_network_audit net; |
3716 | #endif | 3805 | #endif |
3717 | 3806 | ||
3807 | #if IS_ENABLED(CONFIG_IPV6) | ||
3718 | if (family == PF_INET6) { | 3808 | if (family == PF_INET6) { |
3719 | /* | 3809 | /* |
3720 | * Handle mapped IPv4 packets arriving | 3810 | * Handle mapped IPv4 packets arriving |
@@ -3726,6 +3816,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, | |||
3726 | else | 3816 | else |
3727 | return 0; | 3817 | return 0; |
3728 | } | 3818 | } |
3819 | #endif /* CONFIG_IPV6 */ | ||
3729 | 3820 | ||
3730 | netlbl_secattr_init(&secattr); | 3821 | netlbl_secattr_init(&secattr); |
3731 | rc = netlbl_skbuff_getattr(skb, family, &secattr); | 3822 | rc = netlbl_skbuff_getattr(skb, family, &secattr); |
@@ -3834,11 +3925,11 @@ static void smack_key_free(struct key *key) | |||
3834 | key->security = NULL; | 3925 | key->security = NULL; |
3835 | } | 3926 | } |
3836 | 3927 | ||
3837 | /* | 3928 | /** |
3838 | * smack_key_permission - Smack access on a key | 3929 | * smack_key_permission - Smack access on a key |
3839 | * @key_ref: gets to the object | 3930 | * @key_ref: gets to the object |
3840 | * @cred: the credentials to use | 3931 | * @cred: the credentials to use |
3841 | * @perm: unused | 3932 | * @perm: requested key permissions |
3842 | * | 3933 | * |
3843 | * Return 0 if the task has read and write to the object, | 3934 | * Return 0 if the task has read and write to the object, |
3844 | * an error code otherwise | 3935 | * an error code otherwise |
@@ -4184,7 +4275,9 @@ struct security_operations smack_ops = { | |||
4184 | .unix_may_send = smack_unix_may_send, | 4275 | .unix_may_send = smack_unix_may_send, |
4185 | 4276 | ||
4186 | .socket_post_create = smack_socket_post_create, | 4277 | .socket_post_create = smack_socket_post_create, |
4278 | #ifndef CONFIG_SECURITY_SMACK_NETFILTER | ||
4187 | .socket_bind = smack_socket_bind, | 4279 | .socket_bind = smack_socket_bind, |
4280 | #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ | ||
4188 | .socket_connect = smack_socket_connect, | 4281 | .socket_connect = smack_socket_connect, |
4189 | .socket_sendmsg = smack_socket_sendmsg, | 4282 | .socket_sendmsg = smack_socket_sendmsg, |
4190 | .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, | 4283 | .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, |
@@ -4265,6 +4358,8 @@ static __init int smack_init(void) | |||
4265 | if (!security_module_enable(&smack_ops)) | 4358 | if (!security_module_enable(&smack_ops)) |
4266 | return 0; | 4359 | return 0; |
4267 | 4360 | ||
4361 | smack_enabled = 1; | ||
4362 | |||
4268 | smack_inode_cache = KMEM_CACHE(inode_smack, 0); | 4363 | smack_inode_cache = KMEM_CACHE(inode_smack, 0); |
4269 | if (!smack_inode_cache) | 4364 | if (!smack_inode_cache) |
4270 | return -ENOMEM; | 4365 | return -ENOMEM; |