diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 102 |
1 files changed, 81 insertions, 21 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6da7532893a1..29c39e0b03ed 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -401,23 +401,14 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) | |||
401 | { | 401 | { |
402 | struct superblock_security_struct *sbsec = sb->s_security; | 402 | struct superblock_security_struct *sbsec = sb->s_security; |
403 | 403 | ||
404 | if (sbsec->behavior == SECURITY_FS_USE_XATTR || | 404 | return sbsec->behavior == SECURITY_FS_USE_XATTR || |
405 | sbsec->behavior == SECURITY_FS_USE_TRANS || | 405 | sbsec->behavior == SECURITY_FS_USE_TRANS || |
406 | sbsec->behavior == SECURITY_FS_USE_TASK) | 406 | sbsec->behavior == SECURITY_FS_USE_TASK || |
407 | return 1; | 407 | /* Special handling. Genfs but also in-core setxattr handler */ |
408 | 408 | !strcmp(sb->s_type->name, "sysfs") || | |
409 | /* Special handling for sysfs. Is genfs but also has setxattr handler*/ | 409 | !strcmp(sb->s_type->name, "pstore") || |
410 | if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0) | 410 | !strcmp(sb->s_type->name, "debugfs") || |
411 | return 1; | 411 | !strcmp(sb->s_type->name, "rootfs"); |
412 | |||
413 | /* | ||
414 | * Special handling for rootfs. Is genfs but supports | ||
415 | * setting SELinux context on in-core inodes. | ||
416 | */ | ||
417 | if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0) | ||
418 | return 1; | ||
419 | |||
420 | return 0; | ||
421 | } | 412 | } |
422 | 413 | ||
423 | static int sb_finish_set_opts(struct super_block *sb) | 414 | static int sb_finish_set_opts(struct super_block *sb) |
@@ -456,10 +447,6 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
456 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) | 447 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) |
457 | printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", | 448 | printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", |
458 | sb->s_id, sb->s_type->name); | 449 | sb->s_id, sb->s_type->name); |
459 | else | ||
460 | printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n", | ||
461 | sb->s_id, sb->s_type->name, | ||
462 | labeling_behaviors[sbsec->behavior-1]); | ||
463 | 450 | ||
464 | sbsec->flags |= SE_SBINITIALIZED; | 451 | sbsec->flags |= SE_SBINITIALIZED; |
465 | if (selinux_is_sblabel_mnt(sb)) | 452 | if (selinux_is_sblabel_mnt(sb)) |
@@ -1933,6 +1920,74 @@ static inline u32 open_file_to_av(struct file *file) | |||
1933 | 1920 | ||
1934 | /* Hook functions begin here. */ | 1921 | /* Hook functions begin here. */ |
1935 | 1922 | ||
1923 | static int selinux_binder_set_context_mgr(struct task_struct *mgr) | ||
1924 | { | ||
1925 | u32 mysid = current_sid(); | ||
1926 | u32 mgrsid = task_sid(mgr); | ||
1927 | |||
1928 | return avc_has_perm(mysid, mgrsid, SECCLASS_BINDER, | ||
1929 | BINDER__SET_CONTEXT_MGR, NULL); | ||
1930 | } | ||
1931 | |||
1932 | static int selinux_binder_transaction(struct task_struct *from, | ||
1933 | struct task_struct *to) | ||
1934 | { | ||
1935 | u32 mysid = current_sid(); | ||
1936 | u32 fromsid = task_sid(from); | ||
1937 | u32 tosid = task_sid(to); | ||
1938 | int rc; | ||
1939 | |||
1940 | if (mysid != fromsid) { | ||
1941 | rc = avc_has_perm(mysid, fromsid, SECCLASS_BINDER, | ||
1942 | BINDER__IMPERSONATE, NULL); | ||
1943 | if (rc) | ||
1944 | return rc; | ||
1945 | } | ||
1946 | |||
1947 | return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__CALL, | ||
1948 | NULL); | ||
1949 | } | ||
1950 | |||
1951 | static int selinux_binder_transfer_binder(struct task_struct *from, | ||
1952 | struct task_struct *to) | ||
1953 | { | ||
1954 | u32 fromsid = task_sid(from); | ||
1955 | u32 tosid = task_sid(to); | ||
1956 | |||
1957 | return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER, | ||
1958 | NULL); | ||
1959 | } | ||
1960 | |||
1961 | static int selinux_binder_transfer_file(struct task_struct *from, | ||
1962 | struct task_struct *to, | ||
1963 | struct file *file) | ||
1964 | { | ||
1965 | u32 sid = task_sid(to); | ||
1966 | struct file_security_struct *fsec = file->f_security; | ||
1967 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1968 | struct inode_security_struct *isec = inode->i_security; | ||
1969 | struct common_audit_data ad; | ||
1970 | int rc; | ||
1971 | |||
1972 | ad.type = LSM_AUDIT_DATA_PATH; | ||
1973 | ad.u.path = file->f_path; | ||
1974 | |||
1975 | if (sid != fsec->sid) { | ||
1976 | rc = avc_has_perm(sid, fsec->sid, | ||
1977 | SECCLASS_FD, | ||
1978 | FD__USE, | ||
1979 | &ad); | ||
1980 | if (rc) | ||
1981 | return rc; | ||
1982 | } | ||
1983 | |||
1984 | if (unlikely(IS_PRIVATE(inode))) | ||
1985 | return 0; | ||
1986 | |||
1987 | return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file), | ||
1988 | &ad); | ||
1989 | } | ||
1990 | |||
1936 | static int selinux_ptrace_access_check(struct task_struct *child, | 1991 | static int selinux_ptrace_access_check(struct task_struct *child, |
1937 | unsigned int mode) | 1992 | unsigned int mode) |
1938 | { | 1993 | { |
@@ -5810,6 +5865,11 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) | |||
5810 | static struct security_operations selinux_ops = { | 5865 | static struct security_operations selinux_ops = { |
5811 | .name = "selinux", | 5866 | .name = "selinux", |
5812 | 5867 | ||
5868 | .binder_set_context_mgr = selinux_binder_set_context_mgr, | ||
5869 | .binder_transaction = selinux_binder_transaction, | ||
5870 | .binder_transfer_binder = selinux_binder_transfer_binder, | ||
5871 | .binder_transfer_file = selinux_binder_transfer_file, | ||
5872 | |||
5813 | .ptrace_access_check = selinux_ptrace_access_check, | 5873 | .ptrace_access_check = selinux_ptrace_access_check, |
5814 | .ptrace_traceme = selinux_ptrace_traceme, | 5874 | .ptrace_traceme = selinux_ptrace_traceme, |
5815 | .capget = selinux_capget, | 5875 | .capget = selinux_capget, |