Re: [PATCH] selinux: hooks: Add permission for network MAC address

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Oct 9, 2014 at 7:48 AM, Stephen Smalley <sds@xxxxxxxxxxxxx> wrote:

There was some earlier discussion of filtering ioctls via SELinux.  If
you want to do that in general, this approach won't get you there - it
cannot scale to deal with more than a handful of ioctl commands.  If
however you truly only want this control for this particular ioctl
command, see below for comments on the code.  Otherwise, if you want to
explore a generic facility for ioctl filtering, I can send you pointers
to the earlier discussions.

That makes sense. I am a bit conflicted. This is my only use-case, but it sounds like regular filtering of ioctl commands would be generally useful. I understand that my current approach would not scale and would lead to an explosion in permissions. So I am weighing the benefits of this particular permission which seems broadly useful with the risk of either waiting on a general approach or the risk of implementing something that doesn't get mainlined. I would appreciate your thoughts on this.  Can you point me towards the earlier discussions?

You can't safely call file_has_perm() with a SOCKET permission as the
file may reference an object with a non-socket security class.  So for
example, if a process called ioctl with this command value on a file,
you'd end up getting a very different permission check - whatever that
permission bit corresponds to in the file security class (I guess
nothing at this point, but could potentially be filled in the future).
So I think you need to first check that the file represents a socket
before performing the second check.  The other alternative would be to
define the permission in COMMON_FILE_SOCK_PERMS so that it is defined
for all objects that can be presented by struct file, but that would
waste a permission bit for the file classes.

For the first option, something along the lines of:
struct inode *inode = file->f_path.dentry->d_inode;
struct socket *socket;
if (inode->i_sb->s_magic != SOCKFS_MAGIC)
        break;
socket = SOCKET_I(inode);
error = sock_has_perm(current, socket->sk, SOCKET__GET_HWADDR);
break;




Thank you for catching that. Here is the patch updated with your recommendations:

---
 security/selinux/hooks.c            | 14 ++++++++++++++
 security/selinux/include/classmap.h |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1e1266b..5105341 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3104,10 +3104,14 @@ static void selinux_file_free_security(struct file *file)
  file_free_security(file);
 }
 
+static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms);
+
 static int selinux_file_ioctl(struct file *file, unsigned int cmd,
       unsigned long arg)
 {
  const struct cred *cred = current_cred();
+    struct inode *inode = file->f_path.dentry->d_inode;
+    struct socket *socket;
  int error = 0;
 
  switch (cmd) {
@@ -3142,6 +3146,16 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
     SECURITY_CAP_AUDIT);
  break;
 
+    case SIOCGIFHWADDR:
+        error = file_has_perm(cred, file, FILE__IOCTL);
+        if (error)
+            break;
+        if (inode->i_sb->s_magic != SOCKFS_MAGIC)
+            break;
+        socket = SOCKET_I(inode);
+        error = sock_has_perm(current, socket->sk, SOCKET__GET_HWADDR);
+        break;
+
  /* default case assumes that the command will go
  * to the file's ioctl() function.
  */
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index c32ff7b..306f0d2 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -7,7 +7,7 @@
 
 #define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \
     "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom",  \
-    "sendto", "recv_msg", "send_msg", "name_bind"
+    "sendto", "recv_msg", "send_msg", "name_bind", "get_hwaddr"
 
 #define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \
     "write", "associate", "unix_read", "unix_write"
-- 
2.1.0.rc2.206.gedb03e5

_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux