diff options
author | Eric Paris <eparis@redhat.com> | 2008-02-28 12:58:40 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-04-18 06:26:06 -0400 |
commit | b0c636b99997c8594da6a46e166ce4fcf6956fda (patch) | |
tree | 16308f0324846cd8c19180b6a45793268dd16f50 | |
parent | d4ee4231a3a8731576ef0e0a7e1225e4fde1e659 (diff) |
SELinux: create new open permission
Adds a new open permission inside SELinux when 'opening' a file. The idea
is that opening a file and reading/writing to that file are not the same
thing. Its different if a program had its stdout redirected to /tmp/output
than if the program tried to directly open /tmp/output. This should allow
policy writers to more liberally give read/write permissions across the
policy while still blocking many design and programing flaws SELinux is so
good at catching today.
Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Reviewed-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r-- | security/selinux/hooks.c | 31 | ||||
-rw-r--r-- | security/selinux/include/av_perm_to_string.h | 5 | ||||
-rw-r--r-- | security/selinux/include/av_permissions.h | 5 | ||||
-rw-r--r-- | security/selinux/include/security.h | 2 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 3 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 3 |
6 files changed, 47 insertions, 2 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 710894d4841b..d569cde440e6 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1615,6 +1615,35 @@ static inline u32 file_mask_to_av(int mode, int mask) | |||
1615 | return av; | 1615 | return av; |
1616 | } | 1616 | } |
1617 | 1617 | ||
1618 | /* | ||
1619 | * Convert a file mask to an access vector and include the correct open | ||
1620 | * open permission. | ||
1621 | */ | ||
1622 | static inline u32 open_file_mask_to_av(int mode, int mask) | ||
1623 | { | ||
1624 | u32 av = file_mask_to_av(mode, mask); | ||
1625 | |||
1626 | if (selinux_policycap_openperm) { | ||
1627 | /* | ||
1628 | * lnk files and socks do not really have an 'open' | ||
1629 | */ | ||
1630 | if (S_ISREG(mode)) | ||
1631 | av |= FILE__OPEN; | ||
1632 | else if (S_ISCHR(mode)) | ||
1633 | av |= CHR_FILE__OPEN; | ||
1634 | else if (S_ISBLK(mode)) | ||
1635 | av |= BLK_FILE__OPEN; | ||
1636 | else if (S_ISFIFO(mode)) | ||
1637 | av |= FIFO_FILE__OPEN; | ||
1638 | else if (S_ISDIR(mode)) | ||
1639 | av |= DIR__OPEN; | ||
1640 | else | ||
1641 | printk(KERN_ERR "SELinux: WARNING: inside open_file_to_av " | ||
1642 | "with unknown mode:%x\n", mode); | ||
1643 | } | ||
1644 | return av; | ||
1645 | } | ||
1646 | |||
1618 | /* Convert a Linux file to an access vector. */ | 1647 | /* Convert a Linux file to an access vector. */ |
1619 | static inline u32 file_to_av(struct file *file) | 1648 | static inline u32 file_to_av(struct file *file) |
1620 | { | 1649 | { |
@@ -2532,7 +2561,7 @@ static int selinux_inode_permission(struct inode *inode, int mask, | |||
2532 | } | 2561 | } |
2533 | 2562 | ||
2534 | return inode_has_perm(current, inode, | 2563 | return inode_has_perm(current, inode, |
2535 | file_mask_to_av(inode->i_mode, mask), NULL); | 2564 | open_file_mask_to_av(inode->i_mode, mask), NULL); |
2536 | } | 2565 | } |
2537 | 2566 | ||
2538 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | 2567 | static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) |
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index d5696690d3a2..1223b4ff9bee 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h | |||
@@ -14,12 +14,17 @@ | |||
14 | S_(SECCLASS_DIR, DIR__REPARENT, "reparent") | 14 | S_(SECCLASS_DIR, DIR__REPARENT, "reparent") |
15 | S_(SECCLASS_DIR, DIR__SEARCH, "search") | 15 | S_(SECCLASS_DIR, DIR__SEARCH, "search") |
16 | S_(SECCLASS_DIR, DIR__RMDIR, "rmdir") | 16 | S_(SECCLASS_DIR, DIR__RMDIR, "rmdir") |
17 | S_(SECCLASS_DIR, DIR__OPEN, "open") | ||
17 | S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans") | 18 | S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans") |
18 | S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint") | 19 | S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint") |
19 | S_(SECCLASS_FILE, FILE__EXECMOD, "execmod") | 20 | S_(SECCLASS_FILE, FILE__EXECMOD, "execmod") |
21 | S_(SECCLASS_FILE, FILE__OPEN, "open") | ||
20 | S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans") | 22 | S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans") |
21 | S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint") | 23 | S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint") |
22 | S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod") | 24 | S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod") |
25 | S_(SECCLASS_CHR_FILE, CHR_FILE__OPEN, "open") | ||
26 | S_(SECCLASS_BLK_FILE, BLK_FILE__OPEN, "open") | ||
27 | S_(SECCLASS_FIFO_FILE, FIFO_FILE__OPEN, "open") | ||
23 | S_(SECCLASS_FD, FD__USE, "use") | 28 | S_(SECCLASS_FD, FD__USE, "use") |
24 | S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto") | 29 | S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto") |
25 | S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn") | 30 | S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn") |
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index 75b41311ab86..c4c51165c505 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h | |||
@@ -79,6 +79,7 @@ | |||
79 | #define DIR__REPARENT 0x00080000UL | 79 | #define DIR__REPARENT 0x00080000UL |
80 | #define DIR__SEARCH 0x00100000UL | 80 | #define DIR__SEARCH 0x00100000UL |
81 | #define DIR__RMDIR 0x00200000UL | 81 | #define DIR__RMDIR 0x00200000UL |
82 | #define DIR__OPEN 0x00400000UL | ||
82 | #define FILE__IOCTL 0x00000001UL | 83 | #define FILE__IOCTL 0x00000001UL |
83 | #define FILE__READ 0x00000002UL | 84 | #define FILE__READ 0x00000002UL |
84 | #define FILE__WRITE 0x00000004UL | 85 | #define FILE__WRITE 0x00000004UL |
@@ -99,6 +100,7 @@ | |||
99 | #define FILE__EXECUTE_NO_TRANS 0x00020000UL | 100 | #define FILE__EXECUTE_NO_TRANS 0x00020000UL |
100 | #define FILE__ENTRYPOINT 0x00040000UL | 101 | #define FILE__ENTRYPOINT 0x00040000UL |
101 | #define FILE__EXECMOD 0x00080000UL | 102 | #define FILE__EXECMOD 0x00080000UL |
103 | #define FILE__OPEN 0x00100000UL | ||
102 | #define LNK_FILE__IOCTL 0x00000001UL | 104 | #define LNK_FILE__IOCTL 0x00000001UL |
103 | #define LNK_FILE__READ 0x00000002UL | 105 | #define LNK_FILE__READ 0x00000002UL |
104 | #define LNK_FILE__WRITE 0x00000004UL | 106 | #define LNK_FILE__WRITE 0x00000004UL |
@@ -136,6 +138,7 @@ | |||
136 | #define CHR_FILE__EXECUTE_NO_TRANS 0x00020000UL | 138 | #define CHR_FILE__EXECUTE_NO_TRANS 0x00020000UL |
137 | #define CHR_FILE__ENTRYPOINT 0x00040000UL | 139 | #define CHR_FILE__ENTRYPOINT 0x00040000UL |
138 | #define CHR_FILE__EXECMOD 0x00080000UL | 140 | #define CHR_FILE__EXECMOD 0x00080000UL |
141 | #define CHR_FILE__OPEN 0x00100000UL | ||
139 | #define BLK_FILE__IOCTL 0x00000001UL | 142 | #define BLK_FILE__IOCTL 0x00000001UL |
140 | #define BLK_FILE__READ 0x00000002UL | 143 | #define BLK_FILE__READ 0x00000002UL |
141 | #define BLK_FILE__WRITE 0x00000004UL | 144 | #define BLK_FILE__WRITE 0x00000004UL |
@@ -153,6 +156,7 @@ | |||
153 | #define BLK_FILE__SWAPON 0x00004000UL | 156 | #define BLK_FILE__SWAPON 0x00004000UL |
154 | #define BLK_FILE__QUOTAON 0x00008000UL | 157 | #define BLK_FILE__QUOTAON 0x00008000UL |
155 | #define BLK_FILE__MOUNTON 0x00010000UL | 158 | #define BLK_FILE__MOUNTON 0x00010000UL |
159 | #define BLK_FILE__OPEN 0x00020000UL | ||
156 | #define SOCK_FILE__IOCTL 0x00000001UL | 160 | #define SOCK_FILE__IOCTL 0x00000001UL |
157 | #define SOCK_FILE__READ 0x00000002UL | 161 | #define SOCK_FILE__READ 0x00000002UL |
158 | #define SOCK_FILE__WRITE 0x00000004UL | 162 | #define SOCK_FILE__WRITE 0x00000004UL |
@@ -187,6 +191,7 @@ | |||
187 | #define FIFO_FILE__SWAPON 0x00004000UL | 191 | #define FIFO_FILE__SWAPON 0x00004000UL |
188 | #define FIFO_FILE__QUOTAON 0x00008000UL | 192 | #define FIFO_FILE__QUOTAON 0x00008000UL |
189 | #define FIFO_FILE__MOUNTON 0x00010000UL | 193 | #define FIFO_FILE__MOUNTON 0x00010000UL |
194 | #define FIFO_FILE__OPEN 0x00020000UL | ||
190 | #define FD__USE 0x00000001UL | 195 | #define FD__USE 0x00000001UL |
191 | #define SOCKET__IOCTL 0x00000001UL | 196 | #define SOCKET__IOCTL 0x00000001UL |
192 | #define SOCKET__READ 0x00000002UL | 197 | #define SOCKET__READ 0x00000002UL |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 44e12ec88090..315b4ec1e12a 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -48,11 +48,13 @@ extern int selinux_mls_enabled; | |||
48 | /* Policy capabilities */ | 48 | /* Policy capabilities */ |
49 | enum { | 49 | enum { |
50 | POLICYDB_CAPABILITY_NETPEER, | 50 | POLICYDB_CAPABILITY_NETPEER, |
51 | POLICYDB_CAPABILITY_OPENPERM, | ||
51 | __POLICYDB_CAPABILITY_MAX | 52 | __POLICYDB_CAPABILITY_MAX |
52 | }; | 53 | }; |
53 | #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) | 54 | #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) |
54 | 55 | ||
55 | extern int selinux_policycap_netpeer; | 56 | extern int selinux_policycap_netpeer; |
57 | extern int selinux_policycap_openperm; | ||
56 | 58 | ||
57 | int security_load_policy(void * data, size_t len); | 59 | int security_load_policy(void * data, size_t len); |
58 | 60 | ||
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 0341567665b3..1d996bb953b8 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -42,7 +42,8 @@ | |||
42 | 42 | ||
43 | /* Policy capability filenames */ | 43 | /* Policy capability filenames */ |
44 | static char *policycap_names[] = { | 44 | static char *policycap_names[] = { |
45 | "network_peer_controls" | 45 | "network_peer_controls", |
46 | "open_perms" | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; | 49 | unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 26de2be0c8e2..4a14348de876 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -61,6 +61,7 @@ extern void selnl_notify_policyload(u32 seqno); | |||
61 | unsigned int policydb_loaded_version; | 61 | unsigned int policydb_loaded_version; |
62 | 62 | ||
63 | int selinux_policycap_netpeer; | 63 | int selinux_policycap_netpeer; |
64 | int selinux_policycap_openperm; | ||
64 | 65 | ||
65 | /* | 66 | /* |
66 | * This is declared in avc.c | 67 | * This is declared in avc.c |
@@ -1308,6 +1309,8 @@ static void security_load_policycaps(void) | |||
1308 | { | 1309 | { |
1309 | selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, | 1310 | selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, |
1310 | POLICYDB_CAPABILITY_NETPEER); | 1311 | POLICYDB_CAPABILITY_NETPEER); |
1312 | selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, | ||
1313 | POLICYDB_CAPABILITY_OPENPERM); | ||
1311 | } | 1314 | } |
1312 | 1315 | ||
1313 | extern void selinux_complete_init(void); | 1316 | extern void selinux_complete_init(void); |