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-moduleat_private http://mail.wirex.com/mailman/listinfo/linux-security-module
This archive was generated by hypermail 2b30 : Mon Jul 23 2001 - 10:17:08 PDT