linux/security/selinux/ss
Eric Paris b138004ea0 SELinux: fix selinuxfs policy file on big endian systems
The /sys/fs/selinux/policy file is not valid on big endian systems like
ppc64 or s390.  Let's see why:

static int hashtab_cnt(void *key, void *data, void *ptr)
{
	int *cnt = ptr;
	*cnt = *cnt + 1;

	return 0;
}

static int range_write(struct policydb *p, void *fp)
{
	size_t nel;
[...]
	/* count the number of entries in the hashtab */
	nel = 0;
	rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
	if (rc)
		return rc;
	buf[0] = cpu_to_le32(nel);
	rc = put_entry(buf, sizeof(u32), 1, fp);

So size_t is 64 bits.  But then we pass a pointer to it as we do to
hashtab_cnt.  hashtab_cnt thinks it is a 32 bit int and only deals with
the first 4 bytes.  On x86_64 which is little endian, those first 4
bytes and the least significant, so this works out fine.  On ppc64/s390
those first 4 bytes of memory are the high order bits.  So at the end of
the call to hashtab_map nel has a HUGE number.  But the least
significant 32 bits are all 0's.

We then pass that 64 bit number to cpu_to_le32() which happily truncates
it to a 32 bit number and does endian swapping.  But the low 32 bits are
all 0's.  So no matter how many entries are in the hashtab, big endian
systems always say there are 0 entries because I screwed up the
counting.

The fix is easy.  Use a 32 bit int, as the hashtab_cnt expects, for nel.

Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Paul Moore <pmoore@redhat.com>
2013-07-25 13:02:44 -04:00
..
avtab.c SELinux: allow userspace to read policy back out of the kernel 2010-10-21 10:12:58 +11:00
avtab.h SELinux: Use dentry name in new object labeling 2011-02-01 11:12:30 -05:00
conditional.c selinux: Casting (void *) value returned by kmalloc is useless 2011-12-19 11:23:56 +11:00
conditional.h selinux: sparse fix: fix several warnings in the security server code 2011-09-09 16:56:32 -07:00
constraint.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
context.h SELinux: allow default source/target selectors for user/role/range 2012-04-09 12:22:47 -04:00
ebitmap.c SELinux: Reduce overhead of mls_level_isvalid() function call 2013-07-25 13:02:18 -04:00
ebitmap.h SELinux: Increase ebitmap_node size for 64-bit configuration 2013-07-25 13:02:31 -04:00
hashtab.c selinux: Unify for- and while-loop style 2008-08-15 08:40:47 +10:00
hashtab.h SELinux: hashtab.h whitespace, syntax, and other cleanups 2008-04-28 09:29:04 +10:00
mls_types.h SELinux: Reduce overhead of mls_level_isvalid() function call 2013-07-25 13:02:18 -04:00
mls.c SELinux: Reduce overhead of mls_level_isvalid() function call 2013-07-25 13:02:18 -04:00
mls.h doc: Update the email address for Paul Moore in various source files 2011-08-01 17:58:33 -07:00
policydb.c SELinux: fix selinuxfs policy file on big endian systems 2013-07-25 13:02:44 -04:00
policydb.h SELinux: add default_type statements 2012-04-09 12:22:48 -04:00
services.c userns: Convert selinux to use kuid and kgid where appropriate 2012-09-21 03:13:22 -07:00
services.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sidtab.c selinux: cache sidtab_context_to_sid results 2010-12-07 16:44:01 -05:00
sidtab.h selinux: cache sidtab_context_to_sid results 2010-12-07 16:44:01 -05:00
status.c selinux: fix up style problem on /selinux/status 2010-10-21 10:12:41 +11:00
symtab.c selinux: fix error codes in symtab_init() 2010-08-02 15:35:04 +10:00
symtab.h Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00