0001
0002 #ifndef __LINUX_NET_SCM_H
0003 #define __LINUX_NET_SCM_H
0004
0005 #include <linux/limits.h>
0006 #include <linux/net.h>
0007 #include <linux/cred.h>
0008 #include <linux/security.h>
0009 #include <linux/pid.h>
0010 #include <linux/nsproxy.h>
0011 #include <linux/sched/signal.h>
0012
0013
0014
0015
0016 #define SCM_MAX_FD 253
0017
0018 struct scm_creds {
0019 u32 pid;
0020 kuid_t uid;
0021 kgid_t gid;
0022 };
0023
0024 struct scm_fp_list {
0025 short count;
0026 short max;
0027 struct user_struct *user;
0028 struct file *fp[SCM_MAX_FD];
0029 };
0030
0031 struct scm_cookie {
0032 struct pid *pid;
0033 struct scm_fp_list *fp;
0034 struct scm_creds creds;
0035 #ifdef CONFIG_SECURITY_NETWORK
0036 u32 secid;
0037 #endif
0038 };
0039
0040 void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
0041 void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
0042 int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
0043 void __scm_destroy(struct scm_cookie *scm);
0044 struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
0045
0046 #ifdef CONFIG_SECURITY_NETWORK
0047 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
0048 {
0049 security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
0050 }
0051 #else
0052 static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
0053 { }
0054 #endif
0055
0056 static __inline__ void scm_set_cred(struct scm_cookie *scm,
0057 struct pid *pid, kuid_t uid, kgid_t gid)
0058 {
0059 scm->pid = get_pid(pid);
0060 scm->creds.pid = pid_vnr(pid);
0061 scm->creds.uid = uid;
0062 scm->creds.gid = gid;
0063 }
0064
0065 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
0066 {
0067 put_pid(scm->pid);
0068 scm->pid = NULL;
0069 }
0070
0071 static __inline__ void scm_destroy(struct scm_cookie *scm)
0072 {
0073 scm_destroy_cred(scm);
0074 if (scm->fp)
0075 __scm_destroy(scm);
0076 }
0077
0078 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
0079 struct scm_cookie *scm, bool forcecreds)
0080 {
0081 memset(scm, 0, sizeof(*scm));
0082 scm->creds.uid = INVALID_UID;
0083 scm->creds.gid = INVALID_GID;
0084 if (forcecreds)
0085 scm_set_cred(scm, task_tgid(current), current_uid(), current_gid());
0086 unix_get_peersec_dgram(sock, scm);
0087 if (msg->msg_controllen <= 0)
0088 return 0;
0089 return __scm_send(sock, msg, scm);
0090 }
0091
0092 #ifdef CONFIG_SECURITY_NETWORK
0093 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
0094 {
0095 char *secdata;
0096 u32 seclen;
0097 int err;
0098
0099 if (test_bit(SOCK_PASSSEC, &sock->flags)) {
0100 err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
0101
0102 if (!err) {
0103 put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
0104 security_release_secctx(secdata, seclen);
0105 }
0106 }
0107 }
0108 #else
0109 static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
0110 { }
0111 #endif
0112
0113 static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
0114 struct scm_cookie *scm, int flags)
0115 {
0116 if (!msg->msg_control) {
0117 if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
0118 msg->msg_flags |= MSG_CTRUNC;
0119 scm_destroy(scm);
0120 return;
0121 }
0122
0123 if (test_bit(SOCK_PASSCRED, &sock->flags)) {
0124 struct user_namespace *current_ns = current_user_ns();
0125 struct ucred ucreds = {
0126 .pid = scm->creds.pid,
0127 .uid = from_kuid_munged(current_ns, scm->creds.uid),
0128 .gid = from_kgid_munged(current_ns, scm->creds.gid),
0129 };
0130 put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
0131 }
0132
0133 scm_destroy_cred(scm);
0134
0135 scm_passec(sock, msg, scm);
0136
0137 if (!scm->fp)
0138 return;
0139
0140 scm_detach_fds(msg, scm);
0141 }
0142
0143
0144 #endif
0145