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      253
  14
  15struct scm_fp_list {
  16        struct list_head        list;
  17        short                   count;
  18        short                   max;
  19        struct file             *fp[SCM_MAX_FD];
  20};
  21
  22struct scm_cookie {
  23        struct pid              *pid;           /* Skb credentials */
  24        const struct cred       *cred;
  25        struct scm_fp_list      *fp;            /* Passed files         */
  26        struct ucred            creds;          /* Skb credentials      */
  27#ifdef CONFIG_SECURITY_NETWORK
  28        u32                     secid;          /* Passed security ID   */
  29#endif
  30};
  31
  32extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
  33extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
  34extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
  35extern void __scm_destroy(struct scm_cookie *scm);
  36extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
  37
  38#ifdef CONFIG_SECURITY_NETWORK
  39static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
  40{
  41        security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
  42}
  43#else
  44static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
  45{ }
  46#endif /* CONFIG_SECURITY_NETWORK */
  47
  48static __inline__ void scm_set_cred(struct scm_cookie *scm,
  49                                    struct pid *pid, const struct cred *cred)
  50{
  51        scm->pid  = get_pid(pid);
  52        scm->cred = get_cred(cred);
  53        cred_to_ucred(pid, cred, &scm->creds);
  54}
  55
  56static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
  57{
  58        put_pid(scm->pid);
  59        scm->pid  = NULL;
  60
  61        if (scm->cred)
  62                put_cred(scm->cred);
  63        scm->cred = NULL;
  64}
  65
  66static __inline__ void scm_destroy(struct scm_cookie *scm)
  67{
  68        scm_destroy_cred(scm);
  69        if (scm && scm->fp)
  70                __scm_destroy(scm);
  71}
  72
  73static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
  74                               struct scm_cookie *scm)
  75{
  76        scm_set_cred(scm, task_tgid(current), current_cred());
  77        scm->fp = NULL;
  78        unix_get_peersec_dgram(sock, scm);
  79        if (msg->msg_controllen <= 0)
  80                return 0;
  81        return __scm_send(sock, msg, scm);
  82}
  83
  84#ifdef CONFIG_SECURITY_NETWORK
  85static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
  86{
  87        char *secdata;
  88        u32 seclen;
  89        int err;
  90
  91        if (test_bit(SOCK_PASSSEC, &sock->flags)) {
  92                err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
  93
  94                if (!err) {
  95                        put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
  96                        security_release_secctx(secdata, seclen);
  97                }
  98        }
  99}
 100#else
 101static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
 102{ }
 103#endif /* CONFIG_SECURITY_NETWORK */
 104
 105static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 106                                struct scm_cookie *scm, int flags)
 107{
 108        if (!msg->msg_control) {
 109                if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
 110                        msg->msg_flags |= MSG_CTRUNC;
 111                scm_destroy(scm);
 112                return;
 113        }
 114
 115        if (test_bit(SOCK_PASSCRED, &sock->flags))
 116                put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
 117
 118        scm_destroy_cred(scm);
 119
 120        scm_passec(sock, msg, scm);
 121
 122        if (!scm->fp)
 123                return;
 124        
 125        scm_detach_fds(msg, scm);
 126}
 127
 128
 129#endif /* __LINUX_NET_SCM_H */
 130
 131