 8153ff5c5f
			
		
	
	
	8153ff5c5f
	
	
	
		
			
			There are a mix of function prototypes with and without extern in the kernel sources. Standardize on not using extern for function prototypes. Function prototypes don't need to be written with extern. extern is assumed by the compiler. Its use is as unnecessary as using auto to declare automatic/local variables in a block. Signed-off-by: Joe Perches <joe@perches.com> Signed-off-by: David S. Miller <davem@davemloft.net>
		
			
				
	
	
		
			141 lines
		
	
	
	
		
			3.4 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
	
		
			3.4 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| #ifndef __LINUX_NET_SCM_H
 | |
| #define __LINUX_NET_SCM_H
 | |
| 
 | |
| #include <linux/limits.h>
 | |
| #include <linux/net.h>
 | |
| #include <linux/security.h>
 | |
| #include <linux/pid.h>
 | |
| #include <linux/nsproxy.h>
 | |
| 
 | |
| /* Well, we should have at least one descriptor open
 | |
|  * to accept passed FDs 8)
 | |
|  */
 | |
| #define SCM_MAX_FD	253
 | |
| 
 | |
| struct scm_creds {
 | |
| 	u32	pid;
 | |
| 	kuid_t	uid;
 | |
| 	kgid_t	gid;
 | |
| };
 | |
| 
 | |
| struct scm_fp_list {
 | |
| 	short			count;
 | |
| 	short			max;
 | |
| 	struct file		*fp[SCM_MAX_FD];
 | |
| };
 | |
| 
 | |
| struct scm_cookie {
 | |
| 	struct pid		*pid;		/* Skb credentials */
 | |
| 	struct scm_fp_list	*fp;		/* Passed files		*/
 | |
| 	struct scm_creds	creds;		/* Skb credentials	*/
 | |
| #ifdef CONFIG_SECURITY_NETWORK
 | |
| 	u32			secid;		/* Passed security ID 	*/
 | |
| #endif
 | |
| };
 | |
| 
 | |
| void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
 | |
| void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
 | |
| int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
 | |
| void __scm_destroy(struct scm_cookie *scm);
 | |
| struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl);
 | |
| 
 | |
| #ifdef CONFIG_SECURITY_NETWORK
 | |
| static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
 | |
| {
 | |
| 	security_socket_getpeersec_dgram(sock, NULL, &scm->secid);
 | |
| }
 | |
| #else
 | |
| static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm)
 | |
| { }
 | |
| #endif /* CONFIG_SECURITY_NETWORK */
 | |
| 
 | |
| static __inline__ void scm_set_cred(struct scm_cookie *scm,
 | |
| 				    struct pid *pid, kuid_t uid, kgid_t gid)
 | |
| {
 | |
| 	scm->pid  = get_pid(pid);
 | |
| 	scm->creds.pid = pid_vnr(pid);
 | |
| 	scm->creds.uid = uid;
 | |
| 	scm->creds.gid = gid;
 | |
| }
 | |
| 
 | |
| static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 | |
| {
 | |
| 	put_pid(scm->pid);
 | |
| 	scm->pid  = NULL;
 | |
| }
 | |
| 
 | |
| static __inline__ void scm_destroy(struct scm_cookie *scm)
 | |
| {
 | |
| 	scm_destroy_cred(scm);
 | |
| 	if (scm->fp)
 | |
| 		__scm_destroy(scm);
 | |
| }
 | |
| 
 | |
| static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 | |
| 			       struct scm_cookie *scm, bool forcecreds)
 | |
| {
 | |
| 	memset(scm, 0, sizeof(*scm));
 | |
| 	scm->creds.uid = INVALID_UID;
 | |
| 	scm->creds.gid = INVALID_GID;
 | |
| 	if (forcecreds)
 | |
| 		scm_set_cred(scm, task_tgid(current), current_uid(), current_gid());
 | |
| 	unix_get_peersec_dgram(sock, scm);
 | |
| 	if (msg->msg_controllen <= 0)
 | |
| 		return 0;
 | |
| 	return __scm_send(sock, msg, scm);
 | |
| }
 | |
| 
 | |
| #ifdef CONFIG_SECURITY_NETWORK
 | |
| static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
 | |
| {
 | |
| 	char *secdata;
 | |
| 	u32 seclen;
 | |
| 	int err;
 | |
| 
 | |
| 	if (test_bit(SOCK_PASSSEC, &sock->flags)) {
 | |
| 		err = security_secid_to_secctx(scm->secid, &secdata, &seclen);
 | |
| 
 | |
| 		if (!err) {
 | |
| 			put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
 | |
| 			security_release_secctx(secdata, seclen);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| #else
 | |
| static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
 | |
| { }
 | |
| #endif /* CONFIG_SECURITY_NETWORK */
 | |
| 
 | |
| static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
 | |
| 				struct scm_cookie *scm, int flags)
 | |
| {
 | |
| 	if (!msg->msg_control) {
 | |
| 		if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
 | |
| 			msg->msg_flags |= MSG_CTRUNC;
 | |
| 		scm_destroy(scm);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if (test_bit(SOCK_PASSCRED, &sock->flags)) {
 | |
| 		struct user_namespace *current_ns = current_user_ns();
 | |
| 		struct ucred ucreds = {
 | |
| 			.pid = scm->creds.pid,
 | |
| 			.uid = from_kuid_munged(current_ns, scm->creds.uid),
 | |
| 			.gid = from_kgid_munged(current_ns, scm->creds.gid),
 | |
| 		};
 | |
| 		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(ucreds), &ucreds);
 | |
| 	}
 | |
| 
 | |
| 	scm_destroy_cred(scm);
 | |
| 
 | |
| 	scm_passec(sock, msg, scm);
 | |
| 
 | |
| 	if (!scm->fp)
 | |
| 		return;
 | |
| 	
 | |
| 	scm_detach_fds(msg, scm);
 | |
| }
 | |
| 
 | |
| 
 | |
| #endif /* __LINUX_NET_SCM_H */
 | |
| 
 |