Blame view

include/net/scm.h 2.71 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
  #ifndef __LINUX_NET_SCM_H
  #define __LINUX_NET_SCM_H
  
  #include <linux/limits.h>
  #include <linux/net.h>
dc49c1f94   Catherine Zhang   [AF_UNIX]: Kernel...
6
  #include <linux/security.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  
  /* Well, we should have at least one descriptor open
   * to accept passed FDs 8)
   */
  #define SCM_MAX_FD	(OPEN_MAX-1)
  
  struct scm_fp_list
  {
  	int		count;
  	struct file	*fp[SCM_MAX_FD];
  };
  
  struct scm_cookie
  {
  	struct ucred		creds;		/* Skb credentials	*/
  	struct scm_fp_list	*fp;		/* Passed files		*/
877ce7c1b   Catherine Zhang   [AF_UNIX]: Datagr...
23
  #ifdef CONFIG_SECURITY_NETWORK
dc49c1f94   Catherine Zhang   [AF_UNIX]: Kernel...
24
  	u32			secid;		/* Passed security ID 	*/
877ce7c1b   Catherine Zhang   [AF_UNIX]: Datagr...
25
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
29
30
31
32
33
  	unsigned long		seq;		/* Connection seqno	*/
  };
  
  extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
  extern void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm);
  extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm);
  extern void __scm_destroy(struct scm_cookie *scm);
  extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl);
dc49c1f94   Catherine Zhang   [AF_UNIX]: Kernel...
34
35
36
37
38
39
40
41
42
  #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 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
46
47
48
49
50
51
  static __inline__ void scm_destroy(struct scm_cookie *scm)
  {
  	if (scm && scm->fp)
  		__scm_destroy(scm);
  }
  
  static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
  			       struct scm_cookie *scm)
  {
1d541ddd7   Benjamin LaHaise   [AF_UNIX]: scm: b...
52
53
54
55
56
57
  	struct task_struct *p = current;
  	scm->creds.uid = p->uid;
  	scm->creds.gid = p->gid;
  	scm->creds.pid = p->tgid;
  	scm->fp = NULL;
  	scm->seq = 0;
dc49c1f94   Catherine Zhang   [AF_UNIX]: Kernel...
58
  	unix_get_peersec_dgram(sock, scm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
  	if (msg->msg_controllen <= 0)
  		return 0;
  	return __scm_send(sock, msg, scm);
  }
877ce7c1b   Catherine Zhang   [AF_UNIX]: Datagr...
63
64
65
  #ifdef CONFIG_SECURITY_NETWORK
  static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
  {
dc49c1f94   Catherine Zhang   [AF_UNIX]: Kernel...
66
67
68
69
70
71
72
73
74
75
76
77
  	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);
  		}
  	}
877ce7c1b   Catherine Zhang   [AF_UNIX]: Datagr...
78
79
80
81
82
  }
  #else
  static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
  { }
  #endif /* CONFIG_SECURITY_NETWORK */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
85
86
87
88
89
90
91
92
93
94
95
  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))
  		put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
877ce7c1b   Catherine Zhang   [AF_UNIX]: Datagr...
96
  	scm_passec(sock, msg, scm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
100
101
102
103
104
  	if (!scm->fp)
  		return;
  	
  	scm_detach_fds(msg, scm);
  }
  
  
  #endif /* __LINUX_NET_SCM_H */