aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/ebitmap.c
diff options
context:
space:
mode:
authorVenkat Yekkirala <vyekkirala@TrustedCS.com>2006-08-05 02:17:57 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 17:53:36 -0400
commit7420ed23a4f77480b5b7b3245e5da30dd24b7575 (patch)
tree016f5bb996c5eae66754b10243c5be6226d773f2 /security/selinux/ss/ebitmap.c
parent96cb8e3313c7a12e026c1ed510522ae6f6023875 (diff)
[NetLabel]: SELinux support
Add NetLabel support to the SELinux LSM and modify the socket_post_create() LSM hook to return an error code. The most significant part of this patch is the addition of NetLabel hooks into the following SELinux LSM hooks: * selinux_file_permission() * selinux_socket_sendmsg() * selinux_socket_post_create() * selinux_socket_sock_rcv_skb() * selinux_socket_getpeersec_stream() * selinux_socket_getpeersec_dgram() * selinux_sock_graft() * selinux_inet_conn_request() The basic reasoning behind this patch is that outgoing packets are "NetLabel'd" by labeling their socket and the NetLabel security attributes are checked via the additional hook in selinux_socket_sock_rcv_skb(). NetLabel itself is only a labeling mechanism, similar to filesystem extended attributes, it is up to the SELinux enforcement mechanism to perform the actual access checks. In addition to the changes outlined above this patch also includes some changes to the extended bitmap (ebitmap) and multi-level security (mls) code to import and export SELinux TE/MLS attributes into and out of NetLabel. Signed-off-by: Paul Moore <paul.moore@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'security/selinux/ss/ebitmap.c')
-rw-r--r--security/selinux/ss/ebitmap.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 47024a6e1844..4b915eb60c45 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -3,6 +3,14 @@
3 * 3 *
4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
5 */ 5 */
6/*
7 * Updated: Hewlett-Packard <paul.moore@hp.com>
8 *
9 * Added ebitmap_export() and ebitmap_import()
10 *
11 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
12 */
13
6#include <linux/kernel.h> 14#include <linux/kernel.h>
7#include <linux/slab.h> 15#include <linux/slab.h>
8#include <linux/errno.h> 16#include <linux/errno.h>
@@ -59,6 +67,142 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
59 return 0; 67 return 0;
60} 68}
61 69
70/**
71 * ebitmap_export - Export an ebitmap to a unsigned char bitmap string
72 * @src: the ebitmap to export
73 * @dst: the resulting bitmap string
74 * @dst_len: length of dst in bytes
75 *
76 * Description:
77 * Allocate a buffer at least src->highbit bits long and export the extensible
78 * bitmap into the buffer. The bitmap string will be in little endian format,
79 * i.e. LSB first. The value returned in dst_len may not the true size of the
80 * buffer as the length of the buffer is rounded up to a multiple of MAPTYPE.
81 * The caller must free the buffer when finished. Returns zero on success,
82 * negative values on failure.
83 *
84 */
85int ebitmap_export(const struct ebitmap *src,
86 unsigned char **dst,
87 size_t *dst_len)
88{
89 size_t bitmap_len;
90 unsigned char *bitmap;
91 struct ebitmap_node *iter_node;
92 MAPTYPE node_val;
93 size_t bitmap_byte;
94 unsigned char bitmask;
95
96 bitmap_len = src->highbit / 8;
97 if (src->highbit % 7)
98 bitmap_len += 1;
99 if (bitmap_len == 0)
100 return -EINVAL;
101
102 bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) +
103 sizeof(MAPTYPE),
104 GFP_ATOMIC);
105 if (bitmap == NULL)
106 return -ENOMEM;
107
108 iter_node = src->node;
109 do {
110 bitmap_byte = iter_node->startbit / 8;
111 bitmask = 0x80;
112 node_val = iter_node->map;
113 do {
114 if (bitmask == 0) {
115 bitmap_byte++;
116 bitmask = 0x80;
117 }
118 if (node_val & (MAPTYPE)0x01)
119 bitmap[bitmap_byte] |= bitmask;
120 node_val >>= 1;
121 bitmask >>= 1;
122 } while (node_val > 0);
123 iter_node = iter_node->next;
124 } while (iter_node);
125
126 *dst = bitmap;
127 *dst_len = bitmap_len;
128 return 0;
129}
130
131/**
132 * ebitmap_import - Import an unsigned char bitmap string into an ebitmap
133 * @src: the bitmap string
134 * @src_len: the bitmap length in bytes
135 * @dst: the empty ebitmap
136 *
137 * Description:
138 * This function takes a little endian bitmap string in src and imports it into
139 * the ebitmap pointed to by dst. Returns zero on success, negative values on
140 * failure.
141 *
142 */
143int ebitmap_import(const unsigned char *src,
144 size_t src_len,
145 struct ebitmap *dst)
146{
147 size_t src_off = 0;
148 struct ebitmap_node *node_new;
149 struct ebitmap_node *node_last = NULL;
150 size_t iter;
151 size_t iter_bit;
152 size_t iter_limit;
153 unsigned char src_byte;
154
155 do {
156 iter_limit = src_len - src_off;
157 if (iter_limit >= sizeof(MAPTYPE)) {
158 if (*(MAPTYPE *)&src[src_off] == 0) {
159 src_off += sizeof(MAPTYPE);
160 continue;
161 }
162 iter_limit = sizeof(MAPTYPE);
163 } else {
164 iter = src_off;
165 src_byte = 0;
166 do {
167 src_byte |= src[iter++];
168 } while (iter < src_len && src_byte == 0);
169 if (src_byte == 0)
170 break;
171 }
172
173 node_new = kzalloc(sizeof(*node_new), GFP_ATOMIC);
174 if (unlikely(node_new == NULL)) {
175 ebitmap_destroy(dst);
176 return -ENOMEM;
177 }
178 node_new->startbit = src_off * 8;
179 iter = 0;
180 do {
181 src_byte = src[src_off++];
182 iter_bit = iter++ * 8;
183 while (src_byte != 0) {
184 if (src_byte & 0x80)
185 node_new->map |= MAPBIT << iter_bit;
186 iter_bit++;
187 src_byte <<= 1;
188 }
189 } while (iter < iter_limit);
190
191 if (node_last != NULL)
192 node_last->next = node_new;
193 else
194 dst->node = node_new;
195 node_last = node_new;
196 } while (src_off < src_len);
197
198 if (likely(node_last != NULL))
199 dst->highbit = node_last->startbit + MAPSIZE;
200 else
201 ebitmap_init(dst);
202
203 return 0;
204}
205
62int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) 206int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
63{ 207{
64 struct ebitmap_node *n1, *n2; 208 struct ebitmap_node *n1, *n2;