diff options
| author | James Morris <james.l.morris@oracle.com> | 2015-01-21 21:22:23 -0500 |
|---|---|---|
| committer | James Morris <james.l.morris@oracle.com> | 2015-01-21 21:22:23 -0500 |
| commit | 9d5a5f65fcabb876cb0092901d56627bd5cbfc44 (patch) | |
| tree | 475a0e28bd239d0f766e06f6bac669dfe662a42b | |
| parent | 743410a03bbf110da8942a715cf1358344ecc281 (diff) | |
| parent | 6d1cff2a885850b78b40c34777b46cf5da5d1050 (diff) | |
Merge branch 'smack-for-3.20-rebased' of git://git.gitorious.org/smack-next/kernel into next
| -rw-r--r-- | security/smack/Kconfig | 12 | ||||
| -rw-r--r-- | security/smack/Makefile | 1 | ||||
| -rw-r--r-- | security/smack/smack.h | 11 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 199 | ||||
| -rw-r--r-- | security/smack/smack_netfilter.c | 96 |
5 files changed, 267 insertions, 52 deletions
diff --git a/security/smack/Kconfig b/security/smack/Kconfig index b065f9789418..271adae81796 100644 --- a/security/smack/Kconfig +++ b/security/smack/Kconfig | |||
| @@ -28,3 +28,15 @@ config SECURITY_SMACK_BRINGUP | |||
| 28 | access rule set once the behavior is well understood. | 28 | access rule set once the behavior is well understood. |
| 29 | This is a superior mechanism to the oft abused | 29 | This is a superior mechanism to the oft abused |
| 30 | "permissive" mode of other systems. | 30 | "permissive" mode of other systems. |
| 31 | If you are unsure how to answer this question, answer N. | ||
| 32 | |||
| 33 | config SECURITY_SMACK_NETFILTER | ||
| 34 | bool "Packet marking using secmarks for netfilter" | ||
| 35 | depends on SECURITY_SMACK | ||
| 36 | depends on NETWORK_SECMARK | ||
| 37 | depends on NETFILTER | ||
| 38 | default n | ||
| 39 | help | ||
| 40 | This enables security marking of network packets using | ||
| 41 | Smack labels. | ||
| 42 | If you are unsure how to answer this question, answer N. | ||
diff --git a/security/smack/Makefile b/security/smack/Makefile index 67a63aaec827..616cf93b368e 100644 --- a/security/smack/Makefile +++ b/security/smack/Makefile | |||
| @@ -5,3 +5,4 @@ | |||
| 5 | obj-$(CONFIG_SECURITY_SMACK) := smack.o | 5 | obj-$(CONFIG_SECURITY_SMACK) := smack.o |
| 6 | 6 | ||
| 7 | smack-y := smack_lsm.o smack_access.o smackfs.o | 7 | smack-y := smack_lsm.o smack_access.o smackfs.o |
| 8 | smack-$(CONFIG_NETFILTER) += smack_netfilter.o | ||
diff --git a/security/smack/smack.h b/security/smack/smack.h index b828a379377c..67ccb7b2b89b 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
| @@ -248,6 +248,7 @@ struct smack_known *smk_find_entry(const char *); | |||
| 248 | /* | 248 | /* |
| 249 | * Shared data. | 249 | * Shared data. |
| 250 | */ | 250 | */ |
| 251 | extern int smack_enabled; | ||
| 251 | extern int smack_cipso_direct; | 252 | extern int smack_cipso_direct; |
| 252 | extern int smack_cipso_mapped; | 253 | extern int smack_cipso_mapped; |
| 253 | extern struct smack_known *smack_net_ambient; | 254 | extern struct smack_known *smack_net_ambient; |
| @@ -298,6 +299,16 @@ static inline struct smack_known *smk_of_task(const struct task_smack *tsp) | |||
| 298 | return tsp->smk_task; | 299 | return tsp->smk_task; |
| 299 | } | 300 | } |
| 300 | 301 | ||
| 302 | static inline struct smack_known *smk_of_task_struct(const struct task_struct *t) | ||
| 303 | { | ||
| 304 | struct smack_known *skp; | ||
| 305 | |||
| 306 | rcu_read_lock(); | ||
| 307 | skp = smk_of_task(__task_cred(t)->security); | ||
| 308 | rcu_read_unlock(); | ||
| 309 | return skp; | ||
| 310 | } | ||
| 311 | |||
| 301 | /* | 312 | /* |
| 302 | * Present a pointer to the forked smack label entry in an task blob. | 313 | * Present a pointer to the forked smack label entry in an task blob. |
| 303 | */ | 314 | */ |
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; |
diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c new file mode 100644 index 000000000000..c952632afb0d --- /dev/null +++ b/security/smack/smack_netfilter.c | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | /* | ||
| 2 | * Simplified MAC Kernel (smack) security module | ||
| 3 | * | ||
| 4 | * This file contains the Smack netfilter implementation | ||
| 5 | * | ||
| 6 | * Author: | ||
| 7 | * Casey Schaufler <casey@schaufler-ca.com> | ||
| 8 | * | ||
| 9 | * Copyright (C) 2014 Casey Schaufler <casey@schaufler-ca.com> | ||
| 10 | * Copyright (C) 2014 Intel Corporation. | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License version 2, | ||
| 14 | * as published by the Free Software Foundation. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/netfilter_ipv4.h> | ||
| 18 | #include <linux/netfilter_ipv6.h> | ||
| 19 | #include <linux/netdevice.h> | ||
| 20 | #include "smack.h" | ||
| 21 | |||
| 22 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 23 | |||
| 24 | static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, | ||
| 25 | struct sk_buff *skb, | ||
| 26 | const struct net_device *in, | ||
| 27 | const struct net_device *out, | ||
| 28 | int (*okfn)(struct sk_buff *)) | ||
| 29 | { | ||
| 30 | struct socket_smack *ssp; | ||
| 31 | struct smack_known *skp; | ||
| 32 | |||
| 33 | if (skb && skb->sk && skb->sk->sk_security) { | ||
| 34 | ssp = skb->sk->sk_security; | ||
| 35 | skp = ssp->smk_out; | ||
| 36 | skb->secmark = skp->smk_secid; | ||
| 37 | } | ||
| 38 | |||
| 39 | return NF_ACCEPT; | ||
| 40 | } | ||
| 41 | #endif /* IPV6 */ | ||
| 42 | |||
| 43 | static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops, | ||
| 44 | struct sk_buff *skb, | ||
| 45 | const struct net_device *in, | ||
| 46 | const struct net_device *out, | ||
| 47 | int (*okfn)(struct sk_buff *)) | ||
| 48 | { | ||
| 49 | struct socket_smack *ssp; | ||
| 50 | struct smack_known *skp; | ||
| 51 | |||
| 52 | if (skb && skb->sk && skb->sk->sk_security) { | ||
| 53 | ssp = skb->sk->sk_security; | ||
| 54 | skp = ssp->smk_out; | ||
| 55 | skb->secmark = skp->smk_secid; | ||
| 56 | } | ||
| 57 | |||
| 58 | return NF_ACCEPT; | ||
| 59 | } | ||
| 60 | |||
| 61 | static struct nf_hook_ops smack_nf_ops[] = { | ||
| 62 | { | ||
| 63 | .hook = smack_ipv4_output, | ||
| 64 | .owner = THIS_MODULE, | ||
| 65 | .pf = NFPROTO_IPV4, | ||
| 66 | .hooknum = NF_INET_LOCAL_OUT, | ||
| 67 | .priority = NF_IP_PRI_SELINUX_FIRST, | ||
| 68 | }, | ||
| 69 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 70 | { | ||
| 71 | .hook = smack_ipv6_output, | ||
| 72 | .owner = THIS_MODULE, | ||
| 73 | .pf = NFPROTO_IPV6, | ||
| 74 | .hooknum = NF_INET_LOCAL_OUT, | ||
| 75 | .priority = NF_IP6_PRI_SELINUX_FIRST, | ||
| 76 | }, | ||
| 77 | #endif /* IPV6 */ | ||
| 78 | }; | ||
| 79 | |||
| 80 | static int __init smack_nf_ip_init(void) | ||
| 81 | { | ||
| 82 | int err; | ||
| 83 | |||
| 84 | if (smack_enabled == 0) | ||
| 85 | return 0; | ||
| 86 | |||
| 87 | printk(KERN_DEBUG "Smack: Registering netfilter hooks\n"); | ||
| 88 | |||
| 89 | err = nf_register_hooks(smack_nf_ops, ARRAY_SIZE(smack_nf_ops)); | ||
| 90 | if (err) | ||
| 91 | pr_info("Smack: nf_register_hooks: error %d\n", err); | ||
| 92 | |||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | __initcall(smack_nf_ip_init); | ||
