aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan O'Hara <rohara@redhat.com>2006-05-22 10:08:35 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-05-22 10:08:35 -0400
commit639b6d79b8c20cce4079fb035640c65456324d1c (patch)
treeef3cf33f8b7f3d943ced0e461e1987cd34fc8c42
parentd2f222e6310b073ae3d91b8d3d676621fae1314e (diff)
[GFS2] selinux support
This adds support to GFS2 for selinux extended attributes. There is a known bug in gfs2_ea_get() which is believed to be independant of this patch. Further patches will follow once that bug is fixed in order to make GFS2 use as much of the generic eattr infrastructure as possible. Signed-off-by: Ryan O'Hara <rohara@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/eaops.c41
-rw-r--r--fs/gfs2/eaops.h2
-rw-r--r--fs/gfs2/eattr.c15
-rw-r--r--fs/gfs2/eattr.h17
-rw-r--r--include/linux/gfs2_ondisk.h3
5 files changed, 71 insertions, 7 deletions
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c
index 85c1dbace88b..2243b44ecb07 100644
--- a/fs/gfs2/eaops.c
+++ b/fs/gfs2/eaops.c
@@ -43,6 +43,10 @@ unsigned int gfs2_ea_name2type(const char *name, char **truncated_name)
43 type = GFS2_EATYPE_USR; 43 type = GFS2_EATYPE_USR;
44 if (truncated_name) 44 if (truncated_name)
45 *truncated_name = strchr(name, '.') + 1; 45 *truncated_name = strchr(name, '.') + 1;
46 } else if (strncmp(name, "security.", 9) == 0) {
47 type = GFS2_EATYPE_SECURITY;
48 if (truncated_name)
49 *truncated_name = strchr(name, '.') + 1;
46 } else { 50 } else {
47 type = GFS2_EATYPE_UNUSED; 51 type = GFS2_EATYPE_UNUSED;
48 if (truncated_name) 52 if (truncated_name)
@@ -166,6 +170,36 @@ static int system_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
166 return gfs2_ea_remove_i(ip, er); 170 return gfs2_ea_remove_i(ip, er);
167} 171}
168 172
173static int security_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
174{
175 struct inode *inode = ip->i_vnode;
176 int error = permission(inode, MAY_READ, NULL);
177 if (error)
178 return error;
179
180 return gfs2_ea_get_i(ip, er);
181}
182
183static int security_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
184{
185 struct inode *inode = ip->i_vnode;
186 int error = permission(inode, MAY_WRITE, NULL);
187 if (error)
188 return error;
189
190 return gfs2_ea_set_i(ip, er);
191}
192
193static int security_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
194{
195 struct inode *inode = ip->i_vnode;
196 int error = permission(inode, MAY_WRITE, NULL);
197 if (error)
198 return error;
199
200 return gfs2_ea_remove_i(ip, er);
201}
202
169static struct gfs2_eattr_operations gfs2_user_eaops = { 203static struct gfs2_eattr_operations gfs2_user_eaops = {
170 .eo_get = user_eo_get, 204 .eo_get = user_eo_get,
171 .eo_set = user_eo_set, 205 .eo_set = user_eo_set,
@@ -180,6 +214,13 @@ struct gfs2_eattr_operations gfs2_system_eaops = {
180 .eo_name = "system", 214 .eo_name = "system",
181}; 215};
182 216
217struct gfs2_eattr_operations gfs2_security_eaops = {
218 .eo_get = security_eo_get,
219 .eo_set = security_eo_set,
220 .eo_remove = security_eo_remove,
221 .eo_name = "security",
222};
223
183struct gfs2_eattr_operations *gfs2_ea_ops[] = { 224struct gfs2_eattr_operations *gfs2_ea_ops[] = {
184 NULL, 225 NULL,
185 &gfs2_user_eaops, 226 &gfs2_user_eaops,
diff --git a/fs/gfs2/eaops.h b/fs/gfs2/eaops.h
index 3dece17e3116..965a235c96e8 100644
--- a/fs/gfs2/eaops.h
+++ b/fs/gfs2/eaops.h
@@ -23,6 +23,8 @@ unsigned int gfs2_ea_name2type(const char *name, char **truncated_name);
23 23
24extern struct gfs2_eattr_operations gfs2_system_eaops; 24extern struct gfs2_eattr_operations gfs2_system_eaops;
25 25
26extern struct gfs2_eattr_operations gfs2_security_eaops;
27
26extern struct gfs2_eattr_operations *gfs2_ea_ops[]; 28extern struct gfs2_eattr_operations *gfs2_ea_ops[];
27 29
28#endif /* __EAOPS_DOT_H__ */ 30#endif /* __EAOPS_DOT_H__ */
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c
index f5169a42a919..187fba1c4678 100644
--- a/fs/gfs2/eattr.c
+++ b/fs/gfs2/eattr.c
@@ -368,7 +368,7 @@ static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
368{ 368{
369 struct ea_list *ei = private; 369 struct ea_list *ei = private;
370 struct gfs2_ea_request *er = ei->ei_er; 370 struct gfs2_ea_request *er = ei->ei_er;
371 unsigned int ea_size = GFS2_EA_STRLEN(ea); 371 unsigned int ea_size = gfs2_ea_strlen(ea);
372 372
373 if (ea->ea_type == GFS2_EATYPE_UNUSED) 373 if (ea->ea_type == GFS2_EATYPE_UNUSED)
374 return 0; 374 return 0;
@@ -381,12 +381,21 @@ static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
381 if (ei->ei_size + ea_size > er->er_data_len) 381 if (ei->ei_size + ea_size > er->er_data_len)
382 return -ERANGE; 382 return -ERANGE;
383 383
384 if (ea->ea_type == GFS2_EATYPE_USR) { 384 switch (ea->ea_type) {
385 case GFS2_EATYPE_USR:
385 prefix = "user."; 386 prefix = "user.";
386 l = 5; 387 l = 5;
387 } else { 388 break;
389 case GFS2_EATYPE_SYS:
388 prefix = "system."; 390 prefix = "system.";
389 l = 7; 391 l = 7;
392 break;
393 case GFS2_EATYPE_SECURITY:
394 prefix = "security.";
395 l = 9;
396 break;
397 default:
398 break;
390 } 399 }
391 400
392 memcpy(er->er_data + ei->ei_size, 401 memcpy(er->er_data + ei->ei_size,
diff --git a/fs/gfs2/eattr.h b/fs/gfs2/eattr.h
index 19fb1dc4ddc4..ae199692e51d 100644
--- a/fs/gfs2/eattr.h
+++ b/fs/gfs2/eattr.h
@@ -18,9 +18,6 @@ ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \
18 ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \ 18 ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \
19 (sizeof(uint64_t) * (ea)->ea_num_ptrs)), 8) 19 (sizeof(uint64_t) * (ea)->ea_num_ptrs)), 8)
20 20
21#define GFS2_EA_STRLEN(ea) \
22((((ea)->ea_type == GFS2_EATYPE_USR) ? 5 : 7) + (ea)->ea_name_len + 1)
23
24#define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) 21#define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs)
25#define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST) 22#define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST)
26 23
@@ -83,4 +80,18 @@ int gfs2_ea_get_copy(struct gfs2_inode *ip,
83int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el, 80int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
84 struct iattr *attr, char *data); 81 struct iattr *attr, char *data);
85 82
83static inline unsigned int gfs2_ea_strlen(struct gfs2_ea_header *ea)
84{
85 switch (ea->ea_type) {
86 case GFS2_EATYPE_USR:
87 return (5 + (ea->ea_name_len + 1));
88 case GFS2_EATYPE_SYS:
89 return (7 + (ea->ea_name_len + 1));
90 case GFS2_EATYPE_SECURITY:
91 return (9 + (ea->ea_name_len + 1));
92 default:
93 return (0);
94 }
95}
96
86#endif /* __EATTR_DOT_H__ */ 97#endif /* __EATTR_DOT_H__ */
diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
index 4356e3864643..3893aac4e3ae 100644
--- a/include/linux/gfs2_ondisk.h
+++ b/include/linux/gfs2_ondisk.h
@@ -311,8 +311,9 @@ struct gfs2_leaf {
311#define GFS2_EATYPE_UNUSED 0 311#define GFS2_EATYPE_UNUSED 0
312#define GFS2_EATYPE_USR 1 312#define GFS2_EATYPE_USR 1
313#define GFS2_EATYPE_SYS 2 313#define GFS2_EATYPE_SYS 2
314#define GFS2_EATYPE_SECURITY 3
314 315
315#define GFS2_EATYPE_LAST 2 316#define GFS2_EATYPE_LAST 3
316#define GFS2_EATYPE_VALID(x) ((x) <= GFS2_EATYPE_LAST) 317#define GFS2_EATYPE_VALID(x) ((x) <= GFS2_EATYPE_LAST)
317 318
318#define GFS2_EAFLAG_LAST 0x01 /* last ea in block */ 319#define GFS2_EAFLAG_LAST 0x01 /* last ea in block */