root/include/net/scm.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. unix_get_peersec_dgram
  2. unix_get_peersec_dgram
  3. scm_set_cred
  4. scm_destroy_cred
  5. scm_destroy
  6. scm_send
  7. scm_passec
  8. scm_passec
  9. scm_recv

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef __LINUX_NET_SCM_H
   3 #define __LINUX_NET_SCM_H
   4 
   5 #include <linux/limits.h>
   6 #include <linux/net.h>
   7 #include <linux/cred.h>
   8 #include <linux/security.h>
   9 #include <linux/pid.h>
  10 #include <linux/nsproxy.h>
  11 #include <linux/sched/signal.h>
  12 
  13 /* Well, we should have at least one descriptor open
  14  * to accept passed FDs 8)
  15  */
  16 #define SCM_MAX_FD      253
  17 
  18 struct scm_creds {
  19         u32     pid;
  20         kuid_t  uid;
  21         kgid_t  gid;
  22 };
  23 
  24 struct scm_fp_list {
  25         short                   count;
  26         short                   max;
  27         struct user_struct      *user;
  28         struct file             *fp[SCM_MAX_FD];
  29 };
  30 
  31 struct scm_cookie {
  32         struct pid              *pid;           /* Skb credentials */
  33         struct scm_fp_list      *fp;            /* Passed files         */
  34         struct scm_creds        creds;          /* Skb credentials      */
  35 #ifdef CONFIG_SECURITY_NETWORK
  36         u32                     secid;          /* Passed security ID   */
  37 #endif
  38 };
  39 
  40 void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
  41 void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
  42 int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
  43 void __scm_destroy(struct scm_cookie *scm);
  44 struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
  45 
  46 #ifdef CONFIG_SECURITY_NETWORK
  47 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
  48 {
  49         security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
  50 }
  51 #else
  52 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
  53 { }
  54 #endif /* CONFIG_SECURITY_NETWORK */
  55 
  56 static __inline__ void scm_set_cred(struct scm_cookie *scm,
  57                                     struct pid *pid, kuid_t uid, kgid_t gid)
  58 {
  59         scm->pid  = get_pid(pid);
  60         scm->creds.pid = pid_vnr(pid);
  61         scm->creds.uid = uid;
  62         scm->creds.gid = gid;
  63 }
  64 
  65 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
  66 {
  67         put_pid(scm->pid);
  68         scm->pid  = NULL;
  69 }
  70 
  71 static __inline__ void scm_destroy(struct scm_cookie *scm)
  72 {
  73         scm_destroy_cred(scm);
  74         if (scm->fp)
  75                 __scm_destroy(scm);
  76 }
  77 
  78 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
  79                                struct scm_cookie *scm, bool forcecreds)
  80 {
  81         memset(scm, 0, sizeof(*scm));
  82         scm->creds.uid = INVALID_UID;
  83         scm->creds.gid = INVALID_GID;
  84         if (forcecreds)
  85                 scm_set_cred(scm, task_tgid(current), current_uid(), current_gid());
  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
  93 static 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
 109 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
 110 { }
 111 #endif /* CONFIG_SECURITY_NETWORK */
 112 
 113 static __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 

/* [<][>][^][v][top][bottom][index][help] */