aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2011-05-24 03:06:26 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-05-24 03:06:26 -0400
commitb73077eb03f510a84b102fb97640e595a958403c (patch)
tree8b639000418e2756bf6baece4e00e07d2534bccc /security/selinux/hooks.c
parent28350e330cfab46b60a1dbf763b678d859f9f3d9 (diff)
parent9d2e173644bb5c42ff1b280fbdda3f195a7cf1f7 (diff)
Merge branch 'next' into for-linus
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c377
1 files changed, 206 insertions, 171 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index e276eb468536..f9c3764e4859 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -24,9 +24,11 @@
24 */ 24 */
25 25
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/kd.h>
27#include <linux/kernel.h> 28#include <linux/kernel.h>
28#include <linux/tracehook.h> 29#include <linux/tracehook.h>
29#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/ext2_fs.h>
30#include <linux/sched.h> 32#include <linux/sched.h>
31#include <linux/security.h> 33#include <linux/security.h>
32#include <linux/xattr.h> 34#include <linux/xattr.h>
@@ -36,14 +38,15 @@
36#include <linux/mman.h> 38#include <linux/mman.h>
37#include <linux/slab.h> 39#include <linux/slab.h>
38#include <linux/pagemap.h> 40#include <linux/pagemap.h>
41#include <linux/proc_fs.h>
39#include <linux/swap.h> 42#include <linux/swap.h>
40#include <linux/spinlock.h> 43#include <linux/spinlock.h>
41#include <linux/syscalls.h> 44#include <linux/syscalls.h>
45#include <linux/dcache.h>
42#include <linux/file.h> 46#include <linux/file.h>
43#include <linux/fdtable.h> 47#include <linux/fdtable.h>
44#include <linux/namei.h> 48#include <linux/namei.h>
45#include <linux/mount.h> 49#include <linux/mount.h>
46#include <linux/proc_fs.h>
47#include <linux/netfilter_ipv4.h> 50#include <linux/netfilter_ipv4.h>
48#include <linux/netfilter_ipv6.h> 51#include <linux/netfilter_ipv6.h>
49#include <linux/tty.h> 52#include <linux/tty.h>
@@ -70,13 +73,13 @@
70#include <net/ipv6.h> 73#include <net/ipv6.h>
71#include <linux/hugetlb.h> 74#include <linux/hugetlb.h>
72#include <linux/personality.h> 75#include <linux/personality.h>
73#include <linux/sysctl.h>
74#include <linux/audit.h> 76#include <linux/audit.h>
75#include <linux/string.h> 77#include <linux/string.h>
76#include <linux/selinux.h> 78#include <linux/selinux.h>
77#include <linux/mutex.h> 79#include <linux/mutex.h>
78#include <linux/posix-timers.h> 80#include <linux/posix-timers.h>
79#include <linux/syslog.h> 81#include <linux/syslog.h>
82#include <linux/user_namespace.h>
80 83
81#include "avc.h" 84#include "avc.h"
82#include "objsec.h" 85#include "objsec.h"
@@ -1120,39 +1123,35 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
1120} 1123}
1121 1124
1122#ifdef CONFIG_PROC_FS 1125#ifdef CONFIG_PROC_FS
1123static int selinux_proc_get_sid(struct proc_dir_entry *de, 1126static int selinux_proc_get_sid(struct dentry *dentry,
1124 u16 tclass, 1127 u16 tclass,
1125 u32 *sid) 1128 u32 *sid)
1126{ 1129{
1127 int buflen, rc; 1130 int rc;
1128 char *buffer, *path, *end; 1131 char *buffer, *path;
1129 1132
1130 buffer = (char *)__get_free_page(GFP_KERNEL); 1133 buffer = (char *)__get_free_page(GFP_KERNEL);
1131 if (!buffer) 1134 if (!buffer)
1132 return -ENOMEM; 1135 return -ENOMEM;
1133 1136
1134 buflen = PAGE_SIZE; 1137 path = dentry_path_raw(dentry, buffer, PAGE_SIZE);
1135 end = buffer+buflen; 1138 if (IS_ERR(path))
1136 *--end = '\0'; 1139 rc = PTR_ERR(path);
1137 buflen--; 1140 else {
1138 path = end-1; 1141 /* each process gets a /proc/PID/ entry. Strip off the
1139 *path = '/'; 1142 * PID part to get a valid selinux labeling.
1140 while (de && de != de->parent) { 1143 * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
1141 buflen -= de->namelen + 1; 1144 while (path[1] >= '0' && path[1] <= '9') {
1142 if (buflen < 0) 1145 path[1] = '/';
1143 break; 1146 path++;
1144 end -= de->namelen; 1147 }
1145 memcpy(end, de->name, de->namelen); 1148 rc = security_genfs_sid("proc", path, tclass, sid);
1146 *--end = '/';
1147 path = end;
1148 de = de->parent;
1149 } 1149 }
1150 rc = security_genfs_sid("proc", path, tclass, sid);
1151 free_page((unsigned long)buffer); 1150 free_page((unsigned long)buffer);
1152 return rc; 1151 return rc;
1153} 1152}
1154#else 1153#else
1155static int selinux_proc_get_sid(struct proc_dir_entry *de, 1154static int selinux_proc_get_sid(struct dentry *dentry,
1156 u16 tclass, 1155 u16 tclass,
1157 u32 *sid) 1156 u32 *sid)
1158{ 1157{
@@ -1300,10 +1299,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1300 1299
1301 /* Try to obtain a transition SID. */ 1300 /* Try to obtain a transition SID. */
1302 isec->sclass = inode_mode_to_security_class(inode->i_mode); 1301 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1303 rc = security_transition_sid(isec->task_sid, 1302 rc = security_transition_sid(isec->task_sid, sbsec->sid,
1304 sbsec->sid, 1303 isec->sclass, NULL, &sid);
1305 isec->sclass,
1306 &sid);
1307 if (rc) 1304 if (rc)
1308 goto out_unlock; 1305 goto out_unlock;
1309 isec->sid = sid; 1306 isec->sid = sid;
@@ -1316,10 +1313,9 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1316 isec->sid = sbsec->sid; 1313 isec->sid = sbsec->sid;
1317 1314
1318 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { 1315 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
1319 struct proc_inode *proci = PROC_I(inode); 1316 if (opt_dentry) {
1320 if (proci->pde) {
1321 isec->sclass = inode_mode_to_security_class(inode->i_mode); 1317 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1322 rc = selinux_proc_get_sid(proci->pde, 1318 rc = selinux_proc_get_sid(opt_dentry,
1323 isec->sclass, 1319 isec->sclass,
1324 &sid); 1320 &sid);
1325 if (rc) 1321 if (rc)
@@ -1578,7 +1574,7 @@ static int may_create(struct inode *dir,
1578 return rc; 1574 return rc;
1579 1575
1580 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 1576 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
1581 rc = security_transition_sid(sid, dsec->sid, tclass, &newsid); 1577 rc = security_transition_sid(sid, dsec->sid, tclass, NULL, &newsid);
1582 if (rc) 1578 if (rc)
1583 return rc; 1579 return rc;
1584 } 1580 }
@@ -1851,93 +1847,17 @@ static int selinux_capset(struct cred *new, const struct cred *old,
1851 */ 1847 */
1852 1848
1853static int selinux_capable(struct task_struct *tsk, const struct cred *cred, 1849static int selinux_capable(struct task_struct *tsk, const struct cred *cred,
1854 int cap, int audit) 1850 struct user_namespace *ns, int cap, int audit)
1855{ 1851{
1856 int rc; 1852 int rc;
1857 1853
1858 rc = cap_capable(tsk, cred, cap, audit); 1854 rc = cap_capable(tsk, cred, ns, cap, audit);
1859 if (rc) 1855 if (rc)
1860 return rc; 1856 return rc;
1861 1857
1862 return task_has_capability(tsk, cred, cap, audit); 1858 return task_has_capability(tsk, cred, cap, audit);
1863} 1859}
1864 1860
1865static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
1866{
1867 int buflen, rc;
1868 char *buffer, *path, *end;
1869
1870 rc = -ENOMEM;
1871 buffer = (char *)__get_free_page(GFP_KERNEL);
1872 if (!buffer)
1873 goto out;
1874
1875 buflen = PAGE_SIZE;
1876 end = buffer+buflen;
1877 *--end = '\0';
1878 buflen--;
1879 path = end-1;
1880 *path = '/';
1881 while (table) {
1882 const char *name = table->procname;
1883 size_t namelen = strlen(name);
1884 buflen -= namelen + 1;
1885 if (buflen < 0)
1886 goto out_free;
1887 end -= namelen;
1888 memcpy(end, name, namelen);
1889 *--end = '/';
1890 path = end;
1891 table = table->parent;
1892 }
1893 buflen -= 4;
1894 if (buflen < 0)
1895 goto out_free;
1896 end -= 4;
1897 memcpy(end, "/sys", 4);
1898 path = end;
1899 rc = security_genfs_sid("proc", path, tclass, sid);
1900out_free:
1901 free_page((unsigned long)buffer);
1902out:
1903 return rc;
1904}
1905
1906static int selinux_sysctl(ctl_table *table, int op)
1907{
1908 int error = 0;
1909 u32 av;
1910 u32 tsid, sid;
1911 int rc;
1912
1913 sid = current_sid();
1914
1915 rc = selinux_sysctl_get_sid(table, (op == 0001) ?
1916 SECCLASS_DIR : SECCLASS_FILE, &tsid);
1917 if (rc) {
1918 /* Default to the well-defined sysctl SID. */
1919 tsid = SECINITSID_SYSCTL;
1920 }
1921
1922 /* The op values are "defined" in sysctl.c, thereby creating
1923 * a bad coupling between this module and sysctl.c */
1924 if (op == 001) {
1925 error = avc_has_perm(sid, tsid,
1926 SECCLASS_DIR, DIR__SEARCH, NULL);
1927 } else {
1928 av = 0;
1929 if (op & 004)
1930 av |= FILE__READ;
1931 if (op & 002)
1932 av |= FILE__WRITE;
1933 if (av)
1934 error = avc_has_perm(sid, tsid,
1935 SECCLASS_FILE, av, NULL);
1936 }
1937
1938 return error;
1939}
1940
1941static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) 1861static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
1942{ 1862{
1943 const struct cred *cred = current_cred(); 1863 const struct cred *cred = current_cred();
@@ -2012,7 +1932,8 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2012{ 1932{
2013 int rc, cap_sys_admin = 0; 1933 int rc, cap_sys_admin = 0;
2014 1934
2015 rc = selinux_capable(current, current_cred(), CAP_SYS_ADMIN, 1935 rc = selinux_capable(current, current_cred(),
1936 &init_user_ns, CAP_SYS_ADMIN,
2016 SECURITY_CAP_NOAUDIT); 1937 SECURITY_CAP_NOAUDIT);
2017 if (rc == 0) 1938 if (rc == 0)
2018 cap_sys_admin = 1; 1939 cap_sys_admin = 1;
@@ -2060,7 +1981,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2060 } else { 1981 } else {
2061 /* Check for a default transition on this program. */ 1982 /* Check for a default transition on this program. */
2062 rc = security_transition_sid(old_tsec->sid, isec->sid, 1983 rc = security_transition_sid(old_tsec->sid, isec->sid,
2063 SECCLASS_PROCESS, &new_tsec->sid); 1984 SECCLASS_PROCESS, NULL,
1985 &new_tsec->sid);
2064 if (rc) 1986 if (rc)
2065 return rc; 1987 return rc;
2066 } 1988 }
@@ -2443,6 +2365,91 @@ out:
2443 return rc; 2365 return rc;
2444} 2366}
2445 2367
2368static int selinux_sb_remount(struct super_block *sb, void *data)
2369{
2370 int rc, i, *flags;
2371 struct security_mnt_opts opts;
2372 char *secdata, **mount_options;
2373 struct superblock_security_struct *sbsec = sb->s_security;
2374
2375 if (!(sbsec->flags & SE_SBINITIALIZED))
2376 return 0;
2377
2378 if (!data)
2379 return 0;
2380
2381 if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
2382 return 0;
2383
2384 security_init_mnt_opts(&opts);
2385 secdata = alloc_secdata();
2386 if (!secdata)
2387 return -ENOMEM;
2388 rc = selinux_sb_copy_data(data, secdata);
2389 if (rc)
2390 goto out_free_secdata;
2391
2392 rc = selinux_parse_opts_str(secdata, &opts);
2393 if (rc)
2394 goto out_free_secdata;
2395
2396 mount_options = opts.mnt_opts;
2397 flags = opts.mnt_opts_flags;
2398
2399 for (i = 0; i < opts.num_mnt_opts; i++) {
2400 u32 sid;
2401 size_t len;
2402
2403 if (flags[i] == SE_SBLABELSUPP)
2404 continue;
2405 len = strlen(mount_options[i]);
2406 rc = security_context_to_sid(mount_options[i], len, &sid);
2407 if (rc) {
2408 printk(KERN_WARNING "SELinux: security_context_to_sid"
2409 "(%s) failed for (dev %s, type %s) errno=%d\n",
2410 mount_options[i], sb->s_id, sb->s_type->name, rc);
2411 goto out_free_opts;
2412 }
2413 rc = -EINVAL;
2414 switch (flags[i]) {
2415 case FSCONTEXT_MNT:
2416 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
2417 goto out_bad_option;
2418 break;
2419 case CONTEXT_MNT:
2420 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
2421 goto out_bad_option;
2422 break;
2423 case ROOTCONTEXT_MNT: {
2424 struct inode_security_struct *root_isec;
2425 root_isec = sb->s_root->d_inode->i_security;
2426
2427 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
2428 goto out_bad_option;
2429 break;
2430 }
2431 case DEFCONTEXT_MNT:
2432 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
2433 goto out_bad_option;
2434 break;
2435 default:
2436 goto out_free_opts;
2437 }
2438 }
2439
2440 rc = 0;
2441out_free_opts:
2442 security_free_mnt_opts(&opts);
2443out_free_secdata:
2444 free_secdata(secdata);
2445 return rc;
2446out_bad_option:
2447 printk(KERN_WARNING "SELinux: unable to change security options "
2448 "during remount (dev %s, type=%s)\n", sb->s_id,
2449 sb->s_type->name);
2450 goto out_free_opts;
2451}
2452
2446static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) 2453static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
2447{ 2454{
2448 const struct cred *cred = current_cred(); 2455 const struct cred *cred = current_cred();
@@ -2509,8 +2516,8 @@ static void selinux_inode_free_security(struct inode *inode)
2509} 2516}
2510 2517
2511static int selinux_inode_init_security(struct inode *inode, struct inode *dir, 2518static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2512 char **name, void **value, 2519 const struct qstr *qstr, char **name,
2513 size_t *len) 2520 void **value, size_t *len)
2514{ 2521{
2515 const struct task_security_struct *tsec = current_security(); 2522 const struct task_security_struct *tsec = current_security();
2516 struct inode_security_struct *dsec; 2523 struct inode_security_struct *dsec;
@@ -2531,7 +2538,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2531 else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 2538 else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
2532 rc = security_transition_sid(sid, dsec->sid, 2539 rc = security_transition_sid(sid, dsec->sid,
2533 inode_mode_to_security_class(inode->i_mode), 2540 inode_mode_to_security_class(inode->i_mode),
2534 &newsid); 2541 qstr, &newsid);
2535 if (rc) { 2542 if (rc) {
2536 printk(KERN_WARNING "%s: " 2543 printk(KERN_WARNING "%s: "
2537 "security_transition_sid failed, rc=%d (dev=%s " 2544 "security_transition_sid failed, rc=%d (dev=%s "
@@ -2718,7 +2725,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2718 if (!(sbsec->flags & SE_SBLABELSUPP)) 2725 if (!(sbsec->flags & SE_SBLABELSUPP))
2719 return -EOPNOTSUPP; 2726 return -EOPNOTSUPP;
2720 2727
2721 if (!is_owner_or_cap(inode)) 2728 if (!inode_owner_or_capable(inode))
2722 return -EPERM; 2729 return -EPERM;
2723 2730
2724 COMMON_AUDIT_DATA_INIT(&ad, FS); 2731 COMMON_AUDIT_DATA_INIT(&ad, FS);
@@ -2829,7 +2836,8 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
2829 * and lack of permission just means that we fall back to the 2836 * and lack of permission just means that we fall back to the
2830 * in-core context value, not a denial. 2837 * in-core context value, not a denial.
2831 */ 2838 */
2832 error = selinux_capable(current, current_cred(), CAP_MAC_ADMIN, 2839 error = selinux_capable(current, current_cred(),
2840 &init_user_ns, CAP_MAC_ADMIN,
2833 SECURITY_CAP_NOAUDIT); 2841 SECURITY_CAP_NOAUDIT);
2834 if (!error) 2842 if (!error)
2835 error = security_sid_to_context_force(isec->sid, &context, 2843 error = security_sid_to_context_force(isec->sid, &context,
@@ -2932,16 +2940,47 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
2932 unsigned long arg) 2940 unsigned long arg)
2933{ 2941{
2934 const struct cred *cred = current_cred(); 2942 const struct cred *cred = current_cred();
2935 u32 av = 0; 2943 int error = 0;
2936 2944
2937 if (_IOC_DIR(cmd) & _IOC_WRITE) 2945 switch (cmd) {
2938 av |= FILE__WRITE; 2946 case FIONREAD:
2939 if (_IOC_DIR(cmd) & _IOC_READ) 2947 /* fall through */
2940 av |= FILE__READ; 2948 case FIBMAP:
2941 if (!av) 2949 /* fall through */
2942 av = FILE__IOCTL; 2950 case FIGETBSZ:
2951 /* fall through */
2952 case EXT2_IOC_GETFLAGS:
2953 /* fall through */
2954 case EXT2_IOC_GETVERSION:
2955 error = file_has_perm(cred, file, FILE__GETATTR);
2956 break;
2957
2958 case EXT2_IOC_SETFLAGS:
2959 /* fall through */
2960 case EXT2_IOC_SETVERSION:
2961 error = file_has_perm(cred, file, FILE__SETATTR);
2962 break;
2963
2964 /* sys_ioctl() checks */
2965 case FIONBIO:
2966 /* fall through */
2967 case FIOASYNC:
2968 error = file_has_perm(cred, file, 0);
2969 break;
2970
2971 case KDSKBENT:
2972 case KDSKBSENT:
2973 error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG,
2974 SECURITY_CAP_AUDIT);
2975 break;
2943 2976
2944 return file_has_perm(cred, file, av); 2977 /* default case assumes that the command will go
2978 * to the file's ioctl() function.
2979 */
2980 default:
2981 error = file_has_perm(cred, file, FILE__IOCTL);
2982 }
2983 return error;
2945} 2984}
2946 2985
2947static int default_noexec; 2986static int default_noexec;
@@ -3198,7 +3237,11 @@ static void selinux_cred_free(struct cred *cred)
3198{ 3237{
3199 struct task_security_struct *tsec = cred->security; 3238 struct task_security_struct *tsec = cred->security;
3200 3239
3201 BUG_ON((unsigned long) cred->security < PAGE_SIZE); 3240 /*
3241 * cred->security == NULL if security_cred_alloc_blank() or
3242 * security_prepare_creds() returned an error.
3243 */
3244 BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE);
3202 cred->security = (void *) 0x7UL; 3245 cred->security = (void *) 0x7UL;
3203 kfree(tsec); 3246 kfree(tsec);
3204} 3247}
@@ -3640,9 +3683,16 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3640 3683
3641/* socket security operations */ 3684/* socket security operations */
3642 3685
3643static u32 socket_sockcreate_sid(const struct task_security_struct *tsec) 3686static int socket_sockcreate_sid(const struct task_security_struct *tsec,
3687 u16 secclass, u32 *socksid)
3644{ 3688{
3645 return tsec->sockcreate_sid ? : tsec->sid; 3689 if (tsec->sockcreate_sid > SECSID_NULL) {
3690 *socksid = tsec->sockcreate_sid;
3691 return 0;
3692 }
3693
3694 return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL,
3695 socksid);
3646} 3696}
3647 3697
3648static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) 3698static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
@@ -3666,12 +3716,16 @@ static int selinux_socket_create(int family, int type,
3666 const struct task_security_struct *tsec = current_security(); 3716 const struct task_security_struct *tsec = current_security();
3667 u32 newsid; 3717 u32 newsid;
3668 u16 secclass; 3718 u16 secclass;
3719 int rc;
3669 3720
3670 if (kern) 3721 if (kern)
3671 return 0; 3722 return 0;
3672 3723
3673 newsid = socket_sockcreate_sid(tsec);
3674 secclass = socket_type_to_security_class(family, type, protocol); 3724 secclass = socket_type_to_security_class(family, type, protocol);
3725 rc = socket_sockcreate_sid(tsec, secclass, &newsid);
3726 if (rc)
3727 return rc;
3728
3675 return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL); 3729 return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
3676} 3730}
3677 3731
@@ -3683,12 +3737,16 @@ static int selinux_socket_post_create(struct socket *sock, int family,
3683 struct sk_security_struct *sksec; 3737 struct sk_security_struct *sksec;
3684 int err = 0; 3738 int err = 0;
3685 3739
3740 isec->sclass = socket_type_to_security_class(family, type, protocol);
3741
3686 if (kern) 3742 if (kern)
3687 isec->sid = SECINITSID_KERNEL; 3743 isec->sid = SECINITSID_KERNEL;
3688 else 3744 else {
3689 isec->sid = socket_sockcreate_sid(tsec); 3745 err = socket_sockcreate_sid(tsec, isec->sclass, &(isec->sid));
3746 if (err)
3747 return err;
3748 }
3690 3749
3691 isec->sclass = socket_type_to_security_class(family, type, protocol);
3692 isec->initialized = 1; 3750 isec->initialized = 1;
3693 3751
3694 if (sock->sk) { 3752 if (sock->sk) {
@@ -3998,7 +4056,6 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
3998{ 4056{
3999 int err = 0; 4057 int err = 0;
4000 struct sk_security_struct *sksec = sk->sk_security; 4058 struct sk_security_struct *sksec = sk->sk_security;
4001 u32 peer_sid;
4002 u32 sk_sid = sksec->sid; 4059 u32 sk_sid = sksec->sid;
4003 struct common_audit_data ad; 4060 struct common_audit_data ad;
4004 char *addrp; 4061 char *addrp;
@@ -4017,20 +4074,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
4017 return err; 4074 return err;
4018 } 4075 }
4019 4076
4020 if (selinux_policycap_netpeer) { 4077 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4021 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); 4078 if (err)
4022 if (err) 4079 return err;
4023 return err; 4080 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
4024 err = avc_has_perm(sk_sid, peer_sid,
4025 SECCLASS_PEER, PEER__RECV, &ad);
4026 if (err)
4027 selinux_netlbl_err(skb, err, 0);
4028 } else {
4029 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4030 if (err)
4031 return err;
4032 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
4033 }
4034 4081
4035 return err; 4082 return err;
4036} 4083}
@@ -4302,7 +4349,7 @@ static void selinux_secmark_refcount_dec(void)
4302static void selinux_req_classify_flow(const struct request_sock *req, 4349static void selinux_req_classify_flow(const struct request_sock *req,
4303 struct flowi *fl) 4350 struct flowi *fl)
4304{ 4351{
4305 fl->secid = req->secid; 4352 fl->flowi_secid = req->secid;
4306} 4353}
4307 4354
4308static int selinux_tun_dev_create(void) 4355static int selinux_tun_dev_create(void)
@@ -4525,9 +4572,8 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
4525 SECCLASS_PACKET, PACKET__SEND, &ad)) 4572 SECCLASS_PACKET, PACKET__SEND, &ad))
4526 return NF_DROP_ERR(-ECONNREFUSED); 4573 return NF_DROP_ERR(-ECONNREFUSED);
4527 4574
4528 if (selinux_policycap_netpeer) 4575 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
4529 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) 4576 return NF_DROP_ERR(-ECONNREFUSED);
4530 return NF_DROP_ERR(-ECONNREFUSED);
4531 4577
4532 return NF_ACCEPT; 4578 return NF_ACCEPT;
4533} 4579}
@@ -4570,27 +4616,14 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4570 * from the sending socket, otherwise use the kernel's sid */ 4616 * from the sending socket, otherwise use the kernel's sid */
4571 sk = skb->sk; 4617 sk = skb->sk;
4572 if (sk == NULL) { 4618 if (sk == NULL) {
4573 switch (family) { 4619 if (skb->skb_iif) {
4574 case PF_INET: 4620 secmark_perm = PACKET__FORWARD_OUT;
4575 if (IPCB(skb)->flags & IPSKB_FORWARDED)
4576 secmark_perm = PACKET__FORWARD_OUT;
4577 else
4578 secmark_perm = PACKET__SEND;
4579 break;
4580 case PF_INET6:
4581 if (IP6CB(skb)->flags & IP6SKB_FORWARDED)
4582 secmark_perm = PACKET__FORWARD_OUT;
4583 else
4584 secmark_perm = PACKET__SEND;
4585 break;
4586 default:
4587 return NF_DROP_ERR(-ECONNREFUSED);
4588 }
4589 if (secmark_perm == PACKET__FORWARD_OUT) {
4590 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) 4621 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
4591 return NF_DROP; 4622 return NF_DROP;
4592 } else 4623 } else {
4624 secmark_perm = PACKET__SEND;
4593 peer_sid = SECINITSID_KERNEL; 4625 peer_sid = SECINITSID_KERNEL;
4626 }
4594 } else { 4627 } else {
4595 struct sk_security_struct *sksec = sk->sk_security; 4628 struct sk_security_struct *sksec = sk->sk_security;
4596 peer_sid = sksec->sid; 4629 peer_sid = sksec->sid;
@@ -4665,6 +4698,7 @@ static int selinux_netlink_recv(struct sk_buff *skb, int capability)
4665{ 4698{
4666 int err; 4699 int err;
4667 struct common_audit_data ad; 4700 struct common_audit_data ad;
4701 u32 sid;
4668 4702
4669 err = cap_netlink_recv(skb, capability); 4703 err = cap_netlink_recv(skb, capability);
4670 if (err) 4704 if (err)
@@ -4673,8 +4707,9 @@ static int selinux_netlink_recv(struct sk_buff *skb, int capability)
4673 COMMON_AUDIT_DATA_INIT(&ad, CAP); 4707 COMMON_AUDIT_DATA_INIT(&ad, CAP);
4674 ad.u.cap = capability; 4708 ad.u.cap = capability;
4675 4709
4676 return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, 4710 security_task_getsecid(current, &sid);
4677 SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad); 4711 return avc_has_perm(sid, sid, SECCLASS_CAPABILITY,
4712 CAP_TO_MASK(capability), &ad);
4678} 4713}
4679 4714
4680static int ipc_alloc_security(struct task_struct *task, 4715static int ipc_alloc_security(struct task_struct *task,
@@ -4844,7 +4879,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
4844 * message queue this message will be stored in 4879 * message queue this message will be stored in
4845 */ 4880 */
4846 rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG, 4881 rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG,
4847 &msec->sid); 4882 NULL, &msec->sid);
4848 if (rc) 4883 if (rc)
4849 return rc; 4884 return rc;
4850 } 4885 }
@@ -5398,7 +5433,6 @@ static struct security_operations selinux_ops = {
5398 .ptrace_traceme = selinux_ptrace_traceme, 5433 .ptrace_traceme = selinux_ptrace_traceme,
5399 .capget = selinux_capget, 5434 .capget = selinux_capget,
5400 .capset = selinux_capset, 5435 .capset = selinux_capset,
5401 .sysctl = selinux_sysctl,
5402 .capable = selinux_capable, 5436 .capable = selinux_capable,
5403 .quotactl = selinux_quotactl, 5437 .quotactl = selinux_quotactl,
5404 .quota_on = selinux_quota_on, 5438 .quota_on = selinux_quota_on,
@@ -5416,6 +5450,7 @@ static struct security_operations selinux_ops = {
5416 .sb_alloc_security = selinux_sb_alloc_security, 5450 .sb_alloc_security = selinux_sb_alloc_security,
5417 .sb_free_security = selinux_sb_free_security, 5451 .sb_free_security = selinux_sb_free_security,
5418 .sb_copy_data = selinux_sb_copy_data, 5452 .sb_copy_data = selinux_sb_copy_data,
5453 .sb_remount = selinux_sb_remount,
5419 .sb_kern_mount = selinux_sb_kern_mount, 5454 .sb_kern_mount = selinux_sb_kern_mount,
5420 .sb_show_options = selinux_sb_show_options, 5455 .sb_show_options = selinux_sb_show_options,
5421 .sb_statfs = selinux_sb_statfs, 5456 .sb_statfs = selinux_sb_statfs,