aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/audit.h8
-rw-r--r--include/linux/security.h27
-rw-r--r--ipc/msg.c5
-rw-r--r--ipc/sem.c5
-rw-r--r--ipc/shm.c4
-rw-r--r--kernel/audit.c2
-rw-r--r--kernel/auditsc.c142
-rw-r--r--security/dummy.c6
-rw-r--r--security/selinux/hooks.c96
9 files changed, 226 insertions, 69 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 8fa1a8fbc04d..1912d8e8ae90 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -285,13 +285,14 @@ extern void auditsc_get_stamp(struct audit_context *ctx,
285 struct timespec *t, unsigned int *serial); 285 struct timespec *t, unsigned int *serial);
286extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); 286extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
287extern uid_t audit_get_loginuid(struct audit_context *ctx); 287extern uid_t audit_get_loginuid(struct audit_context *ctx);
288extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); 288extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp);
289extern int audit_socketcall(int nargs, unsigned long *args); 289extern int audit_socketcall(int nargs, unsigned long *args);
290extern int audit_sockaddr(int len, void *addr); 290extern int audit_sockaddr(int len, void *addr);
291extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); 291extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
292extern void audit_signal_info(int sig, struct task_struct *t); 292extern void audit_signal_info(int sig, struct task_struct *t);
293extern int audit_filter_user(struct netlink_skb_parms *cb, int type); 293extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
294extern int audit_filter_type(int type); 294extern int audit_filter_type(int type);
295extern int audit_set_macxattr(const char *name);
295#else 296#else
296#define audit_alloc(t) ({ 0; }) 297#define audit_alloc(t) ({ 0; })
297#define audit_free(t) do { ; } while (0) 298#define audit_free(t) do { ; } while (0)
@@ -306,12 +307,13 @@ extern int audit_filter_type(int type);
306#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; }) 307#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
307#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) 308#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
308#define audit_get_loginuid(c) ({ -1; }) 309#define audit_get_loginuid(c) ({ -1; })
309#define audit_ipc_perms(q,u,g,m) ({ 0; }) 310#define audit_ipc_perms(q,u,g,m,i) ({ 0; })
310#define audit_socketcall(n,a) ({ 0; }) 311#define audit_socketcall(n,a) ({ 0; })
311#define audit_sockaddr(len, addr) ({ 0; }) 312#define audit_sockaddr(len, addr) ({ 0; })
312#define audit_avc_path(dentry, mnt) ({ 0; }) 313#define audit_avc_path(dentry, mnt) ({ 0; })
313#define audit_signal_info(s,t) do { ; } while (0) 314#define audit_signal_info(s,t) do { ; } while (0)
314#define audit_filter_user(cb,t) ({ 1; }) 315#define audit_filter_user(cb,t) ({ 1; })
316#define audit_set_macxattr(n) do { ; } while (0)
315#endif 317#endif
316 318
317#ifdef CONFIG_AUDIT 319#ifdef CONFIG_AUDIT
@@ -340,6 +342,7 @@ extern void audit_send_reply(int pid, int seq, int type,
340 int done, int multi, 342 int done, int multi,
341 void *payload, int size); 343 void *payload, int size);
342extern void audit_log_lost(const char *message); 344extern void audit_log_lost(const char *message);
345extern void audit_panic(const char *message);
343extern struct semaphore audit_netlink_sem; 346extern struct semaphore audit_netlink_sem;
344#else 347#else
345#define audit_log(c,g,t,f,...) do { ; } while (0) 348#define audit_log(c,g,t,f,...) do { ; } while (0)
@@ -350,6 +353,7 @@ extern struct semaphore audit_netlink_sem;
350#define audit_log_hex(a,b,l) do { ; } while (0) 353#define audit_log_hex(a,b,l) do { ; } while (0)
351#define audit_log_untrustedstring(a,s) do { ; } while (0) 354#define audit_log_untrustedstring(a,s) do { ; } while (0)
352#define audit_log_d_path(b,p,d,v) do { ; } while (0) 355#define audit_log_d_path(b,p,d,v) do { ; } while (0)
356#define audit_panic(m) do { ; } while (0)
353#endif 357#endif
354#endif 358#endif
355#endif 359#endif
diff --git a/include/linux/security.h b/include/linux/security.h
index 7cbef482e13a..ec0bbbc3ffc2 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -869,6 +869,11 @@ struct swap_info_struct;
869 * @ipcp contains the kernel IPC permission structure 869 * @ipcp contains the kernel IPC permission structure
870 * @flag contains the desired (requested) permission set 870 * @flag contains the desired (requested) permission set
871 * Return 0 if permission is granted. 871 * Return 0 if permission is granted.
872 * @ipc_getsecurity:
873 * Copy the security label associated with the ipc object into
874 * @buffer. @buffer may be NULL to request the size of the buffer
875 * required. @size indicates the size of @buffer in bytes. Return
876 * number of bytes used/required on success.
872 * 877 *
873 * Security hooks for individual messages held in System V IPC message queues 878 * Security hooks for individual messages held in System V IPC message queues
874 * @msg_msg_alloc_security: 879 * @msg_msg_alloc_security:
@@ -1168,6 +1173,7 @@ struct security_operations {
1168 int (*inode_getxattr) (struct dentry *dentry, char *name); 1173 int (*inode_getxattr) (struct dentry *dentry, char *name);
1169 int (*inode_listxattr) (struct dentry *dentry); 1174 int (*inode_listxattr) (struct dentry *dentry);
1170 int (*inode_removexattr) (struct dentry *dentry, char *name); 1175 int (*inode_removexattr) (struct dentry *dentry, char *name);
1176 char *(*inode_xattr_getsuffix) (void);
1171 int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err); 1177 int (*inode_getsecurity)(struct inode *inode, const char *name, void *buffer, size_t size, int err);
1172 int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags); 1178 int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
1173 int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size); 1179 int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
@@ -1217,6 +1223,7 @@ struct security_operations {
1217 void (*task_to_inode)(struct task_struct *p, struct inode *inode); 1223 void (*task_to_inode)(struct task_struct *p, struct inode *inode);
1218 1224
1219 int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag); 1225 int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag);
1226 int (*ipc_getsecurity)(struct kern_ipc_perm *ipcp, void *buffer, size_t size);
1220 1227
1221 int (*msg_msg_alloc_security) (struct msg_msg * msg); 1228 int (*msg_msg_alloc_security) (struct msg_msg * msg);
1222 void (*msg_msg_free_security) (struct msg_msg * msg); 1229 void (*msg_msg_free_security) (struct msg_msg * msg);
@@ -1674,6 +1681,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
1674 return security_ops->inode_removexattr (dentry, name); 1681 return security_ops->inode_removexattr (dentry, name);
1675} 1682}
1676 1683
1684static inline const char *security_inode_xattr_getsuffix(void)
1685{
1686 return security_ops->inode_xattr_getsuffix();
1687}
1688
1677static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) 1689static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
1678{ 1690{
1679 if (unlikely (IS_PRIVATE (inode))) 1691 if (unlikely (IS_PRIVATE (inode)))
@@ -1869,6 +1881,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
1869 return security_ops->ipc_permission (ipcp, flag); 1881 return security_ops->ipc_permission (ipcp, flag);
1870} 1882}
1871 1883
1884static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
1885{
1886 return security_ops->ipc_getsecurity(ipcp, buffer, size);
1887}
1888
1872static inline int security_msg_msg_alloc (struct msg_msg * msg) 1889static inline int security_msg_msg_alloc (struct msg_msg * msg)
1873{ 1890{
1874 return security_ops->msg_msg_alloc_security (msg); 1891 return security_ops->msg_msg_alloc_security (msg);
@@ -2316,6 +2333,11 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
2316 return cap_inode_removexattr(dentry, name); 2333 return cap_inode_removexattr(dentry, name);
2317} 2334}
2318 2335
2336static inline const char *security_inode_xattr_getsuffix (void)
2337{
2338 return NULL ;
2339}
2340
2319static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) 2341static inline int security_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
2320{ 2342{
2321 return -EOPNOTSUPP; 2343 return -EOPNOTSUPP;
@@ -2499,6 +2521,11 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
2499 return 0; 2521 return 0;
2500} 2522}
2501 2523
2524static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
2525{
2526 return -EOPNOTSUPP;
2527}
2528
2502static inline int security_msg_msg_alloc (struct msg_msg * msg) 2529static inline int security_msg_msg_alloc (struct msg_msg * msg)
2503{ 2530{
2504 return 0; 2531 return 0;
diff --git a/ipc/msg.c b/ipc/msg.c
index fbf757064a32..8c30ec2f6e34 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -429,8 +429,6 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
429 return -EFAULT; 429 return -EFAULT;
430 if (copy_msqid_from_user (&setbuf, buf, version)) 430 if (copy_msqid_from_user (&setbuf, buf, version))
431 return -EFAULT; 431 return -EFAULT;
432 if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode)))
433 return err;
434 break; 432 break;
435 case IPC_RMID: 433 case IPC_RMID:
436 break; 434 break;
@@ -461,6 +459,9 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf)
461 switch (cmd) { 459 switch (cmd) {
462 case IPC_SET: 460 case IPC_SET:
463 { 461 {
462 if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp)))
463 goto out_unlock_up;
464
464 err = -EPERM; 465 err = -EPERM;
465 if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE)) 466 if (setbuf.qbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE))
466 goto out_unlock_up; 467 goto out_unlock_up;
diff --git a/ipc/sem.c b/ipc/sem.c
index 31fd4027d2b5..59696a840be1 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -809,8 +809,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
809 if(cmd == IPC_SET) { 809 if(cmd == IPC_SET) {
810 if(copy_semid_from_user (&setbuf, arg.buf, version)) 810 if(copy_semid_from_user (&setbuf, arg.buf, version))
811 return -EFAULT; 811 return -EFAULT;
812 if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
813 return err;
814 } 812 }
815 sma = sem_lock(semid); 813 sma = sem_lock(semid);
816 if(sma==NULL) 814 if(sma==NULL)
@@ -821,7 +819,6 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
821 goto out_unlock; 819 goto out_unlock;
822 } 820 }
823 ipcp = &sma->sem_perm; 821 ipcp = &sma->sem_perm;
824
825 if (current->euid != ipcp->cuid && 822 if (current->euid != ipcp->cuid &&
826 current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) { 823 current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) {
827 err=-EPERM; 824 err=-EPERM;
@@ -838,6 +835,8 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun
838 err = 0; 835 err = 0;
839 break; 836 break;
840 case IPC_SET: 837 case IPC_SET:
838 if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp)))
839 goto out_unlock;
841 ipcp->uid = setbuf.uid; 840 ipcp->uid = setbuf.uid;
842 ipcp->gid = setbuf.gid; 841 ipcp->gid = setbuf.gid;
843 ipcp->mode = (ipcp->mode & ~S_IRWXUGO) 842 ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
diff --git a/ipc/shm.c b/ipc/shm.c
index 9162123a7b23..a88c8a02e7f3 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -620,13 +620,13 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
620 err = -EFAULT; 620 err = -EFAULT;
621 goto out; 621 goto out;
622 } 622 }
623 if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode)))
624 return err;
625 down(&shm_ids.sem); 623 down(&shm_ids.sem);
626 shp = shm_lock(shmid); 624 shp = shm_lock(shmid);
627 err=-EINVAL; 625 err=-EINVAL;
628 if(shp==NULL) 626 if(shp==NULL)
629 goto out_up; 627 goto out_up;
628 if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, &(shp->shm_perm))))
629 goto out_unlock_up;
630 err = shm_checkid(shp,shmid); 630 err = shm_checkid(shp,shmid);
631 if(err) 631 if(err)
632 goto out_unlock_up; 632 goto out_unlock_up;
diff --git a/kernel/audit.c b/kernel/audit.c
index 1c3eb1b12bfc..45c123ef77a7 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -142,7 +142,7 @@ static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
142 nlh->nlmsg_pid = pid; 142 nlh->nlmsg_pid = pid;
143} 143}
144 144
145static void audit_panic(const char *message) 145void audit_panic(const char *message)
146{ 146{
147 switch (audit_failure) 147 switch (audit_failure)
148 { 148 {
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;
diff --git a/security/dummy.c b/security/dummy.c
index f1a5bd98bf10..6febe7d39fa0 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -558,6 +558,11 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag)
558 return 0; 558 return 0;
559} 559}
560 560
561static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
562{
563 return -EOPNOTSUPP;
564}
565
561static int dummy_msg_msg_alloc_security (struct msg_msg *msg) 566static int dummy_msg_msg_alloc_security (struct msg_msg *msg)
562{ 567{
563 return 0; 568 return 0;
@@ -959,6 +964,7 @@ void security_fixup_ops (struct security_operations *ops)
959 set_to_dummy_if_null(ops, task_reparent_to_init); 964 set_to_dummy_if_null(ops, task_reparent_to_init);
960 set_to_dummy_if_null(ops, task_to_inode); 965 set_to_dummy_if_null(ops, task_to_inode);
961 set_to_dummy_if_null(ops, ipc_permission); 966 set_to_dummy_if_null(ops, ipc_permission);
967 set_to_dummy_if_null(ops, ipc_getsecurity);
962 set_to_dummy_if_null(ops, msg_msg_alloc_security); 968 set_to_dummy_if_null(ops, msg_msg_alloc_security);
963 set_to_dummy_if_null(ops, msg_msg_free_security); 969 set_to_dummy_if_null(ops, msg_msg_free_security);
964 set_to_dummy_if_null(ops, msg_queue_alloc_security); 970 set_to_dummy_if_null(ops, msg_queue_alloc_security);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b65c201e9ff5..9c08a19cc81b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -117,6 +117,32 @@ static struct security_operations *secondary_ops = NULL;
117static LIST_HEAD(superblock_security_head); 117static LIST_HEAD(superblock_security_head);
118static DEFINE_SPINLOCK(sb_security_lock); 118static DEFINE_SPINLOCK(sb_security_lock);
119 119
120/* Return security context for a given sid or just the context
121 length if the buffer is null or length is 0 */
122static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
123{
124 char *context;
125 unsigned len;
126 int rc;
127
128 rc = security_sid_to_context(sid, &context, &len);
129 if (rc)
130 return rc;
131
132 if (!buffer || !size)
133 goto getsecurity_exit;
134
135 if (size < len) {
136 len = -ERANGE;
137 goto getsecurity_exit;
138 }
139 memcpy(buffer, context, len);
140
141getsecurity_exit:
142 kfree(context);
143 return len;
144}
145
120/* Allocate and free functions for each kind of security blob. */ 146/* Allocate and free functions for each kind of security blob. */
121 147
122static int task_alloc_security(struct task_struct *task) 148static int task_alloc_security(struct task_struct *task)
@@ -2209,6 +2235,11 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2209 return -EACCES; 2235 return -EACCES;
2210} 2236}
2211 2237
2238static const char *selinux_inode_xattr_getsuffix(void)
2239{
2240 return XATTR_SELINUX_SUFFIX;
2241}
2242
2212/* 2243/*
2213 * Copy the in-core inode security context value to the user. If the 2244 * Copy the in-core inode security context value to the user. If the
2214 * getxattr() prior to this succeeded, check to see if we need to 2245 * getxattr() prior to this succeeded, check to see if we need to
@@ -2219,44 +2250,11 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2219static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) 2250static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
2220{ 2251{
2221 struct inode_security_struct *isec = inode->i_security; 2252 struct inode_security_struct *isec = inode->i_security;
2222 char *context;
2223 unsigned len;
2224 int rc;
2225
2226 if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
2227 rc = -EOPNOTSUPP;
2228 goto out;
2229 }
2230
2231 rc = security_sid_to_context(isec->sid, &context, &len);
2232 if (rc)
2233 goto out;
2234
2235 /* Probe for required buffer size */
2236 if (!buffer || !size) {
2237 rc = len;
2238 goto out_free;
2239 }
2240 2253
2241 if (size < len) { 2254 if (strcmp(name, XATTR_SELINUX_SUFFIX))
2242 rc = -ERANGE; 2255 return -EOPNOTSUPP;
2243 goto out_free;
2244 }
2245 2256
2246 if (err > 0) { 2257 return selinux_getsecurity(isec->sid, buffer, size);
2247 if ((len == err) && !(memcmp(context, buffer, len))) {
2248 /* Don't need to canonicalize value */
2249 rc = err;
2250 goto out_free;
2251 }
2252 memset(buffer, 0, size);
2253 }
2254 memcpy(buffer, context, len);
2255 rc = len;
2256out_free:
2257 kfree(context);
2258out:
2259 return rc;
2260} 2258}
2261 2259
2262static int selinux_inode_setsecurity(struct inode *inode, const char *name, 2260static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -4022,6 +4020,13 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
4022 return ipc_has_perm(ipcp, av); 4020 return ipc_has_perm(ipcp, av);
4023} 4021}
4024 4022
4023static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
4024{
4025 struct ipc_security_struct *isec = ipcp->security;
4026
4027 return selinux_getsecurity(isec->sid, buffer, size);
4028}
4029
4025/* module stacking operations */ 4030/* module stacking operations */
4026static int selinux_register_security (const char *name, struct security_operations *ops) 4031static int selinux_register_security (const char *name, struct security_operations *ops)
4027{ 4032{
@@ -4063,8 +4068,7 @@ static int selinux_getprocattr(struct task_struct *p,
4063 char *name, void *value, size_t size) 4068 char *name, void *value, size_t size)
4064{ 4069{
4065 struct task_security_struct *tsec; 4070 struct task_security_struct *tsec;
4066 u32 sid, len; 4071 u32 sid;
4067 char *context;
4068 int error; 4072 int error;
4069 4073
4070 if (current != p) { 4074 if (current != p) {
@@ -4073,9 +4077,6 @@ static int selinux_getprocattr(struct task_struct *p,
4073 return error; 4077 return error;
4074 } 4078 }
4075 4079
4076 if (!size)
4077 return -ERANGE;
4078
4079 tsec = p->security; 4080 tsec = p->security;
4080 4081
4081 if (!strcmp(name, "current")) 4082 if (!strcmp(name, "current"))
@@ -4092,16 +4093,7 @@ static int selinux_getprocattr(struct task_struct *p,
4092 if (!sid) 4093 if (!sid)
4093 return 0; 4094 return 0;
4094 4095
4095 error = security_sid_to_context(sid, &context, &len); 4096 return selinux_getsecurity(sid, value, size);
4096 if (error)
4097 return error;
4098 if (len > size) {
4099 kfree(context);
4100 return -ERANGE;
4101 }
4102 memcpy(value, context, len);
4103 kfree(context);
4104 return len;
4105} 4097}
4106 4098
4107static int selinux_setprocattr(struct task_struct *p, 4099static int selinux_setprocattr(struct task_struct *p,
@@ -4259,6 +4251,7 @@ static struct security_operations selinux_ops = {
4259 .inode_getxattr = selinux_inode_getxattr, 4251 .inode_getxattr = selinux_inode_getxattr,
4260 .inode_listxattr = selinux_inode_listxattr, 4252 .inode_listxattr = selinux_inode_listxattr,
4261 .inode_removexattr = selinux_inode_removexattr, 4253 .inode_removexattr = selinux_inode_removexattr,
4254 .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix,
4262 .inode_getsecurity = selinux_inode_getsecurity, 4255 .inode_getsecurity = selinux_inode_getsecurity,
4263 .inode_setsecurity = selinux_inode_setsecurity, 4256 .inode_setsecurity = selinux_inode_setsecurity,
4264 .inode_listsecurity = selinux_inode_listsecurity, 4257 .inode_listsecurity = selinux_inode_listsecurity,
@@ -4296,6 +4289,7 @@ static struct security_operations selinux_ops = {
4296 .task_to_inode = selinux_task_to_inode, 4289 .task_to_inode = selinux_task_to_inode,
4297 4290
4298 .ipc_permission = selinux_ipc_permission, 4291 .ipc_permission = selinux_ipc_permission,
4292 .ipc_getsecurity = selinux_ipc_getsecurity,
4299 4293
4300 .msg_msg_alloc_security = selinux_msg_msg_alloc_security, 4294 .msg_msg_alloc_security = selinux_msg_msg_alloc_security,
4301 .msg_msg_free_security = selinux_msg_msg_free_security, 4295 .msg_msg_free_security = selinux_msg_msg_free_security,