LCOV - code coverage report
Current view: top level - include/net - scm.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 25 25 100.0 %
Date: 2022-03-28 16:04:14 Functions: 3 3 100.0 %
Branches: 8 8 100.0 %

           Branch data     Line data    Source code
       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                 :      26018 : static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
      48                 :            : {
      49                 :      26018 :         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                 :      25230 : static __inline__ void scm_set_cred(struct scm_cookie *scm,
      57                 :            :                                     struct pid *pid, kuid_t uid, kgid_t gid)
      58                 :            : {
      59         [ +  + ]:      25230 :         scm->pid  = get_pid(pid);
      60                 :      25230 :         scm->creds.pid = pid_vnr(pid);
      61                 :      25230 :         scm->creds.uid = uid;
      62                 :      25230 :         scm->creds.gid = gid;
      63                 :      25230 : }
      64                 :            : 
      65                 :      39389 : static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
      66                 :            : {
      67                 :      39389 :         put_pid(scm->pid);
      68                 :      39389 :         scm->pid  = NULL;
      69                 :            : }
      70                 :            : 
      71                 :      39389 : static __inline__ void scm_destroy(struct scm_cookie *scm)
      72                 :            : {
      73                 :      39389 :         scm_destroy_cred(scm);
      74         [ +  + ]:      39389 :         if (scm->fp)
      75                 :        338 :                 __scm_destroy(scm);
      76                 :      39389 : }
      77                 :            : 
      78                 :      26018 : static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
      79                 :            :                                struct scm_cookie *scm, bool forcecreds)
      80                 :            : {
      81                 :      26018 :         memset(scm, 0, sizeof(*scm));
      82                 :      26018 :         scm->creds.uid = INVALID_UID;
      83                 :      26018 :         scm->creds.gid = INVALID_GID;
      84         [ +  + ]:      26018 :         if (forcecreds)
      85                 :      14437 :                 scm_set_cred(scm, task_tgid(current), current_uid(), current_gid());
      86                 :      26018 :         unix_get_peersec_dgram(sock, scm);
      87         [ +  + ]:      26018 :         if (msg->msg_controllen <= 0)
      88                 :            :                 return 0;
      89                 :       1639 :         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                 :            : 

Generated by: LCOV version 1.14