aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/auditsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r--kernel/auditsc.c142
1 files changed, 134 insertions, 8 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 31917ac730af..4e2256ec7cf3 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -34,6 +34,9 @@
34 * 34 *
35 * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional 35 * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional
36 * filesystem information. 36 * filesystem information.
37 *
38 * Subject and object context labeling support added by <danjones@us.ibm.com>
39 * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance.
37 */ 40 */
38 41
39#include <linux/init.h> 42#include <linux/init.h>
@@ -53,6 +56,7 @@
53#include <linux/netlink.h> 56#include <linux/netlink.h>
54#include <linux/compiler.h> 57#include <linux/compiler.h>
55#include <asm/unistd.h> 58#include <asm/unistd.h>
59#include <linux/security.h>
56 60
57/* 0 = no checking 61/* 0 = no checking
58 1 = put_count checking 62 1 = put_count checking
@@ -109,6 +113,7 @@ struct audit_names {
109 uid_t uid; 113 uid_t uid;
110 gid_t gid; 114 gid_t gid;
111 dev_t rdev; 115 dev_t rdev;
116 char *ctx;
112}; 117};
113 118
114struct audit_aux_data { 119struct audit_aux_data {
@@ -125,6 +130,7 @@ struct audit_aux_data_ipcctl {
125 uid_t uid; 130 uid_t uid;
126 gid_t gid; 131 gid_t gid;
127 mode_t mode; 132 mode_t mode;
133 char *ctx;
128}; 134};
129 135
130struct audit_aux_data_socketcall { 136struct audit_aux_data_socketcall {
@@ -743,10 +749,11 @@ static inline void audit_free_names(struct audit_context *context)
743 context->serial, context->major, context->in_syscall, 749 context->serial, context->major, context->in_syscall,
744 context->name_count, context->put_count, 750 context->name_count, context->put_count,
745 context->ino_count); 751 context->ino_count);
746 for (i = 0; i < context->name_count; i++) 752 for (i = 0; i < context->name_count; i++) {
747 printk(KERN_ERR "names[%d] = %p = %s\n", i, 753 printk(KERN_ERR "names[%d] = %p = %s\n", i,
748 context->names[i].name, 754 context->names[i].name,
749 context->names[i].name ?: "(null)"); 755 context->names[i].name ?: "(null)");
756 }
750 dump_stack(); 757 dump_stack();
751 return; 758 return;
752 } 759 }
@@ -756,9 +763,13 @@ static inline void audit_free_names(struct audit_context *context)
756 context->ino_count = 0; 763 context->ino_count = 0;
757#endif 764#endif
758 765
759 for (i = 0; i < context->name_count; i++) 766 for (i = 0; i < context->name_count; i++) {
767 char *p = context->names[i].ctx;
768 context->names[i].ctx = NULL;
769 kfree(p);
760 if (context->names[i].name) 770 if (context->names[i].name)
761 __putname(context->names[i].name); 771 __putname(context->names[i].name);
772 }
762 context->name_count = 0; 773 context->name_count = 0;
763 if (context->pwd) 774 if (context->pwd)
764 dput(context->pwd); 775 dput(context->pwd);
@@ -778,6 +789,12 @@ static inline void audit_free_aux(struct audit_context *context)
778 dput(axi->dentry); 789 dput(axi->dentry);
779 mntput(axi->mnt); 790 mntput(axi->mnt);
780 } 791 }
792 if ( aux->type == AUDIT_IPC ) {
793 struct audit_aux_data_ipcctl *axi = (void *)aux;
794 if (axi->ctx)
795 kfree(axi->ctx);
796 }
797
781 context->aux = aux->next; 798 context->aux = aux->next;
782 kfree(aux); 799 kfree(aux);
783 } 800 }
@@ -862,7 +879,38 @@ static inline void audit_free_context(struct audit_context *context)
862 printk(KERN_ERR "audit: freed %d contexts\n", count); 879 printk(KERN_ERR "audit: freed %d contexts\n", count);
863} 880}
864 881
865static void audit_log_task_info(struct audit_buffer *ab) 882static void audit_log_task_context(struct audit_buffer *ab, gfp_t gfp_mask)
883{
884 char *ctx = NULL;
885 ssize_t len = 0;
886
887 len = security_getprocattr(current, "current", NULL, 0);
888 if (len < 0) {
889 if (len != -EINVAL)
890 goto error_path;
891 return;
892 }
893
894 ctx = kmalloc(len, gfp_mask);
895 if (!ctx) {
896 goto error_path;
897 return;
898 }
899
900 len = security_getprocattr(current, "current", ctx, len);
901 if (len < 0 )
902 goto error_path;
903
904 audit_log_format(ab, " subj=%s", ctx);
905
906error_path:
907 if (ctx)
908 kfree(ctx);
909 audit_panic("security_getprocattr error in audit_log_task_context");
910 return;
911}
912
913static void audit_log_task_info(struct audit_buffer *ab, gfp_t gfp_mask)
866{ 914{
867 char name[sizeof(current->comm)]; 915 char name[sizeof(current->comm)];
868 struct mm_struct *mm = current->mm; 916 struct mm_struct *mm = current->mm;
@@ -875,6 +923,10 @@ static void audit_log_task_info(struct audit_buffer *ab)
875 if (!mm) 923 if (!mm)
876 return; 924 return;
877 925
926 /*
927 * this is brittle; all callers that pass GFP_ATOMIC will have
928 * NULL current->mm and we won't get here.
929 */
878 down_read(&mm->mmap_sem); 930 down_read(&mm->mmap_sem);
879 vma = mm->mmap; 931 vma = mm->mmap;
880 while (vma) { 932 while (vma) {
@@ -888,6 +940,7 @@ static void audit_log_task_info(struct audit_buffer *ab)
888 vma = vma->vm_next; 940 vma = vma->vm_next;
889 } 941 }
890 up_read(&mm->mmap_sem); 942 up_read(&mm->mmap_sem);
943 audit_log_task_context(ab, gfp_mask);
891} 944}
892 945
893static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask) 946static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
@@ -923,7 +976,7 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
923 context->gid, 976 context->gid,
924 context->euid, context->suid, context->fsuid, 977 context->euid, context->suid, context->fsuid,
925 context->egid, context->sgid, context->fsgid); 978 context->egid, context->sgid, context->fsgid);
926 audit_log_task_info(ab); 979 audit_log_task_info(ab, gfp_mask);
927 audit_log_end(ab); 980 audit_log_end(ab);
928 981
929 for (aux = context->aux; aux; aux = aux->next) { 982 for (aux = context->aux; aux; aux = aux->next) {
@@ -936,8 +989,8 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
936 case AUDIT_IPC: { 989 case AUDIT_IPC: {
937 struct audit_aux_data_ipcctl *axi = (void *)aux; 990 struct audit_aux_data_ipcctl *axi = (void *)aux;
938 audit_log_format(ab, 991 audit_log_format(ab,
939 " qbytes=%lx iuid=%u igid=%u mode=%x", 992 " qbytes=%lx iuid=%u igid=%u mode=%x obj=%s",
940 axi->qbytes, axi->uid, axi->gid, axi->mode); 993 axi->qbytes, axi->uid, axi->gid, axi->mode, axi->ctx);
941 break; } 994 break; }
942 995
943 case AUDIT_SOCKETCALL: { 996 case AUDIT_SOCKETCALL: {
@@ -1001,6 +1054,11 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask)
1001 context->names[i].gid, 1054 context->names[i].gid,
1002 MAJOR(context->names[i].rdev), 1055 MAJOR(context->names[i].rdev),
1003 MINOR(context->names[i].rdev)); 1056 MINOR(context->names[i].rdev));
1057 if (context->names[i].ctx) {
1058 audit_log_format(ab, " obj=%s",
1059 context->names[i].ctx);
1060 }
1061
1004 audit_log_end(ab); 1062 audit_log_end(ab);
1005 } 1063 }
1006} 1064}
@@ -1243,6 +1301,39 @@ void audit_putname(const char *name)
1243#endif 1301#endif
1244} 1302}
1245 1303
1304void audit_inode_context(int idx, const struct inode *inode)
1305{
1306 struct audit_context *context = current->audit_context;
1307 char *ctx = NULL;
1308 int len = 0;
1309
1310 if (!security_inode_xattr_getsuffix())
1311 return;
1312
1313 len = security_inode_getsecurity(inode, (char *)security_inode_xattr_getsuffix(), NULL, 0, 0);
1314 if (len < 0)
1315 goto error_path;
1316
1317 ctx = kmalloc(len, GFP_KERNEL);
1318 if (!ctx)
1319 goto error_path;
1320
1321 len = security_inode_getsecurity(inode, (char *)security_inode_xattr_getsuffix(), ctx, len, 0);
1322 if (len < 0)
1323 goto error_path;
1324
1325 kfree(context->names[idx].ctx);
1326 context->names[idx].ctx = ctx;
1327 return;
1328
1329error_path:
1330 if (ctx)
1331 kfree(ctx);
1332 audit_panic("error in audit_inode_context");
1333 return;
1334}
1335
1336
1246/** 1337/**
1247 * audit_inode - store the inode and device from a lookup 1338 * audit_inode - store the inode and device from a lookup
1248 * @name: name being audited 1339 * @name: name being audited
@@ -1282,6 +1373,7 @@ void __audit_inode(const char *name, const struct inode *inode, unsigned flags)
1282 context->names[idx].uid = inode->i_uid; 1373 context->names[idx].uid = inode->i_uid;
1283 context->names[idx].gid = inode->i_gid; 1374 context->names[idx].gid = inode->i_gid;
1284 context->names[idx].rdev = inode->i_rdev; 1375 context->names[idx].rdev = inode->i_rdev;
1376 audit_inode_context(idx, inode);
1285 if ((flags & LOOKUP_PARENT) && (strcmp(name, "/") != 0) && 1377 if ((flags & LOOKUP_PARENT) && (strcmp(name, "/") != 0) &&
1286 (strcmp(name, ".") != 0)) { 1378 (strcmp(name, ".") != 0)) {
1287 context->names[idx].ino = (unsigned long)-1; 1379 context->names[idx].ino = (unsigned long)-1;
@@ -1363,6 +1455,7 @@ update_context:
1363 context->names[idx].uid = inode->i_uid; 1455 context->names[idx].uid = inode->i_uid;
1364 context->names[idx].gid = inode->i_gid; 1456 context->names[idx].gid = inode->i_gid;
1365 context->names[idx].rdev = inode->i_rdev; 1457 context->names[idx].rdev = inode->i_rdev;
1458 audit_inode_context(idx, inode);
1366 } 1459 }
1367} 1460}
1368 1461
@@ -1423,6 +1516,38 @@ uid_t audit_get_loginuid(struct audit_context *ctx)
1423 return ctx ? ctx->loginuid : -1; 1516 return ctx ? ctx->loginuid : -1;
1424} 1517}
1425 1518
1519static char *audit_ipc_context(struct kern_ipc_perm *ipcp)
1520{
1521 struct audit_context *context = current->audit_context;
1522 char *ctx = NULL;
1523 int len = 0;
1524
1525 if (likely(!context))
1526 return NULL;
1527
1528 len = security_ipc_getsecurity(ipcp, NULL, 0);
1529 if (len == -EOPNOTSUPP)
1530 goto ret;
1531 if (len < 0)
1532 goto error_path;
1533
1534 ctx = kmalloc(len, GFP_ATOMIC);
1535 if (!ctx)
1536 goto error_path;
1537
1538 len = security_ipc_getsecurity(ipcp, ctx, len);
1539 if (len < 0)
1540 goto error_path;
1541
1542 return ctx;
1543
1544error_path:
1545 kfree(ctx);
1546 audit_panic("error in audit_ipc_context");
1547ret:
1548 return NULL;
1549}
1550
1426/** 1551/**
1427 * audit_ipc_perms - record audit data for ipc 1552 * audit_ipc_perms - record audit data for ipc
1428 * @qbytes: msgq bytes 1553 * @qbytes: msgq bytes
@@ -1432,7 +1557,7 @@ uid_t audit_get_loginuid(struct audit_context *ctx)
1432 * 1557 *
1433 * Returns 0 for success or NULL context or < 0 on error. 1558 * Returns 0 for success or NULL context or < 0 on error.
1434 */ 1559 */
1435int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) 1560int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp)
1436{ 1561{
1437 struct audit_aux_data_ipcctl *ax; 1562 struct audit_aux_data_ipcctl *ax;
1438 struct audit_context *context = current->audit_context; 1563 struct audit_context *context = current->audit_context;
@@ -1440,7 +1565,7 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
1440 if (likely(!context)) 1565 if (likely(!context))
1441 return 0; 1566 return 0;
1442 1567
1443 ax = kmalloc(sizeof(*ax), GFP_KERNEL); 1568 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
1444 if (!ax) 1569 if (!ax)
1445 return -ENOMEM; 1570 return -ENOMEM;
1446 1571
@@ -1448,6 +1573,7 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
1448 ax->uid = uid; 1573 ax->uid = uid;
1449 ax->gid = gid; 1574 ax->gid = gid;
1450 ax->mode = mode; 1575 ax->mode = mode;
1576 ax->ctx = audit_ipc_context(ipcp);
1451 1577
1452 ax->d.type = AUDIT_IPC; 1578 ax->d.type = AUDIT_IPC;
1453 ax->d.next = context->aux; 1579 ax->d.next = context->aux;