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        struct list_head        list;
  18        int                     count;
  19        struct file             *fp[SCM_MAX_FD];
  20};
  21
  22struct scm_cookie
  23{
  24        struct ucred            creds;          /* Skb credentials      */
  25        struct scm_fp_list      *fp;            /* Passed files         */
  26#ifdef CONFIG_SECURITY_NETWORK
  27        u32                     secid;          /* Passed security ID   */
  28#endif
  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 = current_uid();
  58        scm->creds.gid = current_gid();
  59        scm->creds.pid = task_tgid_vnr(p);
  60        scm->fp = NULL;
  61        unix_get_peersec_dgram(sock, scm);
  62        if (msg->msg_controllen <= 0)
  63                return 0;
  64        return __scm_send(sock, msg, scm);
  65}
  66
  67#ifdef CONFIG_SECURITY_NETWORK
  68static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
  69{
  70        char *secdata;
  71        u32 seclen;
  72        int err;
  73
  74        if (test_bit(SOCK_PASSSEC, &sock->flags)) {
  75                err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
  76
  77                if (!err) {
  78                        put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
  79                        security_release_secctx(secdata, seclen);
  80                }
  81        }
  82}
  83#else
  84static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
  85{ }
  86#endif /* CONFIG_SECURITY_NETWORK */
  87
  88static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
  89                                struct scm_cookie *scm, int flags)
  90{
  91        if (!msg->msg_control)
  92        {
  93                if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
  94                        msg->msg_flags |= MSG_CTRUNC;
  95                scm_destroy(scm);
  96                return;
  97        }
  98
  99        if (test_bit(SOCK_PASSCRED, &sock->flags))
 100                put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
 101
 102        scm_passec(sock, msg, scm);
 103
 104        if (!scm->fp)
 105                return;
 106        
 107        scm_detach_fds(msg, scm);
 108}
 109
 110
 111#endif /* __LINUX_NET_SCM_H */
 112
 113