2005-04-17 06:20:36 +08:00
|
|
|
#ifndef __LINUX_NET_SCM_H
|
|
|
|
#define __LINUX_NET_SCM_H
|
|
|
|
|
|
|
|
#include <linux/limits.h>
|
|
|
|
#include <linux/net.h>
|
2006-08-03 05:12:06 +08:00
|
|
|
#include <linux/security.h>
|
2007-10-19 14:40:14 +08:00
|
|
|
#include <linux/pid.h>
|
|
|
|
#include <linux/nsproxy.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
/* Well, we should have at least one descriptor open
|
|
|
|
* to accept passed FDs 8)
|
|
|
|
*/
|
2010-11-23 22:09:15 +08:00
|
|
|
#define SCM_MAX_FD 253
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2012-09-07 02:20:01 +08:00
|
|
|
struct scm_creds {
|
|
|
|
u32 pid;
|
|
|
|
kuid_t uid;
|
|
|
|
kgid_t gid;
|
|
|
|
};
|
|
|
|
|
2009-11-03 11:26:03 +08:00
|
|
|
struct scm_fp_list {
|
2010-11-23 22:09:15 +08:00
|
|
|
short count;
|
|
|
|
short max;
|
2008-11-06 16:37:40 +08:00
|
|
|
struct file *fp[SCM_MAX_FD];
|
2005-04-17 06:20:36 +08:00
|
|
|
};
|
|
|
|
|
2009-11-03 11:26:03 +08:00
|
|
|
struct scm_cookie {
|
2010-06-13 11:32:34 +08:00
|
|
|
struct pid *pid; /* Skb credentials */
|
2005-04-17 06:20:36 +08:00
|
|
|
struct scm_fp_list *fp; /* Passed files */
|
2012-09-07 02:20:01 +08:00
|
|
|
struct scm_creds creds; /* Skb credentials */
|
[AF_UNIX]: Datagram getpeersec
This patch implements an API whereby an application can determine the
label of its peer's Unix datagram sockets via the auxiliary data mechanism of
recvmsg.
Patch purpose:
This patch enables a security-aware application to retrieve the
security context of the peer of a Unix datagram socket. The application
can then use this security context to determine the security context for
processing on behalf of the peer who sent the packet.
Patch design and implementation:
The design and implementation is very similar to the UDP case for INET
sockets. Basically we build upon the existing Unix domain socket API for
retrieving user credentials. Linux offers the API for obtaining user
credentials via ancillary messages (i.e., out of band/control messages
that are bundled together with a normal message). To retrieve the security
context, the application first indicates to the kernel such desire by
setting the SO_PASSSEC option via getsockopt. Then the application
retrieves the security context using the auxiliary data mechanism.
An example server application for Unix datagram socket should look like this:
toggle = 1;
toggle_len = sizeof(toggle);
setsockopt(sockfd, SOL_SOCKET, SO_PASSSEC, &toggle, &toggle_len);
recvmsg(sockfd, &msg_hdr, 0);
if (msg_hdr.msg_controllen > sizeof(struct cmsghdr)) {
cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr);
if (cmsg_hdr->cmsg_len <= CMSG_LEN(sizeof(scontext)) &&
cmsg_hdr->cmsg_level == SOL_SOCKET &&
cmsg_hdr->cmsg_type == SCM_SECURITY) {
memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext));
}
}
sock_setsockopt is enhanced with a new socket option SOCK_PASSSEC to allow
a server socket to receive security context of the peer.
Testing:
We have tested the patch by setting up Unix datagram client and server
applications. We verified that the server can retrieve the security context
using the auxiliary data mechanism of recvmsg.
Signed-off-by: Catherine Zhang <cxzhang@watson.ibm.com>
Acked-by: Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-06-30 03:27:47 +08:00
|
|
|
#ifdef CONFIG_SECURITY_NETWORK
|
2006-08-03 05:12:06 +08:00
|
|
|
u32 secid; /* Passed security ID */
|
[AF_UNIX]: Datagram getpeersec
This patch implements an API whereby an application can determine the
label of its peer's Unix datagram sockets via the auxiliary data mechanism of
recvmsg.
Patch purpose:
This patch enables a security-aware application to retrieve the
security context of the peer of a Unix datagram socket. The application
can then use this security context to determine the security context for
processing on behalf of the peer who sent the packet.
Patch design and implementation:
The design and implementation is very similar to the UDP case for INET
sockets. Basically we build upon the existing Unix domain socket API for
retrieving user credentials. Linux offers the API for obtaining user
credentials via ancillary messages (i.e., out of band/control messages
that are bundled together with a normal message). To retrieve the security
context, the application first indicates to the kernel such desire by
setting the SO_PASSSEC option via getsockopt. Then the application
retrieves the security context using the auxiliary data mechanism.
An example server application for Unix datagram socket should look like this:
toggle = 1;
toggle_len = sizeof(toggle);
setsockopt(sockfd, SOL_SOCKET, SO_PASSSEC, &toggle, &toggle_len);
recvmsg(sockfd, &msg_hdr, 0);
if (msg_hdr.msg_controllen > sizeof(struct cmsghdr)) {
cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr);
if (cmsg_hdr->cmsg_len <= CMSG_LEN(sizeof(scontext)) &&
cmsg_hdr->cmsg_level == SOL_SOCKET &&
cmsg_hdr->cmsg_type == SCM_SECURITY) {
memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext));
}
}
sock_setsockopt is enhanced with a new socket option SOCK_PASSSEC to allow
a server socket to receive security context of the peer.
Testing:
We have tested the patch by setting up Unix datagram client and server
applications. We verified that the server can retrieve the security context
using the auxiliary data mechanism of recvmsg.
Signed-off-by: Catherine Zhang <cxzhang@watson.ibm.com>
Acked-by: Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-06-30 03:27:47 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
};
|
|
|
|
|
2013-09-23 01:32:24 +08:00
|
|
|
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);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2006-08-03 05:12:06 +08:00
|
|
|
#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 */
|
|
|
|
|
2010-06-13 11:32:34 +08:00
|
|
|
static __inline__ void scm_set_cred(struct scm_cookie *scm,
|
2013-04-04 01:28:16 +08:00
|
|
|
struct pid *pid, kuid_t uid, kgid_t gid)
|
2010-06-13 11:32:34 +08:00
|
|
|
{
|
|
|
|
scm->pid = get_pid(pid);
|
2012-09-07 02:20:01 +08:00
|
|
|
scm->creds.pid = pid_vnr(pid);
|
2013-04-04 01:28:16 +08:00
|
|
|
scm->creds.uid = uid;
|
|
|
|
scm->creds.gid = gid;
|
2010-06-13 11:32:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
|
|
|
|
{
|
|
|
|
put_pid(scm->pid);
|
|
|
|
scm->pid = NULL;
|
|
|
|
}
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
static __inline__ void scm_destroy(struct scm_cookie *scm)
|
|
|
|
{
|
2010-06-13 11:32:34 +08:00
|
|
|
scm_destroy_cred(scm);
|
2012-09-25 03:52:33 +08:00
|
|
|
if (scm->fp)
|
2005-04-17 06:20:36 +08:00
|
|
|
__scm_destroy(scm);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
|
2012-08-21 14:21:17 +08:00
|
|
|
struct scm_cookie *scm, bool forcecreds)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2011-09-19 13:52:27 +08:00
|
|
|
memset(scm, 0, sizeof(*scm));
|
2013-04-04 01:28:16 +08:00
|
|
|
scm->creds.uid = INVALID_UID;
|
|
|
|
scm->creds.gid = INVALID_GID;
|
2012-08-21 14:21:17 +08:00
|
|
|
if (forcecreds)
|
2013-04-23 08:32:51 +08:00
|
|
|
scm_set_cred(scm, task_tgid(current), current_uid(), current_gid());
|
2006-08-03 05:12:06 +08:00
|
|
|
unix_get_peersec_dgram(sock, scm);
|
2005-04-17 06:20:36 +08:00
|
|
|
if (msg->msg_controllen <= 0)
|
|
|
|
return 0;
|
|
|
|
return __scm_send(sock, msg, scm);
|
|
|
|
}
|
|
|
|
|
[AF_UNIX]: Datagram getpeersec
This patch implements an API whereby an application can determine the
label of its peer's Unix datagram sockets via the auxiliary data mechanism of
recvmsg.
Patch purpose:
This patch enables a security-aware application to retrieve the
security context of the peer of a Unix datagram socket. The application
can then use this security context to determine the security context for
processing on behalf of the peer who sent the packet.
Patch design and implementation:
The design and implementation is very similar to the UDP case for INET
sockets. Basically we build upon the existing Unix domain socket API for
retrieving user credentials. Linux offers the API for obtaining user
credentials via ancillary messages (i.e., out of band/control messages
that are bundled together with a normal message). To retrieve the security
context, the application first indicates to the kernel such desire by
setting the SO_PASSSEC option via getsockopt. Then the application
retrieves the security context using the auxiliary data mechanism.
An example server application for Unix datagram socket should look like this:
toggle = 1;
toggle_len = sizeof(toggle);
setsockopt(sockfd, SOL_SOCKET, SO_PASSSEC, &toggle, &toggle_len);
recvmsg(sockfd, &msg_hdr, 0);
if (msg_hdr.msg_controllen > sizeof(struct cmsghdr)) {
cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr);
if (cmsg_hdr->cmsg_len <= CMSG_LEN(sizeof(scontext)) &&
cmsg_hdr->cmsg_level == SOL_SOCKET &&
cmsg_hdr->cmsg_type == SCM_SECURITY) {
memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext));
}
}
sock_setsockopt is enhanced with a new socket option SOCK_PASSSEC to allow
a server socket to receive security context of the peer.
Testing:
We have tested the patch by setting up Unix datagram client and server
applications. We verified that the server can retrieve the security context
using the auxiliary data mechanism of recvmsg.
Signed-off-by: Catherine Zhang <cxzhang@watson.ibm.com>
Acked-by: Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-06-30 03:27:47 +08:00
|
|
|
#ifdef CONFIG_SECURITY_NETWORK
|
|
|
|
static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
|
|
|
|
{
|
2006-08-03 05:12:06 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
[AF_UNIX]: Datagram getpeersec
This patch implements an API whereby an application can determine the
label of its peer's Unix datagram sockets via the auxiliary data mechanism of
recvmsg.
Patch purpose:
This patch enables a security-aware application to retrieve the
security context of the peer of a Unix datagram socket. The application
can then use this security context to determine the security context for
processing on behalf of the peer who sent the packet.
Patch design and implementation:
The design and implementation is very similar to the UDP case for INET
sockets. Basically we build upon the existing Unix domain socket API for
retrieving user credentials. Linux offers the API for obtaining user
credentials via ancillary messages (i.e., out of band/control messages
that are bundled together with a normal message). To retrieve the security
context, the application first indicates to the kernel such desire by
setting the SO_PASSSEC option via getsockopt. Then the application
retrieves the security context using the auxiliary data mechanism.
An example server application for Unix datagram socket should look like this:
toggle = 1;
toggle_len = sizeof(toggle);
setsockopt(sockfd, SOL_SOCKET, SO_PASSSEC, &toggle, &toggle_len);
recvmsg(sockfd, &msg_hdr, 0);
if (msg_hdr.msg_controllen > sizeof(struct cmsghdr)) {
cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr);
if (cmsg_hdr->cmsg_len <= CMSG_LEN(sizeof(scontext)) &&
cmsg_hdr->cmsg_level == SOL_SOCKET &&
cmsg_hdr->cmsg_type == SCM_SECURITY) {
memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext));
}
}
sock_setsockopt is enhanced with a new socket option SOCK_PASSSEC to allow
a server socket to receive security context of the peer.
Testing:
We have tested the patch by setting up Unix datagram client and server
applications. We verified that the server can retrieve the security context
using the auxiliary data mechanism of recvmsg.
Signed-off-by: Catherine Zhang <cxzhang@watson.ibm.com>
Acked-by: Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-06-30 03:27:47 +08:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
|
|
|
|
{ }
|
|
|
|
#endif /* CONFIG_SECURITY_NETWORK */
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
|
|
|
|
struct scm_cookie *scm, int flags)
|
|
|
|
{
|
2009-11-03 11:26:03 +08:00
|
|
|
if (!msg->msg_control) {
|
2005-04-17 06:20:36 +08:00
|
|
|
if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
|
|
|
|
msg->msg_flags |= MSG_CTRUNC;
|
2011-09-17 07:34:00 +08:00
|
|
|
scm_destroy(scm);
|
2005-04-17 06:20:36 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-09-07 02:20:01 +08:00
|
|
|
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);
|
|
|
|
}
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2011-09-17 07:34:00 +08:00
|
|
|
scm_destroy_cred(scm);
|
|
|
|
|
[AF_UNIX]: Datagram getpeersec
This patch implements an API whereby an application can determine the
label of its peer's Unix datagram sockets via the auxiliary data mechanism of
recvmsg.
Patch purpose:
This patch enables a security-aware application to retrieve the
security context of the peer of a Unix datagram socket. The application
can then use this security context to determine the security context for
processing on behalf of the peer who sent the packet.
Patch design and implementation:
The design and implementation is very similar to the UDP case for INET
sockets. Basically we build upon the existing Unix domain socket API for
retrieving user credentials. Linux offers the API for obtaining user
credentials via ancillary messages (i.e., out of band/control messages
that are bundled together with a normal message). To retrieve the security
context, the application first indicates to the kernel such desire by
setting the SO_PASSSEC option via getsockopt. Then the application
retrieves the security context using the auxiliary data mechanism.
An example server application for Unix datagram socket should look like this:
toggle = 1;
toggle_len = sizeof(toggle);
setsockopt(sockfd, SOL_SOCKET, SO_PASSSEC, &toggle, &toggle_len);
recvmsg(sockfd, &msg_hdr, 0);
if (msg_hdr.msg_controllen > sizeof(struct cmsghdr)) {
cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr);
if (cmsg_hdr->cmsg_len <= CMSG_LEN(sizeof(scontext)) &&
cmsg_hdr->cmsg_level == SOL_SOCKET &&
cmsg_hdr->cmsg_type == SCM_SECURITY) {
memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext));
}
}
sock_setsockopt is enhanced with a new socket option SOCK_PASSSEC to allow
a server socket to receive security context of the peer.
Testing:
We have tested the patch by setting up Unix datagram client and server
applications. We verified that the server can retrieve the security context
using the auxiliary data mechanism of recvmsg.
Signed-off-by: Catherine Zhang <cxzhang@watson.ibm.com>
Acked-by: Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2006-06-30 03:27:47 +08:00
|
|
|
scm_passec(sock, msg, scm);
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
if (!scm->fp)
|
|
|
|
return;
|
|
|
|
|
|
|
|
scm_detach_fds(msg, scm);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* __LINUX_NET_SCM_H */
|
|
|
|
|