[PATCH] Miscellaneous bug and warning fixes
[powerpc.git] / security / selinux / hooks.c
index 4ae834d..81b726b 100644 (file)
@@ -117,6 +117,32 @@ static struct security_operations *secondary_ops = NULL;
 static LIST_HEAD(superblock_security_head);
 static DEFINE_SPINLOCK(sb_security_lock);
 
+/* Return security context for a given sid or just the context 
+   length if the buffer is null or length is 0 */
+static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
+{
+       char *context;
+       unsigned len;
+       int rc;
+
+       rc = security_sid_to_context(sid, &context, &len);
+       if (rc)
+               return rc;
+
+       if (!buffer || !size)
+               goto getsecurity_exit;
+
+       if (size < len) {
+               len = -ERANGE;
+               goto getsecurity_exit;
+       }
+       memcpy(buffer, context, len);
+
+getsecurity_exit:
+       kfree(context);
+       return len;
+}
+
 /* Allocate and free functions for each kind of security blob. */
 
 static int task_alloc_security(struct task_struct *task)
@@ -232,7 +258,6 @@ static void superblock_free_security(struct super_block *sb)
        kfree(sbsec);
 }
 
-#ifdef CONFIG_SECURITY_NETWORK
 static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
 {
        struct sk_security_struct *ssec;
@@ -261,7 +286,6 @@ static void sk_free_security(struct sock *sk)
        sk->sk_security = NULL;
        kfree(ssec);
 }
-#endif /* CONFIG_SECURITY_NETWORK */
 
 /* The security server must be initialized before
    any labeling or access decisions can be provided. */
@@ -1264,7 +1288,7 @@ static int selinux_ptrace(struct task_struct *parent, struct task_struct *child)
 
        rc = task_has_perm(parent, child, PROCESS__PTRACE);
        /* Save the SID of the tracing process for later use in apply_creds. */
-       if (!rc)
+       if (!(child->ptrace & PT_PTRACED) && !rc)
                csec->ptrace_sid = psec->sid;
        return rc;
 }
@@ -2211,6 +2235,11 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
        return -EACCES;
 }
 
+static const char *selinux_inode_xattr_getsuffix(void)
+{
+      return XATTR_SELINUX_SUFFIX;
+}
+
 /*
  * Copy the in-core inode security context value to the user.  If the
  * getxattr() prior to this succeeded, check to see if we need to
@@ -2218,47 +2247,14 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
  *
  * Permission check is handled by selinux_inode_getxattr hook.
  */
-static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err)
+static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
 {
        struct inode_security_struct *isec = inode->i_security;
-       char *context;
-       unsigned len;
-       int rc;
-
-       if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
-               rc = -EOPNOTSUPP;
-               goto out;
-       }
-
-       rc = security_sid_to_context(isec->sid, &context, &len);
-       if (rc)
-               goto out;
-
-       /* Probe for required buffer size */
-       if (!buffer || !size) {
-               rc = len;
-               goto out_free;
-       }
 
-       if (size < len) {
-               rc = -ERANGE;
-               goto out_free;
-       }
+       if (strcmp(name, XATTR_SELINUX_SUFFIX))
+               return -EOPNOTSUPP;
 
-       if (err > 0) {
-               if ((len == err) && !(memcmp(context, buffer, len))) {
-                       /* Don't need to canonicalize value */
-                       rc = err;
-                       goto out_free;
-               }
-               memset(buffer, 0, size);
-       }
-       memcpy(buffer, context, len);
-       rc = len;
-out_free:
-       kfree(context);
-out:
-       return rc;
+       return selinux_getsecurity(isec->sid, buffer, size);
 }
 
 static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -2736,8 +2732,6 @@ static void selinux_task_to_inode(struct task_struct *p,
        return;
 }
 
-#ifdef CONFIG_SECURITY_NETWORK
-
 /* Returns error only if unable to parse addresses */
 static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad)
 {
@@ -3556,15 +3550,6 @@ static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum,
 
 #endif /* CONFIG_NETFILTER */
 
-#else
-
-static inline int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
-{
-       return 0;
-}
-
-#endif /* CONFIG_SECURITY_NETWORK */
-
 static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
        struct task_security_struct *tsec;
@@ -4035,6 +4020,13 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
        return ipc_has_perm(ipcp, av);
 }
 
