tty: isicom: sort out the board init logic
[safe/jmp/linux-2.6] / include / net / scm.h
index 540619c..8360e47 100644 (file)
@@ -3,23 +3,27 @@
 
 #include <linux/limits.h>
 #include <linux/net.h>
+#include <linux/security.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
 
 /* Well, we should have at least one descriptor open
  * to accept passed FDs 8)
  */
-#define SCM_MAX_FD     (OPEN_MAX-1)
+#define SCM_MAX_FD     255
 
-struct scm_fp_list
-{
-       int             count;
-       struct file     *fp[SCM_MAX_FD];
+struct scm_fp_list {
+       struct list_head        list;
+       int                     count;
+       struct file             *fp[SCM_MAX_FD];
 };
 
-struct scm_cookie
-{
+struct scm_cookie {
        struct ucred            creds;          /* Skb credentials      */
        struct scm_fp_list      *fp;            /* Passed files         */
-       unsigned long           seq;            /* Connection seqno     */
+#ifdef CONFIG_SECURITY_NETWORK
+       u32                     secid;          /* Passed security ID   */
+#endif
 };
 
 extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
@@ -28,6 +32,16 @@ extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie
 extern void __scm_destroy(struct scm_cookie *scm);
 extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
 
+#ifdef CONFIG_SECURITY_NETWORK
+static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
+{
+       security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
+}
+#else
+static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
+{ }
+#endif /* CONFIG_SECURITY_NETWORK */
+
 static __inline__ void scm_destroy(struct scm_cookie *scm)
 {
        if (scm && scm->fp)
@@ -38,21 +52,41 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
                               struct scm_cookie *scm)
 {
        struct task_struct *p = current;
-       scm->creds.uid = p->uid;
-       scm->creds.gid = p->gid;
-       scm->creds.pid = p->tgid;
+       scm->creds.uid = current_uid();
+       scm->creds.gid = current_gid();
+       scm->creds.pid = task_tgid_vnr(p);
        scm->fp = NULL;
-       scm->seq = 0;
+       unix_get_peersec_dgram(sock, scm);
        if (msg->msg_controllen <= 0)
                return 0;
        return __scm_send(sock, msg, scm);
 }
 
+#ifdef CONFIG_SECURITY_NETWORK
+static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
+{
+       char *secdata;
+       u32 seclen;
+       int err;
+
+       if (test_bit(SOCK_PASSSEC, &sock->flags)) {
+               err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
+
+               if (!err) {
+                       put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
+                       security_release_secctx(secdata, seclen);
+               }
+       }
+}
+#else
+static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
+{ }
+#endif /* CONFIG_SECURITY_NETWORK */
+
 static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
                                struct scm_cookie *scm, int flags)
 {
-       if (!msg->msg_control)
-       {
+       if (!msg->msg_control) {
                if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
                        msg->msg_flags |= MSG_CTRUNC;
                scm_destroy(scm);
@@ -62,6 +96,8 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
        if (test_bit(SOCK_PASSCRED, &sock->flags))
                put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
 
+       scm_passec(sock, msg, scm);
+
        if (!scm->fp)
                return;