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_creds {
  16        u32     pid;
  17        kuid_t  uid;
  18        kgid_t  gid;
  19};
  20
  21struct scm_fp_list {
  22        short                   count;
  23        short                   max;
  24        struct file             *fp[SCM_MAX_FD];
  25};
  26
  27struct scm_cookie {
  28        struct pid              *pid;           /* Skb credentials */
  29        const struct cred       *cred;
  30        struct scm_fp_list      *fp;            /* Passed files         */
  31        struct scm_creds        creds;          /* Skb credentials      */
  32#ifdef CONFIG_SECURITY_NETWORK
  33        u32                     secid;          /* Passed security ID   */
  34#endif
  35};
  36
  37extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
  38extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
  39extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
  40extern void __scm_destroy(struct scm_cookie *scm);
  41extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
  42
  43#ifdef CONFIG_SECURITY_NETWORK
  44static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
  45{
  46        security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
  47}
  48#else
  49static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
  50{ }
  51#endif /* CONFIG_SECURITY_NETWORK */
  52
  53static __inline__ void scm_set_cred(struct scm_cookie *scm,
  54                                    struct pid *pid, const struct cred *cred)
  55{
  56        scm->pid  = get_pid(pid);
  57        scm->cred = cred ? get_cred(cred) : NULL;
  58        scm->creds.pid = pid_vnr(pid);
  59        scm->creds.uid = cred ? cred->euid : INVALID_UID;
  60        scm->creds.gid = cred ? cred->egid : INVALID_GID;
  61}
  62
  63static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
  64{
  65        put_pid(scm->pid);
  66        scm->pid  = NULL;
  67
  68        if (scm->cred)
  69                put_cred(scm->cred);
  70        scm->cred = NULL;
  71}
  72
  73static __inline__ void scm_destroy(struct scm_cookie *scm)
  74{
  75        scm_destroy_cred(scm);
  76        if (scm->fp)
  77                __scm_destroy(scm);
  78}
  79
  80static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
  81                               struct scm_cookie *scm, bool forcecreds)
  82{
  83        memset(scm, 0, sizeof(*scm));
  84        if (forcecreds)
  85                scm_set_cred(scm, task_tgid(current), current_cred());
  86        unix_get_peersec_dgram(sock, scm);
  87        if (msg->msg_controllen <= 0)
  88                return 0;
  89        return __scm_send(sock, msg, scm);
  90}
  91
  92#ifdef CONFIG_SECURITY_NETWORK
  93static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
  94{
  95        char *secdata;
  96        u32 seclen;
  97        int err;
  98
  99        if (test_bit(SOCK_PASSSEC, &sock->flags)) {
 100                err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
 101
 102                if (!err) {
 103                        put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
 104                        security_release_secctx(secdata, seclen);
 105                }
 106        }
 107}
 108#else
 109static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
 110{ }
 111#endif /* CONFIG_SECURITY_NETWORK */
 112
 113static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 114                                struct scm_cookie *scm, int flags)
 115{
 116        if (!msg->msg_control) {
 117                if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
 118                        msg->msg_flags |= MSG_CTRUNC;
 119                scm_destroy(scm);
 120                return;
 121        }
 122
 123        if (test_bit(SOCK_PASSCRED, &sock->flags)) {
 124                struct user_namespace *current_ns = current_user_ns();
 125                struct ucred ucreds = {
 126                        .pid = scm->creds.pid,
 127                        .uid = from_kuid_munged(current_ns, scm->creds.uid),
 128                        .gid = from_kgid_munged(current_ns, scm->creds.gid),
 129                };
 130                put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
 131        }
 132
 133        scm_destroy_cred(scm);
 134
 135        scm_passec(sock, msg, scm);
 136
 137        if (!scm->fp)
 138                return;
 139        
 140        scm_detach_fds(msg, scm);
 141}
 142
 143
 144#endif /* __LINUX_NET_SCM_H */
 145
 146
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.