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 = cred ? get_cred(cred) : NULL;
  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        memset(scm, 0, sizeof(*scm));
  77        unix_get_peersec_dgram(sock, scm);
  78        if (msg->msg_controllen <= 0)
  79                return 0;
  80        return __scm_send(sock, msg, scm);
  81}
  82
  83#ifdef CONFIG_SECURITY_NETWORK
  84static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
  85{
  86        char *secdata;
  87        u32 seclen;
  88        int err;
  89
  90        if (test_bit(SOCK_PASSSEC, &sock->flags)) {
  91                err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
  92
  93                if (!err) {
  94                        put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
  95                        security_release_secctx(secdata, seclen);
  96                }
  97        }
  98}
  99#else
 100static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
 101{ }
 102#endif /* CONFIG_SECURITY_NETWORK */
 103
 104static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 105                                struct scm_cookie *scm, int flags)
 106{
 107        if (!msg->msg_control) {
 108                if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
 109                        msg->msg_flags |= MSG_CTRUNC;
 110                scm_destroy(scm);
 111                return;
 112        }
 113
 114        if (test_bit(SOCK_PASSCRED, &sock->flags))
 115                put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
 116
 117        scm_destroy_cred(scm);
 118
 119        scm_passec(sock, msg, scm);
 120
 121        if (!scm->fp)
 122                return;
 123        
 124        scm_detach_fds(msg, scm);
 125}
 126
 127
 128#endif /* __LINUX_NET_SCM_H */
 129
 130