+static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
+{
+       struct ipc_security_struct *isec = ipcp->security;
+
+       return selinux_getsecurity(isec->sid, buffer, size);
+}
+
 /* module stacking operations */
 static int selinux_register_security (const char *name, struct security_operations *ops)
 {
@@ -4076,8 +4068,7 @@ static int selinux_getprocattr(struct task_struct *p,
                               char *name, void *value, size_t size)
 {
        struct task_security_struct *tsec;
-       u32 sid, len;
-       char *context;
+       u32 sid;
        int error;
 
        if (current != p) {
@@ -4086,9 +4077,6 @@ static int selinux_getprocattr(struct task_struct *p,
                        return error;
        }
 
-       if (!size)
-               return -ERANGE;
-
        tsec = p->security;
 
        if (!strcmp(name, "current"))
@@ -4105,16 +4093,7 @@ static int selinux_getprocattr(struct task_struct *p,
        if (!sid)
                return 0;
 
-       error = security_sid_to_context(sid, &context, &len);
-       if (error)
-               return error;
-       if (len > size) {
-               kfree(context);
-               return -ERANGE;
-       }
-       memcpy(value, context, len);
-       kfree(context);
-       return len;
+       return selinux_getsecurity(sid, value, size);
 }
 
 static int selinux_setprocattr(struct task_struct *p,
@@ -4272,6 +4251,7 @@ static struct security_operations selinux_ops = {
        .inode_getxattr =               selinux_inode_getxattr,
        .inode_listxattr =              selinux_inode_listxattr,
        .inode_removexattr =            selinux_inode_removexattr,
+       .inode_xattr_getsuffix =        selinux_inode_xattr_getsuffix,
        .inode_getsecurity =            selinux_inode_getsecurity,
        .inode_setsecurity =            selinux_inode_setsecurity,
        .inode_listsecurity =           selinux_inode_listsecurity,
@@ -4309,6 +4289,7 @@ static struct security_operations selinux_ops = {
        .task_to_inode =                selinux_task_to_inode,
 
        .ipc_permission =               selinux_ipc_permission,
+       .ipc_getsecurity =              selinux_ipc_getsecurity,
 
        .msg_msg_alloc_security =       selinux_msg_msg_alloc_security,
        .msg_msg_free_security =        selinux_msg_msg_free_security,
@@ -4340,7 +4321,6 @@ static struct security_operations selinux_ops = {
        .getprocattr =                  selinux_getprocattr,
        .setprocattr =                  selinux_setprocattr,
 
-#ifdef CONFIG_SECURITY_NETWORK
         .unix_stream_connect =         selinux_socket_unix_stream_connect,
        .unix_may_send =                selinux_socket_unix_may_send,
 
@@ -4362,7 +4342,6 @@ static struct security_operations selinux_ops = {
        .sk_alloc_security =            selinux_sk_alloc_security,
        .sk_free_security =             selinux_sk_free_security,
        .sk_getsid =                    selinux_sk_getsid_security,
-#endif
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
        .xfrm_policy_alloc_security =   selinux_xfrm_policy_alloc,
@@ -4440,7 +4419,7 @@ next_sb:
    all processes and objects when they are created. */
 security_initcall(selinux_init);
 
-#if defined(CONFIG_SECURITY_NETWORK) && defined(CONFIG_NETFILTER)
+#if defined(CONFIG_NETFILTER)
 
 static struct nf_hook_ops selinux_ipv4_op = {
        .hook =         selinux_ipv4_postroute_last,
@@ -4501,13 +4480,13 @@ static void selinux_nf_ip_exit(void)
 }
 #endif
 
-#else /* CONFIG_SECURITY_NETWORK && CONFIG_NETFILTER */
+#else /* CONFIG_NETFILTER */
 
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 #define selinux_nf_ip_exit()
 #endif
 
-#endif /* CONFIG_SECURITY_NETWORK && CONFIG_NETFILTER */
+#endif /* CONFIG_NETFILTER */
 
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 int selinux_disable(void)