linux/include/net/scm.h
<<
>>
Prefs
   1#ifndef __LINUX_NET_SCM_H
   2#define __LINUX_NET_SCM_H
   3
   4#include <linux/limits.h>
   5#include <linux/net.h>
   6#include <linux/security.h>
   7#include <linux/pid.h>
   8#include <linux/nsproxy.h>
   9
  10/* Well, we should have at least one descriptor open
  11 * to accept passed FDs 8)
  12 */
  13#define SCM_MAX_FD      255
  14
  15struct scm_fp_list
  16{
  17        int             count;
  18        struct file     *fp[SCM_MAX_FD];
  19};
  20
  21struct scm_cookie
  22{
  23        struct ucred            creds;          /* Skb credentials      */
  24        struct scm_fp_list      *fp;            /* Passed files         */
  25#ifdef CONFIG_SECURITY_NETWORK
  26        u32                     secid;          /* Passed security ID   */
  27#endif
  28        unsigned long           seq;            /* Connection seqno     */
  29};
  30
  31extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
  32extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
  33extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
  34extern void __scm_destroy(struct scm_cookie *scm);
  35extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
  36
  37#ifdef CONFIG_SECURITY_NETWORK
  38static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
  39{
  40        security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
  41}
  42#else
  43static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
  44{ }
  45#endif /* CONFIG_SECURITY_NETWORK */
  46
  47static __inline__ void scm_destroy(struct scm_cookie *scm)
  48{
  49        if (scm && scm->fp)
  50                __scm_destroy(scm);
  51}
  52
  53static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
  54                               struct scm_cookie *scm)
  55{
  56        struct task_struct *p = current;
  57        scm->creds.uid = p->uid;
  58        scm->creds.gid = p->gid;
  59        scm->creds.pid = task_tgid_vnr(p);
  60        scm->fp = NULL;
  61        scm->seq = 0;
  62        unix_get_peersec_dgram(sock, scm);
  63        if (msg->msg_controllen <= 0)
  64                return 0;
  65        return __scm_send(sock, msg, scm);
  66}
  67
  68#ifdef CONFIG_SECURITY_NETWORK
  69static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
  70{
  71        char *secdata;
  72        u32 seclen;
  73        int err;
  74
  75        if (test_bit(SOCK_PASSSEC, &sock->flags)) {
  76                err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
  77
  78                if (!err) {
  79                        put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
  80                        security_release_secctx(secdata, seclen);
  81                }
  82        }
  83}
  84#else
  85static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
  86{ }
  87#endif /* CONFIG_SECURITY_NETWORK */
  88
  89static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
  90                                struct scm_cookie *scm, int flags)
  91{
  92        if (!msg->msg_control)
  93        {
  94                if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
  95                        msg->msg_flags |= MSG_CTRUNC;
  96                scm_destroy(scm);
  97                return;
  98        }
  99
 100        if (test_bit(SOCK_PASSCRED, &sock->flags))
 101                put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
 102
 103        scm_passec(sock, msg, scm);
 104
 105        if (!scm->fp)
 106                return;
 107        
 108        scm_detach_fds(msg, scm);
 109}
 110
 111
 112#endif /* __LINUX_NET_SCM_H */
 113
 114