]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - include/net/scm.h
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[net-next-2.6.git] / include / net / scm.h
index 8360e47aa7e322336099d09163db1b4254e47016..31656506d967a4a2349a74a158cdb3fa3ecb6986 100644 (file)
@@ -19,8 +19,10 @@ struct scm_fp_list {
 };
 
 struct scm_cookie {
-       struct ucred            creds;          /* Skb credentials      */
+       struct pid              *pid;           /* Skb credentials */
+       const struct cred       *cred;
        struct scm_fp_list      *fp;            /* Passed files         */
+       struct ucred            creds;          /* Skb credentials      */
 #ifdef CONFIG_SECURITY_NETWORK
        u32                     secid;          /* Passed security ID   */
 #endif
@@ -42,8 +44,27 @@ static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_co
 { }
 #endif /* CONFIG_SECURITY_NETWORK */
 
+static __inline__ void scm_set_cred(struct scm_cookie *scm,
+                                   struct pid *pid, const struct cred *cred)
+{
+       scm->pid  = get_pid(pid);
+       scm->cred = get_cred(cred);
+       cred_to_ucred(pid, cred, &scm->creds);
+}
+
+static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
+{
+       put_pid(scm->pid);
+       scm->pid  = NULL;
+
+       if (scm->cred)
+               put_cred(scm->cred);
+       scm->cred = NULL;
+}
+
 static __inline__ void scm_destroy(struct scm_cookie *scm)
 {
+       scm_destroy_cred(scm);
        if (scm && scm->fp)
                __scm_destroy(scm);
 }
@@ -51,10 +72,7 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
                               struct scm_cookie *scm)
 {
-       struct task_struct *p = current;
-       scm->creds.uid = current_uid();
-       scm->creds.gid = current_gid();
-       scm->creds.pid = task_tgid_vnr(p);
+       scm_set_cred(scm, task_tgid(current), current_cred());
        scm->fp = NULL;
        unix_get_peersec_dgram(sock, scm);
        if (msg->msg_controllen <= 0)
@@ -96,6 +114,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_destroy_cred(scm);
+
        scm_passec(sock, msg, scm);
 
        if (!scm->fp)