Attached is a patch that is identical to the first, with the exception
that the extra user-space parameters have been removed from the accept and
setsockopt hooks. This new patch should replace the previously posted
one.
chris.
On Fri, 20 Jul 2001, Greg KH wrote:
> On Fri, Jul 20, 2001 at 04:09:31PM -0400, Chris Vance wrote:
> >
> > Something escaped my first pass. Note that two of these hooks have
> > parameters that are user-space variables - accept and setsockopt. In the
> > first case, accept, they should be removed. In the second case,
> > setsockopt, it's not clear whether an LSM module would care precisely what
> > value is being set. It would need to be copied into kernel memory and the
> > possibly of a race condition exists.
> >
> > Perhaps removing these paramters would be the safest thing to do.
>
> I agree. Keeping lsm modules from having to handle userspace variables
> is a good thing. Where ever possible I think we should try to avoid it.
>
> Other than that, the patch looks nice. However I don't profess to know
> anything about the network stack code :)
>
> Anyone else want to comment if these hooks will work out for their
> projects?
>
> thanks,
>
> greg k-h
>
Index: include/linux/netdevice.h
===================================================================
RCS file: /cvs/lsm/lsm/include/linux/netdevice.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 netdevice.h
--- include/linux/netdevice.h 2001/06/11 18:19:59 1.1.1.1
+++ include/linux/netdevice.h 2001/07/23 15:43:03
@@ -291,6 +291,7 @@
unsigned short type; /* interface hardware type */
unsigned short hard_header_len; /* hardware hdr length */
void *priv; /* pointer to private data */
+ void *d_security; /* device security block */
struct net_device *master; /* Pointer to master device of a group,
* which this device is member of.
Index: include/linux/security.h
===================================================================
RCS file: /cvs/lsm/lsm/include/linux/security.h,v
retrieving revision 1.19
diff -u -r1.19 security.h
--- include/linux/security.h 2001/07/06 19:39:42 1.19
+++ include/linux/security.h 2001/07/23 15:43:03
@@ -121,6 +121,19 @@
};
struct socket_security_ops {
+ int (* create) (int family, int type, int protocol);
+ void (* post_create) (struct socket *sock, int family, int type, int protocol);
+ int (* bind) (struct socket *sock, struct sockaddr *address, int addrlen);
+ int (* connect) (struct socket *sock, struct sockaddr *address, int addrlen);
+ int (* listen) (struct socket *sock, int backlog);
+ int (* accept) (struct socket *sock, struct socket *newsock);
+ int (* sendmsg) (struct socket *sock, struct msghdr *msg, int size);
+ int (* recvmsg) (struct socket *sock, struct msghdr *msg, int size, int flags);
+ int (* getsockname) (struct socket *sock);
+ int (* getpeername) (struct socket *sock);
+ int (* getsockopt) (struct socket *sock, int level, int optname);
+ int (* setsockopt) (struct socket *sock, int level, int optname);
+ int (* shutdown) (struct socket *sock, int how);
};
struct module_security_ops {
Index: kernel/capability_plug.c
===================================================================
RCS file: /cvs/lsm/lsm/kernel/capability_plug.c,v
retrieving revision 1.7
diff -u -r1.7 capability_plug.c
--- kernel/capability_plug.c 2001/07/06 19:39:42 1.7
+++ kernel/capability_plug.c 2001/07/23 15:43:04
@@ -56,6 +56,7 @@
static int cap_setcapablity (void) {return 0;}
static int cap_acct (struct file *file) {return 0;}
+static int cap_sysctl (ctl_table * table, int op) {return 0;}
static int cap_binprm_alloc_security(struct linux_binprm *bprm)
{
@@ -290,6 +291,20 @@
return;
}
+static int cap_socket_create (int family, int type, int protocol) {return 0;}
+static void cap_socket_post_create (struct socket *sock, int family, int type, int protocol) {return;}
+static int cap_socket_bind (struct socket *sock, struct sockaddr *address, int addrlen) {return 0;}
+static int cap_socket_connect (struct socket *sock, struct sockaddr *address, int addrlen) {return 0;}
+static int cap_socket_listen (struct socket *sock, int backlog) {return 0;}
+static int cap_socket_accept( struct socket *sock, struct socket *newsock) {return 0;}
+static int cap_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) {return 0;}
+static int cap_socket_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags) {return 0;}
+static int cap_socket_getsockname (struct socket *sock) {return 0;}
+static int cap_socket_getpeername (struct socket *sock) {return 0;}
+static int cap_socket_setsockopt (struct socket *sock, int level, int optname) {return 0;}
+static int cap_socket_getsockopt (struct socket *sock, int level, int optname) {return 0;}
+static int cap_socket_shutdown (struct socket *sock, int how) {return 0;}
+
static int cap_module_create_module (const char *name_user, size_t size) {return 0;}
static int cap_module_init_module (const char *name_user, struct module *mod_user) {return 0;}
static int cap_module_delete_module (const char *name_user) {return 0;}
@@ -396,7 +411,21 @@
kmod_set_label: cap_task_kmod_set_label,
};
-static struct socket_security_ops cap_socket_ops = {};
+static struct socket_security_ops cap_socket_ops = {
+ create: cap_socket_create,
+ post_create: cap_socket_post_create,
+ bind: cap_socket_bind,
+ connect: cap_socket_connect,
+ listen: cap_socket_listen,
+ accept: cap_socket_accept,
+ sendmsg: cap_socket_sendmsg,
+ recvmsg: cap_socket_recvmsg,
+ getsockname: cap_socket_getsockname,
+ getpeername: cap_socket_getpeername,
+ getsockopt: cap_socket_getsockopt,
+ setsockopt: cap_socket_setsockopt,
+ shutdown: cap_socket_shutdown,
+};
static struct module_security_ops cap_module_ops = {
create_module: cap_module_create_module,
@@ -458,6 +487,7 @@
ptrace: cap_ptrace,
setcapability: cap_setcapablity,
acct: cap_acct,
+ sysctl: cap_sysctl,
capable: cap_capable,
bprm_ops: &cap_binprm_ops,
Index: kernel/security.c
===================================================================
RCS file: /cvs/lsm/lsm/kernel/security.c,v
retrieving revision 1.20
diff -u -r1.20 security.c
--- kernel/security.c 2001/07/06 19:39:42 1.20
+++ kernel/security.c 2001/07/23 15:43:04
@@ -127,6 +127,21 @@
static void dummy_task_kmod_set_label (void) {return;}
+static int dummy_socket_create(int family, int type, int protocol) {return 0;}
+static void dummy_socket_post_create(struct socket *sock, int family, int type, int protocol) {return;}
+static int dummy_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) {return 0;}
+static int dummy_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) {return 0;}
+static int dummy_socket_listen(struct socket *sock, int backlog) {return 0;}
+static int dummy_socket_accept(struct socket *sock, struct socket *newsock) {return 0;}
+static int dummy_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) {return 0;}
+static int dummy_socket_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags) {return 0;}
+static int dummy_socket_getsockname(struct socket *sock) {return 0;}
+static int dummy_socket_getpeername(struct socket *sock) {return 0;}
+static int dummy_socket_setsockopt(struct socket *sock, int level, int optname) {return 0;}
+static int dummy_socket_getsockopt(struct socket *sock, int level, int optname) {return 0;}
+static int dummy_socket_shutdown(struct socket *sock, int how) {return 0;}
+
+
static int dummy_module_create_module (const char *name_user, size_t size) {return 0;}
static int dummy_module_init_module (const char *name_user, struct module *mod_user) {return 0;}
static int dummy_module_delete_module (const char *name_user) {return 0;}
@@ -233,7 +248,21 @@
kmod_set_label: dummy_task_kmod_set_label,
};
-static struct socket_security_ops dummy_socket_ops = {};
+static struct socket_security_ops dummy_socket_ops = {
+ create: dummy_socket_create,
+ post_create: dummy_socket_post_create,
+ bind: dummy_socket_bind,
+ connect: dummy_socket_connect,
+ listen: dummy_socket_listen,
+ accept: dummy_socket_accept,
+ sendmsg: dummy_socket_sendmsg,
+ recvmsg: dummy_socket_recvmsg,
+ getsockname: dummy_socket_getsockname,
+ getpeername: dummy_socket_getpeername,
+ getsockopt: dummy_socket_getsockopt,
+ setsockopt: dummy_socket_setsockopt,
+ shutdown: dummy_socket_shutdown,
+};
static struct module_security_ops dummy_module_ops = {
create_module: dummy_module_create_module,
Index: mm/mmap.c
===================================================================
RCS file: /cvs/lsm/lsm/mm/mmap.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- mm/mmap.c 2001/06/21 15:46:47 1.3
+++ mm/mmap.c 2001/07/12 17:23:47 1.4
@@ -292,7 +292,7 @@
}
}
- error = security_ops->file_ops->mmap(file, flags, prot);
+ error = security_ops->file_ops->mmap(file, prot, flags);
if (error)
return error;
Index: net/socket.c
===================================================================
RCS file: /cvs/lsm/lsm/net/socket.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 socket.c
--- net/socket.c 2001/06/18 19:26:34 1.1.1.2
+++ net/socket.c 2001/07/23 15:43:04
@@ -507,6 +507,10 @@
int err;
struct scm_cookie scm;
+ err = security_ops->socket_ops->sendmsg(sock, msg, size);
+ if (err)
+ return err;
+
err = scm_send(sock, msg, &scm);
if (err >= 0) {
err = sock->ops->sendmsg(sock, msg, size, &scm);
@@ -518,6 +522,11 @@
int sock_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags)
{
struct scm_cookie scm;
+ int err;
+
+ err = security_ops->socket_ops->recvmsg(sock, msg, size, flags);
+ if (err)
+ return err;
memset(&scm, 0, sizeof(scm));
@@ -836,6 +845,7 @@
int sock_create(int family, int type, int protocol, struct socket **res)
{
int i;
+ int err;
struct socket *sock;
/*
@@ -857,6 +867,13 @@
}
family = PF_PACKET;
}
+
+ /*
+ * Don't even allow modules to be loaded if this fails.
+ */
+ err = security_ops->socket_ops->create(family, type, protocol);
+ if (err)
+ return err;
#if defined(CONFIG_KMOD) && defined(CONFIG_NET)
/* Attempt to load a protocol module if the find failed.
@@ -903,6 +920,8 @@
*res = sock;
+ security_ops->socket_ops->post_create(sock, family, type, protocol);
+
out:
net_family_read_unlock();
return i;
@@ -1012,8 +1031,14 @@
if((sock = sockfd_lookup(fd,&err))!=NULL)
{
- if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
+ if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
+ err = security_ops->socket_ops->bind(sock, (struct sockaddr *)address, addrlen);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
+ }
sockfd_put(sock);
}
return err;
@@ -1034,6 +1059,13 @@
if ((sock = sockfd_lookup(fd, &err)) != NULL) {
if ((unsigned) backlog > SOMAXCONN)
backlog = SOMAXCONN;
+
+ err = security_ops->socket_ops->listen(sock, backlog);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
err=sock->ops->listen(sock, backlog);
sockfd_put(sock);
}
@@ -1070,6 +1102,10 @@
newsock->type = sock->type;
newsock->ops = sock->ops;
+ err = security_ops->socket_ops->accept(sock, newsock);
+ if (err)
+ goto out_release;
+
err = sock->ops->accept(sock, newsock, sock->file->f_flags);
if (err < 0)
goto out_release;
@@ -1124,8 +1160,14 @@
err = move_addr_to_kernel(uservaddr, addrlen, address);
if (err < 0)
goto out_put;
+
+ err = security_ops->socket_ops->connect(sock, (struct sockaddr *)address, addrlen);
+ if (err)
+ goto out_put;
+
err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
sock->file->f_flags);
+
out_put:
sockfd_put(sock);
out:
@@ -1146,6 +1188,11 @@
sock = sockfd_lookup(fd, &err);
if (!sock)
goto out;
+
+ err = security_ops->socket_ops->getsockname(sock);
+ if (err)
+ goto out_put;
+
err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0);
if (err)
goto out_put;
@@ -1170,6 +1217,12 @@
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
+ err = security_ops->socket_ops->getpeername(sock);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
if (!err)
err=move_addr_to_user(address,len, usockaddr, usockaddr_len);
@@ -1297,6 +1350,12 @@
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
+ err = security_ops->socket_ops->setsockopt(sock,level,optname);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
if (level == SOL_SOCKET)
err=sock_setsockopt(sock,level,optname,optval,optlen);
else
@@ -1318,6 +1377,13 @@
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
+ err = security_ops->socket_ops->getsockopt(sock, level,
+ optname);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
if (level == SOL_SOCKET)
err=sock_getsockopt(sock,level,optname,optval,optlen);
else
@@ -1339,6 +1405,12 @@
if ((sock = sockfd_lookup(fd, &err))!=NULL)
{
+ err = security_ops->socket_ops->shutdown(sock, how);
+ if (err) {
+ sockfd_put(sock);
+ return err;
+ }
+
err=sock->ops->shutdown(sock, how);
sockfd_put(sock);
}
_______________________________________________
linux-security-module mailing list
linux-security-module@wirex.com
http://mail.wirex.com/mailman/listinfo/linux-security-module
This archive was generated by hypermail 2b30 : Mon Jul 23 2001 - 10:17:08 PDT