cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

scm.h (3621B)


      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
     18struct scm_creds {
     19	u32	pid;
     20	kuid_t	uid;
     21	kgid_t	gid;
     22};
     23
     24struct scm_fp_list {
     25	short			count;
     26	short			max;
     27	struct user_struct	*user;
     28	struct file		*fp[SCM_MAX_FD];
     29};
     30
     31struct 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
     40void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
     41void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
     42int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
     43void __scm_destroy(struct scm_cookie *scm);
     44struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
     45
     46#ifdef CONFIG_SECURITY_NETWORK
     47static __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
     52static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
     53{ }
     54#endif /* CONFIG_SECURITY_NETWORK */
     55
     56static __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
     65static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
     66{
     67	put_pid(scm->pid);
     68	scm->pid  = NULL;
     69}
     70
     71static __inline__ void scm_destroy(struct scm_cookie *scm)
     72{
     73	scm_destroy_cred(scm);
     74	if (scm->fp)
     75		__scm_destroy(scm);
     76}
     77
     78static __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
     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