int i;
 
        scm->fp = UNIXCB(skb).fp;
-       skb->destructor = sock_wfree;
        UNIXCB(skb).fp = NULL;
 
        for (i = scm->fp->count-1; i >= 0; i--)
                unix_notinflight(scm->fp->fp[i]);
 }
 
-static void unix_destruct_fds(struct sk_buff *skb)
+static void unix_destruct_scm(struct sk_buff *skb)
 {
        struct scm_cookie scm;
        memset(&scm, 0, sizeof(scm));
-       unix_detach_fds(&scm, skb);
+       scm.pid  = UNIXCB(skb).pid;
+       scm.cred = UNIXCB(skb).cred;
+       if (UNIXCB(skb).fp)
+               unix_detach_fds(&scm, skb);
 
        /* Alas, it calls VFS */
        /* So fscking what? fput() had been SMP-safe since the last Summer */
 
        for (i = scm->fp->count-1; i >= 0; i--)
                unix_inflight(scm->fp->fp[i]);
-       skb->destructor = unix_destruct_fds;
        return 0;
 }
 
+static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
+{
+       int err = 0;
+       UNIXCB(skb).pid  = get_pid(scm->pid);
+       UNIXCB(skb).cred = get_cred(scm->cred);
+       UNIXCB(skb).fp = NULL;
+       if (scm->fp && send_fds)
+               err = unix_attach_fds(scm, skb);
+
+       skb->destructor = unix_destruct_scm;
+       return err;
+}
+
 /*
  *     Send AF_UNIX data.
  */
        if (skb == NULL)
                goto out;
 
-       memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
-       if (siocb->scm->fp) {
-               err = unix_attach_fds(siocb->scm, skb);
-               if (err)
-                       goto out_free;
-       }
+       err = unix_scm_to_skb(siocb->scm, skb, true);
+       if (err)
+               goto out_free;
        unix_get_secdata(siocb->scm, skb);
 
        skb_reset_transport_header(skb);
                 */
                size = min_t(int, size, skb_tailroom(skb));
 
-               memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
+
                /* Only send the fds in the first buffer */
-               if (siocb->scm->fp && !fds_sent) {
-                       err = unix_attach_fds(siocb->scm, skb);
-                       if (err) {
-                               kfree_skb(skb);
-                               goto out_err;
-                       }
-                       fds_sent = true;
+               err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
+               if (err) {
+                       kfree_skb(skb);
+                       goto out_err;
                }
+               fds_sent = true;
 
                err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
                if (err) {
                siocb->scm = &tmp_scm;
                memset(&tmp_scm, 0, sizeof(tmp_scm));
        }
-       siocb->scm->creds = *UNIXCREDS(skb);
+       scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
        unix_set_secdata(siocb->scm, skb);
 
        if (!(flags & MSG_PEEK)) {
 
                if (check_creds) {
                        /* Never glue messages from different writers */
-                       if (memcmp(UNIXCREDS(skb), &siocb->scm->creds,
-                                  sizeof(siocb->scm->creds)) != 0) {
+                       if ((UNIXCB(skb).pid  != siocb->scm->pid) ||
+                           (UNIXCB(skb).cred != siocb->scm->cred)) {
                                skb_queue_head(&sk->sk_receive_queue, skb);
                                break;
                        }
                } else {
                        /* Copy credentials */
-                       siocb->scm->creds = *UNIXCREDS(skb);
+                       scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
                        check_creds = 1;
                }