aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-10 14:18:59 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-10 14:18:59 -0500
commite0e736fc0d33861335e2a132e4f688f7fd380c61 (patch)
treed9febe9ca1ef1e24efc5e6e1e34e412316d246bd
parenta08948812b30653eb2c536ae613b635a989feb6f (diff)
parentaeda4ac3efc29e4d55989abd0a73530453aa69ba (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (30 commits) MAINTAINERS: Add tomoyo-dev-en ML. SELinux: define permissions for DCB netlink messages encrypted-keys: style and other cleanup encrypted-keys: verify datablob size before converting to binary trusted-keys: kzalloc and other cleanup trusted-keys: additional TSS return code and other error handling syslog: check cap_syslog when dmesg_restrict Smack: Transmute labels on specified directories selinux: cache sidtab_context_to_sid results SELinux: do not compute transition labels on mountpoint labeled filesystems This patch adds a new security attribute to Smack called SMACK64EXEC. It defines label that is used while task is running. SELinux: merge policydb_index_classes and policydb_index_others selinux: convert part of the sym_val_to_name array to use flex_array selinux: convert type_val_to_struct to flex_array flex_array: fix flex_array_put_ptr macro to be valid C SELinux: do not set automatic i_ino in selinuxfs selinux: rework security_netlbl_secattr_to_sid SELinux: standardize return code handling in selinuxfs.c SELinux: standardize return code handling in selinuxfs.c SELinux: standardize return code handling in policydb.c ...
-rw-r--r--Documentation/keys-trusted-encrypted.txt145
-rw-r--r--Documentation/sysctl/kernel.txt2
-rw-r--r--MAINTAINERS3
-rw-r--r--drivers/char/tpm/tpm.c20
-rw-r--r--drivers/char/tpm/tpm.h5
-rw-r--r--include/keys/encrypted-type.h29
-rw-r--r--include/keys/trusted-type.h31
-rw-r--r--include/linux/capability.h7
-rw-r--r--include/linux/flex_array.h2
-rw-r--r--include/linux/kernel.h3
-rw-r--r--include/linux/security.h3
-rw-r--r--include/linux/tpm.h4
-rw-r--r--include/linux/tpm_command.h28
-rw-r--r--include/linux/xattr.h4
-rw-r--r--kernel/printk.c14
-rw-r--r--lib/hexdump.c16
-rw-r--r--security/Kconfig31
-rw-r--r--security/keys/Makefile2
-rw-r--r--security/keys/encrypted_defined.c903
-rw-r--r--security/keys/encrypted_defined.h54
-rw-r--r--security/keys/trusted_defined.c1175
-rw-r--r--security/keys/trusted_defined.h134
-rw-r--r--security/selinux/hooks.c5
-rw-r--r--security/selinux/include/classmap.h2
-rw-r--r--security/selinux/nlmsgtab.c2
-rw-r--r--security/selinux/selinuxfs.c649
-rw-r--r--security/selinux/ss/conditional.c6
-rw-r--r--security/selinux/ss/mls.c25
-rw-r--r--security/selinux/ss/policydb.c701
-rw-r--r--security/selinux/ss/policydb.h19
-rw-r--r--security/selinux/ss/services.c425
-rw-r--r--security/selinux/ss/sidtab.c39
-rw-r--r--security/selinux/ss/sidtab.h2
-rw-r--r--security/smack/smack.h45
-rw-r--r--security/smack/smack_access.c58
-rw-r--r--security/smack/smack_lsm.c354
-rw-r--r--security/smack/smackfs.c41
37 files changed, 3914 insertions, 1074 deletions
diff --git a/Documentation/keys-trusted-encrypted.txt b/Documentation/keys-trusted-encrypted.txt
new file mode 100644
index 000000000000..8fb79bc1ac4b
--- /dev/null
+++ b/Documentation/keys-trusted-encrypted.txt
@@ -0,0 +1,145 @@
1 Trusted and Encrypted Keys
2
3Trusted and Encrypted Keys are two new key types added to the existing kernel
4key ring service. Both of these new types are variable length symmetic keys,
5and in both cases all keys are created in the kernel, and user space sees,
6stores, and loads only encrypted blobs. Trusted Keys require the availability
7of a Trusted Platform Module (TPM) chip for greater security, while Encrypted
8Keys can be used on any system. All user level blobs, are displayed and loaded
9in hex ascii for convenience, and are integrity verified.
10
11Trusted Keys use a TPM both to generate and to seal the keys. Keys are sealed
12under a 2048 bit RSA key in the TPM, and optionally sealed to specified PCR
13(integrity measurement) values, and only unsealed by the TPM, if PCRs and blob
14integrity verifications match. A loaded Trusted Key can be updated with new
15(future) PCR values, so keys are easily migrated to new pcr values, such as
16when the kernel and initramfs are updated. The same key can have many saved
17blobs under different PCR values, so multiple boots are easily supported.
18
19By default, trusted keys are sealed under the SRK, which has the default
20authorization value (20 zeros). This can be set at takeownership time with the
21trouser's utility: "tpm_takeownership -u -z".
22
23Usage:
24 keyctl add trusted name "new keylen [options]" ring
25 keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring
26 keyctl update key "update [options]"
27 keyctl print keyid
28
29 options:
30 keyhandle= ascii hex value of sealing key default 0x40000000 (SRK)
31 keyauth= ascii hex auth for sealing key default 0x00...i
32 (40 ascii zeros)
33 blobauth= ascii hex auth for sealed data default 0x00...
34 (40 ascii zeros)
35 blobauth= ascii hex auth for sealed data default 0x00...
36 (40 ascii zeros)
37 pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
38 pcrlock= pcr number to be extended to "lock" blob
39 migratable= 0|1 indicating permission to reseal to new PCR values,
40 default 1 (resealing allowed)
41
42"keyctl print" returns an ascii hex copy of the sealed key, which is in standard
43TPM_STORED_DATA format. The key length for new keys are always in bytes.
44Trusted Keys can be 32 - 128 bytes (256 - 1024 bits), the upper limit is to fit
45within the 2048 bit SRK (RSA) keylength, with all necessary structure/padding.
46
47Encrypted keys do not depend on a TPM, and are faster, as they use AES for
48encryption/decryption. New keys are created from kernel generated random
49numbers, and are encrypted/decrypted using a specified 'master' key. The
50'master' key can either be a trusted-key or user-key type. The main
51disadvantage of encrypted keys is that if they are not rooted in a trusted key,
52they are only as secure as the user key encrypting them. The master user key
53should therefore be loaded in as secure a way as possible, preferably early in
54boot.
55
56Usage:
57 keyctl add encrypted name "new key-type:master-key-name keylen" ring
58 keyctl add encrypted name "load hex_blob" ring
59 keyctl update keyid "update key-type:master-key-name"
60
61where 'key-type' is either 'trusted' or 'user'.
62
63Examples of trusted and encrypted key usage:
64
65Create and save a trusted key named "kmk" of length 32 bytes:
66
67 $ keyctl add trusted kmk "new 32" @u
68 440502848
69
70 $ keyctl show
71 Session Keyring
72 -3 --alswrv 500 500 keyring: _ses
73 97833714 --alswrv 500 -1 \_ keyring: _uid.500
74 440502848 --alswrv 500 500 \_ trusted: kmk
75
76 $ keyctl print 440502848
77 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
78 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
79 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
80 a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
81 d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
82 dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
83 f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
84 e4a8aea2b607ec96931e6f4d4fe563ba
85
86 $ keyctl pipe 440502848 > kmk.blob
87
88Load a trusted key from the saved blob:
89
90 $ keyctl add trusted kmk "load `cat kmk.blob`" @u
91 268728824
92
93 $ keyctl print 268728824
94 0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
95 3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
96 27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
97 a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
98 d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
99 dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
100 f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
101 e4a8aea2b607ec96931e6f4d4fe563ba
102
103Reseal a trusted key under new pcr values:
104
105 $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`"
106 $ keyctl print 268728824
107 010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805
108 77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73
109 d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e
110 df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4
111 9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6
112 e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610
113 94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9
114 7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
115 df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8
116
117Create and save an encrypted key "evm" using the above trusted key "kmk":
118
119 $ keyctl add encrypted evm "new trusted:kmk 32" @u
120 159771175
121
122 $ keyctl print 159771175
123 trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
124 be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
125 5972dcb82ab2dde83376d82b2e3c09ffc
126
127 $ keyctl pipe 159771175 > evm.blob
128
129Load an encrypted key "evm" from saved blob:
130
131 $ keyctl add encrypted evm "load `cat evm.blob`" @u
132 831684262
133
134 $ keyctl print 831684262
135 trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
136 be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
137 5972dcb82ab2dde83376d82b2e3c09ffc
138
139
140The initial consumer of trusted keys is EVM, which at boot time needs a high
141quality symmetric key for HMAC protection of file metadata. The use of a
142trusted key provides strong guarantees that the EVM key has not been
143compromised by a user level problem, and when sealed to specific boot PCR
144values, protects against boot and offline attacks. Other uses for trusted and
145encrypted keys, such as for disk and file encryption are anticipated.
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 209e1584c3dc..574067194f38 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -219,7 +219,7 @@ dmesg_restrict:
219This toggle indicates whether unprivileged users are prevented from using 219This toggle indicates whether unprivileged users are prevented from using
220dmesg(8) to view messages from the kernel's log buffer. When 220dmesg(8) to view messages from the kernel's log buffer. When
221dmesg_restrict is set to (0) there are no restrictions. When 221dmesg_restrict is set to (0) there are no restrictions. When
222dmesg_restrict is set set to (1), users must have CAP_SYS_ADMIN to use 222dmesg_restrict is set set to (1), users must have CAP_SYSLOG to use
223dmesg(8). 223dmesg(8).
224 224
225The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default 225The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default
diff --git a/MAINTAINERS b/MAINTAINERS
index 03c516a1edfa..9e4d4ca690e2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5930,7 +5930,8 @@ F: drivers/net/tlan.*
5930TOMOYO SECURITY MODULE 5930TOMOYO SECURITY MODULE
5931M: Kentaro Takeda <takedakn@nttdata.co.jp> 5931M: Kentaro Takeda <takedakn@nttdata.co.jp>
5932M: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> 5932M: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5933L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English) 5933L: tomoyo-dev-en@lists.sourceforge.jp (subscribers-only, for developers in English)
5934L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for users in English)
5934L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese) 5935L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese)
5935L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese) 5936L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese)
5936W: http://tomoyo.sourceforge.jp/ 5937W: http://tomoyo.sourceforge.jp/
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 0b3af3fe6766..1f46f1cd9225 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -736,7 +736,7 @@ int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
736 if (chip == NULL) 736 if (chip == NULL)
737 return -ENODEV; 737 return -ENODEV;
738 rc = __tpm_pcr_read(chip, pcr_idx, res_buf); 738 rc = __tpm_pcr_read(chip, pcr_idx, res_buf);
739 module_put(chip->dev->driver->owner); 739 tpm_chip_put(chip);
740 return rc; 740 return rc;
741} 741}
742EXPORT_SYMBOL_GPL(tpm_pcr_read); 742EXPORT_SYMBOL_GPL(tpm_pcr_read);
@@ -775,11 +775,27 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
775 rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 775 rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
776 "attempting extend a PCR value"); 776 "attempting extend a PCR value");
777 777
778 module_put(chip->dev->driver->owner); 778 tpm_chip_put(chip);
779 return rc; 779 return rc;
780} 780}
781EXPORT_SYMBOL_GPL(tpm_pcr_extend); 781EXPORT_SYMBOL_GPL(tpm_pcr_extend);
782 782
783int tpm_send(u32 chip_num, void *cmd, size_t buflen)
784{
785 struct tpm_chip *chip;
786 int rc;
787
788 chip = tpm_chip_find_get(chip_num);
789 if (chip == NULL)
790 return -ENODEV;
791
792 rc = transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
793
794 tpm_chip_put(chip);
795 return rc;
796}
797EXPORT_SYMBOL_GPL(tpm_send);
798
783ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, 799ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
784 char *buf) 800 char *buf)
785{ 801{
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 792868d24f2a..72ddb031b69a 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -113,6 +113,11 @@ struct tpm_chip {
113 113
114#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) 114#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
115 115
116static inline void tpm_chip_put(struct tpm_chip *chip)
117{
118 module_put(chip->dev->driver->owner);
119}
120
116static inline int tpm_read_index(int base, int index) 121static inline int tpm_read_index(int base, int index)
117{ 122{
118 outb(index, base); 123 outb(index, base);
diff --git a/include/keys/encrypted-type.h b/include/keys/encrypted-type.h
new file mode 100644
index 000000000000..95855017a32b
--- /dev/null
+++ b/include/keys/encrypted-type.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 * Author: Mimi Zohar <zohar@us.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
8 */
9
10#ifndef _KEYS_ENCRYPTED_TYPE_H
11#define _KEYS_ENCRYPTED_TYPE_H
12
13#include <linux/key.h>
14#include <linux/rcupdate.h>
15
16struct encrypted_key_payload {
17 struct rcu_head rcu;
18 char *master_desc; /* datablob: master key name */
19 char *datalen; /* datablob: decrypted key length */
20 u8 *iv; /* datablob: iv */
21 u8 *encrypted_data; /* datablob: encrypted data */
22 unsigned short datablob_len; /* length of datablob */
23 unsigned short decrypted_datalen; /* decrypted data length */
24 u8 decrypted_data[0]; /* decrypted data + datablob + hmac */
25};
26
27extern struct key_type key_type_encrypted;
28
29#endif /* _KEYS_ENCRYPTED_TYPE_H */
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
new file mode 100644
index 000000000000..56f82e5c9975
--- /dev/null
+++ b/include/keys/trusted-type.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 * Author: David Safford <safford@us.ibm.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 2 of the License.
8 */
9
10#ifndef _KEYS_TRUSTED_TYPE_H
11#define _KEYS_TRUSTED_TYPE_H
12
13#include <linux/key.h>
14#include <linux/rcupdate.h>
15
16#define MIN_KEY_SIZE 32
17#define MAX_KEY_SIZE 128
18#define MAX_BLOB_SIZE 320
19
20struct trusted_key_payload {
21 struct rcu_head rcu;
22 unsigned int key_len;
23 unsigned int blob_len;
24 unsigned char migratable;
25 unsigned char key[MAX_KEY_SIZE + 1];
26 unsigned char blob[MAX_BLOB_SIZE];
27};
28
29extern struct key_type key_type_trusted;
30
31#endif /* _KEYS_TRUSTED_TYPE_H */
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 90012b9ddbf3..fb16a3699b99 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -246,7 +246,6 @@ struct cpu_vfs_cap_data {
246/* Allow configuration of the secure attention key */ 246/* Allow configuration of the secure attention key */
247/* Allow administration of the random device */ 247/* Allow administration of the random device */
248/* Allow examination and configuration of disk quotas */ 248/* Allow examination and configuration of disk quotas */
249/* Allow configuring the kernel's syslog (printk behaviour) */
250/* Allow setting the domainname */ 249/* Allow setting the domainname */
251/* Allow setting the hostname */ 250/* Allow setting the hostname */
252/* Allow calling bdflush() */ 251/* Allow calling bdflush() */
@@ -352,7 +351,11 @@ struct cpu_vfs_cap_data {
352 351
353#define CAP_MAC_ADMIN 33 352#define CAP_MAC_ADMIN 33
354 353
355#define CAP_LAST_CAP CAP_MAC_ADMIN 354/* Allow configuring the kernel's syslog (printk behaviour) */
355
356#define CAP_SYSLOG 34
357
358#define CAP_LAST_CAP CAP_SYSLOG
356 359
357#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) 360#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
358 361
diff --git a/include/linux/flex_array.h b/include/linux/flex_array.h
index 631b77f2ac70..70e4efabe0fb 100644
--- a/include/linux/flex_array.h
+++ b/include/linux/flex_array.h
@@ -71,7 +71,7 @@ void *flex_array_get(struct flex_array *fa, unsigned int element_nr);
71int flex_array_shrink(struct flex_array *fa); 71int flex_array_shrink(struct flex_array *fa);
72 72
73#define flex_array_put_ptr(fa, nr, src, gfp) \ 73#define flex_array_put_ptr(fa, nr, src, gfp) \
74 flex_array_put(fa, nr, &(void *)(src), gfp) 74 flex_array_put(fa, nr, (void *)&(src), gfp)
75 75
76void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr); 76void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr);
77 77
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index b6de9a6f7018..d0fbc043de60 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -56,6 +56,8 @@
56 56
57#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) 57#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
58#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 58#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
59
60/* The `const' in roundup() prevents gcc-3.3 from calling __divdi3 */
59#define roundup(x, y) ( \ 61#define roundup(x, y) ( \
60{ \ 62{ \
61 const typeof(y) __y = y; \ 63 const typeof(y) __y = y; \
@@ -263,6 +265,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
263} 265}
264 266
265extern int hex_to_bin(char ch); 267extern int hex_to_bin(char ch);
268extern void hex2bin(u8 *dst, const char *src, size_t count);
266 269
267/* 270/*
268 * General tracing related utility functions - trace_printk(), 271 * General tracing related utility functions - trace_printk(),
diff --git a/include/linux/security.h b/include/linux/security.h
index 1ac42475ea08..c642bb8b8f5a 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1058,8 +1058,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1058 * @cred points to the credentials to provide the context against which to 1058 * @cred points to the credentials to provide the context against which to
1059 * evaluate the security data on the key. 1059 * evaluate the security data on the key.
1060 * @perm describes the combination of permissions required of this key. 1060 * @perm describes the combination of permissions required of this key.
1061 * Return 1 if permission granted, 0 if permission denied and -ve it the 1061 * Return 0 if permission is granted, -ve error otherwise.
1062 * normal permissions model should be effected.
1063 * @key_getsecurity: 1062 * @key_getsecurity:
1064 * Get a textual representation of the security context attached to a key 1063 * Get a textual representation of the security context attached to a key
1065 * for the purposes of honouring KEYCTL_GETSECURITY. This function 1064 * for the purposes of honouring KEYCTL_GETSECURITY. This function
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index ac5d1c1285d9..fdc718abf83b 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -31,6 +31,7 @@
31 31
32extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf); 32extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf);
33extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash); 33extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash);
34extern int tpm_send(u32 chip_num, void *cmd, size_t buflen);
34#else 35#else
35static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) { 36static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) {
36 return -ENODEV; 37 return -ENODEV;
@@ -38,5 +39,8 @@ static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) {
38static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) { 39static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) {
39 return -ENODEV; 40 return -ENODEV;
40} 41}
42static inline int tpm_send(u32 chip_num, void *cmd, size_t buflen) {
43 return -ENODEV;
44}
41#endif 45#endif
42#endif 46#endif
diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
new file mode 100644
index 000000000000..727512e249b5
--- /dev/null
+++ b/include/linux/tpm_command.h
@@ -0,0 +1,28 @@
1#ifndef __LINUX_TPM_COMMAND_H__
2#define __LINUX_TPM_COMMAND_H__
3
4/*
5 * TPM Command constants from specifications at
6 * http://www.trustedcomputinggroup.org
7 */
8
9/* Command TAGS */
10#define TPM_TAG_RQU_COMMAND 193
11#define TPM_TAG_RQU_AUTH1_COMMAND 194
12#define TPM_TAG_RQU_AUTH2_COMMAND 195
13#define TPM_TAG_RSP_COMMAND 196
14#define TPM_TAG_RSP_AUTH1_COMMAND 197
15#define TPM_TAG_RSP_AUTH2_COMMAND 198
16
17/* Command Ordinals */
18#define TPM_ORD_GETRANDOM 70
19#define TPM_ORD_OSAP 11
20#define TPM_ORD_OIAP 10
21#define TPM_ORD_SEAL 23
22#define TPM_ORD_UNSEAL 24
23
24/* Other constants */
25#define SRKHANDLE 0x40000000
26#define TPM_NONCE_SIZE 20
27
28#endif
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index f1e5bde4b35a..e6131ef98d8f 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -40,9 +40,13 @@
40#define XATTR_SMACK_SUFFIX "SMACK64" 40#define XATTR_SMACK_SUFFIX "SMACK64"
41#define XATTR_SMACK_IPIN "SMACK64IPIN" 41#define XATTR_SMACK_IPIN "SMACK64IPIN"
42#define XATTR_SMACK_IPOUT "SMACK64IPOUT" 42#define XATTR_SMACK_IPOUT "SMACK64IPOUT"
43#define XATTR_SMACK_EXEC "SMACK64EXEC"
44#define XATTR_SMACK_TRANSMUTE "SMACK64TRANSMUTE"
43#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX 45#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX
44#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN 46#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
45#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT 47#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
48#define XATTR_NAME_SMACKEXEC XATTR_SECURITY_PREFIX XATTR_SMACK_EXEC
49#define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE
46 50
47#define XATTR_CAPS_SUFFIX "capability" 51#define XATTR_CAPS_SUFFIX "capability"
48#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX 52#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
diff --git a/kernel/printk.c b/kernel/printk.c
index 4642a5c439eb..f64b8997fc76 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -273,12 +273,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
273 * at open time. 273 * at open time.
274 */ 274 */
275 if (type == SYSLOG_ACTION_OPEN || !from_file) { 275 if (type == SYSLOG_ACTION_OPEN || !from_file) {
276 if (dmesg_restrict && !capable(CAP_SYS_ADMIN)) 276 if (dmesg_restrict && !capable(CAP_SYSLOG))
277 return -EPERM; 277 goto warn; /* switch to return -EPERM after 2.6.39 */
278 if ((type != SYSLOG_ACTION_READ_ALL && 278 if ((type != SYSLOG_ACTION_READ_ALL &&
279 type != SYSLOG_ACTION_SIZE_BUFFER) && 279 type != SYSLOG_ACTION_SIZE_BUFFER) &&
280 !capable(CAP_SYS_ADMIN)) 280 !capable(CAP_SYSLOG))
281 return -EPERM; 281 goto warn; /* switch to return -EPERM after 2.6.39 */
282 } 282 }
283 283
284 error = security_syslog(type); 284 error = security_syslog(type);
@@ -422,6 +422,12 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
422 } 422 }
423out: 423out:
424 return error; 424 return error;
425warn:
426 /* remove after 2.6.39 */
427 if (capable(CAP_SYS_ADMIN))
428 WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
429 "but no CAP_SYSLOG (deprecated and denied).\n");
430 return -EPERM;
425} 431}
426 432
427SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) 433SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 5d7a4802c562..b66b2bd67952 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -34,6 +34,22 @@ int hex_to_bin(char ch)
34EXPORT_SYMBOL(hex_to_bin); 34EXPORT_SYMBOL(hex_to_bin);
35 35
36/** 36/**
37 * hex2bin - convert an ascii hexadecimal string to its binary representation
38 * @dst: binary result
39 * @src: ascii hexadecimal string
40 * @count: result length
41 */
42void hex2bin(u8 *dst, const char *src, size_t count)
43{
44 while (count--) {
45 *dst = hex_to_bin(*src++) << 4;
46 *dst += hex_to_bin(*src++);
47 dst++;
48 }
49}
50EXPORT_SYMBOL(hex2bin);
51
52/**
37 * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory 53 * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
38 * @buf: data blob to dump 54 * @buf: data blob to dump
39 * @len: number of bytes in the @buf 55 * @len: number of bytes in the @buf
diff --git a/security/Kconfig b/security/Kconfig
index e80da955e687..95accd442d55 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -21,6 +21,37 @@ config KEYS
21 21
22 If you are unsure as to whether this is required, answer N. 22 If you are unsure as to whether this is required, answer N.
23 23
24config TRUSTED_KEYS
25 tristate "TRUSTED KEYS"
26 depends on KEYS && TCG_TPM
27 select CRYPTO
28 select CRYPTO_HMAC
29 select CRYPTO_SHA1
30 help
31 This option provides support for creating, sealing, and unsealing
32 keys in the kernel. Trusted keys are random number symmetric keys,
33 generated and RSA-sealed by the TPM. The TPM only unseals the keys,
34 if the boot PCRs and other criteria match. Userspace will only ever
35 see encrypted blobs.
36
37 If you are unsure as to whether this is required, answer N.
38
39config ENCRYPTED_KEYS
40 tristate "ENCRYPTED KEYS"
41 depends on KEYS && TRUSTED_KEYS
42 select CRYPTO_AES
43 select CRYPTO_CBC
44 select CRYPTO_SHA256
45 select CRYPTO_RNG
46 help
47 This option provides support for create/encrypting/decrypting keys
48 in the kernel. Encrypted keys are kernel generated random numbers,
49 which are encrypted/decrypted with a 'master' symmetric key. The
50 'master' key can be either a trusted-key or user-key type.
51 Userspace only ever sees/stores encrypted blobs.
52
53 If you are unsure as to whether this is required, answer N.
54
24config KEYS_DEBUG_PROC_KEYS 55config KEYS_DEBUG_PROC_KEYS
25 bool "Enable the /proc/keys file by which keys may be viewed" 56 bool "Enable the /proc/keys file by which keys may be viewed"
26 depends on KEYS 57 depends on KEYS
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 74d5447d7df7..6c941050f573 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -13,6 +13,8 @@ obj-y := \
13 request_key_auth.o \ 13 request_key_auth.o \
14 user_defined.o 14 user_defined.o
15 15
16obj-$(CONFIG_TRUSTED_KEYS) += trusted_defined.o
17obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted_defined.o
16obj-$(CONFIG_KEYS_COMPAT) += compat.o 18obj-$(CONFIG_KEYS_COMPAT) += compat.o
17obj-$(CONFIG_PROC_FS) += proc.o 19obj-$(CONFIG_PROC_FS) += proc.o
18obj-$(CONFIG_SYSCTL) += sysctl.o 20obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/encrypted_defined.c b/security/keys/encrypted_defined.c
new file mode 100644
index 000000000000..32d27c858388
--- /dev/null
+++ b/security/keys/encrypted_defined.c
@@ -0,0 +1,903 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 *
4 * Author:
5 * Mimi Zohar <zohar@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 * See Documentation/keys-trusted-encrypted.txt
12 */
13
14#include <linux/uaccess.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/parser.h>
19#include <linux/string.h>
20#include <linux/err.h>
21#include <keys/user-type.h>
22#include <keys/trusted-type.h>
23#include <keys/encrypted-type.h>
24#include <linux/key-type.h>
25#include <linux/random.h>
26#include <linux/rcupdate.h>
27#include <linux/scatterlist.h>
28#include <linux/crypto.h>
29#include <crypto/hash.h>
30#include <crypto/sha.h>
31#include <crypto/aes.h>
32
33#include "encrypted_defined.h"
34
35static const char KEY_TRUSTED_PREFIX[] = "trusted:";
36static const char KEY_USER_PREFIX[] = "user:";
37static const char hash_alg[] = "sha256";
38static const char hmac_alg[] = "hmac(sha256)";
39static const char blkcipher_alg[] = "cbc(aes)";
40static unsigned int ivsize;
41static int blksize;
42
43#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1)
44#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1)
45#define HASH_SIZE SHA256_DIGEST_SIZE
46#define MAX_DATA_SIZE 4096
47#define MIN_DATA_SIZE 20
48
49struct sdesc {
50 struct shash_desc shash;
51 char ctx[];
52};
53
54static struct crypto_shash *hashalg;
55static struct crypto_shash *hmacalg;
56
57enum {
58 Opt_err = -1, Opt_new, Opt_load, Opt_update
59};
60
61static const match_table_t key_tokens = {
62 {Opt_new, "new"},
63 {Opt_load, "load"},
64 {Opt_update, "update"},
65 {Opt_err, NULL}
66};
67
68static int aes_get_sizes(void)
69{
70 struct crypto_blkcipher *tfm;
71
72 tfm = crypto_alloc_blkcipher(blkcipher_alg, 0, CRYPTO_ALG_ASYNC);
73 if (IS_ERR(tfm)) {
74 pr_err("encrypted_key: failed to alloc_cipher (%ld)\n",
75 PTR_ERR(tfm));
76 return PTR_ERR(tfm);
77 }
78 ivsize = crypto_blkcipher_ivsize(tfm);
79 blksize = crypto_blkcipher_blocksize(tfm);
80 crypto_free_blkcipher(tfm);
81 return 0;
82}
83
84/*
85 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
86 *
87 * key-type:= "trusted:" | "encrypted:"
88 * desc:= master-key description
89 *
90 * Verify that 'key-type' is valid and that 'desc' exists. On key update,
91 * only the master key description is permitted to change, not the key-type.
92 * The key-type remains constant.
93 *
94 * On success returns 0, otherwise -EINVAL.
95 */
96static int valid_master_desc(const char *new_desc, const char *orig_desc)
97{
98 if (!memcmp(new_desc, KEY_TRUSTED_PREFIX, KEY_TRUSTED_PREFIX_LEN)) {
99 if (strlen(new_desc) == KEY_TRUSTED_PREFIX_LEN)
100 goto out;
101 if (orig_desc)
102 if (memcmp(new_desc, orig_desc, KEY_TRUSTED_PREFIX_LEN))
103 goto out;
104 } else if (!memcmp(new_desc, KEY_USER_PREFIX, KEY_USER_PREFIX_LEN)) {
105 if (strlen(new_desc) == KEY_USER_PREFIX_LEN)
106 goto out;
107 if (orig_desc)
108 if (memcmp(new_desc, orig_desc, KEY_USER_PREFIX_LEN))
109 goto out;
110 } else
111 goto out;
112 return 0;
113out:
114 return -EINVAL;
115}
116
117/*
118 * datablob_parse - parse the keyctl data
119 *
120 * datablob format:
121 * new <master-key name> <decrypted data length>
122 * load <master-key name> <decrypted data length> <encrypted iv + data>
123 * update <new-master-key name>
124 *
125 * Tokenizes a copy of the keyctl data, returning a pointer to each token,
126 * which is null terminated.
127 *
128 * On success returns 0, otherwise -EINVAL.
129 */
130static int datablob_parse(char *datablob, char **master_desc,
131 char **decrypted_datalen, char **hex_encoded_iv)
132{
133 substring_t args[MAX_OPT_ARGS];
134 int ret = -EINVAL;
135 int key_cmd;
136 char *p;
137
138 p = strsep(&datablob, " \t");
139 if (!p)
140 return ret;
141 key_cmd = match_token(p, key_tokens, args);
142
143 *master_desc = strsep(&datablob, " \t");
144 if (!*master_desc)
145 goto out;
146
147 if (valid_master_desc(*master_desc, NULL) < 0)
148 goto out;
149
150 if (decrypted_datalen) {
151 *decrypted_datalen = strsep(&datablob, " \t");
152 if (!*decrypted_datalen)
153 goto out;
154 }
155
156 switch (key_cmd) {
157 case Opt_new:
158 if (!decrypted_datalen)
159 break;
160 ret = 0;
161 break;
162 case Opt_load:
163 if (!decrypted_datalen)
164 break;
165 *hex_encoded_iv = strsep(&datablob, " \t");
166 if (!*hex_encoded_iv)
167 break;
168 ret = 0;
169 break;
170 case Opt_update:
171 if (decrypted_datalen)
172 break;
173 ret = 0;
174 break;
175 case Opt_err:
176 break;
177 }
178out:
179 return ret;
180}
181
182/*
183 * datablob_format - format as an ascii string, before copying to userspace
184 */
185static char *datablob_format(struct encrypted_key_payload *epayload,
186 size_t asciiblob_len)
187{
188 char *ascii_buf, *bufp;
189 u8 *iv = epayload->iv;
190 int len;
191 int i;
192
193 ascii_buf = kmalloc(asciiblob_len + 1, GFP_KERNEL);
194 if (!ascii_buf)
195 goto out;
196
197 ascii_buf[asciiblob_len] = '\0';
198
199 /* copy datablob master_desc and datalen strings */
200 len = sprintf(ascii_buf, "%s %s ", epayload->master_desc,
201 epayload->datalen);
202
203 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */
204 bufp = &ascii_buf[len];
205 for (i = 0; i < (asciiblob_len - len) / 2; i++)
206 bufp = pack_hex_byte(bufp, iv[i]);
207out:
208 return ascii_buf;
209}
210
211/*
212 * request_trusted_key - request the trusted key
213 *
214 * Trusted keys are sealed to PCRs and other metadata. Although userspace
215 * manages both trusted/encrypted key-types, like the encrypted key type
216 * data, trusted key type data is not visible decrypted from userspace.
217 */
218static struct key *request_trusted_key(const char *trusted_desc,
219 u8 **master_key, size_t *master_keylen)
220{
221 struct trusted_key_payload *tpayload;
222 struct key *tkey;
223
224 tkey = request_key(&key_type_trusted, trusted_desc, NULL);
225 if (IS_ERR(tkey))
226 goto error;
227
228 down_read(&tkey->sem);
229 tpayload = rcu_dereference(tkey->payload.data);
230 *master_key = tpayload->key;
231 *master_keylen = tpayload->key_len;
232error:
233 return tkey;
234}
235
236/*
237 * request_user_key - request the user key
238 *
239 * Use a user provided key to encrypt/decrypt an encrypted-key.
240 */
241static struct key *request_user_key(const char *master_desc, u8 **master_key,
242 size_t *master_keylen)
243{
244 struct user_key_payload *upayload;
245 struct key *ukey;
246
247 ukey = request_key(&key_type_user, master_desc, NULL);
248 if (IS_ERR(ukey))
249 goto error;
250
251 down_read(&ukey->sem);
252 upayload = rcu_dereference(ukey->payload.data);
253 *master_key = upayload->data;
254 *master_keylen = upayload->datalen;
255error:
256 return ukey;
257}
258
259static struct sdesc *alloc_sdesc(struct crypto_shash *alg)
260{
261 struct sdesc *sdesc;
262 int size;
263
264 size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
265 sdesc = kmalloc(size, GFP_KERNEL);
266 if (!sdesc)
267 return ERR_PTR(-ENOMEM);
268 sdesc->shash.tfm = alg;
269 sdesc->shash.flags = 0x0;
270 return sdesc;
271}
272
273static int calc_hmac(u8 *digest, const u8 *key, unsigned int keylen,
274 const u8 *buf, unsigned int buflen)
275{
276 struct sdesc *sdesc;
277 int ret;
278
279 sdesc = alloc_sdesc(hmacalg);
280 if (IS_ERR(sdesc)) {
281 pr_info("encrypted_key: can't alloc %s\n", hmac_alg);
282 return PTR_ERR(sdesc);
283 }
284
285 ret = crypto_shash_setkey(hmacalg, key, keylen);
286 if (!ret)
287 ret = crypto_shash_digest(&sdesc->shash, buf, buflen, digest);
288 kfree(sdesc);
289 return ret;
290}
291
292static int calc_hash(u8 *digest, const u8 *buf, unsigned int buflen)
293{
294 struct sdesc *sdesc;
295 int ret;
296
297 sdesc = alloc_sdesc(hashalg);
298 if (IS_ERR(sdesc)) {
299 pr_info("encrypted_key: can't alloc %s\n", hash_alg);
300 return PTR_ERR(sdesc);
301 }
302
303 ret = crypto_shash_digest(&sdesc->shash, buf, buflen, digest);
304 kfree(sdesc);
305 return ret;
306}
307
308enum derived_key_type { ENC_KEY, AUTH_KEY };
309
310/* Derive authentication/encryption key from trusted key */
311static int get_derived_key(u8 *derived_key, enum derived_key_type key_type,
312 const u8 *master_key, size_t master_keylen)
313{
314 u8 *derived_buf;
315 unsigned int derived_buf_len;
316 int ret;
317
318 derived_buf_len = strlen("AUTH_KEY") + 1 + master_keylen;
319 if (derived_buf_len < HASH_SIZE)
320 derived_buf_len = HASH_SIZE;
321
322 derived_buf = kzalloc(derived_buf_len, GFP_KERNEL);
323 if (!derived_buf) {
324 pr_err("encrypted_key: out of memory\n");
325 return -ENOMEM;
326 }
327 if (key_type)
328 strcpy(derived_buf, "AUTH_KEY");
329 else
330 strcpy(derived_buf, "ENC_KEY");
331
332 memcpy(derived_buf + strlen(derived_buf) + 1, master_key,
333 master_keylen);
334 ret = calc_hash(derived_key, derived_buf, derived_buf_len);
335 kfree(derived_buf);
336 return ret;
337}
338
339static int init_blkcipher_desc(struct blkcipher_desc *desc, const u8 *key,
340 unsigned int key_len, const u8 *iv,
341 unsigned int ivsize)
342{
343 int ret;
344
345 desc->tfm = crypto_alloc_blkcipher(blkcipher_alg, 0, CRYPTO_ALG_ASYNC);
346 if (IS_ERR(desc->tfm)) {
347 pr_err("encrypted_key: failed to load %s transform (%ld)\n",
348 blkcipher_alg, PTR_ERR(desc->tfm));
349 return PTR_ERR(desc->tfm);
350 }
351 desc->flags = 0;
352
353 ret = crypto_blkcipher_setkey(desc->tfm, key, key_len);
354 if (ret < 0) {
355 pr_err("encrypted_key: failed to setkey (%d)\n", ret);
356 crypto_free_blkcipher(desc->tfm);
357 return ret;
358 }
359 crypto_blkcipher_set_iv(desc->tfm, iv, ivsize);
360 return 0;
361}
362
363static struct key *request_master_key(struct encrypted_key_payload *epayload,
364 u8 **master_key, size_t *master_keylen)
365{
366 struct key *mkey = NULL;
367
368 if (!strncmp(epayload->master_desc, KEY_TRUSTED_PREFIX,
369 KEY_TRUSTED_PREFIX_LEN)) {
370 mkey = request_trusted_key(epayload->master_desc +
371 KEY_TRUSTED_PREFIX_LEN,
372 master_key, master_keylen);
373 } else if (!strncmp(epayload->master_desc, KEY_USER_PREFIX,
374 KEY_USER_PREFIX_LEN)) {
375 mkey = request_user_key(epayload->master_desc +
376 KEY_USER_PREFIX_LEN,
377 master_key, master_keylen);
378 } else
379 goto out;
380
381 if (IS_ERR(mkey))
382 pr_info("encrypted_key: key %s not found",
383 epayload->master_desc);
384 if (mkey)
385 dump_master_key(*master_key, *master_keylen);
386out:
387 return mkey;
388}
389
390/* Before returning data to userspace, encrypt decrypted data. */
391static int derived_key_encrypt(struct encrypted_key_payload *epayload,
392 const u8 *derived_key,
393 unsigned int derived_keylen)
394{
395 struct scatterlist sg_in[2];
396 struct scatterlist sg_out[1];
397 struct blkcipher_desc desc;
398 unsigned int encrypted_datalen;
399 unsigned int padlen;
400 char pad[16];
401 int ret;
402
403 encrypted_datalen = roundup(epayload->decrypted_datalen, blksize);
404 padlen = encrypted_datalen - epayload->decrypted_datalen;
405
406 ret = init_blkcipher_desc(&desc, derived_key, derived_keylen,
407 epayload->iv, ivsize);
408 if (ret < 0)
409 goto out;
410 dump_decrypted_data(epayload);
411
412 memset(pad, 0, sizeof pad);
413 sg_init_table(sg_in, 2);
414 sg_set_buf(&sg_in[0], epayload->decrypted_data,
415 epayload->decrypted_datalen);
416 sg_set_buf(&sg_in[1], pad, padlen);
417
418 sg_init_table(sg_out, 1);
419 sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen);
420
421 ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in, encrypted_datalen);
422 crypto_free_blkcipher(desc.tfm);
423 if (ret < 0)
424 pr_err("encrypted_key: failed to encrypt (%d)\n", ret);
425 else
426 dump_encrypted_data(epayload, encrypted_datalen);
427out:
428 return ret;
429}
430
431static int datablob_hmac_append(struct encrypted_key_payload *epayload,
432 const u8 *master_key, size_t master_keylen)
433{
434 u8 derived_key[HASH_SIZE];
435 u8 *digest;
436 int ret;
437
438 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
439 if (ret < 0)
440 goto out;
441
442 digest = epayload->master_desc + epayload->datablob_len;
443 ret = calc_hmac(digest, derived_key, sizeof derived_key,
444 epayload->master_desc, epayload->datablob_len);
445 if (!ret)
446 dump_hmac(NULL, digest, HASH_SIZE);
447out:
448 return ret;
449}
450
451/* verify HMAC before decrypting encrypted key */
452static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
453 const u8 *master_key, size_t master_keylen)
454{
455 u8 derived_key[HASH_SIZE];
456 u8 digest[HASH_SIZE];
457 int ret;
458
459 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
460 if (ret < 0)
461 goto out;
462
463 ret = calc_hmac(digest, derived_key, sizeof derived_key,
464 epayload->master_desc, epayload->datablob_len);
465 if (ret < 0)
466 goto out;
467 ret = memcmp(digest, epayload->master_desc + epayload->datablob_len,
468 sizeof digest);
469 if (ret) {
470 ret = -EINVAL;
471 dump_hmac("datablob",
472 epayload->master_desc + epayload->datablob_len,
473 HASH_SIZE);
474 dump_hmac("calc", digest, HASH_SIZE);
475 }
476out:
477 return ret;
478}
479
480static int derived_key_decrypt(struct encrypted_key_payload *epayload,
481 const u8 *derived_key,
482 unsigned int derived_keylen)
483{
484 struct scatterlist sg_in[1];
485 struct scatterlist sg_out[2];
486 struct blkcipher_desc desc;
487 unsigned int encrypted_datalen;
488 char pad[16];
489 int ret;
490
491 encrypted_datalen = roundup(epayload->decrypted_datalen, blksize);
492 ret = init_blkcipher_desc(&desc, derived_key, derived_keylen,
493 epayload->iv, ivsize);
494 if (ret < 0)
495 goto out;
496 dump_encrypted_data(epayload, encrypted_datalen);
497
498 memset(pad, 0, sizeof pad);
499 sg_init_table(sg_in, 1);
500 sg_init_table(sg_out, 2);
501 sg_set_buf(sg_in, epayload->encrypted_data, encrypted_datalen);
502 sg_set_buf(&sg_out[0], epayload->decrypted_data,
503 epayload->decrypted_datalen);
504 sg_set_buf(&sg_out[1], pad, sizeof pad);
505
506 ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, encrypted_datalen);
507 crypto_free_blkcipher(desc.tfm);
508 if (ret < 0)
509 goto out;
510 dump_decrypted_data(epayload);
511out:
512 return ret;
513}
514
515/* Allocate memory for decrypted key and datablob. */
516static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
517 const char *master_desc,
518 const char *datalen)
519{
520 struct encrypted_key_payload *epayload = NULL;
521 unsigned short datablob_len;
522 unsigned short decrypted_datalen;
523 unsigned int encrypted_datalen;
524 long dlen;
525 int ret;
526
527 ret = strict_strtol(datalen, 10, &dlen);
528 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE)
529 return ERR_PTR(-EINVAL);
530
531 decrypted_datalen = dlen;
532 encrypted_datalen = roundup(decrypted_datalen, blksize);
533
534 datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1
535 + ivsize + 1 + encrypted_datalen;
536
537 ret = key_payload_reserve(key, decrypted_datalen + datablob_len
538 + HASH_SIZE + 1);
539 if (ret < 0)
540 return ERR_PTR(ret);
541
542 epayload = kzalloc(sizeof(*epayload) + decrypted_datalen +
543 datablob_len + HASH_SIZE + 1, GFP_KERNEL);
544 if (!epayload)
545 return ERR_PTR(-ENOMEM);
546
547 epayload->decrypted_datalen = decrypted_datalen;
548 epayload->datablob_len = datablob_len;
549 return epayload;
550}
551
552static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
553 const char *hex_encoded_iv)
554{
555 struct key *mkey;
556 u8 derived_key[HASH_SIZE];
557 u8 *master_key;
558 u8 *hmac;
559 const char *hex_encoded_data;
560 unsigned int encrypted_datalen;
561 size_t master_keylen;
562 size_t asciilen;
563 int ret;
564
565 encrypted_datalen = roundup(epayload->decrypted_datalen, blksize);
566 asciilen = (ivsize + 1 + encrypted_datalen + HASH_SIZE) * 2;
567 if (strlen(hex_encoded_iv) != asciilen)
568 return -EINVAL;
569
570 hex_encoded_data = hex_encoded_iv + (2 * ivsize) + 2;
571 hex2bin(epayload->iv, hex_encoded_iv, ivsize);
572 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);
573
574 hmac = epayload->master_desc + epayload->datablob_len;
575 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE);
576
577 mkey = request_master_key(epayload, &master_key, &master_keylen);
578 if (IS_ERR(mkey))
579 return PTR_ERR(mkey);
580
581 ret = datablob_hmac_verify(epayload, master_key, master_keylen);
582 if (ret < 0) {
583 pr_err("encrypted_key: bad hmac (%d)\n", ret);
584 goto out;
585 }
586
587 ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen);
588 if (ret < 0)
589 goto out;
590
591 ret = derived_key_decrypt(epayload, derived_key, sizeof derived_key);
592 if (ret < 0)
593 pr_err("encrypted_key: failed to decrypt key (%d)\n", ret);
594out:
595 up_read(&mkey->sem);
596 key_put(mkey);
597 return ret;
598}
599
600static void __ekey_init(struct encrypted_key_payload *epayload,
601 const char *master_desc, const char *datalen)
602{
603 epayload->master_desc = epayload->decrypted_data
604 + epayload->decrypted_datalen;
605 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1;
606 epayload->iv = epayload->datalen + strlen(datalen) + 1;
607 epayload->encrypted_data = epayload->iv + ivsize + 1;
608
609 memcpy(epayload->master_desc, master_desc, strlen(master_desc));
610 memcpy(epayload->datalen, datalen, strlen(datalen));
611}
612
613/*
614 * encrypted_init - initialize an encrypted key
615 *
616 * For a new key, use a random number for both the iv and data
617 * itself. For an old key, decrypt the hex encoded data.
618 */
619static int encrypted_init(struct encrypted_key_payload *epayload,
620 const char *master_desc, const char *datalen,
621 const char *hex_encoded_iv)
622{
623 int ret = 0;
624
625 __ekey_init(epayload, master_desc, datalen);
626 if (!hex_encoded_iv) {
627 get_random_bytes(epayload->iv, ivsize);
628
629 get_random_bytes(epayload->decrypted_data,
630 epayload->decrypted_datalen);
631 } else
632 ret = encrypted_key_decrypt(epayload, hex_encoded_iv);
633 return ret;
634}
635
636/*
637 * encrypted_instantiate - instantiate an encrypted key
638 *
639 * Decrypt an existing encrypted datablob or create a new encrypted key
640 * based on a kernel random number.
641 *
642 * On success, return 0. Otherwise return errno.
643 */
644static int encrypted_instantiate(struct key *key, const void *data,
645 size_t datalen)
646{
647 struct encrypted_key_payload *epayload = NULL;
648 char *datablob = NULL;
649 char *master_desc = NULL;
650 char *decrypted_datalen = NULL;
651 char *hex_encoded_iv = NULL;
652 int ret;
653
654 if (datalen <= 0 || datalen > 32767 || !data)
655 return -EINVAL;
656
657 datablob = kmalloc(datalen + 1, GFP_KERNEL);
658 if (!datablob)
659 return -ENOMEM;
660 datablob[datalen] = 0;
661 memcpy(datablob, data, datalen);
662 ret = datablob_parse(datablob, &master_desc, &decrypted_datalen,
663 &hex_encoded_iv);
664 if (ret < 0)
665 goto out;
666
667 epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen);
668 if (IS_ERR(epayload)) {
669 ret = PTR_ERR(epayload);
670 goto out;
671 }
672 ret = encrypted_init(epayload, master_desc, decrypted_datalen,
673 hex_encoded_iv);
674 if (ret < 0) {
675 kfree(epayload);
676 goto out;
677 }
678
679 rcu_assign_pointer(key->payload.data, epayload);
680out:
681 kfree(datablob);
682 return ret;
683}
684
685static void encrypted_rcu_free(struct rcu_head *rcu)
686{
687 struct encrypted_key_payload *epayload;
688
689 epayload = container_of(rcu, struct encrypted_key_payload, rcu);
690 memset(epayload->decrypted_data, 0, epayload->decrypted_datalen);
691 kfree(epayload);
692}
693
694/*
695 * encrypted_update - update the master key description
696 *
697 * Change the master key description for an existing encrypted key.
698 * The next read will return an encrypted datablob using the new
699 * master key description.
700 *
701 * On success, return 0. Otherwise return errno.
702 */
703static int encrypted_update(struct key *key, const void *data, size_t datalen)
704{
705 struct encrypted_key_payload *epayload = key->payload.data;
706 struct encrypted_key_payload *new_epayload;
707 char *buf;
708 char *new_master_desc = NULL;
709 int ret = 0;
710
711 if (datalen <= 0 || datalen > 32767 || !data)
712 return -EINVAL;
713
714 buf = kmalloc(datalen + 1, GFP_KERNEL);
715 if (!buf)
716 return -ENOMEM;
717
718 buf[datalen] = 0;
719 memcpy(buf, data, datalen);
720 ret = datablob_parse(buf, &new_master_desc, NULL, NULL);
721 if (ret < 0)
722 goto out;
723
724 ret = valid_master_desc(new_master_desc, epayload->master_desc);
725 if (ret < 0)
726 goto out;
727
728 new_epayload = encrypted_key_alloc(key, new_master_desc,
729 epayload->datalen);
730 if (IS_ERR(new_epayload)) {
731 ret = PTR_ERR(new_epayload);
732 goto out;
733 }
734
735 __ekey_init(new_epayload, new_master_desc, epayload->datalen);
736
737 memcpy(new_epayload->iv, epayload->iv, ivsize);
738 memcpy(new_epayload->decrypted_data, epayload->decrypted_data,
739 epayload->decrypted_datalen);
740
741 rcu_assign_pointer(key->payload.data, new_epayload);
742 call_rcu(&epayload->rcu, encrypted_rcu_free);
743out:
744 kfree(buf);
745 return ret;
746}
747
748/*
749 * encrypted_read - format and copy the encrypted data to userspace
750 *
751 * The resulting datablob format is:
752 * <master-key name> <decrypted data length> <encrypted iv> <encrypted data>
753 *
754 * On success, return to userspace the encrypted key datablob size.
755 */
756static long encrypted_read(const struct key *key, char __user *buffer,
757 size_t buflen)
758{
759 struct encrypted_key_payload *epayload;
760 struct key *mkey;
761 u8 *master_key;
762 size_t master_keylen;
763 char derived_key[HASH_SIZE];
764 char *ascii_buf;
765 size_t asciiblob_len;
766 int ret;
767
768 epayload = rcu_dereference_protected(key->payload.data,
769 rwsem_is_locked(&((struct key *)key)->sem));
770
771 /* returns the hex encoded iv, encrypted-data, and hmac as ascii */
772 asciiblob_len = epayload->datablob_len + ivsize + 1
773 + roundup(epayload->decrypted_datalen, blksize)
774 + (HASH_SIZE * 2);
775
776 if (!buffer || buflen < asciiblob_len)
777 return asciiblob_len;
778
779 mkey = request_master_key(epayload, &master_key, &master_keylen);
780 if (IS_ERR(mkey))
781 return PTR_ERR(mkey);
782
783 ret = get_derived_key(derived_key, ENC_KEY, master_key, master_keylen);
784 if (ret < 0)
785 goto out;
786
787 ret = derived_key_encrypt(epayload, derived_key, sizeof derived_key);
788 if (ret < 0)
789 goto out;
790
791 ret = datablob_hmac_append(epayload, master_key, master_keylen);
792 if (ret < 0)
793 goto out;
794
795 ascii_buf = datablob_format(epayload, asciiblob_len);
796 if (!ascii_buf) {
797 ret = -ENOMEM;
798 goto out;
799 }
800
801 up_read(&mkey->sem);
802 key_put(mkey);
803
804 if (copy_to_user(buffer, ascii_buf, asciiblob_len) != 0)
805 ret = -EFAULT;
806 kfree(ascii_buf);
807
808 return asciiblob_len;
809out:
810 up_read(&mkey->sem);
811 key_put(mkey);
812 return ret;
813}
814
815/*
816 * encrypted_destroy - before freeing the key, clear the decrypted data
817 *
818 * Before freeing the key, clear the memory containing the decrypted
819 * key data.
820 */
821static void encrypted_destroy(struct key *key)
822{
823 struct encrypted_key_payload *epayload = key->payload.data;
824
825 if (!epayload)
826 return;
827
828 memset(epayload->decrypted_data, 0, epayload->decrypted_datalen);
829 kfree(key->payload.data);
830}
831
832struct key_type key_type_encrypted = {
833 .name = "encrypted",
834 .instantiate = encrypted_instantiate,
835 .update = encrypted_update,
836 .match = user_match,
837 .destroy = encrypted_destroy,
838 .describe = user_describe,
839 .read = encrypted_read,
840};
841EXPORT_SYMBOL_GPL(key_type_encrypted);
842
843static void encrypted_shash_release(void)
844{
845 if (hashalg)
846 crypto_free_shash(hashalg);
847 if (hmacalg)
848 crypto_free_shash(hmacalg);
849}
850
851static int __init encrypted_shash_alloc(void)
852{
853 int ret;
854
855 hmacalg = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC);
856 if (IS_ERR(hmacalg)) {
857 pr_info("encrypted_key: could not allocate crypto %s\n",
858 hmac_alg);
859 return PTR_ERR(hmacalg);
860 }
861
862 hashalg = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC);
863 if (IS_ERR(hashalg)) {
864 pr_info("encrypted_key: could not allocate crypto %s\n",
865 hash_alg);
866 ret = PTR_ERR(hashalg);
867 goto hashalg_fail;
868 }
869
870 return 0;
871
872hashalg_fail:
873 crypto_free_shash(hmacalg);
874 return ret;
875}
876
877static int __init init_encrypted(void)
878{
879 int ret;
880
881 ret = encrypted_shash_alloc();
882 if (ret < 0)
883 return ret;
884 ret = register_key_type(&key_type_encrypted);
885 if (ret < 0)
886 goto out;
887 return aes_get_sizes();
888out:
889 encrypted_shash_release();
890 return ret;
891
892}
893
894static void __exit cleanup_encrypted(void)
895{
896 encrypted_shash_release();
897 unregister_key_type(&key_type_encrypted);
898}
899
900late_initcall(init_encrypted);
901module_exit(cleanup_encrypted);
902
903MODULE_LICENSE("GPL");
diff --git a/security/keys/encrypted_defined.h b/security/keys/encrypted_defined.h
new file mode 100644
index 000000000000..cef5e2f2b7d1
--- /dev/null
+++ b/security/keys/encrypted_defined.h
@@ -0,0 +1,54 @@
1#ifndef __ENCRYPTED_KEY_H
2#define __ENCRYPTED_KEY_H
3
4#define ENCRYPTED_DEBUG 0
5
6#if ENCRYPTED_DEBUG
7static inline void dump_master_key(const u8 *master_key, size_t master_keylen)
8{
9 print_hex_dump(KERN_ERR, "master key: ", DUMP_PREFIX_NONE, 32, 1,
10 master_key, master_keylen, 0);
11}
12
13static inline void dump_decrypted_data(struct encrypted_key_payload *epayload)
14{
15 print_hex_dump(KERN_ERR, "decrypted data: ", DUMP_PREFIX_NONE, 32, 1,
16 epayload->decrypted_data,
17 epayload->decrypted_datalen, 0);
18}
19
20static inline void dump_encrypted_data(struct encrypted_key_payload *epayload,
21 unsigned int encrypted_datalen)
22{
23 print_hex_dump(KERN_ERR, "encrypted data: ", DUMP_PREFIX_NONE, 32, 1,
24 epayload->encrypted_data, encrypted_datalen, 0);
25}
26
27static inline void dump_hmac(const char *str, const u8 *digest,
28 unsigned int hmac_size)
29{
30 if (str)
31 pr_info("encrypted_key: %s", str);
32 print_hex_dump(KERN_ERR, "hmac: ", DUMP_PREFIX_NONE, 32, 1, digest,
33 hmac_size, 0);
34}
35#else
36static inline void dump_master_key(const u8 *master_key, size_t master_keylen)
37{
38}
39
40static inline void dump_decrypted_data(struct encrypted_key_payload *epayload)
41{
42}
43
44static inline void dump_encrypted_data(struct encrypted_key_payload *epayload,
45 unsigned int encrypted_datalen)
46{
47}
48
49static inline void dump_hmac(const char *str, const u8 *digest,
50 unsigned int hmac_size)
51{
52}
53#endif
54#endif
diff --git a/security/keys/trusted_defined.c b/security/keys/trusted_defined.c
new file mode 100644
index 000000000000..975e9f29a52c
--- /dev/null
+++ b/security/keys/trusted_defined.c
@@ -0,0 +1,1175 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 *
4 * Author:
5 * David Safford <safford@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 * See Documentation/keys-trusted-encrypted.txt
12 */
13
14#include <linux/uaccess.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/parser.h>
19#include <linux/string.h>
20#include <linux/err.h>
21#include <keys/user-type.h>
22#include <keys/trusted-type.h>
23#include <linux/key-type.h>
24#include <linux/rcupdate.h>
25#include <linux/crypto.h>
26#include <crypto/hash.h>
27#include <crypto/sha.h>
28#include <linux/capability.h>
29#include <linux/tpm.h>
30#include <linux/tpm_command.h>
31
32#include "trusted_defined.h"
33
34static const char hmac_alg[] = "hmac(sha1)";
35static const char hash_alg[] = "sha1";
36
37struct sdesc {
38 struct shash_desc shash;
39 char ctx[];
40};
41
42static struct crypto_shash *hashalg;
43static struct crypto_shash *hmacalg;
44
45static struct sdesc *init_sdesc(struct crypto_shash *alg)
46{
47 struct sdesc *sdesc;
48 int size;
49
50 size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
51 sdesc = kmalloc(size, GFP_KERNEL);
52 if (!sdesc)
53 return ERR_PTR(-ENOMEM);
54 sdesc->shash.tfm = alg;
55 sdesc->shash.flags = 0x0;
56 return sdesc;
57}
58
59static int TSS_sha1(const unsigned char *data, unsigned int datalen,
60 unsigned char *digest)
61{
62 struct sdesc *sdesc;
63 int ret;
64
65 sdesc = init_sdesc(hashalg);
66 if (IS_ERR(sdesc)) {
67 pr_info("trusted_key: can't alloc %s\n", hash_alg);
68 return PTR_ERR(sdesc);
69 }
70
71 ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
72 kfree(sdesc);
73 return ret;
74}
75
76static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
77 unsigned int keylen, ...)
78{
79 struct sdesc *sdesc;
80 va_list argp;
81 unsigned int dlen;
82 unsigned char *data;
83 int ret;
84
85 sdesc = init_sdesc(hmacalg);
86 if (IS_ERR(sdesc)) {
87 pr_info("trusted_key: can't alloc %s\n", hmac_alg);
88 return PTR_ERR(sdesc);
89 }
90
91 ret = crypto_shash_setkey(hmacalg, key, keylen);
92 if (ret < 0)
93 goto out;
94 ret = crypto_shash_init(&sdesc->shash);
95 if (ret < 0)
96 goto out;
97
98 va_start(argp, keylen);
99 for (;;) {
100 dlen = va_arg(argp, unsigned int);
101 if (dlen == 0)
102 break;
103 data = va_arg(argp, unsigned char *);
104 if (data == NULL)
105 return -EINVAL;
106 ret = crypto_shash_update(&sdesc->shash, data, dlen);
107 if (ret < 0)
108 goto out;
109 }
110 va_end(argp);
111 if (!ret)
112 ret = crypto_shash_final(&sdesc->shash, digest);
113out:
114 kfree(sdesc);
115 return ret;
116}
117
118/*
119 * calculate authorization info fields to send to TPM
120 */
121static int TSS_authhmac(unsigned char *digest, const unsigned char *key,
122 unsigned int keylen, unsigned char *h1,
123 unsigned char *h2, unsigned char h3, ...)
124{
125 unsigned char paramdigest[SHA1_DIGEST_SIZE];
126 struct sdesc *sdesc;
127 unsigned int dlen;
128 unsigned char *data;
129 unsigned char c;
130 int ret;
131 va_list argp;
132
133 sdesc = init_sdesc(hashalg);
134 if (IS_ERR(sdesc)) {
135 pr_info("trusted_key: can't alloc %s\n", hash_alg);
136 return PTR_ERR(sdesc);
137 }
138
139 c = h3;
140 ret = crypto_shash_init(&sdesc->shash);
141 if (ret < 0)
142 goto out;
143 va_start(argp, h3);
144 for (;;) {
145 dlen = va_arg(argp, unsigned int);
146 if (dlen == 0)
147 break;
148 data = va_arg(argp, unsigned char *);
149 ret = crypto_shash_update(&sdesc->shash, data, dlen);
150 if (ret < 0) {
151 va_end(argp);
152 goto out;
153 }
154 }
155 va_end(argp);
156 ret = crypto_shash_final(&sdesc->shash, paramdigest);
157 if (!ret)
158 ret = TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE,
159 paramdigest, TPM_NONCE_SIZE, h1,
160 TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
161out:
162 kfree(sdesc);
163 return ret;
164}
165
166/*
167 * verify the AUTH1_COMMAND (Seal) result from TPM
168 */
169static int TSS_checkhmac1(unsigned char *buffer,
170 const uint32_t command,
171 const unsigned char *ononce,
172 const unsigned char *key,
173 unsigned int keylen, ...)
174{
175 uint32_t bufsize;
176 uint16_t tag;
177 uint32_t ordinal;
178 uint32_t result;
179 unsigned char *enonce;
180 unsigned char *continueflag;
181 unsigned char *authdata;
182 unsigned char testhmac[SHA1_DIGEST_SIZE];
183 unsigned char paramdigest[SHA1_DIGEST_SIZE];
184 struct sdesc *sdesc;
185 unsigned int dlen;
186 unsigned int dpos;
187 va_list argp;
188 int ret;
189
190 bufsize = LOAD32(buffer, TPM_SIZE_OFFSET);
191 tag = LOAD16(buffer, 0);
192 ordinal = command;
193 result = LOAD32N(buffer, TPM_RETURN_OFFSET);
194 if (tag == TPM_TAG_RSP_COMMAND)
195 return 0;
196 if (tag != TPM_TAG_RSP_AUTH1_COMMAND)
197 return -EINVAL;
198 authdata = buffer + bufsize - SHA1_DIGEST_SIZE;
199 continueflag = authdata - 1;
200 enonce = continueflag - TPM_NONCE_SIZE;
201
202 sdesc = init_sdesc(hashalg);
203 if (IS_ERR(sdesc)) {
204 pr_info("trusted_key: can't alloc %s\n", hash_alg);
205 return PTR_ERR(sdesc);
206 }
207 ret = crypto_shash_init(&sdesc->shash);
208 if (ret < 0)
209 goto out;
210 ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
211 sizeof result);
212 if (ret < 0)
213 goto out;
214 ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
215 sizeof ordinal);
216 if (ret < 0)
217 goto out;
218 va_start(argp, keylen);
219 for (;;) {
220 dlen = va_arg(argp, unsigned int);
221 if (dlen == 0)
222 break;
223 dpos = va_arg(argp, unsigned int);
224 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
225 if (ret < 0) {
226 va_end(argp);
227 goto out;
228 }
229 }
230 va_end(argp);
231 ret = crypto_shash_final(&sdesc->shash, paramdigest);
232 if (ret < 0)
233 goto out;
234
235 ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest,
236 TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce,
237 1, continueflag, 0, 0);
238 if (ret < 0)
239 goto out;
240
241 if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE))
242 ret = -EINVAL;
243out:
244 kfree(sdesc);
245 return ret;
246}
247
248/*
249 * verify the AUTH2_COMMAND (unseal) result from TPM
250 */
251static int TSS_checkhmac2(unsigned char *buffer,
252 const uint32_t command,
253 const unsigned char *ononce,
254 const unsigned char *key1,
255 unsigned int keylen1,
256 const unsigned char *key2,
257 unsigned int keylen2, ...)
258{
259 uint32_t bufsize;
260 uint16_t tag;
261 uint32_t ordinal;
262 uint32_t result;
263 unsigned char *enonce1;
264 unsigned char *continueflag1;
265 unsigned char *authdata1;
266 unsigned char *enonce2;
267 unsigned char *continueflag2;
268 unsigned char *authdata2;
269 unsigned char testhmac1[SHA1_DIGEST_SIZE];
270 unsigned char testhmac2[SHA1_DIGEST_SIZE];
271 unsigned char paramdigest[SHA1_DIGEST_SIZE];
272 struct sdesc *sdesc;
273 unsigned int dlen;
274 unsigned int dpos;
275 va_list argp;
276 int ret;
277
278 bufsize = LOAD32(buffer, TPM_SIZE_OFFSET);
279 tag = LOAD16(buffer, 0);
280 ordinal = command;
281 result = LOAD32N(buffer, TPM_RETURN_OFFSET);
282
283 if (tag == TPM_TAG_RSP_COMMAND)
284 return 0;
285 if (tag != TPM_TAG_RSP_AUTH2_COMMAND)
286 return -EINVAL;
287 authdata1 = buffer + bufsize - (SHA1_DIGEST_SIZE + 1
288 + SHA1_DIGEST_SIZE + SHA1_DIGEST_SIZE);
289 authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE);
290 continueflag1 = authdata1 - 1;
291 continueflag2 = authdata2 - 1;
292 enonce1 = continueflag1 - TPM_NONCE_SIZE;
293 enonce2 = continueflag2 - TPM_NONCE_SIZE;
294
295 sdesc = init_sdesc(hashalg);
296 if (IS_ERR(sdesc)) {
297 pr_info("trusted_key: can't alloc %s\n", hash_alg);
298 return PTR_ERR(sdesc);
299 }
300 ret = crypto_shash_init(&sdesc->shash);
301 if (ret < 0)
302 goto out;
303 ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
304 sizeof result);
305 if (ret < 0)
306 goto out;
307 ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
308 sizeof ordinal);
309 if (ret < 0)
310 goto out;
311
312 va_start(argp, keylen2);
313 for (;;) {
314 dlen = va_arg(argp, unsigned int);
315 if (dlen == 0)
316 break;
317 dpos = va_arg(argp, unsigned int);
318 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
319 if (ret < 0) {
320 va_end(argp);
321 goto out;
322 }
323 }
324 va_end(argp);
325 ret = crypto_shash_final(&sdesc->shash, paramdigest);
326 if (ret < 0)
327 goto out;
328
329 ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE,
330 paramdigest, TPM_NONCE_SIZE, enonce1,
331 TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0);
332 if (ret < 0)
333 goto out;
334 if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) {
335 ret = -EINVAL;
336 goto out;
337 }
338 ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE,
339 paramdigest, TPM_NONCE_SIZE, enonce2,
340 TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0);
341 if (ret < 0)
342 goto out;
343 if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE))
344 ret = -EINVAL;
345out:
346 kfree(sdesc);
347 return ret;
348}
349
350/*
351 * For key specific tpm requests, we will generate and send our
352 * own TPM command packets using the drivers send function.
353 */
354static int trusted_tpm_send(const u32 chip_num, unsigned char *cmd,
355 size_t buflen)
356{
357 int rc;
358
359 dump_tpm_buf(cmd);
360 rc = tpm_send(chip_num, cmd, buflen);
361 dump_tpm_buf(cmd);
362 if (rc > 0)
363 /* Can't return positive return codes values to keyctl */
364 rc = -EPERM;
365 return rc;
366}
367
368/*
369 * get a random value from TPM
370 */
371static int tpm_get_random(struct tpm_buf *tb, unsigned char *buf, uint32_t len)
372{
373 int ret;
374
375 INIT_BUF(tb);
376 store16(tb, TPM_TAG_RQU_COMMAND);
377 store32(tb, TPM_GETRANDOM_SIZE);
378 store32(tb, TPM_ORD_GETRANDOM);
379 store32(tb, len);
380 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, sizeof tb->data);
381 if (!ret)
382 memcpy(buf, tb->data + TPM_GETRANDOM_SIZE, len);
383 return ret;
384}
385
386static int my_get_random(unsigned char *buf, int len)
387{
388 struct tpm_buf *tb;
389 int ret;
390
391 tb = kmalloc(sizeof *tb, GFP_KERNEL);
392 if (!tb)
393 return -ENOMEM;
394 ret = tpm_get_random(tb, buf, len);
395
396 kfree(tb);
397 return ret;
398}
399
400/*
401 * Lock a trusted key, by extending a selected PCR.
402 *
403 * Prevents a trusted key that is sealed to PCRs from being accessed.
404 * This uses the tpm driver's extend function.
405 */
406static int pcrlock(const int pcrnum)
407{
408 unsigned char hash[SHA1_DIGEST_SIZE];
409 int ret;
410
411 if (!capable(CAP_SYS_ADMIN))
412 return -EPERM;
413 ret = my_get_random(hash, SHA1_DIGEST_SIZE);
414 if (ret < 0)
415 return ret;
416 return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0;
417}
418
419/*
420 * Create an object specific authorisation protocol (OSAP) session
421 */
422static int osap(struct tpm_buf *tb, struct osapsess *s,
423 const unsigned char *key, uint16_t type, uint32_t handle)
424{
425 unsigned char enonce[TPM_NONCE_SIZE];
426 unsigned char ononce[TPM_NONCE_SIZE];
427 int ret;
428
429 ret = tpm_get_random(tb, ononce, TPM_NONCE_SIZE);
430 if (ret < 0)
431 return ret;
432
433 INIT_BUF(tb);
434 store16(tb, TPM_TAG_RQU_COMMAND);
435 store32(tb, TPM_OSAP_SIZE);
436 store32(tb, TPM_ORD_OSAP);
437 store16(tb, type);
438 store32(tb, handle);
439 storebytes(tb, ononce, TPM_NONCE_SIZE);
440
441 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
442 if (ret < 0)
443 return ret;
444
445 s->handle = LOAD32(tb->data, TPM_DATA_OFFSET);
446 memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
447 TPM_NONCE_SIZE);
448 memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
449 TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
450 return TSS_rawhmac(s->secret, key, SHA1_DIGEST_SIZE, TPM_NONCE_SIZE,
451 enonce, TPM_NONCE_SIZE, ononce, 0, 0);
452}
453
454/*
455 * Create an object independent authorisation protocol (oiap) session
456 */
457static int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
458{
459 int ret;
460
461 INIT_BUF(tb);
462 store16(tb, TPM_TAG_RQU_COMMAND);
463 store32(tb, TPM_OIAP_SIZE);
464 store32(tb, TPM_ORD_OIAP);
465 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
466 if (ret < 0)
467 return ret;
468
469 *handle = LOAD32(tb->data, TPM_DATA_OFFSET);
470 memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
471 TPM_NONCE_SIZE);
472 return 0;
473}
474
475struct tpm_digests {
476 unsigned char encauth[SHA1_DIGEST_SIZE];
477 unsigned char pubauth[SHA1_DIGEST_SIZE];
478 unsigned char xorwork[SHA1_DIGEST_SIZE * 2];
479 unsigned char xorhash[SHA1_DIGEST_SIZE];
480 unsigned char nonceodd[TPM_NONCE_SIZE];
481};
482
483/*
484 * Have the TPM seal(encrypt) the trusted key, possibly based on
485 * Platform Configuration Registers (PCRs). AUTH1 for sealing key.
486 */
487static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
488 uint32_t keyhandle, const unsigned char *keyauth,
489 const unsigned char *data, uint32_t datalen,
490 unsigned char *blob, uint32_t *bloblen,
491 const unsigned char *blobauth,
492 const unsigned char *pcrinfo, uint32_t pcrinfosize)
493{
494 struct osapsess sess;
495 struct tpm_digests *td;
496 unsigned char cont;
497 uint32_t ordinal;
498 uint32_t pcrsize;
499 uint32_t datsize;
500 int sealinfosize;
501 int encdatasize;
502 int storedsize;
503 int ret;
504 int i;
505
506 /* alloc some work space for all the hashes */
507 td = kmalloc(sizeof *td, GFP_KERNEL);
508 if (!td)
509 return -ENOMEM;
510
511 /* get session for sealing key */
512 ret = osap(tb, &sess, keyauth, keytype, keyhandle);
513 if (ret < 0)
514 return ret;
515 dump_sess(&sess);
516
517 /* calculate encrypted authorization value */
518 memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
519 memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
520 ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
521 if (ret < 0)
522 return ret;
523
524 ret = tpm_get_random(tb, td->nonceodd, TPM_NONCE_SIZE);
525 if (ret < 0)
526 return ret;
527 ordinal = htonl(TPM_ORD_SEAL);
528 datsize = htonl(datalen);
529 pcrsize = htonl(pcrinfosize);
530 cont = 0;
531
532 /* encrypt data authorization key */
533 for (i = 0; i < SHA1_DIGEST_SIZE; ++i)
534 td->encauth[i] = td->xorhash[i] ^ blobauth[i];
535
536 /* calculate authorization HMAC value */
537 if (pcrinfosize == 0) {
538 /* no pcr info specified */
539 ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
540 sess.enonce, td->nonceodd, cont,
541 sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE,
542 td->encauth, sizeof(uint32_t), &pcrsize,
543 sizeof(uint32_t), &datsize, datalen, data, 0,
544 0);
545 } else {
546 /* pcr info specified */
547 ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
548 sess.enonce, td->nonceodd, cont,
549 sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE,
550 td->encauth, sizeof(uint32_t), &pcrsize,
551 pcrinfosize, pcrinfo, sizeof(uint32_t),
552 &datsize, datalen, data, 0, 0);
553 }
554 if (ret < 0)
555 return ret;
556
557 /* build and send the TPM request packet */
558 INIT_BUF(tb);
559 store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
560 store32(tb, TPM_SEAL_SIZE + pcrinfosize + datalen);
561 store32(tb, TPM_ORD_SEAL);
562 store32(tb, keyhandle);
563 storebytes(tb, td->encauth, SHA1_DIGEST_SIZE);
564 store32(tb, pcrinfosize);
565 storebytes(tb, pcrinfo, pcrinfosize);
566 store32(tb, datalen);
567 storebytes(tb, data, datalen);
568 store32(tb, sess.handle);
569 storebytes(tb, td->nonceodd, TPM_NONCE_SIZE);
570 store8(tb, cont);
571 storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE);
572
573 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
574 if (ret < 0)
575 return ret;
576
577 /* calculate the size of the returned Blob */
578 sealinfosize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t));
579 encdatasize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t) +
580 sizeof(uint32_t) + sealinfosize);
581 storedsize = sizeof(uint32_t) + sizeof(uint32_t) + sealinfosize +
582 sizeof(uint32_t) + encdatasize;
583
584 /* check the HMAC in the response */
585 ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd, sess.secret,
586 SHA1_DIGEST_SIZE, storedsize, TPM_DATA_OFFSET, 0,
587 0);
588
589 /* copy the returned blob to caller */
590 if (!ret) {
591 memcpy(blob, tb->data + TPM_DATA_OFFSET, storedsize);
592 *bloblen = storedsize;
593 }
594 return ret;
595}
596
597/*
598 * use the AUTH2_COMMAND form of unseal, to authorize both key and blob
599 */
600static int tpm_unseal(struct tpm_buf *tb,
601 uint32_t keyhandle, const unsigned char *keyauth,
602 const unsigned char *blob, int bloblen,
603 const unsigned char *blobauth,
604 unsigned char *data, unsigned int *datalen)
605{
606 unsigned char nonceodd[TPM_NONCE_SIZE];
607 unsigned char enonce1[TPM_NONCE_SIZE];
608 unsigned char enonce2[TPM_NONCE_SIZE];
609 unsigned char authdata1[SHA1_DIGEST_SIZE];
610 unsigned char authdata2[SHA1_DIGEST_SIZE];
611 uint32_t authhandle1 = 0;
612 uint32_t authhandle2 = 0;
613 unsigned char cont = 0;
614 uint32_t ordinal;
615 uint32_t keyhndl;
616 int ret;
617
618 /* sessions for unsealing key and data */
619 ret = oiap(tb, &authhandle1, enonce1);
620 if (ret < 0) {
621 pr_info("trusted_key: oiap failed (%d)\n", ret);
622 return ret;
623 }
624 ret = oiap(tb, &authhandle2, enonce2);
625 if (ret < 0) {
626 pr_info("trusted_key: oiap failed (%d)\n", ret);
627 return ret;
628 }
629
630 ordinal = htonl(TPM_ORD_UNSEAL);
631 keyhndl = htonl(SRKHANDLE);
632 ret = tpm_get_random(tb, nonceodd, TPM_NONCE_SIZE);
633 if (ret < 0) {
634 pr_info("trusted_key: tpm_get_random failed (%d)\n", ret);
635 return ret;
636 }
637 ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
638 enonce1, nonceodd, cont, sizeof(uint32_t),
639 &ordinal, bloblen, blob, 0, 0);
640 if (ret < 0)
641 return ret;
642 ret = TSS_authhmac(authdata2, blobauth, TPM_NONCE_SIZE,
643 enonce2, nonceodd, cont, sizeof(uint32_t),
644 &ordinal, bloblen, blob, 0, 0);
645 if (ret < 0)
646 return ret;
647
648 /* build and send TPM request packet */
649 INIT_BUF(tb);
650 store16(tb, TPM_TAG_RQU_AUTH2_COMMAND);
651 store32(tb, TPM_UNSEAL_SIZE + bloblen);
652 store32(tb, TPM_ORD_UNSEAL);
653 store32(tb, keyhandle);
654 storebytes(tb, blob, bloblen);
655 store32(tb, authhandle1);
656 storebytes(tb, nonceodd, TPM_NONCE_SIZE);
657 store8(tb, cont);
658 storebytes(tb, authdata1, SHA1_DIGEST_SIZE);
659 store32(tb, authhandle2);
660 storebytes(tb, nonceodd, TPM_NONCE_SIZE);
661 store8(tb, cont);
662 storebytes(tb, authdata2, SHA1_DIGEST_SIZE);
663
664 ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE);
665 if (ret < 0) {
666 pr_info("trusted_key: authhmac failed (%d)\n", ret);
667 return ret;
668 }
669
670 *datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
671 ret = TSS_checkhmac2(tb->data, ordinal, nonceodd,
672 keyauth, SHA1_DIGEST_SIZE,
673 blobauth, SHA1_DIGEST_SIZE,
674 sizeof(uint32_t), TPM_DATA_OFFSET,
675 *datalen, TPM_DATA_OFFSET + sizeof(uint32_t), 0,
676 0);
677 if (ret < 0) {
678 pr_info("trusted_key: TSS_checkhmac2 failed (%d)\n", ret);
679 return ret;
680 }
681 memcpy(data, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *datalen);
682 return 0;
683}
684
685/*
686 * Have the TPM seal(encrypt) the symmetric key
687 */
688static int key_seal(struct trusted_key_payload *p,
689 struct trusted_key_options *o)
690{
691 struct tpm_buf *tb;
692 int ret;
693
694 tb = kzalloc(sizeof *tb, GFP_KERNEL);
695 if (!tb)
696 return -ENOMEM;
697
698 /* include migratable flag at end of sealed key */
699 p->key[p->key_len] = p->migratable;
700
701 ret = tpm_seal(tb, o->keytype, o->keyhandle, o->keyauth,
702 p->key, p->key_len + 1, p->blob, &p->blob_len,
703 o->blobauth, o->pcrinfo, o->pcrinfo_len);
704 if (ret < 0)
705 pr_info("trusted_key: srkseal failed (%d)\n", ret);
706
707 kfree(tb);
708 return ret;
709}
710
711/*
712 * Have the TPM unseal(decrypt) the symmetric key
713 */
714static int key_unseal(struct trusted_key_payload *p,
715 struct trusted_key_options *o)
716{
717 struct tpm_buf *tb;
718 int ret;
719
720 tb = kzalloc(sizeof *tb, GFP_KERNEL);
721 if (!tb)
722 return -ENOMEM;
723
724 ret = tpm_unseal(tb, o->keyhandle, o->keyauth, p->blob, p->blob_len,
725 o->blobauth, p->key, &p->key_len);
726 if (ret < 0)
727 pr_info("trusted_key: srkunseal failed (%d)\n", ret);
728 else
729 /* pull migratable flag out of sealed key */
730 p->migratable = p->key[--p->key_len];
731
732 kfree(tb);
733 return ret;
734}
735
736enum {
737 Opt_err = -1,
738 Opt_new, Opt_load, Opt_update,
739 Opt_keyhandle, Opt_keyauth, Opt_blobauth,
740 Opt_pcrinfo, Opt_pcrlock, Opt_migratable
741};
742
743static const match_table_t key_tokens = {
744 {Opt_new, "new"},
745 {Opt_load, "load"},
746 {Opt_update, "update"},
747 {Opt_keyhandle, "keyhandle=%s"},
748 {Opt_keyauth, "keyauth=%s"},
749 {Opt_blobauth, "blobauth=%s"},
750 {Opt_pcrinfo, "pcrinfo=%s"},
751 {Opt_pcrlock, "pcrlock=%s"},
752 {Opt_migratable, "migratable=%s"},
753 {Opt_err, NULL}
754};
755
756/* can have zero or more token= options */
757static int getoptions(char *c, struct trusted_key_payload *pay,
758 struct trusted_key_options *opt)
759{
760 substring_t args[MAX_OPT_ARGS];
761 char *p = c;
762 int token;
763 int res;
764 unsigned long handle;
765 unsigned long lock;
766
767 while ((p = strsep(&c, " \t"))) {
768 if (*p == '\0' || *p == ' ' || *p == '\t')
769 continue;
770 token = match_token(p, key_tokens, args);
771
772 switch (token) {
773 case Opt_pcrinfo:
774 opt->pcrinfo_len = strlen(args[0].from) / 2;
775 if (opt->pcrinfo_len > MAX_PCRINFO_SIZE)
776 return -EINVAL;
777 hex2bin(opt->pcrinfo, args[0].from, opt->pcrinfo_len);
778 break;
779 case Opt_keyhandle:
780 res = strict_strtoul(args[0].from, 16, &handle);
781 if (res < 0)
782 return -EINVAL;
783 opt->keytype = SEAL_keytype;
784 opt->keyhandle = handle;
785 break;
786 case Opt_keyauth:
787 if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE)
788 return -EINVAL;
789 hex2bin(opt->keyauth, args[0].from, SHA1_DIGEST_SIZE);
790 break;
791 case Opt_blobauth:
792 if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE)
793 return -EINVAL;
794 hex2bin(opt->blobauth, args[0].from, SHA1_DIGEST_SIZE);
795 break;
796 case Opt_migratable:
797 if (*args[0].from == '0')
798 pay->migratable = 0;
799 else
800 return -EINVAL;
801 break;
802 case Opt_pcrlock:
803 res = strict_strtoul(args[0].from, 10, &lock);
804 if (res < 0)
805 return -EINVAL;
806 opt->pcrlock = lock;
807 break;
808 default:
809 return -EINVAL;
810 }
811 }
812 return 0;
813}
814
815/*
816 * datablob_parse - parse the keyctl data and fill in the
817 * payload and options structures
818 *
819 * On success returns 0, otherwise -EINVAL.
820 */
821static int datablob_parse(char *datablob, struct trusted_key_payload *p,
822 struct trusted_key_options *o)
823{
824 substring_t args[MAX_OPT_ARGS];
825 long keylen;
826 int ret = -EINVAL;
827 int key_cmd;
828 char *c;
829
830 /* main command */
831 c = strsep(&datablob, " \t");
832 if (!c)
833 return -EINVAL;
834 key_cmd = match_token(c, key_tokens, args);
835 switch (key_cmd) {
836 case Opt_new:
837 /* first argument is key size */
838 c = strsep(&datablob, " \t");
839 if (!c)
840 return -EINVAL;
841 ret = strict_strtol(c, 10, &keylen);
842 if (ret < 0 || keylen < MIN_KEY_SIZE || keylen > MAX_KEY_SIZE)
843 return -EINVAL;
844 p->key_len = keylen;
845 ret = getoptions(datablob, p, o);
846 if (ret < 0)
847 return ret;
848 ret = Opt_new;
849 break;
850 case Opt_load:
851 /* first argument is sealed blob */
852 c = strsep(&datablob, " \t");
853 if (!c)
854 return -EINVAL;
855 p->blob_len = strlen(c) / 2;
856 if (p->blob_len > MAX_BLOB_SIZE)
857 return -EINVAL;
858 hex2bin(p->blob, c, p->blob_len);
859 ret = getoptions(datablob, p, o);
860 if (ret < 0)
861 return ret;
862 ret = Opt_load;
863 break;
864 case Opt_update:
865 /* all arguments are options */
866 ret = getoptions(datablob, p, o);
867 if (ret < 0)
868 return ret;
869 ret = Opt_update;
870 break;
871 case Opt_err:
872 return -EINVAL;
873 break;
874 }
875 return ret;
876}
877
878static struct trusted_key_options *trusted_options_alloc(void)
879{
880 struct trusted_key_options *options;
881
882 options = kzalloc(sizeof *options, GFP_KERNEL);
883 if (options) {
884 /* set any non-zero defaults */
885 options->keytype = SRK_keytype;
886 options->keyhandle = SRKHANDLE;
887 }
888 return options;
889}
890
891static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
892{
893 struct trusted_key_payload *p = NULL;
894 int ret;
895
896 ret = key_payload_reserve(key, sizeof *p);
897 if (ret < 0)
898 return p;
899 p = kzalloc(sizeof *p, GFP_KERNEL);
900 if (p)
901 p->migratable = 1; /* migratable by default */
902 return p;
903}
904
905/*
906 * trusted_instantiate - create a new trusted key
907 *
908 * Unseal an existing trusted blob or, for a new key, get a
909 * random key, then seal and create a trusted key-type key,
910 * adding it to the specified keyring.
911 *
912 * On success, return 0. Otherwise return errno.
913 */
914static int trusted_instantiate(struct key *key, const void *data,
915 size_t datalen)
916{
917 struct trusted_key_payload *payload = NULL;
918 struct trusted_key_options *options = NULL;
919 char *datablob;
920 int ret = 0;
921 int key_cmd;
922
923 if (datalen <= 0 || datalen > 32767 || !data)
924 return -EINVAL;
925
926 datablob = kmalloc(datalen + 1, GFP_KERNEL);
927 if (!datablob)
928 return -ENOMEM;
929 memcpy(datablob, data, datalen);
930 datablob[datalen] = '\0';
931
932 options = trusted_options_alloc();
933 if (!options) {
934 ret = -ENOMEM;
935 goto out;
936 }
937 payload = trusted_payload_alloc(key);
938 if (!payload) {
939 ret = -ENOMEM;
940 goto out;
941 }
942
943 key_cmd = datablob_parse(datablob, payload, options);
944 if (key_cmd < 0) {
945 ret = key_cmd;
946 goto out;
947 }
948
949 dump_payload(payload);
950 dump_options(options);
951
952 switch (key_cmd) {
953 case Opt_load:
954 ret = key_unseal(payload, options);
955 dump_payload(payload);
956 dump_options(options);
957 if (ret < 0)
958 pr_info("trusted_key: key_unseal failed (%d)\n", ret);
959 break;
960 case Opt_new:
961 ret = my_get_random(payload->key, payload->key_len);
962 if (ret < 0) {
963 pr_info("trusted_key: key_create failed (%d)\n", ret);
964 goto out;
965 }
966 ret = key_seal(payload, options);
967 if (ret < 0)
968 pr_info("trusted_key: key_seal failed (%d)\n", ret);
969 break;
970 default:
971 ret = -EINVAL;
972 goto out;
973 }
974 if (!ret && options->pcrlock)
975 ret = pcrlock(options->pcrlock);
976out:
977 kfree(datablob);
978 kfree(options);
979 if (!ret)
980 rcu_assign_pointer(key->payload.data, payload);
981 else
982 kfree(payload);
983 return ret;
984}
985
986static void trusted_rcu_free(struct rcu_head *rcu)
987{
988 struct trusted_key_payload *p;
989
990 p = container_of(rcu, struct trusted_key_payload, rcu);
991 memset(p->key, 0, p->key_len);
992 kfree(p);
993}
994
995/*
996 * trusted_update - reseal an existing key with new PCR values
997 */
998static int trusted_update(struct key *key, const void *data, size_t datalen)
999{
1000 struct trusted_key_payload *p = key->payload.data;
1001 struct trusted_key_payload *new_p;
1002 struct trusted_key_options *new_o;
1003 char *datablob;
1004 int ret = 0;
1005
1006 if (!p->migratable)
1007 return -EPERM;
1008 if (datalen <= 0 || datalen > 32767 || !data)
1009 return -EINVAL;
1010
1011 datablob = kmalloc(datalen + 1, GFP_KERNEL);
1012 if (!datablob)
1013 return -ENOMEM;
1014 new_o = trusted_options_alloc();
1015 if (!new_o) {
1016 ret = -ENOMEM;
1017 goto out;
1018 }
1019 new_p = trusted_payload_alloc(key);
1020 if (!new_p) {
1021 ret = -ENOMEM;
1022 goto out;
1023 }
1024
1025 memcpy(datablob, data, datalen);
1026 datablob[datalen] = '\0';
1027 ret = datablob_parse(datablob, new_p, new_o);
1028 if (ret != Opt_update) {
1029 ret = -EINVAL;
1030 goto out;
1031 }
1032 /* copy old key values, and reseal with new pcrs */
1033 new_p->migratable = p->migratable;
1034 new_p->key_len = p->key_len;
1035 memcpy(new_p->key, p->key, p->key_len);
1036 dump_payload(p);
1037 dump_payload(new_p);
1038
1039 ret = key_seal(new_p, new_o);
1040 if (ret < 0) {
1041 pr_info("trusted_key: key_seal failed (%d)\n", ret);
1042 kfree(new_p);
1043 goto out;
1044 }
1045 if (new_o->pcrlock) {
1046 ret = pcrlock(new_o->pcrlock);
1047 if (ret < 0) {
1048 pr_info("trusted_key: pcrlock failed (%d)\n", ret);
1049 kfree(new_p);
1050 goto out;
1051 }
1052 }
1053 rcu_assign_pointer(key->payload.data, new_p);
1054 call_rcu(&p->rcu, trusted_rcu_free);
1055out:
1056 kfree(datablob);
1057 kfree(new_o);
1058 return ret;
1059}
1060
1061/*
1062 * trusted_read - copy the sealed blob data to userspace in hex.
1063 * On success, return to userspace the trusted key datablob size.
1064 */
1065static long trusted_read(const struct key *key, char __user *buffer,
1066 size_t buflen)
1067{
1068 struct trusted_key_payload *p;
1069 char *ascii_buf;
1070 char *bufp;
1071 int i;
1072
1073 p = rcu_dereference_protected(key->payload.data,
1074 rwsem_is_locked(&((struct key *)key)->sem));
1075 if (!p)
1076 return -EINVAL;
1077 if (!buffer || buflen <= 0)
1078 return 2 * p->blob_len;
1079 ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
1080 if (!ascii_buf)
1081 return -ENOMEM;
1082
1083 bufp = ascii_buf;
1084 for (i = 0; i < p->blob_len; i++)
1085 bufp = pack_hex_byte(bufp, p->blob[i]);
1086 if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) {
1087 kfree(ascii_buf);
1088 return -EFAULT;
1089 }
1090 kfree(ascii_buf);
1091 return 2 * p->blob_len;
1092}
1093
1094/*
1095 * trusted_destroy - before freeing the key, clear the decrypted data
1096 */
1097static void trusted_destroy(struct key *key)
1098{
1099 struct trusted_key_payload *p = key->payload.data;
1100
1101 if (!p)
1102 return;
1103 memset(p->key, 0, p->key_len);
1104 kfree(key->payload.data);
1105}
1106
1107struct key_type key_type_trusted = {
1108 .name = "trusted",
1109 .instantiate = trusted_instantiate,
1110 .update = trusted_update,
1111 .match = user_match,
1112 .destroy = trusted_destroy,
1113 .describe = user_describe,
1114 .read = trusted_read,
1115};
1116
1117EXPORT_SYMBOL_GPL(key_type_trusted);
1118
1119static void trusted_shash_release(void)
1120{
1121 if (hashalg)
1122 crypto_free_shash(hashalg);
1123 if (hmacalg)
1124 crypto_free_shash(hmacalg);
1125}
1126
1127static int __init trusted_shash_alloc(void)
1128{
1129 int ret;
1130
1131 hmacalg = crypto_alloc_shash(hmac_alg, 0, CRYPTO_ALG_ASYNC);
1132 if (IS_ERR(hmacalg)) {
1133 pr_info("trusted_key: could not allocate crypto %s\n",
1134 hmac_alg);
1135 return PTR_ERR(hmacalg);
1136 }
1137
1138 hashalg = crypto_alloc_shash(hash_alg, 0, CRYPTO_ALG_ASYNC);
1139 if (IS_ERR(hashalg)) {
1140 pr_info("trusted_key: could not allocate crypto %s\n",
1141 hash_alg);
1142 ret = PTR_ERR(hashalg);
1143 goto hashalg_fail;
1144 }
1145
1146 return 0;
1147
1148hashalg_fail:
1149 crypto_free_shash(hmacalg);
1150 return ret;
1151}
1152
1153static int __init init_trusted(void)
1154{
1155 int ret;
1156
1157 ret = trusted_shash_alloc();
1158 if (ret < 0)
1159 return ret;
1160 ret = register_key_type(&key_type_trusted);
1161 if (ret < 0)
1162 trusted_shash_release();
1163 return ret;
1164}
1165
1166static void __exit cleanup_trusted(void)
1167{
1168 trusted_shash_release();
1169 unregister_key_type(&key_type_trusted);
1170}
1171
1172late_initcall(init_trusted);
1173module_exit(cleanup_trusted);
1174
1175MODULE_LICENSE("GPL");
diff --git a/security/keys/trusted_defined.h b/security/keys/trusted_defined.h
new file mode 100644
index 000000000000..3249fbd2b653
--- /dev/null
+++ b/security/keys/trusted_defined.h
@@ -0,0 +1,134 @@
1#ifndef __TRUSTED_KEY_H
2#define __TRUSTED_KEY_H
3
4/* implementation specific TPM constants */
5#define MAX_PCRINFO_SIZE 64
6#define MAX_BUF_SIZE 512
7#define TPM_GETRANDOM_SIZE 14
8#define TPM_OSAP_SIZE 36
9#define TPM_OIAP_SIZE 10
10#define TPM_SEAL_SIZE 87
11#define TPM_UNSEAL_SIZE 104
12#define TPM_SIZE_OFFSET 2
13#define TPM_RETURN_OFFSET 6
14#define TPM_DATA_OFFSET 10
15
16#define LOAD32(buffer, offset) (ntohl(*(uint32_t *)&buffer[offset]))
17#define LOAD32N(buffer, offset) (*(uint32_t *)&buffer[offset])
18#define LOAD16(buffer, offset) (ntohs(*(uint16_t *)&buffer[offset]))
19
20struct tpm_buf {
21 int len;
22 unsigned char data[MAX_BUF_SIZE];
23};
24
25#define INIT_BUF(tb) (tb->len = 0)
26
27struct osapsess {
28 uint32_t handle;
29 unsigned char secret[SHA1_DIGEST_SIZE];
30 unsigned char enonce[TPM_NONCE_SIZE];
31};
32
33/* discrete values, but have to store in uint16_t for TPM use */
34enum {
35 SEAL_keytype = 1,
36 SRK_keytype = 4
37};
38
39struct trusted_key_options {
40 uint16_t keytype;
41 uint32_t keyhandle;
42 unsigned char keyauth[SHA1_DIGEST_SIZE];
43 unsigned char blobauth[SHA1_DIGEST_SIZE];
44 uint32_t pcrinfo_len;
45 unsigned char pcrinfo[MAX_PCRINFO_SIZE];
46 int pcrlock;
47};
48
49#define TPM_DEBUG 0
50
51#if TPM_DEBUG
52static inline void dump_options(struct trusted_key_options *o)
53{
54 pr_info("trusted_key: sealing key type %d\n", o->keytype);
55 pr_info("trusted_key: sealing key handle %0X\n", o->keyhandle);
56 pr_info("trusted_key: pcrlock %d\n", o->pcrlock);
57 pr_info("trusted_key: pcrinfo %d\n", o->pcrinfo_len);
58 print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE,
59 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
60}
61
62static inline void dump_payload(struct trusted_key_payload *p)
63{
64 pr_info("trusted_key: key_len %d\n", p->key_len);
65 print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
66 16, 1, p->key, p->key_len, 0);
67 pr_info("trusted_key: bloblen %d\n", p->blob_len);
68 print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
69 16, 1, p->blob, p->blob_len, 0);
70 pr_info("trusted_key: migratable %d\n", p->migratable);
71}
72
73static inline void dump_sess(struct osapsess *s)
74{
75 print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE,
76 16, 1, &s->handle, 4, 0);
77 pr_info("trusted-key: secret:\n");
78 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
79 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
80 pr_info("trusted-key: enonce:\n");
81 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
82 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
83}
84
85static inline void dump_tpm_buf(unsigned char *buf)
86{
87 int len;
88
89 pr_info("\ntrusted-key: tpm buffer\n");
90 len = LOAD32(buf, TPM_SIZE_OFFSET);
91 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
92}
93#else
94static inline void dump_options(struct trusted_key_options *o)
95{
96}
97
98static inline void dump_payload(struct trusted_key_payload *p)
99{
100}
101
102static inline void dump_sess(struct osapsess *s)
103{
104}
105
106static inline void dump_tpm_buf(unsigned char *buf)
107{
108}
109#endif
110
111static inline void store8(struct tpm_buf *buf, const unsigned char value)
112{
113 buf->data[buf->len++] = value;
114}
115
116static inline void store16(struct tpm_buf *buf, const uint16_t value)
117{
118 *(uint16_t *) & buf->data[buf->len] = htons(value);
119 buf->len += sizeof value;
120}
121
122static inline void store32(struct tpm_buf *buf, const uint32_t value)
123{
124 *(uint32_t *) & buf->data[buf->len] = htonl(value);
125 buf->len += sizeof value;
126}
127
128static inline void storebytes(struct tpm_buf *buf, const unsigned char *in,
129 const int len)
130{
131 memcpy(buf->data + buf->len, in, len);
132 buf->len += len;
133}
134#endif
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6f637d2678ac..e276eb468536 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2525,7 +2525,10 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2525 sid = tsec->sid; 2525 sid = tsec->sid;
2526 newsid = tsec->create_sid; 2526 newsid = tsec->create_sid;
2527 2527
2528 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 2528 if ((sbsec->flags & SE_SBINITIALIZED) &&
2529 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT))
2530 newsid = sbsec->mntpoint_sid;
2531 else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
2529 rc = security_transition_sid(sid, dsec->sid, 2532 rc = security_transition_sid(sid, dsec->sid,
2530 inode_mode_to_security_class(inode->i_mode), 2533 inode_mode_to_security_class(inode->i_mode),
2531 &newsid); 2534 &newsid);
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 8858d2b2d4b6..7ed3663332ec 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -142,7 +142,7 @@ struct security_class_mapping secclass_map[] = {
142 "node_bind", "name_connect", NULL } }, 142 "node_bind", "name_connect", NULL } },
143 { "memprotect", { "mmap_zero", NULL } }, 143 { "memprotect", { "mmap_zero", NULL } },
144 { "peer", { "recv", NULL } }, 144 { "peer", { "recv", NULL } },
145 { "capability2", { "mac_override", "mac_admin", NULL } }, 145 { "capability2", { "mac_override", "mac_admin", "syslog", NULL } },
146 { "kernel_service", { "use_as_override", "create_files_as", NULL } }, 146 { "kernel_service", { "use_as_override", "create_files_as", NULL } },
147 { "tun_socket", 147 { "tun_socket",
148 { COMMON_SOCK_PERMS, NULL } }, 148 { COMMON_SOCK_PERMS, NULL } },
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 75ec0c6ebacd..8b02b2137da2 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -65,6 +65,8 @@ static struct nlmsg_perm nlmsg_route_perms[] =
65 { RTM_NEWADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, 65 { RTM_NEWADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
66 { RTM_DELADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, 66 { RTM_DELADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
67 { RTM_GETADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_READ }, 67 { RTM_GETADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_READ },
68 { RTM_GETDCB, NETLINK_ROUTE_SOCKET__NLMSG_READ },
69 { RTM_SETDCB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
68}; 70};
69 71
70static struct nlmsg_perm nlmsg_firewall_perms[] = 72static struct nlmsg_perm nlmsg_firewall_perms[] =
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 43deac219491..ea39cb742ae5 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -141,19 +141,24 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
141 size_t count, loff_t *ppos) 141 size_t count, loff_t *ppos)
142 142
143{ 143{
144 char *page; 144 char *page = NULL;
145 ssize_t length; 145 ssize_t length;
146 int new_value; 146 int new_value;
147 147
148 length = -ENOMEM;
148 if (count >= PAGE_SIZE) 149 if (count >= PAGE_SIZE)
149 return -ENOMEM; 150 goto out;
150 if (*ppos != 0) { 151
151 /* No partial writes. */ 152 /* No partial writes. */
152 return -EINVAL; 153 length = EINVAL;
153 } 154 if (*ppos != 0)
155 goto out;
156
157 length = -ENOMEM;
154 page = (char *)get_zeroed_page(GFP_KERNEL); 158 page = (char *)get_zeroed_page(GFP_KERNEL);
155 if (!page) 159 if (!page)
156 return -ENOMEM; 160 goto out;
161
157 length = -EFAULT; 162 length = -EFAULT;
158 if (copy_from_user(page, buf, count)) 163 if (copy_from_user(page, buf, count))
159 goto out; 164 goto out;
@@ -268,20 +273,25 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
268 size_t count, loff_t *ppos) 273 size_t count, loff_t *ppos)
269 274
270{ 275{
271 char *page; 276 char *page = NULL;
272 ssize_t length; 277 ssize_t length;
273 int new_value; 278 int new_value;
274 extern int selinux_disable(void); 279 extern int selinux_disable(void);
275 280
281 length = -ENOMEM;
276 if (count >= PAGE_SIZE) 282 if (count >= PAGE_SIZE)
277 return -ENOMEM; 283 goto out;;
278 if (*ppos != 0) { 284
279 /* No partial writes. */ 285 /* No partial writes. */
280 return -EINVAL; 286 length = -EINVAL;
281 } 287 if (*ppos != 0)
288 goto out;
289
290 length = -ENOMEM;
282 page = (char *)get_zeroed_page(GFP_KERNEL); 291 page = (char *)get_zeroed_page(GFP_KERNEL);
283 if (!page) 292 if (!page)
284 return -ENOMEM; 293 goto out;
294
285 length = -EFAULT; 295 length = -EFAULT;
286 if (copy_from_user(page, buf, count)) 296 if (copy_from_user(page, buf, count))
287 goto out; 297 goto out;
@@ -292,7 +302,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
292 302
293 if (new_value) { 303 if (new_value) {
294 length = selinux_disable(); 304 length = selinux_disable();
295 if (length < 0) 305 if (length)
296 goto out; 306 goto out;
297 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 307 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
298 "selinux=0 auid=%u ses=%u", 308 "selinux=0 auid=%u ses=%u",
@@ -493,7 +503,6 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
493 size_t count, loff_t *ppos) 503 size_t count, loff_t *ppos)
494 504
495{ 505{
496 int ret;
497 ssize_t length; 506 ssize_t length;
498 void *data = NULL; 507 void *data = NULL;
499 508
@@ -503,17 +512,19 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
503 if (length) 512 if (length)
504 goto out; 513 goto out;
505 514
506 if (*ppos != 0) { 515 /* No partial writes. */
507 /* No partial writes. */ 516 length = -EINVAL;
508 length = -EINVAL; 517 if (*ppos != 0)
509 goto out; 518 goto out;
510 }
511 519
512 if ((count > 64 * 1024 * 1024) 520 length = -EFBIG;
513 || (data = vmalloc(count)) == NULL) { 521 if (count > 64 * 1024 * 1024)
514 length = -ENOMEM; 522 goto out;
523
524 length = -ENOMEM;
525 data = vmalloc(count);
526 if (!data)
515 goto out; 527 goto out;
516 }
517 528
518 length = -EFAULT; 529 length = -EFAULT;
519 if (copy_from_user(data, buf, count) != 0) 530 if (copy_from_user(data, buf, count) != 0)
@@ -523,23 +534,19 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
523 if (length) 534 if (length)
524 goto out; 535 goto out;
525 536
526 ret = sel_make_bools(); 537 length = sel_make_bools();
527 if (ret) { 538 if (length)
528 length = ret;
529 goto out1; 539 goto out1;
530 }
531 540
532 ret = sel_make_classes(); 541 length = sel_make_classes();
533 if (ret) { 542 if (length)
534 length = ret;
535 goto out1; 543 goto out1;
536 }
537 544
538 ret = sel_make_policycap(); 545 length = sel_make_policycap();
539 if (ret) 546 if (length)
540 length = ret; 547 goto out1;
541 else 548
542 length = count; 549 length = count;
543 550
544out1: 551out1:
545 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, 552 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
@@ -559,26 +566,26 @@ static const struct file_operations sel_load_ops = {
559 566
560static ssize_t sel_write_context(struct file *file, char *buf, size_t size) 567static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
561{ 568{
562 char *canon; 569 char *canon = NULL;
563 u32 sid, len; 570 u32 sid, len;
564 ssize_t length; 571 ssize_t length;
565 572
566 length = task_has_security(current, SECURITY__CHECK_CONTEXT); 573 length = task_has_security(current, SECURITY__CHECK_CONTEXT);
567 if (length) 574 if (length)
568 return length; 575 goto out;
569 576
570 length = security_context_to_sid(buf, size, &sid); 577 length = security_context_to_sid(buf, size, &sid);
571 if (length < 0) 578 if (length)
572 return length; 579 goto out;
573 580
574 length = security_sid_to_context(sid, &canon, &len); 581 length = security_sid_to_context(sid, &canon, &len);
575 if (length < 0) 582 if (length)
576 return length; 583 goto out;
577 584
585 length = -ERANGE;
578 if (len > SIMPLE_TRANSACTION_LIMIT) { 586 if (len > SIMPLE_TRANSACTION_LIMIT) {
579 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 587 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
580 "payload max\n", __func__, len); 588 "payload max\n", __func__, len);
581 length = -ERANGE;
582 goto out; 589 goto out;
583 } 590 }
584 591
@@ -602,23 +609,28 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
602static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, 609static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
603 size_t count, loff_t *ppos) 610 size_t count, loff_t *ppos)
604{ 611{
605 char *page; 612 char *page = NULL;
606 ssize_t length; 613 ssize_t length;
607 unsigned int new_value; 614 unsigned int new_value;
608 615
609 length = task_has_security(current, SECURITY__SETCHECKREQPROT); 616 length = task_has_security(current, SECURITY__SETCHECKREQPROT);
610 if (length) 617 if (length)
611 return length; 618 goto out;
612 619
620 length = -ENOMEM;
613 if (count >= PAGE_SIZE) 621 if (count >= PAGE_SIZE)
614 return -ENOMEM; 622 goto out;
615 if (*ppos != 0) { 623
616 /* No partial writes. */ 624 /* No partial writes. */
617 return -EINVAL; 625 length = -EINVAL;
618 } 626 if (*ppos != 0)
627 goto out;
628
629 length = -ENOMEM;
619 page = (char *)get_zeroed_page(GFP_KERNEL); 630 page = (char *)get_zeroed_page(GFP_KERNEL);
620 if (!page) 631 if (!page)
621 return -ENOMEM; 632 goto out;
633
622 length = -EFAULT; 634 length = -EFAULT;
623 if (copy_from_user(page, buf, count)) 635 if (copy_from_user(page, buf, count))
624 goto out; 636 goto out;
@@ -693,7 +705,7 @@ static const struct file_operations transaction_ops = {
693 705
694static ssize_t sel_write_access(struct file *file, char *buf, size_t size) 706static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
695{ 707{
696 char *scon, *tcon; 708 char *scon = NULL, *tcon = NULL;
697 u32 ssid, tsid; 709 u32 ssid, tsid;
698 u16 tclass; 710 u16 tclass;
699 struct av_decision avd; 711 struct av_decision avd;
@@ -701,27 +713,29 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
701 713
702 length = task_has_security(current, SECURITY__COMPUTE_AV); 714 length = task_has_security(current, SECURITY__COMPUTE_AV);
703 if (length) 715 if (length)
704 return length; 716 goto out;
705 717
706 length = -ENOMEM; 718 length = -ENOMEM;
707 scon = kzalloc(size + 1, GFP_KERNEL); 719 scon = kzalloc(size + 1, GFP_KERNEL);
708 if (!scon) 720 if (!scon)
709 return length; 721 goto out;
710 722
723 length = -ENOMEM;
711 tcon = kzalloc(size + 1, GFP_KERNEL); 724 tcon = kzalloc(size + 1, GFP_KERNEL);
712 if (!tcon) 725 if (!tcon)
713 goto out; 726 goto out;
714 727
715 length = -EINVAL; 728 length = -EINVAL;
716 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 729 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
717 goto out2; 730 goto out;
718 731
719 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 732 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
720 if (length < 0) 733 if (length)
721 goto out2; 734 goto out;
735
722 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 736 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
723 if (length < 0) 737 if (length)
724 goto out2; 738 goto out;
725 739
726 security_compute_av_user(ssid, tsid, tclass, &avd); 740 security_compute_av_user(ssid, tsid, tclass, &avd);
727 741
@@ -730,133 +744,131 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
730 avd.allowed, 0xffffffff, 744 avd.allowed, 0xffffffff,
731 avd.auditallow, avd.auditdeny, 745 avd.auditallow, avd.auditdeny,
732 avd.seqno, avd.flags); 746 avd.seqno, avd.flags);
733out2:
734 kfree(tcon);
735out: 747out:
748 kfree(tcon);
736 kfree(scon); 749 kfree(scon);
737 return length; 750 return length;
738} 751}
739 752
740static ssize_t sel_write_create(struct file *file, char *buf, size_t size) 753static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
741{ 754{
742 char *scon, *tcon; 755 char *scon = NULL, *tcon = NULL;
743 u32 ssid, tsid, newsid; 756 u32 ssid, tsid, newsid;
744 u16 tclass; 757 u16 tclass;
745 ssize_t length; 758 ssize_t length;
746 char *newcon; 759 char *newcon = NULL;
747 u32 len; 760 u32 len;
748 761
749 length = task_has_security(current, SECURITY__COMPUTE_CREATE); 762 length = task_has_security(current, SECURITY__COMPUTE_CREATE);
750 if (length) 763 if (length)
751 return length; 764 goto out;
752 765
753 length = -ENOMEM; 766 length = -ENOMEM;
754 scon = kzalloc(size + 1, GFP_KERNEL); 767 scon = kzalloc(size + 1, GFP_KERNEL);
755 if (!scon) 768 if (!scon)
756 return length; 769 goto out;
757 770
771 length = -ENOMEM;
758 tcon = kzalloc(size + 1, GFP_KERNEL); 772 tcon = kzalloc(size + 1, GFP_KERNEL);
759 if (!tcon) 773 if (!tcon)
760 goto out; 774 goto out;
761 775
762 length = -EINVAL; 776 length = -EINVAL;
763 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 777 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
764 goto out2; 778 goto out;
765 779
766 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 780 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
767 if (length < 0) 781 if (length)
768 goto out2; 782 goto out;
783
769 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 784 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
770 if (length < 0) 785 if (length)
771 goto out2; 786 goto out;
772 787
773 length = security_transition_sid_user(ssid, tsid, tclass, &newsid); 788 length = security_transition_sid_user(ssid, tsid, tclass, &newsid);
774 if (length < 0) 789 if (length)
775 goto out2; 790 goto out;
776 791
777 length = security_sid_to_context(newsid, &newcon, &len); 792 length = security_sid_to_context(newsid, &newcon, &len);
778 if (length < 0) 793 if (length)
779 goto out2; 794 goto out;
780 795
796 length = -ERANGE;
781 if (len > SIMPLE_TRANSACTION_LIMIT) { 797 if (len > SIMPLE_TRANSACTION_LIMIT) {
782 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 798 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
783 "payload max\n", __func__, len); 799 "payload max\n", __func__, len);
784 length = -ERANGE; 800 goto out;
785 goto out3;
786 } 801 }
787 802
788 memcpy(buf, newcon, len); 803 memcpy(buf, newcon, len);
789 length = len; 804 length = len;
790out3: 805out:
791 kfree(newcon); 806 kfree(newcon);
792out2:
793 kfree(tcon); 807 kfree(tcon);
794out:
795 kfree(scon); 808 kfree(scon);
796 return length; 809 return length;
797} 810}
798 811
799static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size) 812static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
800{ 813{
801 char *scon, *tcon; 814 char *scon = NULL, *tcon = NULL;
802 u32 ssid, tsid, newsid; 815 u32 ssid, tsid, newsid;
803 u16 tclass; 816 u16 tclass;
804 ssize_t length; 817 ssize_t length;
805 char *newcon; 818 char *newcon = NULL;
806 u32 len; 819 u32 len;
807 820
808 length = task_has_security(current, SECURITY__COMPUTE_RELABEL); 821 length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
809 if (length) 822 if (length)
810 return length; 823 goto out;
811 824
812 length = -ENOMEM; 825 length = -ENOMEM;
813 scon = kzalloc(size + 1, GFP_KERNEL); 826 scon = kzalloc(size + 1, GFP_KERNEL);
814 if (!scon) 827 if (!scon)
815 return length; 828 goto out;
816 829
830 length = -ENOMEM;
817 tcon = kzalloc(size + 1, GFP_KERNEL); 831 tcon = kzalloc(size + 1, GFP_KERNEL);
818 if (!tcon) 832 if (!tcon)
819 goto out; 833 goto out;
820 834
821 length = -EINVAL; 835 length = -EINVAL;
822 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 836 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
823 goto out2; 837 goto out;
824 838
825 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 839 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
826 if (length < 0) 840 if (length)
827 goto out2; 841 goto out;
842
828 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 843 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
829 if (length < 0) 844 if (length)
830 goto out2; 845 goto out;
831 846
832 length = security_change_sid(ssid, tsid, tclass, &newsid); 847 length = security_change_sid(ssid, tsid, tclass, &newsid);
833 if (length < 0) 848 if (length)
834 goto out2; 849 goto out;
835 850
836 length = security_sid_to_context(newsid, &newcon, &len); 851 length = security_sid_to_context(newsid, &newcon, &len);
837 if (length < 0) 852 if (length)
838 goto out2; 853 goto out;
839 854
840 if (len > SIMPLE_TRANSACTION_LIMIT) { 855 length = -ERANGE;
841 length = -ERANGE; 856 if (len > SIMPLE_TRANSACTION_LIMIT)
842 goto out3; 857 goto out;
843 }
844 858
845 memcpy(buf, newcon, len); 859 memcpy(buf, newcon, len);
846 length = len; 860 length = len;
847out3: 861out:
848 kfree(newcon); 862 kfree(newcon);
849out2:
850 kfree(tcon); 863 kfree(tcon);
851out:
852 kfree(scon); 864 kfree(scon);
853 return length; 865 return length;
854} 866}
855 867
856static ssize_t sel_write_user(struct file *file, char *buf, size_t size) 868static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
857{ 869{
858 char *con, *user, *ptr; 870 char *con = NULL, *user = NULL, *ptr;
859 u32 sid, *sids; 871 u32 sid, *sids = NULL;
860 ssize_t length; 872 ssize_t length;
861 char *newcon; 873 char *newcon;
862 int i, rc; 874 int i, rc;
@@ -864,28 +876,29 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
864 876
865 length = task_has_security(current, SECURITY__COMPUTE_USER); 877 length = task_has_security(current, SECURITY__COMPUTE_USER);
866 if (length) 878 if (length)
867 return length; 879 goto out;;
868 880
869 length = -ENOMEM; 881 length = -ENOMEM;
870 con = kzalloc(size + 1, GFP_KERNEL); 882 con = kzalloc(size + 1, GFP_KERNEL);
871 if (!con) 883 if (!con)
872 return length; 884 goto out;;
873 885
886 length = -ENOMEM;
874 user = kzalloc(size + 1, GFP_KERNEL); 887 user = kzalloc(size + 1, GFP_KERNEL);
875 if (!user) 888 if (!user)
876 goto out; 889 goto out;
877 890
878 length = -EINVAL; 891 length = -EINVAL;
879 if (sscanf(buf, "%s %s", con, user) != 2) 892 if (sscanf(buf, "%s %s", con, user) != 2)
880 goto out2; 893 goto out;
881 894
882 length = security_context_to_sid(con, strlen(con) + 1, &sid); 895 length = security_context_to_sid(con, strlen(con) + 1, &sid);
883 if (length < 0) 896 if (length)
884 goto out2; 897 goto out;
885 898
886 length = security_get_user_sids(sid, user, &sids, &nsids); 899 length = security_get_user_sids(sid, user, &sids, &nsids);
887 if (length < 0) 900 if (length)
888 goto out2; 901 goto out;
889 902
890 length = sprintf(buf, "%u", nsids) + 1; 903 length = sprintf(buf, "%u", nsids) + 1;
891 ptr = buf + length; 904 ptr = buf + length;
@@ -893,82 +906,80 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
893 rc = security_sid_to_context(sids[i], &newcon, &len); 906 rc = security_sid_to_context(sids[i], &newcon, &len);
894 if (rc) { 907 if (rc) {
895 length = rc; 908 length = rc;
896 goto out3; 909 goto out;
897 } 910 }
898 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) { 911 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) {
899 kfree(newcon); 912 kfree(newcon);
900 length = -ERANGE; 913 length = -ERANGE;
901 goto out3; 914 goto out;
902 } 915 }
903 memcpy(ptr, newcon, len); 916 memcpy(ptr, newcon, len);
904 kfree(newcon); 917 kfree(newcon);
905 ptr += len; 918 ptr += len;
906 length += len; 919 length += len;
907 } 920 }
908out3: 921out:
909 kfree(sids); 922 kfree(sids);
910out2:
911 kfree(user); 923 kfree(user);
912out:
913 kfree(con); 924 kfree(con);
914 return length; 925 return length;
915} 926}
916 927
917static ssize_t sel_write_member(struct file *file, char *buf, size_t size) 928static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
918{ 929{
919 char *scon, *tcon; 930 char *scon = NULL, *tcon = NULL;
920 u32 ssid, tsid, newsid; 931 u32 ssid, tsid, newsid;
921 u16 tclass; 932 u16 tclass;
922 ssize_t length; 933 ssize_t length;
923 char *newcon; 934 char *newcon = NULL;
924 u32 len; 935 u32 len;
925 936
926 length = task_has_security(current, SECURITY__COMPUTE_MEMBER); 937 length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
927 if (length) 938 if (length)
928 return length; 939 goto out;
929 940
930 length = -ENOMEM; 941 length = -ENOMEM;
931 scon = kzalloc(size + 1, GFP_KERNEL); 942 scon = kzalloc(size + 1, GFP_KERNEL);
932 if (!scon) 943 if (!scon)
933 return length; 944 goto out;;
934 945
946 length = -ENOMEM;
935 tcon = kzalloc(size + 1, GFP_KERNEL); 947 tcon = kzalloc(size + 1, GFP_KERNEL);
936 if (!tcon) 948 if (!tcon)
937 goto out; 949 goto out;
938 950
939 length = -EINVAL; 951 length = -EINVAL;
940 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 952 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
941 goto out2; 953 goto out;
942 954
943 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 955 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
944 if (length < 0) 956 if (length)
945 goto out2; 957 goto out;
958
946 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 959 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
947 if (length < 0) 960 if (length)
948 goto out2; 961 goto out;
949 962
950 length = security_member_sid(ssid, tsid, tclass, &newsid); 963 length = security_member_sid(ssid, tsid, tclass, &newsid);
951 if (length < 0) 964 if (length)
952 goto out2; 965 goto out;
953 966
954 length = security_sid_to_context(newsid, &newcon, &len); 967 length = security_sid_to_context(newsid, &newcon, &len);
955 if (length < 0) 968 if (length)
956 goto out2; 969 goto out;
957 970
971 length = -ERANGE;
958 if (len > SIMPLE_TRANSACTION_LIMIT) { 972 if (len > SIMPLE_TRANSACTION_LIMIT) {
959 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 973 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
960 "payload max\n", __func__, len); 974 "payload max\n", __func__, len);
961 length = -ERANGE; 975 goto out;
962 goto out3;
963 } 976 }
964 977
965 memcpy(buf, newcon, len); 978 memcpy(buf, newcon, len);
966 length = len; 979 length = len;
967out3: 980out:
968 kfree(newcon); 981 kfree(newcon);
969out2:
970 kfree(tcon); 982 kfree(tcon);
971out:
972 kfree(scon); 983 kfree(scon);
973 return length; 984 return length;
974} 985}
@@ -978,7 +989,6 @@ static struct inode *sel_make_inode(struct super_block *sb, int mode)
978 struct inode *ret = new_inode(sb); 989 struct inode *ret = new_inode(sb);
979 990
980 if (ret) { 991 if (ret) {
981 ret->i_ino = get_next_ino();
982 ret->i_mode = mode; 992 ret->i_mode = mode;
983 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; 993 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
984 } 994 }
@@ -998,16 +1008,14 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
998 1008
999 mutex_lock(&sel_mutex); 1009 mutex_lock(&sel_mutex);
1000 1010
1001 if (index >= bool_num || strcmp(name, bool_pending_names[index])) { 1011 ret = -EINVAL;
1002 ret = -EINVAL; 1012 if (index >= bool_num || strcmp(name, bool_pending_names[index]))
1003 goto out; 1013 goto out;
1004 }
1005 1014
1015 ret = -ENOMEM;
1006 page = (char *)get_zeroed_page(GFP_KERNEL); 1016 page = (char *)get_zeroed_page(GFP_KERNEL);
1007 if (!page) { 1017 if (!page)
1008 ret = -ENOMEM;
1009 goto out; 1018 goto out;
1010 }
1011 1019
1012 cur_enforcing = security_get_bool_value(index); 1020 cur_enforcing = security_get_bool_value(index);
1013 if (cur_enforcing < 0) { 1021 if (cur_enforcing < 0) {
@@ -1019,8 +1027,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
1019 ret = simple_read_from_buffer(buf, count, ppos, page, length); 1027 ret = simple_read_from_buffer(buf, count, ppos, page, length);
1020out: 1028out:
1021 mutex_unlock(&sel_mutex); 1029 mutex_unlock(&sel_mutex);
1022 if (page) 1030 free_page((unsigned long)page);
1023 free_page((unsigned long)page);
1024 return ret; 1031 return ret;
1025} 1032}
1026 1033
@@ -1040,26 +1047,23 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
1040 if (length) 1047 if (length)
1041 goto out; 1048 goto out;
1042 1049
1043 if (index >= bool_num || strcmp(name, bool_pending_names[index])) { 1050 length = -EINVAL;
1044 length = -EINVAL; 1051 if (index >= bool_num || strcmp(name, bool_pending_names[index]))
1045 goto out; 1052 goto out;
1046 }
1047 1053
1048 if (count >= PAGE_SIZE) { 1054 length = -ENOMEM;
1049 length = -ENOMEM; 1055 if (count >= PAGE_SIZE)
1050 goto out; 1056 goto out;
1051 }
1052 1057
1053 if (*ppos != 0) { 1058 /* No partial writes. */
1054 /* No partial writes. */ 1059 length = -EINVAL;
1055 length = -EINVAL; 1060 if (*ppos != 0)
1056 goto out; 1061 goto out;
1057 } 1062
1063 length = -ENOMEM;
1058 page = (char *)get_zeroed_page(GFP_KERNEL); 1064 page = (char *)get_zeroed_page(GFP_KERNEL);
1059 if (!page) { 1065 if (!page)
1060 length = -ENOMEM;
1061 goto out; 1066 goto out;
1062 }
1063 1067
1064 length = -EFAULT; 1068 length = -EFAULT;
1065 if (copy_from_user(page, buf, count)) 1069 if (copy_from_user(page, buf, count))
@@ -1077,8 +1081,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
1077 1081
1078out: 1082out:
1079 mutex_unlock(&sel_mutex); 1083 mutex_unlock(&sel_mutex);
1080 if (page) 1084 free_page((unsigned long) page);
1081 free_page((unsigned long) page);
1082 return length; 1085 return length;
1083} 1086}
1084 1087
@@ -1102,19 +1105,19 @@ static ssize_t sel_commit_bools_write(struct file *filep,
1102 if (length) 1105 if (length)
1103 goto out; 1106 goto out;
1104 1107
1105 if (count >= PAGE_SIZE) { 1108 length = -ENOMEM;
1106 length = -ENOMEM; 1109 if (count >= PAGE_SIZE)
1107 goto out; 1110 goto out;
1108 } 1111
1109 if (*ppos != 0) { 1112 /* No partial writes. */
1110 /* No partial writes. */ 1113 length = -EINVAL;
1114 if (*ppos != 0)
1111 goto out; 1115 goto out;
1112 } 1116
1117 length = -ENOMEM;
1113 page = (char *)get_zeroed_page(GFP_KERNEL); 1118 page = (char *)get_zeroed_page(GFP_KERNEL);
1114 if (!page) { 1119 if (!page)
1115 length = -ENOMEM;
1116 goto out; 1120 goto out;
1117 }
1118 1121
1119 length = -EFAULT; 1122 length = -EFAULT;
1120 if (copy_from_user(page, buf, count)) 1123 if (copy_from_user(page, buf, count))
@@ -1124,15 +1127,16 @@ static ssize_t sel_commit_bools_write(struct file *filep,
1124 if (sscanf(page, "%d", &new_value) != 1) 1127 if (sscanf(page, "%d", &new_value) != 1)
1125 goto out; 1128 goto out;
1126 1129
1130 length = 0;
1127 if (new_value && bool_pending_values) 1131 if (new_value && bool_pending_values)
1128 security_set_bools(bool_num, bool_pending_values); 1132 length = security_set_bools(bool_num, bool_pending_values);
1129 1133
1130 length = count; 1134 if (!length)
1135 length = count;
1131 1136
1132out: 1137out:
1133 mutex_unlock(&sel_mutex); 1138 mutex_unlock(&sel_mutex);
1134 if (page) 1139 free_page((unsigned long) page);
1135 free_page((unsigned long) page);
1136 return length; 1140 return length;
1137} 1141}
1138 1142
@@ -1173,7 +1177,7 @@ static void sel_remove_entries(struct dentry *de)
1173 1177
1174static int sel_make_bools(void) 1178static int sel_make_bools(void)
1175{ 1179{
1176 int i, ret = 0; 1180 int i, ret;
1177 ssize_t len; 1181 ssize_t len;
1178 struct dentry *dentry = NULL; 1182 struct dentry *dentry = NULL;
1179 struct dentry *dir = bool_dir; 1183 struct dentry *dir = bool_dir;
@@ -1194,38 +1198,40 @@ static int sel_make_bools(void)
1194 1198
1195 sel_remove_entries(dir); 1199 sel_remove_entries(dir);
1196 1200
1201 ret = -ENOMEM;
1197 page = (char *)get_zeroed_page(GFP_KERNEL); 1202 page = (char *)get_zeroed_page(GFP_KERNEL);
1198 if (!page) 1203 if (!page)
1199 return -ENOMEM; 1204 goto out;
1200 1205
1201 ret = security_get_bools(&num, &names, &values); 1206 ret = security_get_bools(&num, &names, &values);
1202 if (ret != 0) 1207 if (ret)
1203 goto out; 1208 goto out;
1204 1209
1205 for (i = 0; i < num; i++) { 1210 for (i = 0; i < num; i++) {
1211 ret = -ENOMEM;
1206 dentry = d_alloc_name(dir, names[i]); 1212 dentry = d_alloc_name(dir, names[i]);
1207 if (!dentry) { 1213 if (!dentry)
1208 ret = -ENOMEM; 1214 goto out;
1209 goto err; 1215
1210 } 1216 ret = -ENOMEM;
1211 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); 1217 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
1212 if (!inode) { 1218 if (!inode)
1213 ret = -ENOMEM; 1219 goto out;
1214 goto err;
1215 }
1216 1220
1221 ret = -EINVAL;
1217 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); 1222 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
1218 if (len < 0) { 1223 if (len < 0)
1219 ret = -EINVAL; 1224 goto out;
1220 goto err; 1225
1221 } else if (len >= PAGE_SIZE) { 1226 ret = -ENAMETOOLONG;
1222 ret = -ENAMETOOLONG; 1227 if (len >= PAGE_SIZE)
1223 goto err; 1228 goto out;
1224 } 1229
1225 isec = (struct inode_security_struct *)inode->i_security; 1230 isec = (struct inode_security_struct *)inode->i_security;
1226 ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); 1231 ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid);
1227 if (ret) 1232 if (ret)
1228 goto err; 1233 goto out;
1234
1229 isec->sid = sid; 1235 isec->sid = sid;
1230 isec->initialized = 1; 1236 isec->initialized = 1;
1231 inode->i_fop = &sel_bool_ops; 1237 inode->i_fop = &sel_bool_ops;
@@ -1235,10 +1241,12 @@ static int sel_make_bools(void)
1235 bool_num = num; 1241 bool_num = num;
1236 bool_pending_names = names; 1242 bool_pending_names = names;
1237 bool_pending_values = values; 1243 bool_pending_values = values;
1244
1245 free_page((unsigned long)page);
1246 return 0;
1238out: 1247out:
1239 free_page((unsigned long)page); 1248 free_page((unsigned long)page);
1240 return ret; 1249
1241err:
1242 if (names) { 1250 if (names) {
1243 for (i = 0; i < num; i++) 1251 for (i = 0; i < num; i++)
1244 kfree(names[i]); 1252 kfree(names[i]);
@@ -1246,8 +1254,8 @@ err:
1246 } 1254 }
1247 kfree(values); 1255 kfree(values);
1248 sel_remove_entries(dir); 1256 sel_remove_entries(dir);
1249 ret = -ENOMEM; 1257
1250 goto out; 1258 return ret;
1251} 1259}
1252 1260
1253#define NULL_FILE_NAME "null" 1261#define NULL_FILE_NAME "null"
@@ -1269,47 +1277,41 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
1269 size_t count, loff_t *ppos) 1277 size_t count, loff_t *ppos)
1270 1278
1271{ 1279{
1272 char *page; 1280 char *page = NULL;
1273 ssize_t ret; 1281 ssize_t ret;
1274 int new_value; 1282 int new_value;
1275 1283
1276 if (count >= PAGE_SIZE) { 1284 ret = task_has_security(current, SECURITY__SETSECPARAM);
1277 ret = -ENOMEM; 1285 if (ret)
1278 goto out; 1286 goto out;
1279 }
1280 1287
1281 if (*ppos != 0) { 1288 ret = -ENOMEM;
1282 /* No partial writes. */ 1289 if (count >= PAGE_SIZE)
1283 ret = -EINVAL;
1284 goto out; 1290 goto out;
1285 }
1286 1291
1292 /* No partial writes. */
1293 ret = -EINVAL;
1294 if (*ppos != 0)
1295 goto out;
1296
1297 ret = -ENOMEM;
1287 page = (char *)get_zeroed_page(GFP_KERNEL); 1298 page = (char *)get_zeroed_page(GFP_KERNEL);
1288 if (!page) { 1299 if (!page)
1289 ret = -ENOMEM;
1290 goto out; 1300 goto out;
1291 }
1292 1301
1293 if (copy_from_user(page, buf, count)) { 1302 ret = -EFAULT;
1294 ret = -EFAULT; 1303 if (copy_from_user(page, buf, count))
1295 goto out_free; 1304 goto out;
1296 }
1297 1305
1298 if (sscanf(page, "%u", &new_value) != 1) { 1306 ret = -EINVAL;
1299 ret = -EINVAL; 1307 if (sscanf(page, "%u", &new_value) != 1)
1300 goto out; 1308 goto out;
1301 }
1302 1309
1303 if (new_value != avc_cache_threshold) { 1310 avc_cache_threshold = new_value;
1304 ret = task_has_security(current, SECURITY__SETSECPARAM); 1311
1305 if (ret)
1306 goto out_free;
1307 avc_cache_threshold = new_value;
1308 }
1309 ret = count; 1312 ret = count;
1310out_free:
1311 free_page((unsigned long)page);
1312out: 1313out:
1314 free_page((unsigned long)page);
1313 return ret; 1315 return ret;
1314} 1316}
1315 1317
@@ -1317,19 +1319,18 @@ static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
1317 size_t count, loff_t *ppos) 1319 size_t count, loff_t *ppos)
1318{ 1320{
1319 char *page; 1321 char *page;
1320 ssize_t ret = 0; 1322 ssize_t length;
1321 1323
1322 page = (char *)__get_free_page(GFP_KERNEL); 1324 page = (char *)__get_free_page(GFP_KERNEL);
1323 if (!page) { 1325 if (!page)
1324 ret = -ENOMEM; 1326 return -ENOMEM;
1325 goto out; 1327
1326 } 1328 length = avc_get_hash_stats(page);
1327 ret = avc_get_hash_stats(page); 1329 if (length >= 0)
1328 if (ret >= 0) 1330 length = simple_read_from_buffer(buf, count, ppos, page, length);
1329 ret = simple_read_from_buffer(buf, count, ppos, page, ret);
1330 free_page((unsigned long)page); 1331 free_page((unsigned long)page);
1331out: 1332
1332 return ret; 1333 return length;
1333} 1334}
1334 1335
1335static const struct file_operations sel_avc_cache_threshold_ops = { 1336static const struct file_operations sel_avc_cache_threshold_ops = {
@@ -1411,7 +1412,7 @@ static const struct file_operations sel_avc_cache_stats_ops = {
1411 1412
1412static int sel_make_avc_files(struct dentry *dir) 1413static int sel_make_avc_files(struct dentry *dir)
1413{ 1414{
1414 int i, ret = 0; 1415 int i;
1415 static struct tree_descr files[] = { 1416 static struct tree_descr files[] = {
1416 { "cache_threshold", 1417 { "cache_threshold",
1417 &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR }, 1418 &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
@@ -1426,22 +1427,19 @@ static int sel_make_avc_files(struct dentry *dir)
1426 struct dentry *dentry; 1427 struct dentry *dentry;
1427 1428
1428 dentry = d_alloc_name(dir, files[i].name); 1429 dentry = d_alloc_name(dir, files[i].name);
1429 if (!dentry) { 1430 if (!dentry)
1430 ret = -ENOMEM; 1431 return -ENOMEM;
1431 goto out;
1432 }
1433 1432
1434 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); 1433 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1435 if (!inode) { 1434 if (!inode)
1436 ret = -ENOMEM; 1435 return -ENOMEM;
1437 goto out; 1436
1438 }
1439 inode->i_fop = files[i].ops; 1437 inode->i_fop = files[i].ops;
1440 inode->i_ino = ++sel_last_ino; 1438 inode->i_ino = ++sel_last_ino;
1441 d_add(dentry, inode); 1439 d_add(dentry, inode);
1442 } 1440 }
1443out: 1441
1444 return ret; 1442 return 0;
1445} 1443}
1446 1444
1447static ssize_t sel_read_initcon(struct file *file, char __user *buf, 1445static ssize_t sel_read_initcon(struct file *file, char __user *buf,
@@ -1455,7 +1453,7 @@ static ssize_t sel_read_initcon(struct file *file, char __user *buf,
1455 inode = file->f_path.dentry->d_inode; 1453 inode = file->f_path.dentry->d_inode;
1456 sid = inode->i_ino&SEL_INO_MASK; 1454 sid = inode->i_ino&SEL_INO_MASK;
1457 ret = security_sid_to_context(sid, &con, &len); 1455 ret = security_sid_to_context(sid, &con, &len);
1458 if (ret < 0) 1456 if (ret)
1459 return ret; 1457 return ret;
1460 1458
1461 ret = simple_read_from_buffer(buf, count, ppos, con, len); 1459 ret = simple_read_from_buffer(buf, count, ppos, con, len);
@@ -1470,28 +1468,25 @@ static const struct file_operations sel_initcon_ops = {
1470 1468
1471static int sel_make_initcon_files(struct dentry *dir) 1469static int sel_make_initcon_files(struct dentry *dir)
1472{ 1470{
1473 int i, ret = 0; 1471 int i;
1474 1472
1475 for (i = 1; i <= SECINITSID_NUM; i++) { 1473 for (i = 1; i <= SECINITSID_NUM; i++) {
1476 struct inode *inode; 1474 struct inode *inode;
1477 struct dentry *dentry; 1475 struct dentry *dentry;
1478 dentry = d_alloc_name(dir, security_get_initial_sid_context(i)); 1476 dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
1479 if (!dentry) { 1477 if (!dentry)
1480 ret = -ENOMEM; 1478 return -ENOMEM;
1481 goto out;
1482 }
1483 1479
1484 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1480 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1485 if (!inode) { 1481 if (!inode)
1486 ret = -ENOMEM; 1482 return -ENOMEM;
1487 goto out; 1483
1488 }
1489 inode->i_fop = &sel_initcon_ops; 1484 inode->i_fop = &sel_initcon_ops;
1490 inode->i_ino = i|SEL_INITCON_INO_OFFSET; 1485 inode->i_ino = i|SEL_INITCON_INO_OFFSET;
1491 d_add(dentry, inode); 1486 d_add(dentry, inode);
1492 } 1487 }
1493out: 1488
1494 return ret; 1489 return 0;
1495} 1490}
1496 1491
1497static inline unsigned int sel_div(unsigned long a, unsigned long b) 1492static inline unsigned int sel_div(unsigned long a, unsigned long b)
@@ -1527,15 +1522,13 @@ static ssize_t sel_read_class(struct file *file, char __user *buf,
1527 unsigned long ino = file->f_path.dentry->d_inode->i_ino; 1522 unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1528 1523
1529 page = (char *)__get_free_page(GFP_KERNEL); 1524 page = (char *)__get_free_page(GFP_KERNEL);
1530 if (!page) { 1525 if (!page)
1531 rc = -ENOMEM; 1526 return -ENOMEM;
1532 goto out;
1533 }
1534 1527
1535 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino)); 1528 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
1536 rc = simple_read_from_buffer(buf, count, ppos, page, len); 1529 rc = simple_read_from_buffer(buf, count, ppos, page, len);
1537 free_page((unsigned long)page); 1530 free_page((unsigned long)page);
1538out: 1531
1539 return rc; 1532 return rc;
1540} 1533}
1541 1534
@@ -1552,15 +1545,13 @@ static ssize_t sel_read_perm(struct file *file, char __user *buf,
1552 unsigned long ino = file->f_path.dentry->d_inode->i_ino; 1545 unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1553 1546
1554 page = (char *)__get_free_page(GFP_KERNEL); 1547 page = (char *)__get_free_page(GFP_KERNEL);
1555 if (!page) { 1548 if (!page)
1556 rc = -ENOMEM; 1549 return -ENOMEM;
1557 goto out;
1558 }
1559 1550
1560 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino)); 1551 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino));
1561 rc = simple_read_from_buffer(buf, count, ppos, page, len); 1552 rc = simple_read_from_buffer(buf, count, ppos, page, len);
1562 free_page((unsigned long)page); 1553 free_page((unsigned long)page);
1563out: 1554
1564 return rc; 1555 return rc;
1565} 1556}
1566 1557
@@ -1591,39 +1582,37 @@ static const struct file_operations sel_policycap_ops = {
1591static int sel_make_perm_files(char *objclass, int classvalue, 1582static int sel_make_perm_files(char *objclass, int classvalue,
1592 struct dentry *dir) 1583 struct dentry *dir)
1593{ 1584{
1594 int i, rc = 0, nperms; 1585 int i, rc, nperms;
1595 char **perms; 1586 char **perms;
1596 1587
1597 rc = security_get_permissions(objclass, &perms, &nperms); 1588 rc = security_get_permissions(objclass, &perms, &nperms);
1598 if (rc) 1589 if (rc)
1599 goto out; 1590 return rc;
1600 1591
1601 for (i = 0; i < nperms; i++) { 1592 for (i = 0; i < nperms; i++) {
1602 struct inode *inode; 1593 struct inode *inode;
1603 struct dentry *dentry; 1594 struct dentry *dentry;
1604 1595
1596 rc = -ENOMEM;
1605 dentry = d_alloc_name(dir, perms[i]); 1597 dentry = d_alloc_name(dir, perms[i]);
1606 if (!dentry) { 1598 if (!dentry)
1607 rc = -ENOMEM; 1599 goto out;
1608 goto out1;
1609 }
1610 1600
1601 rc = -ENOMEM;
1611 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1602 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1612 if (!inode) { 1603 if (!inode)
1613 rc = -ENOMEM; 1604 goto out;
1614 goto out1; 1605
1615 }
1616 inode->i_fop = &sel_perm_ops; 1606 inode->i_fop = &sel_perm_ops;
1617 /* i+1 since perm values are 1-indexed */ 1607 /* i+1 since perm values are 1-indexed */
1618 inode->i_ino = sel_perm_to_ino(classvalue, i + 1); 1608 inode->i_ino = sel_perm_to_ino(classvalue, i + 1);
1619 d_add(dentry, inode); 1609 d_add(dentry, inode);
1620 } 1610 }
1621 1611 rc = 0;
1622out1: 1612out:
1623 for (i = 0; i < nperms; i++) 1613 for (i = 0; i < nperms; i++)
1624 kfree(perms[i]); 1614 kfree(perms[i]);
1625 kfree(perms); 1615 kfree(perms);
1626out:
1627 return rc; 1616 return rc;
1628} 1617}
1629 1618
@@ -1635,34 +1624,27 @@ static int sel_make_class_dir_entries(char *classname, int index,
1635 int rc; 1624 int rc;
1636 1625
1637 dentry = d_alloc_name(dir, "index"); 1626 dentry = d_alloc_name(dir, "index");
1638 if (!dentry) { 1627 if (!dentry)
1639 rc = -ENOMEM; 1628 return -ENOMEM;
1640 goto out;
1641 }
1642 1629
1643 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1630 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1644 if (!inode) { 1631 if (!inode)
1645 rc = -ENOMEM; 1632 return -ENOMEM;
1646 goto out;
1647 }
1648 1633
1649 inode->i_fop = &sel_class_ops; 1634 inode->i_fop = &sel_class_ops;
1650 inode->i_ino = sel_class_to_ino(index); 1635 inode->i_ino = sel_class_to_ino(index);
1651 d_add(dentry, inode); 1636 d_add(dentry, inode);
1652 1637
1653 dentry = d_alloc_name(dir, "perms"); 1638 dentry = d_alloc_name(dir, "perms");
1654 if (!dentry) { 1639 if (!dentry)
1655 rc = -ENOMEM; 1640 return -ENOMEM;
1656 goto out;
1657 }
1658 1641
1659 rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino); 1642 rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
1660 if (rc) 1643 if (rc)
1661 goto out; 1644 return rc;
1662 1645
1663 rc = sel_make_perm_files(classname, index, dentry); 1646 rc = sel_make_perm_files(classname, index, dentry);
1664 1647
1665out:
1666 return rc; 1648 return rc;
1667} 1649}
1668 1650
@@ -1692,15 +1674,15 @@ static void sel_remove_classes(void)
1692 1674
1693static int sel_make_classes(void) 1675static int sel_make_classes(void)
1694{ 1676{
1695 int rc = 0, nclasses, i; 1677 int rc, nclasses, i;
1696 char **classes; 1678 char **classes;
1697 1679
1698 /* delete any existing entries */ 1680 /* delete any existing entries */
1699 sel_remove_classes(); 1681 sel_remove_classes();
1700 1682
1701 rc = security_get_classes(&classes, &nclasses); 1683 rc = security_get_classes(&classes, &nclasses);
1702 if (rc < 0) 1684 if (rc)
1703 goto out; 1685 return rc;
1704 1686
1705 /* +2 since classes are 1-indexed */ 1687 /* +2 since classes are 1-indexed */
1706 last_class_ino = sel_class_to_ino(nclasses + 2); 1688 last_class_ino = sel_class_to_ino(nclasses + 2);
@@ -1708,29 +1690,27 @@ static int sel_make_classes(void)
1708 for (i = 0; i < nclasses; i++) { 1690 for (i = 0; i < nclasses; i++) {
1709 struct dentry *class_name_dir; 1691 struct dentry *class_name_dir;
1710 1692
1693 rc = -ENOMEM;
1711 class_name_dir = d_alloc_name(class_dir, classes[i]); 1694 class_name_dir = d_alloc_name(class_dir, classes[i]);
1712 if (!class_name_dir) { 1695 if (!class_name_dir)
1713 rc = -ENOMEM; 1696 goto out;
1714 goto out1;
1715 }
1716 1697
1717 rc = sel_make_dir(class_dir->d_inode, class_name_dir, 1698 rc = sel_make_dir(class_dir->d_inode, class_name_dir,
1718 &last_class_ino); 1699 &last_class_ino);
1719 if (rc) 1700 if (rc)
1720 goto out1; 1701 goto out;
1721 1702
1722 /* i+1 since class values are 1-indexed */ 1703 /* i+1 since class values are 1-indexed */
1723 rc = sel_make_class_dir_entries(classes[i], i + 1, 1704 rc = sel_make_class_dir_entries(classes[i], i + 1,
1724 class_name_dir); 1705 class_name_dir);
1725 if (rc) 1706 if (rc)
1726 goto out1; 1707 goto out;
1727 } 1708 }
1728 1709 rc = 0;
1729out1: 1710out:
1730 for (i = 0; i < nclasses; i++) 1711 for (i = 0; i < nclasses; i++)
1731 kfree(classes[i]); 1712 kfree(classes[i]);
1732 kfree(classes); 1713 kfree(classes);
1733out:
1734 return rc; 1714 return rc;
1735} 1715}
1736 1716
@@ -1767,14 +1747,12 @@ static int sel_make_policycap(void)
1767static int sel_make_dir(struct inode *dir, struct dentry *dentry, 1747static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1768 unsigned long *ino) 1748 unsigned long *ino)
1769{ 1749{
1770 int ret = 0;
1771 struct inode *inode; 1750 struct inode *inode;
1772 1751
1773 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO); 1752 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1774 if (!inode) { 1753 if (!inode)
1775 ret = -ENOMEM; 1754 return -ENOMEM;
1776 goto out; 1755
1777 }
1778 inode->i_op = &simple_dir_inode_operations; 1756 inode->i_op = &simple_dir_inode_operations;
1779 inode->i_fop = &simple_dir_operations; 1757 inode->i_fop = &simple_dir_operations;
1780 inode->i_ino = ++(*ino); 1758 inode->i_ino = ++(*ino);
@@ -1783,8 +1761,8 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1783 d_add(dentry, inode); 1761 d_add(dentry, inode);
1784 /* bump link count on parent directory, too */ 1762 /* bump link count on parent directory, too */
1785 inc_nlink(dir); 1763 inc_nlink(dir);
1786out: 1764
1787 return ret; 1765 return 0;
1788} 1766}
1789 1767
1790static int sel_fill_super(struct super_block *sb, void *data, int silent) 1768static int sel_fill_super(struct super_block *sb, void *data, int silent)
@@ -1820,11 +1798,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1820 1798
1821 root_inode = sb->s_root->d_inode; 1799 root_inode = sb->s_root->d_inode;
1822 1800
1801 ret = -ENOMEM;
1823 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); 1802 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1824 if (!dentry) { 1803 if (!dentry)
1825 ret = -ENOMEM;
1826 goto err; 1804 goto err;
1827 }
1828 1805
1829 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1806 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1830 if (ret) 1807 if (ret)
@@ -1832,17 +1809,16 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1832 1809
1833 bool_dir = dentry; 1810 bool_dir = dentry;
1834 1811
1812 ret = -ENOMEM;
1835 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); 1813 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1836 if (!dentry) { 1814 if (!dentry)
1837 ret = -ENOMEM;
1838 goto err; 1815 goto err;
1839 }
1840 1816
1817 ret = -ENOMEM;
1841 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); 1818 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1842 if (!inode) { 1819 if (!inode)
1843 ret = -ENOMEM;
1844 goto err; 1820 goto err;
1845 } 1821
1846 inode->i_ino = ++sel_last_ino; 1822 inode->i_ino = ++sel_last_ino;
1847 isec = (struct inode_security_struct *)inode->i_security; 1823 isec = (struct inode_security_struct *)inode->i_security;
1848 isec->sid = SECINITSID_DEVNULL; 1824 isec->sid = SECINITSID_DEVNULL;
@@ -1853,11 +1829,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1853 d_add(dentry, inode); 1829 d_add(dentry, inode);
1854 selinux_null = dentry; 1830 selinux_null = dentry;
1855 1831
1832 ret = -ENOMEM;
1856 dentry = d_alloc_name(sb->s_root, "avc"); 1833 dentry = d_alloc_name(sb->s_root, "avc");
1857 if (!dentry) { 1834 if (!dentry)
1858 ret = -ENOMEM;
1859 goto err; 1835 goto err;
1860 }
1861 1836
1862 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1837 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1863 if (ret) 1838 if (ret)
@@ -1867,11 +1842,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1867 if (ret) 1842 if (ret)
1868 goto err; 1843 goto err;
1869 1844
1845 ret = -ENOMEM;
1870 dentry = d_alloc_name(sb->s_root, "initial_contexts"); 1846 dentry = d_alloc_name(sb->s_root, "initial_contexts");
1871 if (!dentry) { 1847 if (!dentry)
1872 ret = -ENOMEM;
1873 goto err; 1848 goto err;
1874 }
1875 1849
1876 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1850 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1877 if (ret) 1851 if (ret)
@@ -1881,11 +1855,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1881 if (ret) 1855 if (ret)
1882 goto err; 1856 goto err;
1883 1857
1858 ret = -ENOMEM;
1884 dentry = d_alloc_name(sb->s_root, "class"); 1859 dentry = d_alloc_name(sb->s_root, "class");
1885 if (!dentry) { 1860 if (!dentry)
1886 ret = -ENOMEM;
1887 goto err; 1861 goto err;
1888 }
1889 1862
1890 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1863 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1891 if (ret) 1864 if (ret)
@@ -1893,11 +1866,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1893 1866
1894 class_dir = dentry; 1867 class_dir = dentry;
1895 1868
1869 ret = -ENOMEM;
1896 dentry = d_alloc_name(sb->s_root, "policy_capabilities"); 1870 dentry = d_alloc_name(sb->s_root, "policy_capabilities");
1897 if (!dentry) { 1871 if (!dentry)
1898 ret = -ENOMEM;
1899 goto err; 1872 goto err;
1900 }
1901 1873
1902 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1874 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1903 if (ret) 1875 if (ret)
@@ -1905,12 +1877,11 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1905 1877
1906 policycap_dir = dentry; 1878 policycap_dir = dentry;
1907 1879
1908out: 1880 return 0;
1909 return ret;
1910err: 1881err:
1911 printk(KERN_ERR "SELinux: %s: failed while creating inodes\n", 1882 printk(KERN_ERR "SELinux: %s: failed while creating inodes\n",
1912 __func__); 1883 __func__);
1913 goto out; 1884 return ret;
1914} 1885}
1915 1886
1916static struct dentry *sel_mount(struct file_system_type *fs_type, 1887static struct dentry *sel_mount(struct file_system_type *fs_type,
@@ -1934,14 +1905,16 @@ static int __init init_sel_fs(void)
1934 if (!selinux_enabled) 1905 if (!selinux_enabled)
1935 return 0; 1906 return 0;
1936 err = register_filesystem(&sel_fs_type); 1907 err = register_filesystem(&sel_fs_type);
1937 if (!err) { 1908 if (err)
1938 selinuxfs_mount = kern_mount(&sel_fs_type); 1909 return err;
1939 if (IS_ERR(selinuxfs_mount)) { 1910
1940 printk(KERN_ERR "selinuxfs: could not mount!\n"); 1911 selinuxfs_mount = kern_mount(&sel_fs_type);
1941 err = PTR_ERR(selinuxfs_mount); 1912 if (IS_ERR(selinuxfs_mount)) {
1942 selinuxfs_mount = NULL; 1913 printk(KERN_ERR "selinuxfs: could not mount!\n");
1943 } 1914 err = PTR_ERR(selinuxfs_mount);
1915 selinuxfs_mount = NULL;
1944 } 1916 }
1917
1945 return err; 1918 return err;
1946} 1919}
1947 1920
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index 655fe1c6cc69..c3f845cbcd48 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -193,6 +193,7 @@ int cond_index_bool(void *key, void *datum, void *datap)
193{ 193{
194 struct policydb *p; 194 struct policydb *p;
195 struct cond_bool_datum *booldatum; 195 struct cond_bool_datum *booldatum;
196 struct flex_array *fa;
196 197
197 booldatum = datum; 198 booldatum = datum;
198 p = datap; 199 p = datap;
@@ -200,7 +201,10 @@ int cond_index_bool(void *key, void *datum, void *datap)
200 if (!booldatum->value || booldatum->value > p->p_bools.nprim) 201 if (!booldatum->value || booldatum->value > p->p_bools.nprim)
201 return -EINVAL; 202 return -EINVAL;
202 203
203 p->p_bool_val_to_name[booldatum->value - 1] = key; 204 fa = p->sym_val_to_name[SYM_BOOLS];
205 if (flex_array_put_ptr(fa, booldatum->value - 1, key,
206 GFP_KERNEL | __GFP_ZERO))
207 BUG();
204 p->bool_val_to_struct[booldatum->value - 1] = booldatum; 208 p->bool_val_to_struct[booldatum->value - 1] = booldatum;
205 209
206 return 0; 210 return 0;
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index b4eff7a60c50..1ef8e4e89880 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -45,7 +45,7 @@ int mls_compute_context_len(struct context *context)
45 len = 1; /* for the beginning ":" */ 45 len = 1; /* for the beginning ":" */
46 for (l = 0; l < 2; l++) { 46 for (l = 0; l < 2; l++) {
47 int index_sens = context->range.level[l].sens; 47 int index_sens = context->range.level[l].sens;
48 len += strlen(policydb.p_sens_val_to_name[index_sens - 1]); 48 len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1));
49 49
50 /* categories */ 50 /* categories */
51 head = -2; 51 head = -2;
@@ -55,17 +55,17 @@ int mls_compute_context_len(struct context *context)
55 if (i - prev > 1) { 55 if (i - prev > 1) {
56 /* one or more negative bits are skipped */ 56 /* one or more negative bits are skipped */
57 if (head != prev) { 57 if (head != prev) {
58 nm = policydb.p_cat_val_to_name[prev]; 58 nm = sym_name(&policydb, SYM_CATS, prev);
59 len += strlen(nm) + 1; 59 len += strlen(nm) + 1;
60 } 60 }
61 nm = policydb.p_cat_val_to_name[i]; 61 nm = sym_name(&policydb, SYM_CATS, i);
62 len += strlen(nm) + 1; 62 len += strlen(nm) + 1;
63 head = i; 63 head = i;
64 } 64 }
65 prev = i; 65 prev = i;
66 } 66 }
67 if (prev != head) { 67 if (prev != head) {
68 nm = policydb.p_cat_val_to_name[prev]; 68 nm = sym_name(&policydb, SYM_CATS, prev);
69 len += strlen(nm) + 1; 69 len += strlen(nm) + 1;
70 } 70 }
71 if (l == 0) { 71 if (l == 0) {
@@ -102,8 +102,8 @@ void mls_sid_to_context(struct context *context,
102 scontextp++; 102 scontextp++;
103 103
104 for (l = 0; l < 2; l++) { 104 for (l = 0; l < 2; l++) {
105 strcpy(scontextp, 105 strcpy(scontextp, sym_name(&policydb, SYM_LEVELS,
106 policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 106 context->range.level[l].sens - 1));
107 scontextp += strlen(scontextp); 107 scontextp += strlen(scontextp);
108 108
109 /* categories */ 109 /* categories */
@@ -118,7 +118,7 @@ void mls_sid_to_context(struct context *context,
118 *scontextp++ = '.'; 118 *scontextp++ = '.';
119 else 119 else
120 *scontextp++ = ','; 120 *scontextp++ = ',';
121 nm = policydb.p_cat_val_to_name[prev]; 121 nm = sym_name(&policydb, SYM_CATS, prev);
122 strcpy(scontextp, nm); 122 strcpy(scontextp, nm);
123 scontextp += strlen(nm); 123 scontextp += strlen(nm);
124 } 124 }
@@ -126,7 +126,7 @@ void mls_sid_to_context(struct context *context,
126 *scontextp++ = ':'; 126 *scontextp++ = ':';
127 else 127 else
128 *scontextp++ = ','; 128 *scontextp++ = ',';
129 nm = policydb.p_cat_val_to_name[i]; 129 nm = sym_name(&policydb, SYM_CATS, i);
130 strcpy(scontextp, nm); 130 strcpy(scontextp, nm);
131 scontextp += strlen(nm); 131 scontextp += strlen(nm);
132 head = i; 132 head = i;
@@ -139,7 +139,7 @@ void mls_sid_to_context(struct context *context,
139 *scontextp++ = '.'; 139 *scontextp++ = '.';
140 else 140 else
141 *scontextp++ = ','; 141 *scontextp++ = ',';
142 nm = policydb.p_cat_val_to_name[prev]; 142 nm = sym_name(&policydb, SYM_CATS, prev);
143 strcpy(scontextp, nm); 143 strcpy(scontextp, nm);
144 scontextp += strlen(nm); 144 scontextp += strlen(nm);
145 } 145 }
@@ -166,7 +166,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
166 if (!l->sens || l->sens > p->p_levels.nprim) 166 if (!l->sens || l->sens > p->p_levels.nprim)
167 return 0; 167 return 0;
168 levdatum = hashtab_search(p->p_levels.table, 168 levdatum = hashtab_search(p->p_levels.table,
169 p->p_sens_val_to_name[l->sens - 1]); 169 sym_name(p, SYM_LEVELS, l->sens - 1));
170 if (!levdatum) 170 if (!levdatum)
171 return 0; 171 return 0;
172 172
@@ -482,7 +482,8 @@ int mls_convert_context(struct policydb *oldp,
482 482
483 for (l = 0; l < 2; l++) { 483 for (l = 0; l < 2; l++) {
484 levdatum = hashtab_search(newp->p_levels.table, 484 levdatum = hashtab_search(newp->p_levels.table,
485 oldp->p_sens_val_to_name[c->range.level[l].sens - 1]); 485 sym_name(oldp, SYM_LEVELS,
486 c->range.level[l].sens - 1));
486 487
487 if (!levdatum) 488 if (!levdatum)
488 return -EINVAL; 489 return -EINVAL;
@@ -493,7 +494,7 @@ int mls_convert_context(struct policydb *oldp,
493 int rc; 494 int rc;
494 495
495 catdatum = hashtab_search(newp->p_cats.table, 496 catdatum = hashtab_search(newp->p_cats.table,
496 oldp->p_cat_val_to_name[i]); 497 sym_name(oldp, SYM_CATS, i));
497 if (!catdatum) 498 if (!catdatum)
498 return -EINVAL; 499 return -EINVAL;
499 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 500 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 94f630d93a5c..be9de3872837 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -148,32 +148,30 @@ static int roles_init(struct policydb *p)
148 int rc; 148 int rc;
149 struct role_datum *role; 149 struct role_datum *role;
150 150
151 rc = -ENOMEM;
151 role = kzalloc(sizeof(*role), GFP_KERNEL); 152 role = kzalloc(sizeof(*role), GFP_KERNEL);
152 if (!role) { 153 if (!role)
153 rc = -ENOMEM;
154 goto out; 154 goto out;
155 } 155
156 rc = -EINVAL;
156 role->value = ++p->p_roles.nprim; 157 role->value = ++p->p_roles.nprim;
157 if (role->value != OBJECT_R_VAL) { 158 if (role->value != OBJECT_R_VAL)
158 rc = -EINVAL; 159 goto out;
159 goto out_free_role; 160
160 } 161 rc = -ENOMEM;
161 key = kstrdup(OBJECT_R, GFP_KERNEL); 162 key = kstrdup(OBJECT_R, GFP_KERNEL);
162 if (!key) { 163 if (!key)
163 rc = -ENOMEM; 164 goto out;
164 goto out_free_role; 165
165 }
166 rc = hashtab_insert(p->p_roles.table, key, role); 166 rc = hashtab_insert(p->p_roles.table, key, role);
167 if (rc) 167 if (rc)
168 goto out_free_key; 168 goto out;
169out:
170 return rc;
171 169
172out_free_key: 170 return 0;
171out:
173 kfree(key); 172 kfree(key);
174out_free_role:
175 kfree(role); 173 kfree(role);
176 goto out; 174 return rc;
177} 175}
178 176
179static u32 rangetr_hash(struct hashtab *h, const void *k) 177static u32 rangetr_hash(struct hashtab *h, const void *k)
@@ -213,35 +211,33 @@ static int policydb_init(struct policydb *p)
213 for (i = 0; i < SYM_NUM; i++) { 211 for (i = 0; i < SYM_NUM; i++) {
214 rc = symtab_init(&p->symtab[i], symtab_sizes[i]); 212 rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
215 if (rc) 213 if (rc)
216 goto out_free_symtab; 214 goto out;
217 } 215 }
218 216
219 rc = avtab_init(&p->te_avtab); 217 rc = avtab_init(&p->te_avtab);
220 if (rc) 218 if (rc)
221 goto out_free_symtab; 219 goto out;
222 220
223 rc = roles_init(p); 221 rc = roles_init(p);
224 if (rc) 222 if (rc)
225 goto out_free_symtab; 223 goto out;
226 224
227 rc = cond_policydb_init(p); 225 rc = cond_policydb_init(p);
228 if (rc) 226 if (rc)
229 goto out_free_symtab; 227 goto out;
230 228
231 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); 229 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
232 if (!p->range_tr) 230 if (!p->range_tr)
233 goto out_free_symtab; 231 goto out;
234 232
235 ebitmap_init(&p->policycaps); 233 ebitmap_init(&p->policycaps);
236 ebitmap_init(&p->permissive_map); 234 ebitmap_init(&p->permissive_map);
237 235
236 return 0;
238out: 237out:
239 return rc;
240
241out_free_symtab:
242 for (i = 0; i < SYM_NUM; i++) 238 for (i = 0; i < SYM_NUM; i++)
243 hashtab_destroy(p->symtab[i].table); 239 hashtab_destroy(p->symtab[i].table);
244 goto out; 240 return rc;
245} 241}
246 242
247/* 243/*
@@ -258,12 +254,17 @@ static int common_index(void *key, void *datum, void *datap)
258{ 254{
259 struct policydb *p; 255 struct policydb *p;
260 struct common_datum *comdatum; 256 struct common_datum *comdatum;
257 struct flex_array *fa;
261 258
262 comdatum = datum; 259 comdatum = datum;
263 p = datap; 260 p = datap;
264 if (!comdatum->value || comdatum->value > p->p_commons.nprim) 261 if (!comdatum->value || comdatum->value > p->p_commons.nprim)
265 return -EINVAL; 262 return -EINVAL;
266 p->p_common_val_to_name[comdatum->value - 1] = key; 263
264 fa = p->sym_val_to_name[SYM_COMMONS];
265 if (flex_array_put_ptr(fa, comdatum->value - 1, key,
266 GFP_KERNEL | __GFP_ZERO))
267 BUG();
267 return 0; 268 return 0;
268} 269}
269 270
@@ -271,12 +272,16 @@ static int class_index(void *key, void *datum, void *datap)
271{ 272{
272 struct policydb *p; 273 struct policydb *p;
273 struct class_datum *cladatum; 274 struct class_datum *cladatum;
275 struct flex_array *fa;
274 276
275 cladatum = datum; 277 cladatum = datum;
276 p = datap; 278 p = datap;
277 if (!cladatum->value || cladatum->value > p->p_classes.nprim) 279 if (!cladatum->value || cladatum->value > p->p_classes.nprim)
278 return -EINVAL; 280 return -EINVAL;
279 p->p_class_val_to_name[cladatum->value - 1] = key; 281 fa = p->sym_val_to_name[SYM_CLASSES];
282 if (flex_array_put_ptr(fa, cladatum->value - 1, key,
283 GFP_KERNEL | __GFP_ZERO))
284 BUG();
280 p->class_val_to_struct[cladatum->value - 1] = cladatum; 285 p->class_val_to_struct[cladatum->value - 1] = cladatum;
281 return 0; 286 return 0;
282} 287}
@@ -285,6 +290,7 @@ static int role_index(void *key, void *datum, void *datap)
285{ 290{
286 struct policydb *p; 291 struct policydb *p;
287 struct role_datum *role; 292 struct role_datum *role;
293 struct flex_array *fa;
288 294
289 role = datum; 295 role = datum;
290 p = datap; 296 p = datap;
@@ -292,7 +298,11 @@ static int role_index(void *key, void *datum, void *datap)
292 || role->value > p->p_roles.nprim 298 || role->value > p->p_roles.nprim
293 || role->bounds > p->p_roles.nprim) 299 || role->bounds > p->p_roles.nprim)
294 return -EINVAL; 300 return -EINVAL;
295 p->p_role_val_to_name[role->value - 1] = key; 301
302 fa = p->sym_val_to_name[SYM_ROLES];
303 if (flex_array_put_ptr(fa, role->value - 1, key,
304 GFP_KERNEL | __GFP_ZERO))
305 BUG();
296 p->role_val_to_struct[role->value - 1] = role; 306 p->role_val_to_struct[role->value - 1] = role;
297 return 0; 307 return 0;
298} 308}
@@ -301,6 +311,7 @@ static int type_index(void *key, void *datum, void *datap)
301{ 311{
302 struct policydb *p; 312 struct policydb *p;
303 struct type_datum *typdatum; 313 struct type_datum *typdatum;
314 struct flex_array *fa;
304 315
305 typdatum = datum; 316 typdatum = datum;
306 p = datap; 317 p = datap;
@@ -310,8 +321,15 @@ static int type_index(void *key, void *datum, void *datap)
310 || typdatum->value > p->p_types.nprim 321 || typdatum->value > p->p_types.nprim
311 || typdatum->bounds > p->p_types.nprim) 322 || typdatum->bounds > p->p_types.nprim)
312 return -EINVAL; 323 return -EINVAL;
313 p->p_type_val_to_name[typdatum->value - 1] = key; 324 fa = p->sym_val_to_name[SYM_TYPES];
314 p->type_val_to_struct[typdatum->value - 1] = typdatum; 325 if (flex_array_put_ptr(fa, typdatum->value - 1, key,
326 GFP_KERNEL | __GFP_ZERO))
327 BUG();
328
329 fa = p->type_val_to_struct_array;
330 if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum,
331 GFP_KERNEL | __GFP_ZERO))
332 BUG();
315 } 333 }
316 334
317 return 0; 335 return 0;
@@ -321,6 +339,7 @@ static int user_index(void *key, void *datum, void *datap)
321{ 339{
322 struct policydb *p; 340 struct policydb *p;
323 struct user_datum *usrdatum; 341 struct user_datum *usrdatum;
342 struct flex_array *fa;
324 343
325 usrdatum = datum; 344 usrdatum = datum;
326 p = datap; 345 p = datap;
@@ -328,7 +347,11 @@ static int user_index(void *key, void *datum, void *datap)
328 || usrdatum->value > p->p_users.nprim 347 || usrdatum->value > p->p_users.nprim
329 || usrdatum->bounds > p->p_users.nprim) 348 || usrdatum->bounds > p->p_users.nprim)
330 return -EINVAL; 349 return -EINVAL;
331 p->p_user_val_to_name[usrdatum->value - 1] = key; 350
351 fa = p->sym_val_to_name[SYM_USERS];
352 if (flex_array_put_ptr(fa, usrdatum->value - 1, key,
353 GFP_KERNEL | __GFP_ZERO))
354 BUG();
332 p->user_val_to_struct[usrdatum->value - 1] = usrdatum; 355 p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
333 return 0; 356 return 0;
334} 357}
@@ -337,6 +360,7 @@ static int sens_index(void *key, void *datum, void *datap)
337{ 360{
338 struct policydb *p; 361 struct policydb *p;
339 struct level_datum *levdatum; 362 struct level_datum *levdatum;
363 struct flex_array *fa;
340 364
341 levdatum = datum; 365 levdatum = datum;
342 p = datap; 366 p = datap;
@@ -345,7 +369,10 @@ static int sens_index(void *key, void *datum, void *datap)
345 if (!levdatum->level->sens || 369 if (!levdatum->level->sens ||
346 levdatum->level->sens > p->p_levels.nprim) 370 levdatum->level->sens > p->p_levels.nprim)
347 return -EINVAL; 371 return -EINVAL;
348 p->p_sens_val_to_name[levdatum->level->sens - 1] = key; 372 fa = p->sym_val_to_name[SYM_LEVELS];
373 if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key,
374 GFP_KERNEL | __GFP_ZERO))
375 BUG();
349 } 376 }
350 377
351 return 0; 378 return 0;
@@ -355,6 +382,7 @@ static int cat_index(void *key, void *datum, void *datap)
355{ 382{
356 struct policydb *p; 383 struct policydb *p;
357 struct cat_datum *catdatum; 384 struct cat_datum *catdatum;
385 struct flex_array *fa;
358 386
359 catdatum = datum; 387 catdatum = datum;
360 p = datap; 388 p = datap;
@@ -362,7 +390,10 @@ static int cat_index(void *key, void *datum, void *datap)
362 if (!catdatum->isalias) { 390 if (!catdatum->isalias) {
363 if (!catdatum->value || catdatum->value > p->p_cats.nprim) 391 if (!catdatum->value || catdatum->value > p->p_cats.nprim)
364 return -EINVAL; 392 return -EINVAL;
365 p->p_cat_val_to_name[catdatum->value - 1] = key; 393 fa = p->sym_val_to_name[SYM_CATS];
394 if (flex_array_put_ptr(fa, catdatum->value - 1, key,
395 GFP_KERNEL | __GFP_ZERO))
396 BUG();
366 } 397 }
367 398
368 return 0; 399 return 0;
@@ -380,47 +411,6 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
380 cat_index, 411 cat_index,
381}; 412};
382 413
383/*
384 * Define the common val_to_name array and the class
385 * val_to_name and val_to_struct arrays in a policy
386 * database structure.
387 *
388 * Caller must clean up upon failure.
389 */
390static int policydb_index_classes(struct policydb *p)
391{
392 int rc;
393
394 p->p_common_val_to_name =
395 kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL);
396 if (!p->p_common_val_to_name) {
397 rc = -ENOMEM;
398 goto out;
399 }
400
401 rc = hashtab_map(p->p_commons.table, common_index, p);
402 if (rc)
403 goto out;
404
405 p->class_val_to_struct =
406 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL);
407 if (!p->class_val_to_struct) {
408 rc = -ENOMEM;
409 goto out;
410 }
411
412 p->p_class_val_to_name =
413 kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL);
414 if (!p->p_class_val_to_name) {
415 rc = -ENOMEM;
416 goto out;
417 }
418
419 rc = hashtab_map(p->p_classes.table, class_index, p);
420out:
421 return rc;
422}
423
424#ifdef DEBUG_HASHES 414#ifdef DEBUG_HASHES
425static void symtab_hash_eval(struct symtab *s) 415static void symtab_hash_eval(struct symtab *s)
426{ 416{
@@ -458,9 +448,9 @@ static inline void rangetr_hash_eval(struct hashtab *h)
458 * 448 *
459 * Caller must clean up on failure. 449 * Caller must clean up on failure.
460 */ 450 */
461static int policydb_index_others(struct policydb *p) 451static int policydb_index(struct policydb *p)
462{ 452{
463 int i, rc = 0; 453 int i, rc;
464 454
465 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", 455 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools",
466 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); 456 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
@@ -477,47 +467,63 @@ static int policydb_index_others(struct policydb *p)
477 symtab_hash_eval(p->symtab); 467 symtab_hash_eval(p->symtab);
478#endif 468#endif
479 469
470 rc = -ENOMEM;
471 p->class_val_to_struct =
472 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)),
473 GFP_KERNEL);
474 if (!p->class_val_to_struct)
475 goto out;
476
477 rc = -ENOMEM;
480 p->role_val_to_struct = 478 p->role_val_to_struct =
481 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), 479 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
482 GFP_KERNEL); 480 GFP_KERNEL);
483 if (!p->role_val_to_struct) { 481 if (!p->role_val_to_struct)
484 rc = -ENOMEM;
485 goto out; 482 goto out;
486 }
487 483
484 rc = -ENOMEM;
488 p->user_val_to_struct = 485 p->user_val_to_struct =
489 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), 486 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
490 GFP_KERNEL); 487 GFP_KERNEL);
491 if (!p->user_val_to_struct) { 488 if (!p->user_val_to_struct)
492 rc = -ENOMEM;
493 goto out; 489 goto out;
494 }
495 490
496 p->type_val_to_struct = 491 /* Yes, I want the sizeof the pointer, not the structure */
497 kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)), 492 rc = -ENOMEM;
498 GFP_KERNEL); 493 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *),
499 if (!p->type_val_to_struct) { 494 p->p_types.nprim,
500 rc = -ENOMEM; 495 GFP_KERNEL | __GFP_ZERO);
496 if (!p->type_val_to_struct_array)
501 goto out; 497 goto out;
502 }
503 498
504 if (cond_init_bool_indexes(p)) { 499 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
505 rc = -ENOMEM; 500 p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO);
501 if (rc)
506 goto out; 502 goto out;
507 }
508 503
509 for (i = SYM_ROLES; i < SYM_NUM; i++) { 504 rc = -ENOMEM;
510 p->sym_val_to_name[i] = 505 if (cond_init_bool_indexes(p))
511 kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); 506 goto out;
512 if (!p->sym_val_to_name[i]) { 507
513 rc = -ENOMEM; 508 for (i = 0; i < SYM_NUM; i++) {
509 rc = -ENOMEM;
510 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *),
511 p->symtab[i].nprim,
512 GFP_KERNEL | __GFP_ZERO);
513 if (!p->sym_val_to_name[i])
514 goto out; 514 goto out;
515 } 515
516 rc = flex_array_prealloc(p->sym_val_to_name[i],
517 0, p->symtab[i].nprim - 1,
518 GFP_KERNEL | __GFP_ZERO);
519 if (rc)
520 goto out;
521
516 rc = hashtab_map(p->symtab[i].table, index_f[i], p); 522 rc = hashtab_map(p->symtab[i].table, index_f[i], p);
517 if (rc) 523 if (rc)
518 goto out; 524 goto out;
519 } 525 }
520 526 rc = 0;
521out: 527out:
522 return rc; 528 return rc;
523} 529}
@@ -540,9 +546,11 @@ static int common_destroy(void *key, void *datum, void *p)
540 struct common_datum *comdatum; 546 struct common_datum *comdatum;
541 547
542 kfree(key); 548 kfree(key);
543 comdatum = datum; 549 if (datum) {
544 hashtab_map(comdatum->permissions.table, perm_destroy, NULL); 550 comdatum = datum;
545 hashtab_destroy(comdatum->permissions.table); 551 hashtab_map(comdatum->permissions.table, perm_destroy, NULL);
552 hashtab_destroy(comdatum->permissions.table);
553 }
546 kfree(datum); 554 kfree(datum);
547 return 0; 555 return 0;
548} 556}
@@ -554,38 +562,40 @@ static int cls_destroy(void *key, void *datum, void *p)
554 struct constraint_expr *e, *etmp; 562 struct constraint_expr *e, *etmp;
555 563
556 kfree(key); 564 kfree(key);
557 cladatum = datum; 565 if (datum) {
558 hashtab_map(cladatum->permissions.table, perm_destroy, NULL); 566 cladatum = datum;
559 hashtab_destroy(cladatum->permissions.table); 567 hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
560 constraint = cladatum->constraints; 568 hashtab_destroy(cladatum->permissions.table);
561 while (constraint) { 569 constraint = cladatum->constraints;
562 e = constraint->expr; 570 while (constraint) {
563 while (e) { 571 e = constraint->expr;
564 ebitmap_destroy(&e->names); 572 while (e) {
565 etmp = e; 573 ebitmap_destroy(&e->names);
566 e = e->next; 574 etmp = e;
567 kfree(etmp); 575 e = e->next;
576 kfree(etmp);
577 }
578 ctemp = constraint;
579 constraint = constraint->next;
580 kfree(ctemp);
568 } 581 }
569 ctemp = constraint; 582
570 constraint = constraint->next; 583 constraint = cladatum->validatetrans;
571 kfree(ctemp); 584 while (constraint) {
572 } 585 e = constraint->expr;
573 586 while (e) {
574 constraint = cladatum->validatetrans; 587 ebitmap_destroy(&e->names);
575 while (constraint) { 588 etmp = e;
576 e = constraint->expr; 589 e = e->next;
577 while (e) { 590 kfree(etmp);
578 ebitmap_destroy(&e->names); 591 }
579 etmp = e; 592 ctemp = constraint;
580 e = e->next; 593 constraint = constraint->next;
581 kfree(etmp); 594 kfree(ctemp);
582 } 595 }
583 ctemp = constraint;
584 constraint = constraint->next;
585 kfree(ctemp);
586 }
587 596
588 kfree(cladatum->comkey); 597 kfree(cladatum->comkey);
598 }
589 kfree(datum); 599 kfree(datum);
590 return 0; 600 return 0;
591} 601}
@@ -595,9 +605,11 @@ static int role_destroy(void *key, void *datum, void *p)
595 struct role_datum *role; 605 struct role_datum *role;
596 606
597 kfree(key); 607 kfree(key);
598 role = datum; 608 if (datum) {
599 ebitmap_destroy(&role->dominates); 609 role = datum;
600 ebitmap_destroy(&role->types); 610 ebitmap_destroy(&role->dominates);
611 ebitmap_destroy(&role->types);
612 }
601 kfree(datum); 613 kfree(datum);
602 return 0; 614 return 0;
603} 615}
@@ -614,11 +626,13 @@ static int user_destroy(void *key, void *datum, void *p)
614 struct user_datum *usrdatum; 626 struct user_datum *usrdatum;
615 627
616 kfree(key); 628 kfree(key);
617 usrdatum = datum; 629 if (datum) {
618 ebitmap_destroy(&usrdatum->roles); 630 usrdatum = datum;
619 ebitmap_destroy(&usrdatum->range.level[0].cat); 631 ebitmap_destroy(&usrdatum->roles);
620 ebitmap_destroy(&usrdatum->range.level[1].cat); 632 ebitmap_destroy(&usrdatum->range.level[0].cat);
621 ebitmap_destroy(&usrdatum->dfltlevel.cat); 633 ebitmap_destroy(&usrdatum->range.level[1].cat);
634 ebitmap_destroy(&usrdatum->dfltlevel.cat);
635 }
622 kfree(datum); 636 kfree(datum);
623 return 0; 637 return 0;
624} 638}
@@ -628,9 +642,11 @@ static int sens_destroy(void *key, void *datum, void *p)
628 struct level_datum *levdatum; 642 struct level_datum *levdatum;
629 643
630 kfree(key); 644 kfree(key);
631 levdatum = datum; 645 if (datum) {
632 ebitmap_destroy(&levdatum->level->cat); 646 levdatum = datum;
633 kfree(levdatum->level); 647 ebitmap_destroy(&levdatum->level->cat);
648 kfree(levdatum->level);
649 }
634 kfree(datum); 650 kfree(datum);
635 return 0; 651 return 0;
636} 652}
@@ -695,13 +711,16 @@ void policydb_destroy(struct policydb *p)
695 hashtab_destroy(p->symtab[i].table); 711 hashtab_destroy(p->symtab[i].table);
696 } 712 }
697 713
698 for (i = 0; i < SYM_NUM; i++) 714 for (i = 0; i < SYM_NUM; i++) {
699 kfree(p->sym_val_to_name[i]); 715 if (p->sym_val_to_name[i])
716 flex_array_free(p->sym_val_to_name[i]);
717 }
700 718
701 kfree(p->class_val_to_struct); 719 kfree(p->class_val_to_struct);
702 kfree(p->role_val_to_struct); 720 kfree(p->role_val_to_struct);
703 kfree(p->user_val_to_struct); 721 kfree(p->user_val_to_struct);
704 kfree(p->type_val_to_struct); 722 if (p->type_val_to_struct_array)
723 flex_array_free(p->type_val_to_struct_array);
705 724
706 avtab_destroy(&p->te_avtab); 725 avtab_destroy(&p->te_avtab);
707 726
@@ -785,19 +804,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
785 804
786 head = p->ocontexts[OCON_ISID]; 805 head = p->ocontexts[OCON_ISID];
787 for (c = head; c; c = c->next) { 806 for (c = head; c; c = c->next) {
807 rc = -EINVAL;
788 if (!c->context[0].user) { 808 if (!c->context[0].user) {
789 printk(KERN_ERR "SELinux: SID %s was never " 809 printk(KERN_ERR "SELinux: SID %s was never defined.\n",
790 "defined.\n", c->u.name); 810 c->u.name);
791 rc = -EINVAL;
792 goto out; 811 goto out;
793 } 812 }
794 if (sidtab_insert(s, c->sid[0], &c->context[0])) { 813
795 printk(KERN_ERR "SELinux: unable to load initial " 814 rc = sidtab_insert(s, c->sid[0], &c->context[0]);
796 "SID %s.\n", c->u.name); 815 if (rc) {
797 rc = -EINVAL; 816 printk(KERN_ERR "SELinux: unable to load initial SID %s.\n",
817 c->u.name);
798 goto out; 818 goto out;
799 } 819 }
800 } 820 }
821 rc = 0;
801out: 822out:
802 return rc; 823 return rc;
803} 824}
@@ -846,8 +867,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
846 * Role must be authorized for the type. 867 * Role must be authorized for the type.
847 */ 868 */
848 role = p->role_val_to_struct[c->role - 1]; 869 role = p->role_val_to_struct[c->role - 1];
849 if (!ebitmap_get_bit(&role->types, 870 if (!ebitmap_get_bit(&role->types, c->type - 1))
850 c->type - 1))
851 /* role may not be associated with type */ 871 /* role may not be associated with type */
852 return 0; 872 return 0;
853 873
@@ -858,8 +878,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
858 if (!usrdatum) 878 if (!usrdatum)
859 return 0; 879 return 0;
860 880
861 if (!ebitmap_get_bit(&usrdatum->roles, 881 if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1))
862 c->role - 1))
863 /* user may not be associated with role */ 882 /* user may not be associated with role */
864 return 0; 883 return 0;
865 } 884 }
@@ -881,20 +900,22 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
881 int rc; 900 int rc;
882 901
883 rc = next_entry(buf, fp, sizeof(u32)); 902 rc = next_entry(buf, fp, sizeof(u32));
884 if (rc < 0) 903 if (rc)
885 goto out; 904 goto out;
886 905
906 rc = -EINVAL;
887 items = le32_to_cpu(buf[0]); 907 items = le32_to_cpu(buf[0]);
888 if (items > ARRAY_SIZE(buf)) { 908 if (items > ARRAY_SIZE(buf)) {
889 printk(KERN_ERR "SELinux: mls: range overflow\n"); 909 printk(KERN_ERR "SELinux: mls: range overflow\n");
890 rc = -EINVAL;
891 goto out; 910 goto out;
892 } 911 }
912
893 rc = next_entry(buf, fp, sizeof(u32) * items); 913 rc = next_entry(buf, fp, sizeof(u32) * items);
894 if (rc < 0) { 914 if (rc) {
895 printk(KERN_ERR "SELinux: mls: truncated range\n"); 915 printk(KERN_ERR "SELinux: mls: truncated range\n");
896 goto out; 916 goto out;
897 } 917 }
918
898 r->level[0].sens = le32_to_cpu(buf[0]); 919 r->level[0].sens = le32_to_cpu(buf[0]);
899 if (items > 1) 920 if (items > 1)
900 r->level[1].sens = le32_to_cpu(buf[1]); 921 r->level[1].sens = le32_to_cpu(buf[1]);
@@ -903,15 +924,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
903 924
904 rc = ebitmap_read(&r->level[0].cat, fp); 925 rc = ebitmap_read(&r->level[0].cat, fp);
905 if (rc) { 926 if (rc) {
906 printk(KERN_ERR "SELinux: mls: error reading low " 927 printk(KERN_ERR "SELinux: mls: error reading low categories\n");
907 "categories\n");
908 goto out; 928 goto out;
909 } 929 }
910 if (items > 1) { 930 if (items > 1) {
911 rc = ebitmap_read(&r->level[1].cat, fp); 931 rc = ebitmap_read(&r->level[1].cat, fp);
912 if (rc) { 932 if (rc) {
913 printk(KERN_ERR "SELinux: mls: error reading high " 933 printk(KERN_ERR "SELinux: mls: error reading high categories\n");
914 "categories\n");
915 goto bad_high; 934 goto bad_high;
916 } 935 }
917 } else { 936 } else {
@@ -922,12 +941,11 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
922 } 941 }
923 } 942 }
924 943
925 rc = 0; 944 return 0;
926out:
927 return rc;
928bad_high: 945bad_high:
929 ebitmap_destroy(&r->level[0].cat); 946 ebitmap_destroy(&r->level[0].cat);
930 goto out; 947out:
948 return rc;
931} 949}
932 950
933/* 951/*
@@ -942,7 +960,7 @@ static int context_read_and_validate(struct context *c,
942 int rc; 960 int rc;
943 961
944 rc = next_entry(buf, fp, sizeof buf); 962 rc = next_entry(buf, fp, sizeof buf);
945 if (rc < 0) { 963 if (rc) {
946 printk(KERN_ERR "SELinux: context truncated\n"); 964 printk(KERN_ERR "SELinux: context truncated\n");
947 goto out; 965 goto out;
948 } 966 }
@@ -950,19 +968,20 @@ static int context_read_and_validate(struct context *c,
950 c->role = le32_to_cpu(buf[1]); 968 c->role = le32_to_cpu(buf[1]);
951 c->type = le32_to_cpu(buf[2]); 969 c->type = le32_to_cpu(buf[2]);
952 if (p->policyvers >= POLICYDB_VERSION_MLS) { 970 if (p->policyvers >= POLICYDB_VERSION_MLS) {
953 if (mls_read_range_helper(&c->range, fp)) { 971 rc = mls_read_range_helper(&c->range, fp);
954 printk(KERN_ERR "SELinux: error reading MLS range of " 972 if (rc) {
955 "context\n"); 973 printk(KERN_ERR "SELinux: error reading MLS range of context\n");
956 rc = -EINVAL;
957 goto out; 974 goto out;
958 } 975 }
959 } 976 }
960 977
978 rc = -EINVAL;
961 if (!policydb_context_isvalid(p, c)) { 979 if (!policydb_context_isvalid(p, c)) {
962 printk(KERN_ERR "SELinux: invalid security context\n"); 980 printk(KERN_ERR "SELinux: invalid security context\n");
963 context_destroy(c); 981 context_destroy(c);
964 rc = -EINVAL; 982 goto out;
965 } 983 }
984 rc = 0;
966out: 985out:
967 return rc; 986 return rc;
968} 987}
@@ -981,37 +1000,36 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
981 __le32 buf[2]; 1000 __le32 buf[2];
982 u32 len; 1001 u32 len;
983 1002
1003 rc = -ENOMEM;
984 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); 1004 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
985 if (!perdatum) { 1005 if (!perdatum)
986 rc = -ENOMEM; 1006 goto bad;
987 goto out;
988 }
989 1007
990 rc = next_entry(buf, fp, sizeof buf); 1008 rc = next_entry(buf, fp, sizeof buf);
991 if (rc < 0) 1009 if (rc)
992 goto bad; 1010 goto bad;
993 1011
994 len = le32_to_cpu(buf[0]); 1012 len = le32_to_cpu(buf[0]);
995 perdatum->value = le32_to_cpu(buf[1]); 1013 perdatum->value = le32_to_cpu(buf[1]);
996 1014
1015 rc = -ENOMEM;
997 key = kmalloc(len + 1, GFP_KERNEL); 1016 key = kmalloc(len + 1, GFP_KERNEL);
998 if (!key) { 1017 if (!key)
999 rc = -ENOMEM;
1000 goto bad; 1018 goto bad;
1001 } 1019
1002 rc = next_entry(key, fp, len); 1020 rc = next_entry(key, fp, len);
1003 if (rc < 0) 1021 if (rc)
1004 goto bad; 1022 goto bad;
1005 key[len] = '\0'; 1023 key[len] = '\0';
1006 1024
1007 rc = hashtab_insert(h, key, perdatum); 1025 rc = hashtab_insert(h, key, perdatum);
1008 if (rc) 1026 if (rc)
1009 goto bad; 1027 goto bad;
1010out: 1028
1011 return rc; 1029 return 0;
1012bad: 1030bad:
1013 perm_destroy(key, perdatum, NULL); 1031 perm_destroy(key, perdatum, NULL);
1014 goto out; 1032 return rc;
1015} 1033}
1016 1034
1017static int common_read(struct policydb *p, struct hashtab *h, void *fp) 1035static int common_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1022,14 +1040,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1022 u32 len, nel; 1040 u32 len, nel;
1023 int i, rc; 1041 int i, rc;
1024 1042
1043 rc = -ENOMEM;
1025 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); 1044 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
1026 if (!comdatum) { 1045 if (!comdatum)
1027 rc = -ENOMEM; 1046 goto bad;
1028 goto out;
1029 }
1030 1047
1031 rc = next_entry(buf, fp, sizeof buf); 1048 rc = next_entry(buf, fp, sizeof buf);
1032 if (rc < 0) 1049 if (rc)
1033 goto bad; 1050 goto bad;
1034 1051
1035 len = le32_to_cpu(buf[0]); 1052 len = le32_to_cpu(buf[0]);
@@ -1041,13 +1058,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1041 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 1058 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
1042 nel = le32_to_cpu(buf[3]); 1059 nel = le32_to_cpu(buf[3]);
1043 1060
1061 rc = -ENOMEM;
1044 key = kmalloc(len + 1, GFP_KERNEL); 1062 key = kmalloc(len + 1, GFP_KERNEL);
1045 if (!key) { 1063 if (!key)
1046 rc = -ENOMEM;
1047 goto bad; 1064 goto bad;
1048 } 1065
1049 rc = next_entry(key, fp, len); 1066 rc = next_entry(key, fp, len);
1050 if (rc < 0) 1067 if (rc)
1051 goto bad; 1068 goto bad;
1052 key[len] = '\0'; 1069 key[len] = '\0';
1053 1070
@@ -1060,11 +1077,10 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1060 rc = hashtab_insert(h, key, comdatum); 1077 rc = hashtab_insert(h, key, comdatum);
1061 if (rc) 1078 if (rc)
1062 goto bad; 1079 goto bad;
1063out: 1080 return 0;
1064 return rc;
1065bad: 1081bad:
1066 common_destroy(key, comdatum, NULL); 1082 common_destroy(key, comdatum, NULL);
1067 goto out; 1083 return rc;
1068} 1084}
1069 1085
1070static int read_cons_helper(struct constraint_node **nodep, int ncons, 1086static int read_cons_helper(struct constraint_node **nodep, int ncons,
@@ -1088,7 +1104,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1088 *nodep = c; 1104 *nodep = c;
1089 1105
1090 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 1106 rc = next_entry(buf, fp, (sizeof(u32) * 2));
1091 if (rc < 0) 1107 if (rc)
1092 return rc; 1108 return rc;
1093 c->permissions = le32_to_cpu(buf[0]); 1109 c->permissions = le32_to_cpu(buf[0]);
1094 nexpr = le32_to_cpu(buf[1]); 1110 nexpr = le32_to_cpu(buf[1]);
@@ -1105,7 +1121,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1105 c->expr = e; 1121 c->expr = e;
1106 1122
1107 rc = next_entry(buf, fp, (sizeof(u32) * 3)); 1123 rc = next_entry(buf, fp, (sizeof(u32) * 3));
1108 if (rc < 0) 1124 if (rc)
1109 return rc; 1125 return rc;
1110 e->expr_type = le32_to_cpu(buf[0]); 1126 e->expr_type = le32_to_cpu(buf[0]);
1111 e->attr = le32_to_cpu(buf[1]); 1127 e->attr = le32_to_cpu(buf[1]);
@@ -1133,8 +1149,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1133 if (depth == (CEXPR_MAXDEPTH - 1)) 1149 if (depth == (CEXPR_MAXDEPTH - 1))
1134 return -EINVAL; 1150 return -EINVAL;
1135 depth++; 1151 depth++;
1136 if (ebitmap_read(&e->names, fp)) 1152 rc = ebitmap_read(&e->names, fp);
1137 return -EINVAL; 1153 if (rc)
1154 return rc;
1138 break; 1155 break;
1139 default: 1156 default:
1140 return -EINVAL; 1157 return -EINVAL;
@@ -1157,14 +1174,13 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1157 u32 len, len2, ncons, nel; 1174 u32 len, len2, ncons, nel;
1158 int i, rc; 1175 int i, rc;
1159 1176
1177 rc = -ENOMEM;
1160 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); 1178 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
1161 if (!cladatum) { 1179 if (!cladatum)
1162 rc = -ENOMEM; 1180 goto bad;
1163 goto out;
1164 }
1165 1181
1166 rc = next_entry(buf, fp, sizeof(u32)*6); 1182 rc = next_entry(buf, fp, sizeof(u32)*6);
1167 if (rc < 0) 1183 if (rc)
1168 goto bad; 1184 goto bad;
1169 1185
1170 len = le32_to_cpu(buf[0]); 1186 len = le32_to_cpu(buf[0]);
@@ -1179,33 +1195,30 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1179 1195
1180 ncons = le32_to_cpu(buf[5]); 1196 ncons = le32_to_cpu(buf[5]);
1181 1197
1198 rc = -ENOMEM;
1182 key = kmalloc(len + 1, GFP_KERNEL); 1199 key = kmalloc(len + 1, GFP_KERNEL);
1183 if (!key) { 1200 if (!key)
1184 rc = -ENOMEM;
1185 goto bad; 1201 goto bad;
1186 } 1202
1187 rc = next_entry(key, fp, len); 1203 rc = next_entry(key, fp, len);
1188 if (rc < 0) 1204 if (rc)
1189 goto bad; 1205 goto bad;
1190 key[len] = '\0'; 1206 key[len] = '\0';
1191 1207
1192 if (len2) { 1208 if (len2) {
1209 rc = -ENOMEM;
1193 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); 1210 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
1194 if (!cladatum->comkey) { 1211 if (!cladatum->comkey)
1195 rc = -ENOMEM;
1196 goto bad; 1212 goto bad;
1197 }
1198 rc = next_entry(cladatum->comkey, fp, len2); 1213 rc = next_entry(cladatum->comkey, fp, len2);
1199 if (rc < 0) 1214 if (rc)
1200 goto bad; 1215 goto bad;
1201 cladatum->comkey[len2] = '\0'; 1216 cladatum->comkey[len2] = '\0';
1202 1217
1203 cladatum->comdatum = hashtab_search(p->p_commons.table, 1218 rc = -EINVAL;
1204 cladatum->comkey); 1219 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
1205 if (!cladatum->comdatum) { 1220 if (!cladatum->comdatum) {
1206 printk(KERN_ERR "SELinux: unknown common %s\n", 1221 printk(KERN_ERR "SELinux: unknown common %s\n", cladatum->comkey);
1207 cladatum->comkey);
1208 rc = -EINVAL;
1209 goto bad; 1222 goto bad;
1210 } 1223 }
1211 } 1224 }
@@ -1222,7 +1235,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1222 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { 1235 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) {
1223 /* grab the validatetrans rules */ 1236 /* grab the validatetrans rules */
1224 rc = next_entry(buf, fp, sizeof(u32)); 1237 rc = next_entry(buf, fp, sizeof(u32));
1225 if (rc < 0) 1238 if (rc)
1226 goto bad; 1239 goto bad;
1227 ncons = le32_to_cpu(buf[0]); 1240 ncons = le32_to_cpu(buf[0]);
1228 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); 1241 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);
@@ -1234,12 +1247,10 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1234 if (rc) 1247 if (rc)
1235 goto bad; 1248 goto bad;
1236 1249
1237 rc = 0; 1250 return 0;
1238out:
1239 return rc;
1240bad: 1251bad:
1241 cls_destroy(key, cladatum, NULL); 1252 cls_destroy(key, cladatum, NULL);
1242 goto out; 1253 return rc;
1243} 1254}
1244 1255
1245static int role_read(struct policydb *p, struct hashtab *h, void *fp) 1256static int role_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1250,17 +1261,16 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1250 __le32 buf[3]; 1261 __le32 buf[3];
1251 u32 len; 1262 u32 len;
1252 1263
1264 rc = -ENOMEM;
1253 role = kzalloc(sizeof(*role), GFP_KERNEL); 1265 role = kzalloc(sizeof(*role), GFP_KERNEL);
1254 if (!role) { 1266 if (!role)
1255 rc = -ENOMEM; 1267 goto bad;
1256 goto out;
1257 }
1258 1268
1259 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1269 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1260 to_read = 3; 1270 to_read = 3;
1261 1271
1262 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1272 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1263 if (rc < 0) 1273 if (rc)
1264 goto bad; 1274 goto bad;
1265 1275
1266 len = le32_to_cpu(buf[0]); 1276 len = le32_to_cpu(buf[0]);
@@ -1268,13 +1278,13 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1268 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1278 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1269 role->bounds = le32_to_cpu(buf[2]); 1279 role->bounds = le32_to_cpu(buf[2]);
1270 1280
1281 rc = -ENOMEM;
1271 key = kmalloc(len + 1, GFP_KERNEL); 1282 key = kmalloc(len + 1, GFP_KERNEL);
1272 if (!key) { 1283 if (!key)
1273 rc = -ENOMEM;
1274 goto bad; 1284 goto bad;
1275 } 1285
1276 rc = next_entry(key, fp, len); 1286 rc = next_entry(key, fp, len);
1277 if (rc < 0) 1287 if (rc)
1278 goto bad; 1288 goto bad;
1279 key[len] = '\0'; 1289 key[len] = '\0';
1280 1290
@@ -1287,10 +1297,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1287 goto bad; 1297 goto bad;
1288 1298
1289 if (strcmp(key, OBJECT_R) == 0) { 1299 if (strcmp(key, OBJECT_R) == 0) {
1300 rc = -EINVAL;
1290 if (role->value != OBJECT_R_VAL) { 1301 if (role->value != OBJECT_R_VAL) {
1291 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", 1302 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n",
1292 OBJECT_R, role->value); 1303 OBJECT_R, role->value);
1293 rc = -EINVAL;
1294 goto bad; 1304 goto bad;
1295 } 1305 }
1296 rc = 0; 1306 rc = 0;
@@ -1300,11 +1310,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1300 rc = hashtab_insert(h, key, role); 1310 rc = hashtab_insert(h, key, role);
1301 if (rc) 1311 if (rc)
1302 goto bad; 1312 goto bad;
1303out: 1313 return 0;
1304 return rc;
1305bad: 1314bad:
1306 role_destroy(key, role, NULL); 1315 role_destroy(key, role, NULL);
1307 goto out; 1316 return rc;
1308} 1317}
1309 1318
1310static int type_read(struct policydb *p, struct hashtab *h, void *fp) 1319static int type_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1315,17 +1324,16 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1315 __le32 buf[4]; 1324 __le32 buf[4];
1316 u32 len; 1325 u32 len;
1317 1326
1327 rc = -ENOMEM;
1318 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); 1328 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL);
1319 if (!typdatum) { 1329 if (!typdatum)
1320 rc = -ENOMEM; 1330 goto bad;
1321 return rc;
1322 }
1323 1331
1324 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1332 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1325 to_read = 4; 1333 to_read = 4;
1326 1334
1327 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1335 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1328 if (rc < 0) 1336 if (rc)
1329 goto bad; 1337 goto bad;
1330 1338
1331 len = le32_to_cpu(buf[0]); 1339 len = le32_to_cpu(buf[0]);
@@ -1343,24 +1351,22 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1343 typdatum->primary = le32_to_cpu(buf[2]); 1351 typdatum->primary = le32_to_cpu(buf[2]);
1344 } 1352 }
1345 1353
1354 rc = -ENOMEM;
1346 key = kmalloc(len + 1, GFP_KERNEL); 1355 key = kmalloc(len + 1, GFP_KERNEL);
1347 if (!key) { 1356 if (!key)
1348 rc = -ENOMEM;
1349 goto bad; 1357 goto bad;
1350 }
1351 rc = next_entry(key, fp, len); 1358 rc = next_entry(key, fp, len);
1352 if (rc < 0) 1359 if (rc)
1353 goto bad; 1360 goto bad;
1354 key[len] = '\0'; 1361 key[len] = '\0';
1355 1362
1356 rc = hashtab_insert(h, key, typdatum); 1363 rc = hashtab_insert(h, key, typdatum);
1357 if (rc) 1364 if (rc)
1358 goto bad; 1365 goto bad;
1359out: 1366 return 0;
1360 return rc;
1361bad: 1367bad:
1362 type_destroy(key, typdatum, NULL); 1368 type_destroy(key, typdatum, NULL);
1363 goto out; 1369 return rc;
1364} 1370}
1365 1371
1366 1372
@@ -1376,22 +1382,18 @@ static int mls_read_level(struct mls_level *lp, void *fp)
1376 memset(lp, 0, sizeof(*lp)); 1382 memset(lp, 0, sizeof(*lp));
1377 1383
1378 rc = next_entry(buf, fp, sizeof buf); 1384 rc = next_entry(buf, fp, sizeof buf);
1379 if (rc < 0) { 1385 if (rc) {
1380 printk(KERN_ERR "SELinux: mls: truncated level\n"); 1386 printk(KERN_ERR "SELinux: mls: truncated level\n");
1381 goto bad; 1387 return rc;
1382 } 1388 }
1383 lp->sens = le32_to_cpu(buf[0]); 1389 lp->sens = le32_to_cpu(buf[0]);
1384 1390
1385 if (ebitmap_read(&lp->cat, fp)) { 1391 rc = ebitmap_read(&lp->cat, fp);
1386 printk(KERN_ERR "SELinux: mls: error reading level " 1392 if (rc) {
1387 "categories\n"); 1393 printk(KERN_ERR "SELinux: mls: error reading level categories\n");
1388 goto bad; 1394 return rc;
1389 } 1395 }
1390
1391 return 0; 1396 return 0;
1392
1393bad:
1394 return -EINVAL;
1395} 1397}
1396 1398
1397static int user_read(struct policydb *p, struct hashtab *h, void *fp) 1399static int user_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1402,17 +1404,16 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1402 __le32 buf[3]; 1404 __le32 buf[3];
1403 u32 len; 1405 u32 len;
1404 1406
1407 rc = -ENOMEM;
1405 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); 1408 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
1406 if (!usrdatum) { 1409 if (!usrdatum)
1407 rc = -ENOMEM; 1410 goto bad;
1408 goto out;
1409 }
1410 1411
1411 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1412 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1412 to_read = 3; 1413 to_read = 3;
1413 1414
1414 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1415 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1415 if (rc < 0) 1416 if (rc)
1416 goto bad; 1417 goto bad;
1417 1418
1418 len = le32_to_cpu(buf[0]); 1419 len = le32_to_cpu(buf[0]);
@@ -1420,13 +1421,12 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1420 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1421 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1421 usrdatum->bounds = le32_to_cpu(buf[2]); 1422 usrdatum->bounds = le32_to_cpu(buf[2]);
1422 1423
1424 rc = -ENOMEM;
1423 key = kmalloc(len + 1, GFP_KERNEL); 1425 key = kmalloc(len + 1, GFP_KERNEL);
1424 if (!key) { 1426 if (!key)
1425 rc = -ENOMEM;
1426 goto bad; 1427 goto bad;
1427 }
1428 rc = next_entry(key, fp, len); 1428 rc = next_entry(key, fp, len);
1429 if (rc < 0) 1429 if (rc)
1430 goto bad; 1430 goto bad;
1431 key[len] = '\0'; 1431 key[len] = '\0';
1432 1432
@@ -1446,11 +1446,10 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1446 rc = hashtab_insert(h, key, usrdatum); 1446 rc = hashtab_insert(h, key, usrdatum);
1447 if (rc) 1447 if (rc)
1448 goto bad; 1448 goto bad;
1449out: 1449 return 0;
1450 return rc;
1451bad: 1450bad:
1452 user_destroy(key, usrdatum, NULL); 1451 user_destroy(key, usrdatum, NULL);
1453 goto out; 1452 return rc;
1454} 1453}
1455 1454
1456static int sens_read(struct policydb *p, struct hashtab *h, void *fp) 1455static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1461,47 +1460,43 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1461 __le32 buf[2]; 1460 __le32 buf[2];
1462 u32 len; 1461 u32 len;
1463 1462
1463 rc = -ENOMEM;
1464 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); 1464 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
1465 if (!levdatum) { 1465 if (!levdatum)
1466 rc = -ENOMEM; 1466 goto bad;
1467 goto out;
1468 }
1469 1467
1470 rc = next_entry(buf, fp, sizeof buf); 1468 rc = next_entry(buf, fp, sizeof buf);
1471 if (rc < 0) 1469 if (rc)
1472 goto bad; 1470 goto bad;
1473 1471
1474 len = le32_to_cpu(buf[0]); 1472 len = le32_to_cpu(buf[0]);
1475 levdatum->isalias = le32_to_cpu(buf[1]); 1473 levdatum->isalias = le32_to_cpu(buf[1]);
1476 1474
1475 rc = -ENOMEM;
1477 key = kmalloc(len + 1, GFP_ATOMIC); 1476 key = kmalloc(len + 1, GFP_ATOMIC);
1478 if (!key) { 1477 if (!key)
1479 rc = -ENOMEM;
1480 goto bad; 1478 goto bad;
1481 }
1482 rc = next_entry(key, fp, len); 1479 rc = next_entry(key, fp, len);
1483 if (rc < 0) 1480 if (rc)
1484 goto bad; 1481 goto bad;
1485 key[len] = '\0'; 1482 key[len] = '\0';
1486 1483
1484 rc = -ENOMEM;
1487 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); 1485 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
1488 if (!levdatum->level) { 1486 if (!levdatum->level)
1489 rc = -ENOMEM;
1490 goto bad; 1487 goto bad;
1491 } 1488
1492 if (mls_read_level(levdatum->level, fp)) { 1489 rc = mls_read_level(levdatum->level, fp);
1493 rc = -EINVAL; 1490 if (rc)
1494 goto bad; 1491 goto bad;
1495 }
1496 1492
1497 rc = hashtab_insert(h, key, levdatum); 1493 rc = hashtab_insert(h, key, levdatum);
1498 if (rc) 1494 if (rc)
1499 goto bad; 1495 goto bad;
1500out: 1496 return 0;
1501 return rc;
1502bad: 1497bad:
1503 sens_destroy(key, levdatum, NULL); 1498 sens_destroy(key, levdatum, NULL);
1504 goto out; 1499 return rc;
1505} 1500}
1506 1501
1507static int cat_read(struct policydb *p, struct hashtab *h, void *fp) 1502static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1512,39 +1507,35 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1512 __le32 buf[3]; 1507 __le32 buf[3];
1513 u32 len; 1508 u32 len;
1514 1509
1510 rc = -ENOMEM;
1515 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); 1511 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
1516 if (!catdatum) { 1512 if (!catdatum)
1517 rc = -ENOMEM; 1513 goto bad;
1518 goto out;
1519 }
1520 1514
1521 rc = next_entry(buf, fp, sizeof buf); 1515 rc = next_entry(buf, fp, sizeof buf);
1522 if (rc < 0) 1516 if (rc)
1523 goto bad; 1517 goto bad;
1524 1518
1525 len = le32_to_cpu(buf[0]); 1519 len = le32_to_cpu(buf[0]);
1526 catdatum->value = le32_to_cpu(buf[1]); 1520 catdatum->value = le32_to_cpu(buf[1]);
1527 catdatum->isalias = le32_to_cpu(buf[2]); 1521 catdatum->isalias = le32_to_cpu(buf[2]);
1528 1522
1523 rc = -ENOMEM;
1529 key = kmalloc(len + 1, GFP_ATOMIC); 1524 key = kmalloc(len + 1, GFP_ATOMIC);
1530 if (!key) { 1525 if (!key)
1531 rc = -ENOMEM;
1532 goto bad; 1526 goto bad;
1533 }
1534 rc = next_entry(key, fp, len); 1527 rc = next_entry(key, fp, len);
1535 if (rc < 0) 1528 if (rc)
1536 goto bad; 1529 goto bad;
1537 key[len] = '\0'; 1530 key[len] = '\0';
1538 1531
1539 rc = hashtab_insert(h, key, catdatum); 1532 rc = hashtab_insert(h, key, catdatum);
1540 if (rc) 1533 if (rc)
1541 goto bad; 1534 goto bad;
1542out: 1535 return 0;
1543 return rc;
1544
1545bad: 1536bad:
1546 cat_destroy(key, catdatum, NULL); 1537 cat_destroy(key, catdatum, NULL);
1547 goto out; 1538 return rc;
1548} 1539}
1549 1540
1550static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = 1541static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =
@@ -1585,9 +1576,9 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap)
1585 printk(KERN_ERR 1576 printk(KERN_ERR
1586 "SELinux: boundary violated policy: " 1577 "SELinux: boundary violated policy: "
1587 "user=%s role=%s bounds=%s\n", 1578 "user=%s role=%s bounds=%s\n",
1588 p->p_user_val_to_name[user->value - 1], 1579 sym_name(p, SYM_USERS, user->value - 1),
1589 p->p_role_val_to_name[bit], 1580 sym_name(p, SYM_ROLES, bit),
1590 p->p_user_val_to_name[upper->value - 1]); 1581 sym_name(p, SYM_USERS, upper->value - 1));
1591 1582
1592 return -EINVAL; 1583 return -EINVAL;
1593 } 1584 }
@@ -1622,9 +1613,9 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap)
1622 printk(KERN_ERR 1613 printk(KERN_ERR
1623 "SELinux: boundary violated policy: " 1614 "SELinux: boundary violated policy: "
1624 "role=%s type=%s bounds=%s\n", 1615 "role=%s type=%s bounds=%s\n",
1625 p->p_role_val_to_name[role->value - 1], 1616 sym_name(p, SYM_ROLES, role->value - 1),
1626 p->p_type_val_to_name[bit], 1617 sym_name(p, SYM_TYPES, bit),
1627 p->p_role_val_to_name[upper->value - 1]); 1618 sym_name(p, SYM_ROLES, upper->value - 1));
1628 1619
1629 return -EINVAL; 1620 return -EINVAL;
1630 } 1621 }
@@ -1648,12 +1639,15 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap)
1648 return -EINVAL; 1639 return -EINVAL;
1649 } 1640 }
1650 1641
1651 upper = p->type_val_to_struct[upper->bounds - 1]; 1642 upper = flex_array_get_ptr(p->type_val_to_struct_array,
1643 upper->bounds - 1);
1644 BUG_ON(!upper);
1645
1652 if (upper->attribute) { 1646 if (upper->attribute) {
1653 printk(KERN_ERR "SELinux: type %s: " 1647 printk(KERN_ERR "SELinux: type %s: "
1654 "bounded by attribute %s", 1648 "bounded by attribute %s",
1655 (char *) key, 1649 (char *) key,
1656 p->p_type_val_to_name[upper->value - 1]); 1650 sym_name(p, SYM_TYPES, upper->value - 1));
1657 return -EINVAL; 1651 return -EINVAL;
1658 } 1652 }
1659 } 1653 }
@@ -2066,13 +2060,14 @@ int policydb_read(struct policydb *p, void *fp)
2066 2060
2067 rc = policydb_init(p); 2061 rc = policydb_init(p);
2068 if (rc) 2062 if (rc)
2069 goto out; 2063 return rc;
2070 2064
2071 /* Read the magic number and string length. */ 2065 /* Read the magic number and string length. */
2072 rc = next_entry(buf, fp, sizeof(u32) * 2); 2066 rc = next_entry(buf, fp, sizeof(u32) * 2);
2073 if (rc < 0) 2067 if (rc)
2074 goto bad; 2068 goto bad;
2075 2069
2070 rc = -EINVAL;
2076 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { 2071 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) {
2077 printk(KERN_ERR "SELinux: policydb magic number 0x%x does " 2072 printk(KERN_ERR "SELinux: policydb magic number 0x%x does "
2078 "not match expected magic number 0x%x\n", 2073 "not match expected magic number 0x%x\n",
@@ -2080,6 +2075,7 @@ int policydb_read(struct policydb *p, void *fp)
2080 goto bad; 2075 goto bad;
2081 } 2076 }
2082 2077
2078 rc = -EINVAL;
2083 len = le32_to_cpu(buf[1]); 2079 len = le32_to_cpu(buf[1]);
2084 if (len != strlen(POLICYDB_STRING)) { 2080 if (len != strlen(POLICYDB_STRING)) {
2085 printk(KERN_ERR "SELinux: policydb string length %d does not " 2081 printk(KERN_ERR "SELinux: policydb string length %d does not "
@@ -2087,19 +2083,23 @@ int policydb_read(struct policydb *p, void *fp)
2087 len, strlen(POLICYDB_STRING)); 2083 len, strlen(POLICYDB_STRING));
2088 goto bad; 2084 goto bad;
2089 } 2085 }
2086
2087 rc = -ENOMEM;
2090 policydb_str = kmalloc(len + 1, GFP_KERNEL); 2088 policydb_str = kmalloc(len + 1, GFP_KERNEL);
2091 if (!policydb_str) { 2089 if (!policydb_str) {
2092 printk(KERN_ERR "SELinux: unable to allocate memory for policydb " 2090 printk(KERN_ERR "SELinux: unable to allocate memory for policydb "
2093 "string of length %d\n", len); 2091 "string of length %d\n", len);
2094 rc = -ENOMEM;
2095 goto bad; 2092 goto bad;
2096 } 2093 }
2094
2097 rc = next_entry(policydb_str, fp, len); 2095 rc = next_entry(policydb_str, fp, len);
2098 if (rc < 0) { 2096 if (rc) {
2099 printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); 2097 printk(KERN_ERR "SELinux: truncated policydb string identifier\n");
2100 kfree(policydb_str); 2098 kfree(policydb_str);
2101 goto bad; 2099 goto bad;
2102 } 2100 }
2101
2102 rc = -EINVAL;
2103 policydb_str[len] = '\0'; 2103 policydb_str[len] = '\0';
2104 if (strcmp(policydb_str, POLICYDB_STRING)) { 2104 if (strcmp(policydb_str, POLICYDB_STRING)) {
2105 printk(KERN_ERR "SELinux: policydb string %s does not match " 2105 printk(KERN_ERR "SELinux: policydb string %s does not match "
@@ -2113,9 +2113,10 @@ int policydb_read(struct policydb *p, void *fp)
2113 2113
2114 /* Read the version and table sizes. */ 2114 /* Read the version and table sizes. */
2115 rc = next_entry(buf, fp, sizeof(u32)*4); 2115 rc = next_entry(buf, fp, sizeof(u32)*4);
2116 if (rc < 0) 2116 if (rc)
2117 goto bad; 2117 goto bad;
2118 2118
2119 rc = -EINVAL;
2119 p->policyvers = le32_to_cpu(buf[0]); 2120 p->policyvers = le32_to_cpu(buf[0]);
2120 if (p->policyvers < POLICYDB_VERSION_MIN || 2121 if (p->policyvers < POLICYDB_VERSION_MIN ||
2121 p->policyvers > POLICYDB_VERSION_MAX) { 2122 p->policyvers > POLICYDB_VERSION_MAX) {
@@ -2128,6 +2129,7 @@ int policydb_read(struct policydb *p, void *fp)
2128 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 2129 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
2129 p->mls_enabled = 1; 2130 p->mls_enabled = 1;
2130 2131
2132 rc = -EINVAL;
2131 if (p->policyvers < POLICYDB_VERSION_MLS) { 2133 if (p->policyvers < POLICYDB_VERSION_MLS) {
2132 printk(KERN_ERR "SELinux: security policydb version %d " 2134 printk(KERN_ERR "SELinux: security policydb version %d "
2133 "(MLS) not backwards compatible\n", 2135 "(MLS) not backwards compatible\n",
@@ -2138,14 +2140,19 @@ int policydb_read(struct policydb *p, void *fp)
2138 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 2140 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
2139 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 2141 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
2140 2142
2141 if (p->policyvers >= POLICYDB_VERSION_POLCAP && 2143 if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
2142 ebitmap_read(&p->policycaps, fp) != 0) 2144 rc = ebitmap_read(&p->policycaps, fp);
2143 goto bad; 2145 if (rc)
2146 goto bad;
2147 }
2144 2148
2145 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && 2149 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) {
2146 ebitmap_read(&p->permissive_map, fp) != 0) 2150 rc = ebitmap_read(&p->permissive_map, fp);
2147 goto bad; 2151 if (rc)
2152 goto bad;
2153 }
2148 2154
2155 rc = -EINVAL;
2149 info = policydb_lookup_compat(p->policyvers); 2156 info = policydb_lookup_compat(p->policyvers);
2150 if (!info) { 2157 if (!info) {
2151 printk(KERN_ERR "SELinux: unable to find policy compat info " 2158 printk(KERN_ERR "SELinux: unable to find policy compat info "
@@ -2153,6 +2160,7 @@ int policydb_read(struct policydb *p, void *fp)
2153 goto bad; 2160 goto bad;
2154 } 2161 }
2155 2162
2163 rc = -EINVAL;
2156 if (le32_to_cpu(buf[2]) != info->sym_num || 2164 if (le32_to_cpu(buf[2]) != info->sym_num ||
2157 le32_to_cpu(buf[3]) != info->ocon_num) { 2165 le32_to_cpu(buf[3]) != info->ocon_num) {
2158 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " 2166 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do "
@@ -2164,7 +2172,7 @@ int policydb_read(struct policydb *p, void *fp)
2164 2172
2165 for (i = 0; i < info->sym_num; i++) { 2173 for (i = 0; i < info->sym_num; i++) {
2166 rc = next_entry(buf, fp, sizeof(u32)*2); 2174 rc = next_entry(buf, fp, sizeof(u32)*2);
2167 if (rc < 0) 2175 if (rc)
2168 goto bad; 2176 goto bad;
2169 nprim = le32_to_cpu(buf[0]); 2177 nprim = le32_to_cpu(buf[0]);
2170 nel = le32_to_cpu(buf[1]); 2178 nel = le32_to_cpu(buf[1]);
@@ -2188,78 +2196,73 @@ int policydb_read(struct policydb *p, void *fp)
2188 } 2196 }
2189 2197
2190 rc = next_entry(buf, fp, sizeof(u32)); 2198 rc = next_entry(buf, fp, sizeof(u32));
2191 if (rc < 0) 2199 if (rc)
2192 goto bad; 2200 goto bad;
2193 nel = le32_to_cpu(buf[0]); 2201 nel = le32_to_cpu(buf[0]);
2194 ltr = NULL; 2202 ltr = NULL;
2195 for (i = 0; i < nel; i++) { 2203 for (i = 0; i < nel; i++) {
2204 rc = -ENOMEM;
2196 tr = kzalloc(sizeof(*tr), GFP_KERNEL); 2205 tr = kzalloc(sizeof(*tr), GFP_KERNEL);
2197 if (!tr) { 2206 if (!tr)
2198 rc = -ENOMEM;
2199 goto bad; 2207 goto bad;
2200 }
2201 if (ltr) 2208 if (ltr)
2202 ltr->next = tr; 2209 ltr->next = tr;
2203 else 2210 else
2204 p->role_tr = tr; 2211 p->role_tr = tr;
2205 rc = next_entry(buf, fp, sizeof(u32)*3); 2212 rc = next_entry(buf, fp, sizeof(u32)*3);
2206 if (rc < 0) 2213 if (rc)
2207 goto bad; 2214 goto bad;
2215
2216 rc = -EINVAL;
2208 tr->role = le32_to_cpu(buf[0]); 2217 tr->role = le32_to_cpu(buf[0]);
2209 tr->type = le32_to_cpu(buf[1]); 2218 tr->type = le32_to_cpu(buf[1]);
2210 tr->new_role = le32_to_cpu(buf[2]); 2219 tr->new_role = le32_to_cpu(buf[2]);
2211 if (!policydb_role_isvalid(p, tr->role) || 2220 if (!policydb_role_isvalid(p, tr->role) ||
2212 !policydb_type_isvalid(p, tr->type) || 2221 !policydb_type_isvalid(p, tr->type) ||
2213 !policydb_role_isvalid(p, tr->new_role)) { 2222 !policydb_role_isvalid(p, tr->new_role))
2214 rc = -EINVAL;
2215 goto bad; 2223 goto bad;
2216 }
2217 ltr = tr; 2224 ltr = tr;
2218 } 2225 }
2219 2226
2220 rc = next_entry(buf, fp, sizeof(u32)); 2227 rc = next_entry(buf, fp, sizeof(u32));
2221 if (rc < 0) 2228 if (rc)
2222 goto bad; 2229 goto bad;
2223 nel = le32_to_cpu(buf[0]); 2230 nel = le32_to_cpu(buf[0]);
2224 lra = NULL; 2231 lra = NULL;
2225 for (i = 0; i < nel; i++) { 2232 for (i = 0; i < nel; i++) {
2233 rc = -ENOMEM;
2226 ra = kzalloc(sizeof(*ra), GFP_KERNEL); 2234 ra = kzalloc(sizeof(*ra), GFP_KERNEL);
2227 if (!ra) { 2235 if (!ra)
2228 rc = -ENOMEM;
2229 goto bad; 2236 goto bad;
2230 }
2231 if (lra) 2237 if (lra)
2232 lra->next = ra; 2238 lra->next = ra;
2233 else 2239 else
2234 p->role_allow = ra; 2240 p->role_allow = ra;
2235 rc = next_entry(buf, fp, sizeof(u32)*2); 2241 rc = next_entry(buf, fp, sizeof(u32)*2);
2236 if (rc < 0) 2242 if (rc)
2237 goto bad; 2243 goto bad;
2244
2245 rc = -EINVAL;
2238 ra->role = le32_to_cpu(buf[0]); 2246 ra->role = le32_to_cpu(buf[0]);
2239 ra->new_role = le32_to_cpu(buf[1]); 2247 ra->new_role = le32_to_cpu(buf[1]);
2240 if (!policydb_role_isvalid(p, ra->role) || 2248 if (!policydb_role_isvalid(p, ra->role) ||
2241 !policydb_role_isvalid(p, ra->new_role)) { 2249 !policydb_role_isvalid(p, ra->new_role))
2242 rc = -EINVAL;
2243 goto bad; 2250 goto bad;
2244 }
2245 lra = ra; 2251 lra = ra;
2246 } 2252 }
2247 2253
2248 rc = policydb_index_classes(p); 2254 rc = policydb_index(p);
2249 if (rc)
2250 goto bad;
2251
2252 rc = policydb_index_others(p);
2253 if (rc) 2255 if (rc)
2254 goto bad; 2256 goto bad;
2255 2257
2258 rc = -EINVAL;
2256 p->process_class = string_to_security_class(p, "process"); 2259 p->process_class = string_to_security_class(p, "process");
2257 if (!p->process_class) 2260 if (!p->process_class)
2258 goto bad; 2261 goto bad;
2259 p->process_trans_perms = string_to_av_perm(p, p->process_class, 2262
2260 "transition"); 2263 rc = -EINVAL;
2261 p->process_trans_perms |= string_to_av_perm(p, p->process_class, 2264 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2262 "dyntransition"); 2265 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2263 if (!p->process_trans_perms) 2266 if (!p->process_trans_perms)
2264 goto bad; 2267 goto bad;
2265 2268
@@ -2312,8 +2315,6 @@ int policydb_read(struct policydb *p, void *fp)
2312out: 2315out:
2313 return rc; 2316 return rc;
2314bad: 2317bad:
2315 if (!rc)
2316 rc = -EINVAL;
2317 policydb_destroy(p); 2318 policydb_destroy(p);
2318 goto out; 2319 goto out;
2319} 2320}
@@ -3076,7 +3077,7 @@ int policydb_write(struct policydb *p, void *fp)
3076 if (!info) { 3077 if (!info) {
3077 printk(KERN_ERR "SELinux: compatibility lookup failed for policy " 3078 printk(KERN_ERR "SELinux: compatibility lookup failed for policy "
3078 "version %d", p->policyvers); 3079 "version %d", p->policyvers);
3079 return rc; 3080 return -EINVAL;
3080 } 3081 }
3081 3082
3082 buf[0] = cpu_to_le32(p->policyvers); 3083 buf[0] = cpu_to_le32(p->policyvers);
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 95d3d7de361e..4e3ab9d0b315 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -203,21 +203,13 @@ struct policydb {
203#define p_cats symtab[SYM_CATS] 203#define p_cats symtab[SYM_CATS]
204 204
205 /* symbol names indexed by (value - 1) */ 205 /* symbol names indexed by (value - 1) */
206 char **sym_val_to_name[SYM_NUM]; 206 struct flex_array *sym_val_to_name[SYM_NUM];
207#define p_common_val_to_name sym_val_to_name[SYM_COMMONS]
208#define p_class_val_to_name sym_val_to_name[SYM_CLASSES]
209#define p_role_val_to_name sym_val_to_name[SYM_ROLES]
210#define p_type_val_to_name sym_val_to_name[SYM_TYPES]
211#define p_user_val_to_name sym_val_to_name[SYM_USERS]
212#define p_bool_val_to_name sym_val_to_name[SYM_BOOLS]
213#define p_sens_val_to_name sym_val_to_name[SYM_LEVELS]
214#define p_cat_val_to_name sym_val_to_name[SYM_CATS]
215 207
216 /* class, role, and user attributes indexed by (value - 1) */ 208 /* class, role, and user attributes indexed by (value - 1) */
217 struct class_datum **class_val_to_struct; 209 struct class_datum **class_val_to_struct;
218 struct role_datum **role_val_to_struct; 210 struct role_datum **role_val_to_struct;
219 struct user_datum **user_val_to_struct; 211 struct user_datum **user_val_to_struct;
220 struct type_datum **type_val_to_struct; 212 struct flex_array *type_val_to_struct_array;
221 213
222 /* type enforcement access vectors and transitions */ 214 /* type enforcement access vectors and transitions */
223 struct avtab te_avtab; 215 struct avtab te_avtab;
@@ -321,6 +313,13 @@ static inline int put_entry(void *buf, size_t bytes, int num, struct policy_file
321 return 0; 313 return 0;
322} 314}
323 315
316static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr)
317{
318 struct flex_array *fa = p->sym_val_to_name[sym_num];
319
320 return flex_array_get_ptr(fa, element_nr);
321}
322
324extern u16 string_to_security_class(struct policydb *p, const char *name); 323extern u16 string_to_security_class(struct policydb *p, const char *name);
325extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); 324extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
326 325
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 223c1ff6ef23..a03cfaf0ee07 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -464,7 +464,7 @@ static void security_dump_masked_av(struct context *scontext,
464 if (!permissions) 464 if (!permissions)
465 return; 465 return;
466 466
467 tclass_name = policydb.p_class_val_to_name[tclass - 1]; 467 tclass_name = sym_name(&policydb, SYM_CLASSES, tclass - 1);
468 tclass_dat = policydb.class_val_to_struct[tclass - 1]; 468 tclass_dat = policydb.class_val_to_struct[tclass - 1];
469 common_dat = tclass_dat->comdatum; 469 common_dat = tclass_dat->comdatum;
470 470
@@ -530,12 +530,18 @@ static void type_attribute_bounds_av(struct context *scontext,
530 struct context lo_scontext; 530 struct context lo_scontext;
531 struct context lo_tcontext; 531 struct context lo_tcontext;
532 struct av_decision lo_avd; 532 struct av_decision lo_avd;
533 struct type_datum *source 533 struct type_datum *source;
534 = policydb.type_val_to_struct[scontext->type - 1]; 534 struct type_datum *target;
535 struct type_datum *target
536 = policydb.type_val_to_struct[tcontext->type - 1];
537 u32 masked = 0; 535 u32 masked = 0;
538 536
537 source = flex_array_get_ptr(policydb.type_val_to_struct_array,
538 scontext->type - 1);
539 BUG_ON(!source);
540
541 target = flex_array_get_ptr(policydb.type_val_to_struct_array,
542 tcontext->type - 1);
543 BUG_ON(!target);
544
539 if (source->bounds) { 545 if (source->bounds) {
540 memset(&lo_avd, 0, sizeof(lo_avd)); 546 memset(&lo_avd, 0, sizeof(lo_avd));
541 547
@@ -701,16 +707,16 @@ static int security_validtrans_handle_fail(struct context *ocontext,
701 char *o = NULL, *n = NULL, *t = NULL; 707 char *o = NULL, *n = NULL, *t = NULL;
702 u32 olen, nlen, tlen; 708 u32 olen, nlen, tlen;
703 709
704 if (context_struct_to_string(ocontext, &o, &olen) < 0) 710 if (context_struct_to_string(ocontext, &o, &olen))
705 goto out; 711 goto out;
706 if (context_struct_to_string(ncontext, &n, &nlen) < 0) 712 if (context_struct_to_string(ncontext, &n, &nlen))
707 goto out; 713 goto out;
708 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 714 if (context_struct_to_string(tcontext, &t, &tlen))
709 goto out; 715 goto out;
710 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 716 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
711 "security_validate_transition: denied for" 717 "security_validate_transition: denied for"
712 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", 718 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
713 o, n, t, policydb.p_class_val_to_name[tclass-1]); 719 o, n, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
714out: 720out:
715 kfree(o); 721 kfree(o);
716 kfree(n); 722 kfree(n);
@@ -801,10 +807,11 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
801 struct context *old_context, *new_context; 807 struct context *old_context, *new_context;
802 struct type_datum *type; 808 struct type_datum *type;
803 int index; 809 int index;
804 int rc = -EINVAL; 810 int rc;
805 811
806 read_lock(&policy_rwlock); 812 read_lock(&policy_rwlock);
807 813
814 rc = -EINVAL;
808 old_context = sidtab_search(&sidtab, old_sid); 815 old_context = sidtab_search(&sidtab, old_sid);
809 if (!old_context) { 816 if (!old_context) {
810 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 817 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -812,6 +819,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
812 goto out; 819 goto out;
813 } 820 }
814 821
822 rc = -EINVAL;
815 new_context = sidtab_search(&sidtab, new_sid); 823 new_context = sidtab_search(&sidtab, new_sid);
816 if (!new_context) { 824 if (!new_context) {
817 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 825 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -819,28 +827,27 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
819 goto out; 827 goto out;
820 } 828 }
821 829
830 rc = 0;
822 /* type/domain unchanged */ 831 /* type/domain unchanged */
823 if (old_context->type == new_context->type) { 832 if (old_context->type == new_context->type)
824 rc = 0;
825 goto out; 833 goto out;
826 }
827 834
828 index = new_context->type; 835 index = new_context->type;
829 while (true) { 836 while (true) {
830 type = policydb.type_val_to_struct[index - 1]; 837 type = flex_array_get_ptr(policydb.type_val_to_struct_array,
838 index - 1);
831 BUG_ON(!type); 839 BUG_ON(!type);
832 840
833 /* not bounded anymore */ 841 /* not bounded anymore */
834 if (!type->bounds) { 842 rc = -EPERM;
835 rc = -EPERM; 843 if (!type->bounds)
836 break; 844 break;
837 }
838 845
839 /* @newsid is bounded by @oldsid */ 846 /* @newsid is bounded by @oldsid */
840 if (type->bounds == old_context->type) { 847 rc = 0;
841 rc = 0; 848 if (type->bounds == old_context->type)
842 break; 849 break;
843 } 850
844 index = type->bounds; 851 index = type->bounds;
845 } 852 }
846 853
@@ -1005,9 +1012,9 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1005 } 1012 }
1006 1013
1007 /* Compute the size of the context. */ 1014 /* Compute the size of the context. */
1008 *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1; 1015 *scontext_len += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) + 1;
1009 *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1; 1016 *scontext_len += strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) + 1;
1010 *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1; 1017 *scontext_len += strlen(sym_name(&policydb, SYM_TYPES, context->type - 1)) + 1;
1011 *scontext_len += mls_compute_context_len(context); 1018 *scontext_len += mls_compute_context_len(context);
1012 1019
1013 if (!scontext) 1020 if (!scontext)
@@ -1023,12 +1030,12 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1023 * Copy the user name, role name and type name into the context. 1030 * Copy the user name, role name and type name into the context.
1024 */ 1031 */
1025 sprintf(scontextp, "%s:%s:%s", 1032 sprintf(scontextp, "%s:%s:%s",
1026 policydb.p_user_val_to_name[context->user - 1], 1033 sym_name(&policydb, SYM_USERS, context->user - 1),
1027 policydb.p_role_val_to_name[context->role - 1], 1034 sym_name(&policydb, SYM_ROLES, context->role - 1),
1028 policydb.p_type_val_to_name[context->type - 1]); 1035 sym_name(&policydb, SYM_TYPES, context->type - 1));
1029 scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1036 scontextp += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) +
1030 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + 1037 1 + strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) +
1031 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); 1038 1 + strlen(sym_name(&policydb, SYM_TYPES, context->type - 1));
1032 1039
1033 mls_sid_to_context(context, &scontextp); 1040 mls_sid_to_context(context, &scontextp);
1034 1041
@@ -1187,16 +1194,13 @@ static int string_to_context_struct(struct policydb *pol,
1187 if (rc) 1194 if (rc)
1188 goto out; 1195 goto out;
1189 1196
1190 if ((p - scontext) < scontext_len) { 1197 rc = -EINVAL;
1191 rc = -EINVAL; 1198 if ((p - scontext) < scontext_len)
1192 goto out; 1199 goto out;
1193 }
1194 1200
1195 /* Check the validity of the new context. */ 1201 /* Check the validity of the new context. */
1196 if (!policydb_context_isvalid(pol, ctx)) { 1202 if (!policydb_context_isvalid(pol, ctx))
1197 rc = -EINVAL;
1198 goto out; 1203 goto out;
1199 }
1200 rc = 0; 1204 rc = 0;
1201out: 1205out:
1202 if (rc) 1206 if (rc)
@@ -1235,27 +1239,26 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
1235 1239
1236 if (force) { 1240 if (force) {
1237 /* Save another copy for storing in uninterpreted form */ 1241 /* Save another copy for storing in uninterpreted form */
1242 rc = -ENOMEM;
1238 str = kstrdup(scontext2, gfp_flags); 1243 str = kstrdup(scontext2, gfp_flags);
1239 if (!str) { 1244 if (!str)
1240 kfree(scontext2); 1245 goto out;
1241 return -ENOMEM;
1242 }
1243 } 1246 }
1244 1247
1245 read_lock(&policy_rwlock); 1248 read_lock(&policy_rwlock);
1246 rc = string_to_context_struct(&policydb, &sidtab, 1249 rc = string_to_context_struct(&policydb, &sidtab, scontext2,
1247 scontext2, scontext_len, 1250 scontext_len, &context, def_sid);
1248 &context, def_sid);
1249 if (rc == -EINVAL && force) { 1251 if (rc == -EINVAL && force) {
1250 context.str = str; 1252 context.str = str;
1251 context.len = scontext_len; 1253 context.len = scontext_len;
1252 str = NULL; 1254 str = NULL;
1253 } else if (rc) 1255 } else if (rc)
1254 goto out; 1256 goto out_unlock;
1255 rc = sidtab_context_to_sid(&sidtab, &context, sid); 1257 rc = sidtab_context_to_sid(&sidtab, &context, sid);
1256 context_destroy(&context); 1258 context_destroy(&context);
1257out: 1259out_unlock:
1258 read_unlock(&policy_rwlock); 1260 read_unlock(&policy_rwlock);
1261out:
1259 kfree(scontext2); 1262 kfree(scontext2);
1260 kfree(str); 1263 kfree(str);
1261 return rc; 1264 return rc;
@@ -1319,18 +1322,18 @@ static int compute_sid_handle_invalid_context(
1319 char *s = NULL, *t = NULL, *n = NULL; 1322 char *s = NULL, *t = NULL, *n = NULL;
1320 u32 slen, tlen, nlen; 1323 u32 slen, tlen, nlen;
1321 1324
1322 if (context_struct_to_string(scontext, &s, &slen) < 0) 1325 if (context_struct_to_string(scontext, &s, &slen))
1323 goto out; 1326 goto out;
1324 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 1327 if (context_struct_to_string(tcontext, &t, &tlen))
1325 goto out; 1328 goto out;
1326 if (context_struct_to_string(newcontext, &n, &nlen) < 0) 1329 if (context_struct_to_string(newcontext, &n, &nlen))
1327 goto out; 1330 goto out;
1328 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 1331 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1329 "security_compute_sid: invalid context %s" 1332 "security_compute_sid: invalid context %s"
1330 " for scontext=%s" 1333 " for scontext=%s"
1331 " tcontext=%s" 1334 " tcontext=%s"
1332 " tclass=%s", 1335 " tclass=%s",
1333 n, s, t, policydb.p_class_val_to_name[tclass-1]); 1336 n, s, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
1334out: 1337out:
1335 kfree(s); 1338 kfree(s);
1336 kfree(t); 1339 kfree(t);
@@ -1569,22 +1572,17 @@ static int clone_sid(u32 sid,
1569 1572
1570static inline int convert_context_handle_invalid_context(struct context *context) 1573static inline int convert_context_handle_invalid_context(struct context *context)
1571{ 1574{
1572 int rc = 0; 1575 char *s;
1576 u32 len;
1573 1577
1574 if (selinux_enforcing) { 1578 if (selinux_enforcing)
1575 rc = -EINVAL; 1579 return -EINVAL;
1576 } else { 1580
1577 char *s; 1581 if (!context_struct_to_string(context, &s, &len)) {
1578 u32 len; 1582 printk(KERN_WARNING "SELinux: Context %s would be invalid if enforcing\n", s);
1579 1583 kfree(s);
1580 if (!context_struct_to_string(context, &s, &len)) {
1581 printk(KERN_WARNING
1582 "SELinux: Context %s would be invalid if enforcing\n",
1583 s);
1584 kfree(s);
1585 }
1586 } 1584 }
1587 return rc; 1585 return 0;
1588} 1586}
1589 1587
1590struct convert_context_args { 1588struct convert_context_args {
@@ -1621,17 +1619,17 @@ static int convert_context(u32 key,
1621 1619
1622 if (c->str) { 1620 if (c->str) {
1623 struct context ctx; 1621 struct context ctx;
1622
1623 rc = -ENOMEM;
1624 s = kstrdup(c->str, GFP_KERNEL); 1624 s = kstrdup(c->str, GFP_KERNEL);
1625 if (!s) { 1625 if (!s)
1626 rc = -ENOMEM;
1627 goto out; 1626 goto out;
1628 } 1627
1629 rc = string_to_context_struct(args->newp, NULL, s, 1628 rc = string_to_context_struct(args->newp, NULL, s,
1630 c->len, &ctx, SECSID_NULL); 1629 c->len, &ctx, SECSID_NULL);
1631 kfree(s); 1630 kfree(s);
1632 if (!rc) { 1631 if (!rc) {
1633 printk(KERN_INFO 1632 printk(KERN_INFO "SELinux: Context %s became valid (mapped).\n",
1634 "SELinux: Context %s became valid (mapped).\n",
1635 c->str); 1633 c->str);
1636 /* Replace string with mapped representation. */ 1634 /* Replace string with mapped representation. */
1637 kfree(c->str); 1635 kfree(c->str);
@@ -1643,8 +1641,7 @@ static int convert_context(u32 key,
1643 goto out; 1641 goto out;
1644 } else { 1642 } else {
1645 /* Other error condition, e.g. ENOMEM. */ 1643 /* Other error condition, e.g. ENOMEM. */
1646 printk(KERN_ERR 1644 printk(KERN_ERR "SELinux: Unable to map context %s, rc = %d.\n",
1647 "SELinux: Unable to map context %s, rc = %d.\n",
1648 c->str, -rc); 1645 c->str, -rc);
1649 goto out; 1646 goto out;
1650 } 1647 }
@@ -1654,25 +1651,26 @@ static int convert_context(u32 key,
1654 if (rc) 1651 if (rc)
1655 goto out; 1652 goto out;
1656 1653
1657 rc = -EINVAL;
1658
1659 /* Convert the user. */ 1654 /* Convert the user. */
1655 rc = -EINVAL;
1660 usrdatum = hashtab_search(args->newp->p_users.table, 1656 usrdatum = hashtab_search(args->newp->p_users.table,
1661 args->oldp->p_user_val_to_name[c->user - 1]); 1657 sym_name(args->oldp, SYM_USERS, c->user - 1));
1662 if (!usrdatum) 1658 if (!usrdatum)
1663 goto bad; 1659 goto bad;
1664 c->user = usrdatum->value; 1660 c->user = usrdatum->value;
1665 1661
1666 /* Convert the role. */ 1662 /* Convert the role. */
1663 rc = -EINVAL;
1667 role = hashtab_search(args->newp->p_roles.table, 1664 role = hashtab_search(args->newp->p_roles.table,
1668 args->oldp->p_role_val_to_name[c->role - 1]); 1665 sym_name(args->oldp, SYM_ROLES, c->role - 1));
1669 if (!role) 1666 if (!role)
1670 goto bad; 1667 goto bad;
1671 c->role = role->value; 1668 c->role = role->value;
1672 1669
1673 /* Convert the type. */ 1670 /* Convert the type. */
1671 rc = -EINVAL;
1674 typdatum = hashtab_search(args->newp->p_types.table, 1672 typdatum = hashtab_search(args->newp->p_types.table,
1675 args->oldp->p_type_val_to_name[c->type - 1]); 1673 sym_name(args->oldp, SYM_TYPES, c->type - 1));
1676 if (!typdatum) 1674 if (!typdatum)
1677 goto bad; 1675 goto bad;
1678 c->type = typdatum->value; 1676 c->type = typdatum->value;
@@ -1700,6 +1698,7 @@ static int convert_context(u32 key,
1700 oc = args->newp->ocontexts[OCON_ISID]; 1698 oc = args->newp->ocontexts[OCON_ISID];
1701 while (oc && oc->sid[0] != SECINITSID_UNLABELED) 1699 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1702 oc = oc->next; 1700 oc = oc->next;
1701 rc = -EINVAL;
1703 if (!oc) { 1702 if (!oc) {
1704 printk(KERN_ERR "SELinux: unable to look up" 1703 printk(KERN_ERR "SELinux: unable to look up"
1705 " the initial SIDs list\n"); 1704 " the initial SIDs list\n");
@@ -1719,19 +1718,20 @@ static int convert_context(u32 key,
1719 } 1718 }
1720 1719
1721 context_destroy(&oldc); 1720 context_destroy(&oldc);
1721
1722 rc = 0; 1722 rc = 0;
1723out: 1723out:
1724 return rc; 1724 return rc;
1725bad: 1725bad:
1726 /* Map old representation to string and save it. */ 1726 /* Map old representation to string and save it. */
1727 if (context_struct_to_string(&oldc, &s, &len)) 1727 rc = context_struct_to_string(&oldc, &s, &len);
1728 return -ENOMEM; 1728 if (rc)
1729 return rc;
1729 context_destroy(&oldc); 1730 context_destroy(&oldc);
1730 context_destroy(c); 1731 context_destroy(c);
1731 c->str = s; 1732 c->str = s;
1732 c->len = len; 1733 c->len = len;
1733 printk(KERN_INFO 1734 printk(KERN_INFO "SELinux: Context %s became invalid (unmapped).\n",
1734 "SELinux: Context %s became invalid (unmapped).\n",
1735 c->str); 1735 c->str);
1736 rc = 0; 1736 rc = 0;
1737 goto out; 1737 goto out;
@@ -2012,7 +2012,7 @@ int security_node_sid(u16 domain,
2012 u32 addrlen, 2012 u32 addrlen,
2013 u32 *out_sid) 2013 u32 *out_sid)
2014{ 2014{
2015 int rc = 0; 2015 int rc;
2016 struct ocontext *c; 2016 struct ocontext *c;
2017 2017
2018 read_lock(&policy_rwlock); 2018 read_lock(&policy_rwlock);
@@ -2021,10 +2021,9 @@ int security_node_sid(u16 domain,
2021 case AF_INET: { 2021 case AF_INET: {
2022 u32 addr; 2022 u32 addr;
2023 2023
2024 if (addrlen != sizeof(u32)) { 2024 rc = -EINVAL;
2025 rc = -EINVAL; 2025 if (addrlen != sizeof(u32))
2026 goto out; 2026 goto out;
2027 }
2028 2027
2029 addr = *((u32 *)addrp); 2028 addr = *((u32 *)addrp);
2030 2029
@@ -2038,10 +2037,9 @@ int security_node_sid(u16 domain,
2038 } 2037 }
2039 2038
2040 case AF_INET6: 2039 case AF_INET6:
2041 if (addrlen != sizeof(u64) * 2) { 2040 rc = -EINVAL;
2042 rc = -EINVAL; 2041 if (addrlen != sizeof(u64) * 2)
2043 goto out; 2042 goto out;
2044 }
2045 c = policydb.ocontexts[OCON_NODE6]; 2043 c = policydb.ocontexts[OCON_NODE6];
2046 while (c) { 2044 while (c) {
2047 if (match_ipv6_addrmask(addrp, c->u.node6.addr, 2045 if (match_ipv6_addrmask(addrp, c->u.node6.addr,
@@ -2052,6 +2050,7 @@ int security_node_sid(u16 domain,
2052 break; 2050 break;
2053 2051
2054 default: 2052 default:
2053 rc = 0;
2055 *out_sid = SECINITSID_NODE; 2054 *out_sid = SECINITSID_NODE;
2056 goto out; 2055 goto out;
2057 } 2056 }
@@ -2069,6 +2068,7 @@ int security_node_sid(u16 domain,
2069 *out_sid = SECINITSID_NODE; 2068 *out_sid = SECINITSID_NODE;
2070 } 2069 }
2071 2070
2071 rc = 0;
2072out: 2072out:
2073 read_unlock(&policy_rwlock); 2073 read_unlock(&policy_rwlock);
2074 return rc; 2074 return rc;
@@ -2113,24 +2113,22 @@ int security_get_user_sids(u32 fromsid,
2113 2113
2114 context_init(&usercon); 2114 context_init(&usercon);
2115 2115
2116 rc = -EINVAL;
2116 fromcon = sidtab_search(&sidtab, fromsid); 2117 fromcon = sidtab_search(&sidtab, fromsid);
2117 if (!fromcon) { 2118 if (!fromcon)
2118 rc = -EINVAL;
2119 goto out_unlock; 2119 goto out_unlock;
2120 }
2121 2120
2121 rc = -EINVAL;
2122 user = hashtab_search(policydb.p_users.table, username); 2122 user = hashtab_search(policydb.p_users.table, username);
2123 if (!user) { 2123 if (!user)
2124 rc = -EINVAL;
2125 goto out_unlock; 2124 goto out_unlock;
2126 } 2125
2127 usercon.user = user->value; 2126 usercon.user = user->value;
2128 2127
2128 rc = -ENOMEM;
2129 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); 2129 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
2130 if (!mysids) { 2130 if (!mysids)
2131 rc = -ENOMEM;
2132 goto out_unlock; 2131 goto out_unlock;
2133 }
2134 2132
2135 ebitmap_for_each_positive_bit(&user->roles, rnode, i) { 2133 ebitmap_for_each_positive_bit(&user->roles, rnode, i) {
2136 role = policydb.role_val_to_struct[i]; 2134 role = policydb.role_val_to_struct[i];
@@ -2147,12 +2145,11 @@ int security_get_user_sids(u32 fromsid,
2147 if (mynel < maxnel) { 2145 if (mynel < maxnel) {
2148 mysids[mynel++] = sid; 2146 mysids[mynel++] = sid;
2149 } else { 2147 } else {
2148 rc = -ENOMEM;
2150 maxnel += SIDS_NEL; 2149 maxnel += SIDS_NEL;
2151 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); 2150 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
2152 if (!mysids2) { 2151 if (!mysids2)
2153 rc = -ENOMEM;
2154 goto out_unlock; 2152 goto out_unlock;
2155 }
2156 memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); 2153 memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
2157 kfree(mysids); 2154 kfree(mysids);
2158 mysids = mysids2; 2155 mysids = mysids2;
@@ -2160,7 +2157,7 @@ int security_get_user_sids(u32 fromsid,
2160 } 2157 }
2161 } 2158 }
2162 } 2159 }
2163 2160 rc = 0;
2164out_unlock: 2161out_unlock:
2165 read_unlock(&policy_rwlock); 2162 read_unlock(&policy_rwlock);
2166 if (rc || !mynel) { 2163 if (rc || !mynel) {
@@ -2168,9 +2165,9 @@ out_unlock:
2168 goto out; 2165 goto out;
2169 } 2166 }
2170 2167
2168 rc = -ENOMEM;
2171 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); 2169 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL);
2172 if (!mysids2) { 2170 if (!mysids2) {
2173 rc = -ENOMEM;
2174 kfree(mysids); 2171 kfree(mysids);
2175 goto out; 2172 goto out;
2176 } 2173 }
@@ -2211,7 +2208,7 @@ int security_genfs_sid(const char *fstype,
2211 u16 sclass; 2208 u16 sclass;
2212 struct genfs *genfs; 2209 struct genfs *genfs;
2213 struct ocontext *c; 2210 struct ocontext *c;
2214 int rc = 0, cmp = 0; 2211 int rc, cmp = 0;
2215 2212
2216 while (path[0] == '/' && path[1] == '/') 2213 while (path[0] == '/' && path[1] == '/')
2217 path++; 2214 path++;
@@ -2219,6 +2216,7 @@ int security_genfs_sid(const char *fstype,
2219 read_lock(&policy_rwlock); 2216 read_lock(&policy_rwlock);
2220 2217
2221 sclass = unmap_class(orig_sclass); 2218 sclass = unmap_class(orig_sclass);
2219 *sid = SECINITSID_UNLABELED;
2222 2220
2223 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 2221 for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
2224 cmp = strcmp(fstype, genfs->fstype); 2222 cmp = strcmp(fstype, genfs->fstype);
@@ -2226,11 +2224,9 @@ int security_genfs_sid(const char *fstype,
2226 break; 2224 break;
2227 } 2225 }
2228 2226
2229 if (!genfs || cmp) { 2227 rc = -ENOENT;
2230 *sid = SECINITSID_UNLABELED; 2228 if (!genfs || cmp)
2231 rc = -ENOENT;
2232 goto out; 2229 goto out;
2233 }
2234 2230
2235 for (c = genfs->head; c; c = c->next) { 2231 for (c = genfs->head; c; c = c->next) {
2236 len = strlen(c->u.name); 2232 len = strlen(c->u.name);
@@ -2239,21 +2235,18 @@ int security_genfs_sid(const char *fstype,
2239 break; 2235 break;
2240 } 2236 }
2241 2237
2242 if (!c) { 2238 rc = -ENOENT;
2243 *sid = SECINITSID_UNLABELED; 2239 if (!c)
2244 rc = -ENOENT;
2245 goto out; 2240 goto out;
2246 }
2247 2241
2248 if (!c->sid[0]) { 2242 if (!c->sid[0]) {
2249 rc = sidtab_context_to_sid(&sidtab, 2243 rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]);
2250 &c->context[0],
2251 &c->sid[0]);
2252 if (rc) 2244 if (rc)
2253 goto out; 2245 goto out;
2254 } 2246 }
2255 2247
2256 *sid = c->sid[0]; 2248 *sid = c->sid[0];
2249 rc = 0;
2257out: 2250out:
2258 read_unlock(&policy_rwlock); 2251 read_unlock(&policy_rwlock);
2259 return rc; 2252 return rc;
@@ -2285,8 +2278,7 @@ int security_fs_use(
2285 if (c) { 2278 if (c) {
2286 *behavior = c->v.behavior; 2279 *behavior = c->v.behavior;
2287 if (!c->sid[0]) { 2280 if (!c->sid[0]) {
2288 rc = sidtab_context_to_sid(&sidtab, 2281 rc = sidtab_context_to_sid(&sidtab, &c->context[0],
2289 &c->context[0],
2290 &c->sid[0]); 2282 &c->sid[0]);
2291 if (rc) 2283 if (rc)
2292 goto out; 2284 goto out;
@@ -2309,34 +2301,39 @@ out:
2309 2301
2310int security_get_bools(int *len, char ***names, int **values) 2302int security_get_bools(int *len, char ***names, int **values)
2311{ 2303{
2312 int i, rc = -ENOMEM; 2304 int i, rc;
2313 2305
2314 read_lock(&policy_rwlock); 2306 read_lock(&policy_rwlock);
2315 *names = NULL; 2307 *names = NULL;
2316 *values = NULL; 2308 *values = NULL;
2317 2309
2310 rc = 0;
2318 *len = policydb.p_bools.nprim; 2311 *len = policydb.p_bools.nprim;
2319 if (!*len) { 2312 if (!*len)
2320 rc = 0;
2321 goto out; 2313 goto out;
2322 }
2323 2314
2324 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); 2315 rc = -ENOMEM;
2316 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC);
2325 if (!*names) 2317 if (!*names)
2326 goto err; 2318 goto err;
2327 2319
2328 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); 2320 rc = -ENOMEM;
2321 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC);
2329 if (!*values) 2322 if (!*values)
2330 goto err; 2323 goto err;
2331 2324
2332 for (i = 0; i < *len; i++) { 2325 for (i = 0; i < *len; i++) {
2333 size_t name_len; 2326 size_t name_len;
2327
2334 (*values)[i] = policydb.bool_val_to_struct[i]->state; 2328 (*values)[i] = policydb.bool_val_to_struct[i]->state;
2335 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; 2329 name_len = strlen(sym_name(&policydb, SYM_BOOLS, i)) + 1;
2336 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); 2330
2331 rc = -ENOMEM;
2332 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
2337 if (!(*names)[i]) 2333 if (!(*names)[i])
2338 goto err; 2334 goto err;
2339 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); 2335
2336 strncpy((*names)[i], sym_name(&policydb, SYM_BOOLS, i), name_len);
2340 (*names)[i][name_len - 1] = 0; 2337 (*names)[i][name_len - 1] = 0;
2341 } 2338 }
2342 rc = 0; 2339 rc = 0;
@@ -2355,24 +2352,23 @@ err:
2355 2352
2356int security_set_bools(int len, int *values) 2353int security_set_bools(int len, int *values)
2357{ 2354{
2358 int i, rc = 0; 2355 int i, rc;
2359 int lenp, seqno = 0; 2356 int lenp, seqno = 0;
2360 struct cond_node *cur; 2357 struct cond_node *cur;
2361 2358
2362 write_lock_irq(&policy_rwlock); 2359 write_lock_irq(&policy_rwlock);
2363 2360
2361 rc = -EFAULT;
2364 lenp = policydb.p_bools.nprim; 2362 lenp = policydb.p_bools.nprim;
2365 if (len != lenp) { 2363 if (len != lenp)
2366 rc = -EFAULT;
2367 goto out; 2364 goto out;
2368 }
2369 2365
2370 for (i = 0; i < len; i++) { 2366 for (i = 0; i < len; i++) {
2371 if (!!values[i] != policydb.bool_val_to_struct[i]->state) { 2367 if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
2372 audit_log(current->audit_context, GFP_ATOMIC, 2368 audit_log(current->audit_context, GFP_ATOMIC,
2373 AUDIT_MAC_CONFIG_CHANGE, 2369 AUDIT_MAC_CONFIG_CHANGE,
2374 "bool=%s val=%d old_val=%d auid=%u ses=%u", 2370 "bool=%s val=%d old_val=%d auid=%u ses=%u",
2375 policydb.p_bool_val_to_name[i], 2371 sym_name(&policydb, SYM_BOOLS, i),
2376 !!values[i], 2372 !!values[i],
2377 policydb.bool_val_to_struct[i]->state, 2373 policydb.bool_val_to_struct[i]->state,
2378 audit_get_loginuid(current), 2374 audit_get_loginuid(current),
@@ -2391,7 +2387,7 @@ int security_set_bools(int len, int *values)
2391 } 2387 }
2392 2388
2393 seqno = ++latest_granting; 2389 seqno = ++latest_granting;
2394 2390 rc = 0;
2395out: 2391out:
2396 write_unlock_irq(&policy_rwlock); 2392 write_unlock_irq(&policy_rwlock);
2397 if (!rc) { 2393 if (!rc) {
@@ -2405,16 +2401,15 @@ out:
2405 2401
2406int security_get_bool_value(int bool) 2402int security_get_bool_value(int bool)
2407{ 2403{
2408 int rc = 0; 2404 int rc;
2409 int len; 2405 int len;
2410 2406
2411 read_lock(&policy_rwlock); 2407 read_lock(&policy_rwlock);
2412 2408
2409 rc = -EFAULT;
2413 len = policydb.p_bools.nprim; 2410 len = policydb.p_bools.nprim;
2414 if (bool >= len) { 2411 if (bool >= len)
2415 rc = -EFAULT;
2416 goto out; 2412 goto out;
2417 }
2418 2413
2419 rc = policydb.bool_val_to_struct[bool]->state; 2414 rc = policydb.bool_val_to_struct[bool]->state;
2420out: 2415out:
@@ -2464,8 +2459,9 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2464 struct context newcon; 2459 struct context newcon;
2465 char *s; 2460 char *s;
2466 u32 len; 2461 u32 len;
2467 int rc = 0; 2462 int rc;
2468 2463
2464 rc = 0;
2469 if (!ss_initialized || !policydb.mls_enabled) { 2465 if (!ss_initialized || !policydb.mls_enabled) {
2470 *new_sid = sid; 2466 *new_sid = sid;
2471 goto out; 2467 goto out;
@@ -2474,19 +2470,20 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2474 context_init(&newcon); 2470 context_init(&newcon);
2475 2471
2476 read_lock(&policy_rwlock); 2472 read_lock(&policy_rwlock);
2473
2474 rc = -EINVAL;
2477 context1 = sidtab_search(&sidtab, sid); 2475 context1 = sidtab_search(&sidtab, sid);
2478 if (!context1) { 2476 if (!context1) {
2479 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2477 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2480 __func__, sid); 2478 __func__, sid);
2481 rc = -EINVAL;
2482 goto out_unlock; 2479 goto out_unlock;
2483 } 2480 }
2484 2481
2482 rc = -EINVAL;
2485 context2 = sidtab_search(&sidtab, mls_sid); 2483 context2 = sidtab_search(&sidtab, mls_sid);
2486 if (!context2) { 2484 if (!context2) {
2487 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2485 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2488 __func__, mls_sid); 2486 __func__, mls_sid);
2489 rc = -EINVAL;
2490 goto out_unlock; 2487 goto out_unlock;
2491 } 2488 }
2492 2489
@@ -2500,20 +2497,17 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2500 /* Check the validity of the new context. */ 2497 /* Check the validity of the new context. */
2501 if (!policydb_context_isvalid(&policydb, &newcon)) { 2498 if (!policydb_context_isvalid(&policydb, &newcon)) {
2502 rc = convert_context_handle_invalid_context(&newcon); 2499 rc = convert_context_handle_invalid_context(&newcon);
2503 if (rc) 2500 if (rc) {
2504 goto bad; 2501 if (!context_struct_to_string(&newcon, &s, &len)) {
2502 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2503 "security_sid_mls_copy: invalid context %s", s);
2504 kfree(s);
2505 }
2506 goto out_unlock;
2507 }
2505 } 2508 }
2506 2509
2507 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); 2510 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid);
2508 goto out_unlock;
2509
2510bad:
2511 if (!context_struct_to_string(&newcon, &s, &len)) {
2512 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2513 "security_sid_mls_copy: invalid context %s", s);
2514 kfree(s);
2515 }
2516
2517out_unlock: 2511out_unlock:
2518 read_unlock(&policy_rwlock); 2512 read_unlock(&policy_rwlock);
2519 context_destroy(&newcon); 2513 context_destroy(&newcon);
@@ -2549,6 +2543,8 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2549 struct context *nlbl_ctx; 2543 struct context *nlbl_ctx;
2550 struct context *xfrm_ctx; 2544 struct context *xfrm_ctx;
2551 2545
2546 *peer_sid = SECSID_NULL;
2547
2552 /* handle the common (which also happens to be the set of easy) cases 2548 /* handle the common (which also happens to be the set of easy) cases
2553 * right away, these two if statements catch everything involving a 2549 * right away, these two if statements catch everything involving a
2554 * single or absent peer SID/label */ 2550 * single or absent peer SID/label */
@@ -2567,40 +2563,37 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2567 /* we don't need to check ss_initialized here since the only way both 2563 /* we don't need to check ss_initialized here since the only way both
2568 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2564 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2569 * security server was initialized and ss_initialized was true */ 2565 * security server was initialized and ss_initialized was true */
2570 if (!policydb.mls_enabled) { 2566 if (!policydb.mls_enabled)
2571 *peer_sid = SECSID_NULL;
2572 return 0; 2567 return 0;
2573 }
2574 2568
2575 read_lock(&policy_rwlock); 2569 read_lock(&policy_rwlock);
2576 2570
2571 rc = -EINVAL;
2577 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); 2572 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid);
2578 if (!nlbl_ctx) { 2573 if (!nlbl_ctx) {
2579 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2574 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2580 __func__, nlbl_sid); 2575 __func__, nlbl_sid);
2581 rc = -EINVAL; 2576 goto out;
2582 goto out_slowpath;
2583 } 2577 }
2578 rc = -EINVAL;
2584 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); 2579 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid);
2585 if (!xfrm_ctx) { 2580 if (!xfrm_ctx) {
2586 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2581 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2587 __func__, xfrm_sid); 2582 __func__, xfrm_sid);
2588 rc = -EINVAL; 2583 goto out;
2589 goto out_slowpath;
2590 } 2584 }
2591 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); 2585 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES);
2586 if (rc)
2587 goto out;
2592 2588
2593out_slowpath: 2589 /* at present NetLabel SIDs/labels really only carry MLS
2590 * information so if the MLS portion of the NetLabel SID
2591 * matches the MLS portion of the labeled XFRM SID/label
2592 * then pass along the XFRM SID as it is the most
2593 * expressive */
2594 *peer_sid = xfrm_sid;
2595out:
2594 read_unlock(&policy_rwlock); 2596 read_unlock(&policy_rwlock);
2595 if (rc == 0)
2596 /* at present NetLabel SIDs/labels really only carry MLS
2597 * information so if the MLS portion of the NetLabel SID
2598 * matches the MLS portion of the labeled XFRM SID/label
2599 * then pass along the XFRM SID as it is the most
2600 * expressive */
2601 *peer_sid = xfrm_sid;
2602 else
2603 *peer_sid = SECSID_NULL;
2604 return rc; 2597 return rc;
2605} 2598}
2606 2599
@@ -2619,10 +2612,11 @@ static int get_classes_callback(void *k, void *d, void *args)
2619 2612
2620int security_get_classes(char ***classes, int *nclasses) 2613int security_get_classes(char ***classes, int *nclasses)
2621{ 2614{
2622 int rc = -ENOMEM; 2615 int rc;
2623 2616
2624 read_lock(&policy_rwlock); 2617 read_lock(&policy_rwlock);
2625 2618
2619 rc = -ENOMEM;
2626 *nclasses = policydb.p_classes.nprim; 2620 *nclasses = policydb.p_classes.nprim;
2627 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); 2621 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2628 if (!*classes) 2622 if (!*classes)
@@ -2630,7 +2624,7 @@ int security_get_classes(char ***classes, int *nclasses)
2630 2624
2631 rc = hashtab_map(policydb.p_classes.table, get_classes_callback, 2625 rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
2632 *classes); 2626 *classes);
2633 if (rc < 0) { 2627 if (rc) {
2634 int i; 2628 int i;
2635 for (i = 0; i < *nclasses; i++) 2629 for (i = 0; i < *nclasses; i++)
2636 kfree((*classes)[i]); 2630 kfree((*classes)[i]);
@@ -2657,19 +2651,20 @@ static int get_permissions_callback(void *k, void *d, void *args)
2657 2651
2658int security_get_permissions(char *class, char ***perms, int *nperms) 2652int security_get_permissions(char *class, char ***perms, int *nperms)
2659{ 2653{
2660 int rc = -ENOMEM, i; 2654 int rc, i;
2661 struct class_datum *match; 2655 struct class_datum *match;
2662 2656
2663 read_lock(&policy_rwlock); 2657 read_lock(&policy_rwlock);
2664 2658
2659 rc = -EINVAL;
2665 match = hashtab_search(policydb.p_classes.table, class); 2660 match = hashtab_search(policydb.p_classes.table, class);
2666 if (!match) { 2661 if (!match) {
2667 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", 2662 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n",
2668 __func__, class); 2663 __func__, class);
2669 rc = -EINVAL;
2670 goto out; 2664 goto out;
2671 } 2665 }
2672 2666
2667 rc = -ENOMEM;
2673 *nperms = match->permissions.nprim; 2668 *nperms = match->permissions.nprim;
2674 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC); 2669 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2675 if (!*perms) 2670 if (!*perms)
@@ -2678,13 +2673,13 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2678 if (match->comdatum) { 2673 if (match->comdatum) {
2679 rc = hashtab_map(match->comdatum->permissions.table, 2674 rc = hashtab_map(match->comdatum->permissions.table,
2680 get_permissions_callback, *perms); 2675 get_permissions_callback, *perms);
2681 if (rc < 0) 2676 if (rc)
2682 goto err; 2677 goto err;
2683 } 2678 }
2684 2679
2685 rc = hashtab_map(match->permissions.table, get_permissions_callback, 2680 rc = hashtab_map(match->permissions.table, get_permissions_callback,
2686 *perms); 2681 *perms);
2687 if (rc < 0) 2682 if (rc)
2688 goto err; 2683 goto err;
2689 2684
2690out: 2685out:
@@ -2796,36 +2791,39 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2796 switch (field) { 2791 switch (field) {
2797 case AUDIT_SUBJ_USER: 2792 case AUDIT_SUBJ_USER:
2798 case AUDIT_OBJ_USER: 2793 case AUDIT_OBJ_USER:
2794 rc = -EINVAL;
2799 userdatum = hashtab_search(policydb.p_users.table, rulestr); 2795 userdatum = hashtab_search(policydb.p_users.table, rulestr);
2800 if (!userdatum) 2796 if (!userdatum)
2801 rc = -EINVAL; 2797 goto out;
2802 else 2798 tmprule->au_ctxt.user = userdatum->value;
2803 tmprule->au_ctxt.user = userdatum->value;
2804 break; 2799 break;
2805 case AUDIT_SUBJ_ROLE: 2800 case AUDIT_SUBJ_ROLE:
2806 case AUDIT_OBJ_ROLE: 2801 case AUDIT_OBJ_ROLE:
2802 rc = -EINVAL;
2807 roledatum = hashtab_search(policydb.p_roles.table, rulestr); 2803 roledatum = hashtab_search(policydb.p_roles.table, rulestr);
2808 if (!roledatum) 2804 if (!roledatum)
2809 rc = -EINVAL; 2805 goto out;
2810 else 2806 tmprule->au_ctxt.role = roledatum->value;
2811 tmprule->au_ctxt.role = roledatum->value;
2812 break; 2807 break;
2813 case AUDIT_SUBJ_TYPE: 2808 case AUDIT_SUBJ_TYPE:
2814 case AUDIT_OBJ_TYPE: 2809 case AUDIT_OBJ_TYPE:
2810 rc = -EINVAL;
2815 typedatum = hashtab_search(policydb.p_types.table, rulestr); 2811 typedatum = hashtab_search(policydb.p_types.table, rulestr);
2816 if (!typedatum) 2812 if (!typedatum)
2817 rc = -EINVAL; 2813 goto out;
2818 else 2814 tmprule->au_ctxt.type = typedatum->value;
2819 tmprule->au_ctxt.type = typedatum->value;
2820 break; 2815 break;
2821 case AUDIT_SUBJ_SEN: 2816 case AUDIT_SUBJ_SEN:
2822 case AUDIT_SUBJ_CLR: 2817 case AUDIT_SUBJ_CLR:
2823 case AUDIT_OBJ_LEV_LOW: 2818 case AUDIT_OBJ_LEV_LOW:
2824 case AUDIT_OBJ_LEV_HIGH: 2819 case AUDIT_OBJ_LEV_HIGH:
2825 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); 2820 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
2821 if (rc)
2822 goto out;
2826 break; 2823 break;
2827 } 2824 }
2828 2825 rc = 0;
2826out:
2829 read_unlock(&policy_rwlock); 2827 read_unlock(&policy_rwlock);
2830 2828
2831 if (rc) { 2829 if (rc) {
@@ -3050,7 +3048,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
3050int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, 3048int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3051 u32 *sid) 3049 u32 *sid)
3052{ 3050{
3053 int rc = -EIDRM; 3051 int rc;
3054 struct context *ctx; 3052 struct context *ctx;
3055 struct context ctx_new; 3053 struct context ctx_new;
3056 3054
@@ -3061,16 +3059,15 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3061 3059
3062 read_lock(&policy_rwlock); 3060 read_lock(&policy_rwlock);
3063 3061
3064 if (secattr->flags & NETLBL_SECATTR_CACHE) { 3062 if (secattr->flags & NETLBL_SECATTR_CACHE)
3065 *sid = *(u32 *)secattr->cache->data; 3063 *sid = *(u32 *)secattr->cache->data;
3066 rc = 0; 3064 else if (secattr->flags & NETLBL_SECATTR_SECID)
3067 } else if (secattr->flags & NETLBL_SECATTR_SECID) {
3068 *sid = secattr->attr.secid; 3065 *sid = secattr->attr.secid;
3069 rc = 0; 3066 else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
3070 } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { 3067 rc = -EIDRM;
3071 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG); 3068 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG);
3072 if (ctx == NULL) 3069 if (ctx == NULL)
3073 goto netlbl_secattr_to_sid_return; 3070 goto out;
3074 3071
3075 context_init(&ctx_new); 3072 context_init(&ctx_new);
3076 ctx_new.user = ctx->user; 3073 ctx_new.user = ctx->user;
@@ -3078,34 +3075,35 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3078 ctx_new.type = ctx->type; 3075 ctx_new.type = ctx->type;
3079 mls_import_netlbl_lvl(&ctx_new, secattr); 3076 mls_import_netlbl_lvl(&ctx_new, secattr);
3080 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 3077 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
3081 if (ebitmap_netlbl_import(&ctx_new.range.level[0].cat, 3078 rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat,
3082 secattr->attr.mls.cat) != 0) 3079 secattr->attr.mls.cat);
3083 goto netlbl_secattr_to_sid_return; 3080 if (rc)
3081 goto out;
3084 memcpy(&ctx_new.range.level[1].cat, 3082 memcpy(&ctx_new.range.level[1].cat,
3085 &ctx_new.range.level[0].cat, 3083 &ctx_new.range.level[0].cat,
3086 sizeof(ctx_new.range.level[0].cat)); 3084 sizeof(ctx_new.range.level[0].cat));
3087 } 3085 }
3088 if (mls_context_isvalid(&policydb, &ctx_new) != 1) 3086 rc = -EIDRM;
3089 goto netlbl_secattr_to_sid_return_cleanup; 3087 if (!mls_context_isvalid(&policydb, &ctx_new))
3088 goto out_free;
3090 3089
3091 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); 3090 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
3092 if (rc != 0) 3091 if (rc)
3093 goto netlbl_secattr_to_sid_return_cleanup; 3092 goto out_free;
3094 3093
3095 security_netlbl_cache_add(secattr, *sid); 3094 security_netlbl_cache_add(secattr, *sid);
3096 3095
3097 ebitmap_destroy(&ctx_new.range.level[0].cat); 3096 ebitmap_destroy(&ctx_new.range.level[0].cat);
3098 } else { 3097 } else
3099 *sid = SECSID_NULL; 3098 *sid = SECSID_NULL;
3100 rc = 0;
3101 }
3102 3099
3103netlbl_secattr_to_sid_return:
3104 read_unlock(&policy_rwlock); 3100 read_unlock(&policy_rwlock);
3105 return rc; 3101 return 0;
3106netlbl_secattr_to_sid_return_cleanup: 3102out_free:
3107 ebitmap_destroy(&ctx_new.range.level[0].cat); 3103 ebitmap_destroy(&ctx_new.range.level[0].cat);
3108 goto netlbl_secattr_to_sid_return; 3104out:
3105 read_unlock(&policy_rwlock);
3106 return rc;
3109} 3107}
3110 3108
3111/** 3109/**
@@ -3127,28 +3125,23 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
3127 return 0; 3125 return 0;
3128 3126
3129 read_lock(&policy_rwlock); 3127 read_lock(&policy_rwlock);
3128
3129 rc = -ENOENT;
3130 ctx = sidtab_search(&sidtab, sid); 3130 ctx = sidtab_search(&sidtab, sid);
3131 if (ctx == NULL) { 3131 if (ctx == NULL)
3132 rc = -ENOENT; 3132 goto out;
3133 goto netlbl_sid_to_secattr_failure; 3133
3134 } 3134 rc = -ENOMEM;
3135 secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], 3135 secattr->domain = kstrdup(sym_name(&policydb, SYM_TYPES, ctx->type - 1),
3136 GFP_ATOMIC); 3136 GFP_ATOMIC);
3137 if (secattr->domain == NULL) { 3137 if (secattr->domain == NULL)
3138 rc = -ENOMEM; 3138 goto out;
3139 goto netlbl_sid_to_secattr_failure; 3139
3140 }
3141 secattr->attr.secid = sid; 3140 secattr->attr.secid = sid;
3142 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; 3141 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID;
3143 mls_export_netlbl_lvl(ctx, secattr); 3142 mls_export_netlbl_lvl(ctx, secattr);
3144 rc = mls_export_netlbl_cat(ctx, secattr); 3143 rc = mls_export_netlbl_cat(ctx, secattr);
3145 if (rc != 0) 3144out:
3146 goto netlbl_sid_to_secattr_failure;
3147 read_unlock(&policy_rwlock);
3148
3149 return 0;
3150
3151netlbl_sid_to_secattr_failure:
3152 read_unlock(&policy_rwlock); 3145 read_unlock(&policy_rwlock);
3153 return rc; 3146 return rc;
3154} 3147}
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index e817989764cd..5840a35155fc 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -147,6 +147,17 @@ out:
147 return rc; 147 return rc;
148} 148}
149 149
150static void sidtab_update_cache(struct sidtab *s, struct sidtab_node *n, int loc)
151{
152 BUG_ON(loc >= SIDTAB_CACHE_LEN);
153
154 while (loc > 0) {
155 s->cache[loc] = s->cache[loc - 1];
156 loc--;
157 }
158 s->cache[0] = n;
159}
160
150static inline u32 sidtab_search_context(struct sidtab *s, 161static inline u32 sidtab_search_context(struct sidtab *s,
151 struct context *context) 162 struct context *context)
152{ 163{
@@ -156,14 +167,33 @@ static inline u32 sidtab_search_context(struct sidtab *s,
156 for (i = 0; i < SIDTAB_SIZE; i++) { 167 for (i = 0; i < SIDTAB_SIZE; i++) {
157 cur = s->htable[i]; 168 cur = s->htable[i];
158 while (cur) { 169 while (cur) {
159 if (context_cmp(&cur->context, context)) 170 if (context_cmp(&cur->context, context)) {
171 sidtab_update_cache(s, cur, SIDTAB_CACHE_LEN - 1);
160 return cur->sid; 172 return cur->sid;
173 }
161 cur = cur->next; 174 cur = cur->next;
162 } 175 }
163 } 176 }
164 return 0; 177 return 0;
165} 178}
166 179
180static inline u32 sidtab_search_cache(struct sidtab *s, struct context *context)
181{
182 int i;
183 struct sidtab_node *node;
184
185 for (i = 0; i < SIDTAB_CACHE_LEN; i++) {
186 node = s->cache[i];
187 if (unlikely(!node))
188 return 0;
189 if (context_cmp(&node->context, context)) {
190 sidtab_update_cache(s, node, i);
191 return node->sid;
192 }
193 }
194 return 0;
195}
196
167int sidtab_context_to_sid(struct sidtab *s, 197int sidtab_context_to_sid(struct sidtab *s,
168 struct context *context, 198 struct context *context,
169 u32 *out_sid) 199 u32 *out_sid)
@@ -174,7 +204,9 @@ int sidtab_context_to_sid(struct sidtab *s,
174 204
175 *out_sid = SECSID_NULL; 205 *out_sid = SECSID_NULL;
176 206
177 sid = sidtab_search_context(s, context); 207 sid = sidtab_search_cache(s, context);
208 if (!sid)
209 sid = sidtab_search_context(s, context);
178 if (!sid) { 210 if (!sid) {
179 spin_lock_irqsave(&s->lock, flags); 211 spin_lock_irqsave(&s->lock, flags);
180 /* Rescan now that we hold the lock. */ 212 /* Rescan now that we hold the lock. */
@@ -259,12 +291,15 @@ void sidtab_destroy(struct sidtab *s)
259void sidtab_set(struct sidtab *dst, struct sidtab *src) 291void sidtab_set(struct sidtab *dst, struct sidtab *src)
260{ 292{
261 unsigned long flags; 293 unsigned long flags;
294 int i;
262 295
263 spin_lock_irqsave(&src->lock, flags); 296 spin_lock_irqsave(&src->lock, flags);
264 dst->htable = src->htable; 297 dst->htable = src->htable;
265 dst->nel = src->nel; 298 dst->nel = src->nel;
266 dst->next_sid = src->next_sid; 299 dst->next_sid = src->next_sid;
267 dst->shutdown = 0; 300 dst->shutdown = 0;
301 for (i = 0; i < SIDTAB_CACHE_LEN; i++)
302 dst->cache[i] = NULL;
268 spin_unlock_irqrestore(&src->lock, flags); 303 spin_unlock_irqrestore(&src->lock, flags);
269} 304}
270 305
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
index 64ea5b1cdea4..84dc154d9389 100644
--- a/security/selinux/ss/sidtab.h
+++ b/security/selinux/ss/sidtab.h
@@ -26,6 +26,8 @@ struct sidtab {
26 unsigned int nel; /* number of elements */ 26 unsigned int nel; /* number of elements */
27 unsigned int next_sid; /* next SID to allocate */ 27 unsigned int next_sid; /* next SID to allocate */
28 unsigned char shutdown; 28 unsigned char shutdown;
29#define SIDTAB_CACHE_LEN 3
30 struct sidtab_node *cache[SIDTAB_CACHE_LEN];
29 spinlock_t lock; 31 spinlock_t lock;
30}; 32};
31 33
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 43ae747a5aa4..129c4eb8ffb1 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -51,11 +51,18 @@ struct socket_smack {
51 */ 51 */
52struct inode_smack { 52struct inode_smack {
53 char *smk_inode; /* label of the fso */ 53 char *smk_inode; /* label of the fso */
54 char *smk_task; /* label of the task */
54 struct mutex smk_lock; /* initialization lock */ 55 struct mutex smk_lock; /* initialization lock */
55 int smk_flags; /* smack inode flags */ 56 int smk_flags; /* smack inode flags */
56}; 57};
57 58
59struct task_smack {
60 char *smk_task; /* label used for access control */
61 char *smk_forked; /* label when forked */
62};
63
58#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ 64#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
65#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */
59 66
60/* 67/*
61 * A label access rule. 68 * A label access rule.
@@ -161,6 +168,10 @@ struct smack_known {
161#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */ 168#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */
162 169
163/* 170/*
171 * Flag for transmute access
172 */
173#define MAY_TRANSMUTE 64
174/*
164 * Just to make the common cases easier to deal with 175 * Just to make the common cases easier to deal with
165 */ 176 */
166#define MAY_ANY (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) 177#define MAY_ANY (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
@@ -191,6 +202,7 @@ struct inode_smack *new_inode_smack(char *);
191/* 202/*
192 * These functions are in smack_access.c 203 * These functions are in smack_access.c
193 */ 204 */
205int smk_access_entry(char *, char *);
194int smk_access(char *, char *, int, struct smk_audit_info *); 206int smk_access(char *, char *, int, struct smk_audit_info *);
195int smk_curacc(char *, u32, struct smk_audit_info *); 207int smk_curacc(char *, u32, struct smk_audit_info *);
196int smack_to_cipso(const char *, struct smack_cipso *); 208int smack_to_cipso(const char *, struct smack_cipso *);
@@ -234,6 +246,15 @@ static inline void smack_catset_bit(int cat, char *catsetp)
234} 246}
235 247
236/* 248/*
249 * Is the directory transmuting?
250 */
251static inline int smk_inode_transmutable(const struct inode *isp)
252{
253 struct inode_smack *sip = isp->i_security;
254 return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0;
255}
256
257/*
237 * Present a pointer to the smack label in an inode blob. 258 * Present a pointer to the smack label in an inode blob.
238 */ 259 */
239static inline char *smk_of_inode(const struct inode *isp) 260static inline char *smk_of_inode(const struct inode *isp)
@@ -243,6 +264,30 @@ static inline char *smk_of_inode(const struct inode *isp)
243} 264}
244 265
245/* 266/*
267 * Present a pointer to the smack label in an task blob.
268 */
269static inline char *smk_of_task(const struct task_smack *tsp)
270{
271 return tsp->smk_task;
272}
273
274/*
275 * Present a pointer to the forked smack label in an task blob.
276 */
277static inline char *smk_of_forked(const struct task_smack *tsp)
278{
279 return tsp->smk_forked;
280}
281
282/*
283 * Present a pointer to the smack label in the current task blob.
284 */
285static inline char *smk_of_current(void)
286{
287 return smk_of_task(current_security());
288}
289
290/*
246 * logging functions 291 * logging functions
247 */ 292 */
248#define SMACK_AUDIT_DENIED 0x1 293#define SMACK_AUDIT_DENIED 0x1
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index f4fac64c4da8..7ba8478f599e 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -67,6 +67,46 @@ static u32 smack_next_secid = 10;
67int log_policy = SMACK_AUDIT_DENIED; 67int log_policy = SMACK_AUDIT_DENIED;
68 68
69/** 69/**
70 * smk_access_entry - look up matching access rule
71 * @subject_label: a pointer to the subject's Smack label
72 * @object_label: a pointer to the object's Smack label
73 *
74 * This function looks up the subject/object pair in the
75 * access rule list and returns pointer to the matching rule if found,
76 * NULL otherwise.
77 *
78 * NOTE:
79 * Even though Smack labels are usually shared on smack_list
80 * labels that come in off the network can't be imported
81 * and added to the list for locking reasons.
82 *
83 * Therefore, it is necessary to check the contents of the labels,
84 * not just the pointer values. Of course, in most cases the labels
85 * will be on the list, so checking the pointers may be a worthwhile
86 * optimization.
87 */
88int smk_access_entry(char *subject_label, char *object_label)
89{
90 u32 may = MAY_NOT;
91 struct smack_rule *srp;
92
93 rcu_read_lock();
94 list_for_each_entry_rcu(srp, &smack_rule_list, list) {
95 if (srp->smk_subject == subject_label ||
96 strcmp(srp->smk_subject, subject_label) == 0) {
97 if (srp->smk_object == object_label ||
98 strcmp(srp->smk_object, object_label) == 0) {
99 may = srp->smk_access;
100 break;
101 }
102 }
103 }
104 rcu_read_unlock();
105
106 return may;
107}
108
109/**
70 * smk_access - determine if a subject has a specific access to an object 110 * smk_access - determine if a subject has a specific access to an object
71 * @subject_label: a pointer to the subject's Smack label 111 * @subject_label: a pointer to the subject's Smack label
72 * @object_label: a pointer to the object's Smack label 112 * @object_label: a pointer to the object's Smack label
@@ -90,7 +130,6 @@ int smk_access(char *subject_label, char *object_label, int request,
90 struct smk_audit_info *a) 130 struct smk_audit_info *a)
91{ 131{
92 u32 may = MAY_NOT; 132 u32 may = MAY_NOT;
93 struct smack_rule *srp;
94 int rc = 0; 133 int rc = 0;
95 134
96 /* 135 /*
@@ -144,18 +183,7 @@ int smk_access(char *subject_label, char *object_label, int request,
144 * access (e.g. read is included in readwrite) it's 183 * access (e.g. read is included in readwrite) it's
145 * good. 184 * good.
146 */ 185 */
147 rcu_read_lock(); 186 may = smk_access_entry(subject_label, object_label);
148 list_for_each_entry_rcu(srp, &smack_rule_list, list) {
149 if (srp->smk_subject == subject_label ||
150 strcmp(srp->smk_subject, subject_label) == 0) {
151 if (srp->smk_object == object_label ||
152 strcmp(srp->smk_object, object_label) == 0) {
153 may = srp->smk_access;
154 break;
155 }
156 }
157 }
158 rcu_read_unlock();
159 /* 187 /*
160 * This is a bit map operation. 188 * This is a bit map operation.
161 */ 189 */
@@ -185,7 +213,7 @@ out_audit:
185int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 213int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
186{ 214{
187 int rc; 215 int rc;
188 char *sp = current_security(); 216 char *sp = smk_of_current();
189 217
190 rc = smk_access(sp, obj_label, mode, NULL); 218 rc = smk_access(sp, obj_label, mode, NULL);
191 if (rc == 0) 219 if (rc == 0)
@@ -196,7 +224,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
196 * only one that gets privilege and current does not 224 * only one that gets privilege and current does not
197 * have that label. 225 * have that label.
198 */ 226 */
199 if (smack_onlycap != NULL && smack_onlycap != current->cred->security) 227 if (smack_onlycap != NULL && smack_onlycap != sp)
200 goto out_audit; 228 goto out_audit;
201 229
202 if (capable(CAP_MAC_OVERRIDE)) 230 if (capable(CAP_MAC_OVERRIDE))
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index ccb71a044a1a..533bf3255d7f 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3,12 +3,14 @@
3 * 3 *
4 * This file contains the smack hook function implementations. 4 * This file contains the smack hook function implementations.
5 * 5 *
6 * Author: 6 * Authors:
7 * Casey Schaufler <casey@schaufler-ca.com> 7 * Casey Schaufler <casey@schaufler-ca.com>
8 * Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com>
8 * 9 *
9 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 10 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
10 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. 11 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
11 * Paul Moore <paul.moore@hp.com> 12 * Paul Moore <paul.moore@hp.com>
13 * Copyright (C) 2010 Nokia Corporation
12 * 14 *
13 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2, 16 * it under the terms of the GNU General Public License version 2,
@@ -35,6 +37,9 @@
35 37
36#define task_security(task) (task_cred_xxx((task), security)) 38#define task_security(task) (task_cred_xxx((task), security))
37 39
40#define TRANS_TRUE "TRUE"
41#define TRANS_TRUE_SIZE 4
42
38/** 43/**
39 * smk_fetch - Fetch the smack label from a file. 44 * smk_fetch - Fetch the smack label from a file.
40 * @ip: a pointer to the inode 45 * @ip: a pointer to the inode
@@ -43,7 +48,7 @@
43 * Returns a pointer to the master list entry for the Smack label 48 * Returns a pointer to the master list entry for the Smack label
44 * or NULL if there was no label to fetch. 49 * or NULL if there was no label to fetch.
45 */ 50 */
46static char *smk_fetch(struct inode *ip, struct dentry *dp) 51static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
47{ 52{
48 int rc; 53 int rc;
49 char in[SMK_LABELLEN]; 54 char in[SMK_LABELLEN];
@@ -51,7 +56,7 @@ static char *smk_fetch(struct inode *ip, struct dentry *dp)
51 if (ip->i_op->getxattr == NULL) 56 if (ip->i_op->getxattr == NULL)
52 return NULL; 57 return NULL;
53 58
54 rc = ip->i_op->getxattr(dp, XATTR_NAME_SMACK, in, SMK_LABELLEN); 59 rc = ip->i_op->getxattr(dp, name, in, SMK_LABELLEN);
55 if (rc < 0) 60 if (rc < 0)
56 return NULL; 61 return NULL;
57 62
@@ -103,8 +108,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
103 if (rc != 0) 108 if (rc != 0)
104 return rc; 109 return rc;
105 110
106 sp = current_security(); 111 sp = smk_of_current();
107 tsp = task_security(ctp); 112 tsp = smk_of_task(task_security(ctp));
108 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 113 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
109 smk_ad_setfield_u_tsk(&ad, ctp); 114 smk_ad_setfield_u_tsk(&ad, ctp);
110 115
@@ -138,8 +143,8 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
138 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 143 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
139 smk_ad_setfield_u_tsk(&ad, ptp); 144 smk_ad_setfield_u_tsk(&ad, ptp);
140 145
141 sp = current_security(); 146 sp = smk_of_current();
142 tsp = task_security(ptp); 147 tsp = smk_of_task(task_security(ptp));
143 /* we won't log here, because rc can be overriden */ 148 /* we won't log here, because rc can be overriden */
144 rc = smk_access(tsp, sp, MAY_READWRITE, NULL); 149 rc = smk_access(tsp, sp, MAY_READWRITE, NULL);
145 if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) 150 if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE))
@@ -160,7 +165,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
160static int smack_syslog(int typefrom_file) 165static int smack_syslog(int typefrom_file)
161{ 166{
162 int rc = 0; 167 int rc = 0;
163 char *sp = current_security(); 168 char *sp = smk_of_current();
164 169
165 if (capable(CAP_MAC_OVERRIDE)) 170 if (capable(CAP_MAC_OVERRIDE))
166 return 0; 171 return 0;
@@ -391,6 +396,40 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
391} 396}
392 397
393/* 398/*
399 * BPRM hooks
400 */
401
402static int smack_bprm_set_creds(struct linux_binprm *bprm)
403{
404 struct task_smack *tsp = bprm->cred->security;
405 struct inode_smack *isp;
406 struct dentry *dp;
407 int rc;
408
409 rc = cap_bprm_set_creds(bprm);
410 if (rc != 0)
411 return rc;
412
413 if (bprm->cred_prepared)
414 return 0;
415
416 if (bprm->file == NULL || bprm->file->f_dentry == NULL)
417 return 0;
418
419 dp = bprm->file->f_dentry;
420
421 if (dp->d_inode == NULL)
422 return 0;
423
424 isp = dp->d_inode->i_security;
425
426 if (isp->smk_task != NULL)
427 tsp->smk_task = isp->smk_task;
428
429 return 0;
430}
431
432/*
394 * Inode hooks 433 * Inode hooks
395 */ 434 */
396 435
@@ -402,7 +441,7 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
402 */ 441 */
403static int smack_inode_alloc_security(struct inode *inode) 442static int smack_inode_alloc_security(struct inode *inode)
404{ 443{
405 inode->i_security = new_inode_smack(current_security()); 444 inode->i_security = new_inode_smack(smk_of_current());
406 if (inode->i_security == NULL) 445 if (inode->i_security == NULL)
407 return -ENOMEM; 446 return -ENOMEM;
408 return 0; 447 return 0;
@@ -434,6 +473,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
434 char **name, void **value, size_t *len) 473 char **name, void **value, size_t *len)
435{ 474{
436 char *isp = smk_of_inode(inode); 475 char *isp = smk_of_inode(inode);
476 char *dsp = smk_of_inode(dir);
477 u32 may;
437 478
438 if (name) { 479 if (name) {
439 *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL); 480 *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL);
@@ -442,6 +483,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
442 } 483 }
443 484
444 if (value) { 485 if (value) {
486 may = smk_access_entry(smk_of_current(), dsp);
487
488 /*
489 * If the access rule allows transmutation and
490 * the directory requests transmutation then
491 * by all means transmute.
492 */
493 if (((may & MAY_TRANSMUTE) != 0) && smk_inode_transmutable(dir))
494 isp = dsp;
495
445 *value = kstrdup(isp, GFP_KERNEL); 496 *value = kstrdup(isp, GFP_KERNEL);
446 if (*value == NULL) 497 if (*value == NULL)
447 return -ENOMEM; 498 return -ENOMEM;
@@ -664,7 +715,8 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
664 715
665 if (strcmp(name, XATTR_NAME_SMACK) == 0 || 716 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
666 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || 717 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
667 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { 718 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
719 strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
668 if (!capable(CAP_MAC_ADMIN)) 720 if (!capable(CAP_MAC_ADMIN))
669 rc = -EPERM; 721 rc = -EPERM;
670 /* 722 /*
@@ -674,6 +726,12 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
674 if (size == 0 || size >= SMK_LABELLEN || 726 if (size == 0 || size >= SMK_LABELLEN ||
675 smk_import(value, size) == NULL) 727 smk_import(value, size) == NULL)
676 rc = -EINVAL; 728 rc = -EINVAL;
729 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
730 if (!capable(CAP_MAC_ADMIN))
731 rc = -EPERM;
732 if (size != TRANS_TRUE_SIZE ||
733 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
734 rc = -EINVAL;
677 } else 735 } else
678 rc = cap_inode_setxattr(dentry, name, value, size, flags); 736 rc = cap_inode_setxattr(dentry, name, value, size, flags);
679 737
@@ -700,26 +758,23 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
700static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, 758static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
701 const void *value, size_t size, int flags) 759 const void *value, size_t size, int flags)
702{ 760{
703 struct inode_smack *isp;
704 char *nsp; 761 char *nsp;
762 struct inode_smack *isp = dentry->d_inode->i_security;
705 763
706 /* 764 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
707 * Not SMACK 765 nsp = smk_import(value, size);
708 */ 766 if (nsp != NULL)
709 if (strcmp(name, XATTR_NAME_SMACK)) 767 isp->smk_inode = nsp;
710 return; 768 else
711 769 isp->smk_inode = smack_known_invalid.smk_known;
712 isp = dentry->d_inode->i_security; 770 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
713 771 nsp = smk_import(value, size);
714 /* 772 if (nsp != NULL)
715 * No locking is done here. This is a pointer 773 isp->smk_task = nsp;
716 * assignment. 774 else
717 */ 775 isp->smk_task = smack_known_invalid.smk_known;
718 nsp = smk_import(value, size); 776 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
719 if (nsp != NULL) 777 isp->smk_flags |= SMK_INODE_TRANSMUTE;
720 isp->smk_inode = nsp;
721 else
722 isp->smk_inode = smack_known_invalid.smk_known;
723 778
724 return; 779 return;
725} 780}
@@ -752,12 +807,15 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
752 */ 807 */
753static int smack_inode_removexattr(struct dentry *dentry, const char *name) 808static int smack_inode_removexattr(struct dentry *dentry, const char *name)
754{ 809{
810 struct inode_smack *isp;
755 struct smk_audit_info ad; 811 struct smk_audit_info ad;
756 int rc = 0; 812 int rc = 0;
757 813
758 if (strcmp(name, XATTR_NAME_SMACK) == 0 || 814 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
759 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || 815 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
760 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { 816 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
817 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
818 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
761 if (!capable(CAP_MAC_ADMIN)) 819 if (!capable(CAP_MAC_ADMIN))
762 rc = -EPERM; 820 rc = -EPERM;
763 } else 821 } else
@@ -768,6 +826,11 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
768 if (rc == 0) 826 if (rc == 0)
769 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); 827 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
770 828
829 if (rc == 0) {
830 isp = dentry->d_inode->i_security;
831 isp->smk_task = NULL;
832 }
833
771 return rc; 834 return rc;
772} 835}
773 836
@@ -895,7 +958,7 @@ static int smack_file_permission(struct file *file, int mask)
895 */ 958 */
896static int smack_file_alloc_security(struct file *file) 959static int smack_file_alloc_security(struct file *file)
897{ 960{
898 file->f_security = current_security(); 961 file->f_security = smk_of_current();
899 return 0; 962 return 0;
900} 963}
901 964
@@ -1005,7 +1068,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
1005 */ 1068 */
1006static int smack_file_set_fowner(struct file *file) 1069static int smack_file_set_fowner(struct file *file)
1007{ 1070{
1008 file->f_security = current_security(); 1071 file->f_security = smk_of_current();
1009 return 0; 1072 return 0;
1010} 1073}
1011 1074
@@ -1025,7 +1088,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
1025{ 1088{
1026 struct file *file; 1089 struct file *file;
1027 int rc; 1090 int rc;
1028 char *tsp = tsk->cred->security; 1091 char *tsp = smk_of_task(tsk->cred->security);
1029 struct smk_audit_info ad; 1092 struct smk_audit_info ad;
1030 1093
1031 /* 1094 /*
@@ -1082,7 +1145,9 @@ static int smack_file_receive(struct file *file)
1082 */ 1145 */
1083static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) 1146static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
1084{ 1147{
1085 cred->security = NULL; 1148 cred->security = kzalloc(sizeof(struct task_smack), gfp);
1149 if (cred->security == NULL)
1150 return -ENOMEM;
1086 return 0; 1151 return 0;
1087} 1152}
1088 1153
@@ -1097,7 +1162,7 @@ static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
1097 */ 1162 */
1098static void smack_cred_free(struct cred *cred) 1163static void smack_cred_free(struct cred *cred)
1099{ 1164{
1100 cred->security = NULL; 1165 kfree(cred->security);
1101} 1166}
1102 1167
1103/** 1168/**
@@ -1111,7 +1176,16 @@ static void smack_cred_free(struct cred *cred)
1111static int smack_cred_prepare(struct cred *new, const struct cred *old, 1176static int smack_cred_prepare(struct cred *new, const struct cred *old,
1112 gfp_t gfp) 1177 gfp_t gfp)
1113{ 1178{
1114 new->security = old->security; 1179 struct task_smack *old_tsp = old->security;
1180 struct task_smack *new_tsp;
1181
1182 new_tsp = kzalloc(sizeof(struct task_smack), gfp);
1183 if (new_tsp == NULL)
1184 return -ENOMEM;
1185
1186 new_tsp->smk_task = old_tsp->smk_task;
1187 new_tsp->smk_forked = old_tsp->smk_task;
1188 new->security = new_tsp;
1115 return 0; 1189 return 0;
1116} 1190}
1117 1191
@@ -1124,7 +1198,11 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
1124 */ 1198 */
1125static void smack_cred_transfer(struct cred *new, const struct cred *old) 1199static void smack_cred_transfer(struct cred *new, const struct cred *old)
1126{ 1200{
1127 new->security = old->security; 1201 struct task_smack *old_tsp = old->security;
1202 struct task_smack *new_tsp = new->security;
1203
1204 new_tsp->smk_task = old_tsp->smk_task;
1205 new_tsp->smk_forked = old_tsp->smk_task;
1128} 1206}
1129 1207
1130/** 1208/**
@@ -1136,12 +1214,13 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
1136 */ 1214 */
1137static int smack_kernel_act_as(struct cred *new, u32 secid) 1215static int smack_kernel_act_as(struct cred *new, u32 secid)
1138{ 1216{
1217 struct task_smack *new_tsp = new->security;
1139 char *smack = smack_from_secid(secid); 1218 char *smack = smack_from_secid(secid);
1140 1219
1141 if (smack == NULL) 1220 if (smack == NULL)
1142 return -EINVAL; 1221 return -EINVAL;
1143 1222
1144 new->security = smack; 1223 new_tsp->smk_task = smack;
1145 return 0; 1224 return 0;
1146} 1225}
1147 1226
@@ -1157,8 +1236,10 @@ static int smack_kernel_create_files_as(struct cred *new,
1157 struct inode *inode) 1236 struct inode *inode)
1158{ 1237{
1159 struct inode_smack *isp = inode->i_security; 1238 struct inode_smack *isp = inode->i_security;
1239 struct task_smack *tsp = new->security;
1160 1240
1161 new->security = isp->smk_inode; 1241 tsp->smk_forked = isp->smk_inode;
1242 tsp->smk_task = isp->smk_inode;
1162 return 0; 1243 return 0;
1163} 1244}
1164 1245
@@ -1175,7 +1256,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access)
1175 1256
1176 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1257 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1177 smk_ad_setfield_u_tsk(&ad, p); 1258 smk_ad_setfield_u_tsk(&ad, p);
1178 return smk_curacc(task_security(p), access, &ad); 1259 return smk_curacc(smk_of_task(task_security(p)), access, &ad);
1179} 1260}
1180 1261
1181/** 1262/**
@@ -1221,7 +1302,7 @@ static int smack_task_getsid(struct task_struct *p)
1221 */ 1302 */
1222static void smack_task_getsecid(struct task_struct *p, u32 *secid) 1303static void smack_task_getsecid(struct task_struct *p, u32 *secid)
1223{ 1304{
1224 *secid = smack_to_secid(task_security(p)); 1305 *secid = smack_to_secid(smk_of_task(task_security(p)));
1225} 1306}
1226 1307
1227/** 1308/**
@@ -1333,14 +1414,15 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1333 * can write the receiver. 1414 * can write the receiver.
1334 */ 1415 */
1335 if (secid == 0) 1416 if (secid == 0)
1336 return smk_curacc(task_security(p), MAY_WRITE, &ad); 1417 return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE,
1418 &ad);
1337 /* 1419 /*
1338 * If the secid isn't 0 we're dealing with some USB IO 1420 * If the secid isn't 0 we're dealing with some USB IO
1339 * specific behavior. This is not clean. For one thing 1421 * specific behavior. This is not clean. For one thing
1340 * we can't take privilege into account. 1422 * we can't take privilege into account.
1341 */ 1423 */
1342 return smk_access(smack_from_secid(secid), task_security(p), 1424 return smk_access(smack_from_secid(secid),
1343 MAY_WRITE, &ad); 1425 smk_of_task(task_security(p)), MAY_WRITE, &ad);
1344} 1426}
1345 1427
1346/** 1428/**
@@ -1352,12 +1434,12 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
1352static int smack_task_wait(struct task_struct *p) 1434static int smack_task_wait(struct task_struct *p)
1353{ 1435{
1354 struct smk_audit_info ad; 1436 struct smk_audit_info ad;
1355 char *sp = current_security(); 1437 char *sp = smk_of_current();
1356 char *tsp = task_security(p); 1438 char *tsp = smk_of_forked(task_security(p));
1357 int rc; 1439 int rc;
1358 1440
1359 /* we don't log here, we can be overriden */ 1441 /* we don't log here, we can be overriden */
1360 rc = smk_access(sp, tsp, MAY_WRITE, NULL); 1442 rc = smk_access(tsp, sp, MAY_WRITE, NULL);
1361 if (rc == 0) 1443 if (rc == 0)
1362 goto out_log; 1444 goto out_log;
1363 1445
@@ -1378,7 +1460,7 @@ static int smack_task_wait(struct task_struct *p)
1378 out_log: 1460 out_log:
1379 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1461 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
1380 smk_ad_setfield_u_tsk(&ad, p); 1462 smk_ad_setfield_u_tsk(&ad, p);
1381 smack_log(sp, tsp, MAY_WRITE, rc, &ad); 1463 smack_log(tsp, sp, MAY_WRITE, rc, &ad);
1382 return rc; 1464 return rc;
1383} 1465}
1384 1466
@@ -1392,7 +1474,7 @@ static int smack_task_wait(struct task_struct *p)
1392static void smack_task_to_inode(struct task_struct *p, struct inode *inode) 1474static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1393{ 1475{
1394 struct inode_smack *isp = inode->i_security; 1476 struct inode_smack *isp = inode->i_security;
1395 isp->smk_inode = task_security(p); 1477 isp->smk_inode = smk_of_task(task_security(p));
1396} 1478}
1397 1479
1398/* 1480/*
@@ -1411,7 +1493,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
1411 */ 1493 */
1412static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) 1494static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1413{ 1495{
1414 char *csp = current_security(); 1496 char *csp = smk_of_current();
1415 struct socket_smack *ssp; 1497 struct socket_smack *ssp;
1416 1498
1417 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); 1499 ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
@@ -1667,10 +1749,13 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1667 ssp->smk_in = sp; 1749 ssp->smk_in = sp;
1668 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 1750 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
1669 ssp->smk_out = sp; 1751 ssp->smk_out = sp;
1670 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 1752 if (sock->sk->sk_family != PF_UNIX) {
1671 if (rc != 0) 1753 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
1672 printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", 1754 if (rc != 0)
1673 __func__, -rc); 1755 printk(KERN_WARNING
1756 "Smack: \"%s\" netlbl error %d.\n",
1757 __func__, -rc);
1758 }
1674 } else 1759 } else
1675 return -EOPNOTSUPP; 1760 return -EOPNOTSUPP;
1676 1761
@@ -1749,7 +1834,7 @@ static int smack_flags_to_may(int flags)
1749 */ 1834 */
1750static int smack_msg_msg_alloc_security(struct msg_msg *msg) 1835static int smack_msg_msg_alloc_security(struct msg_msg *msg)
1751{ 1836{
1752 msg->security = current_security(); 1837 msg->security = smk_of_current();
1753 return 0; 1838 return 0;
1754} 1839}
1755 1840
@@ -1785,7 +1870,7 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp)
1785{ 1870{
1786 struct kern_ipc_perm *isp = &shp->shm_perm; 1871 struct kern_ipc_perm *isp = &shp->shm_perm;
1787 1872
1788 isp->security = current_security(); 1873 isp->security = smk_of_current();
1789 return 0; 1874 return 0;
1790} 1875}
1791 1876
@@ -1908,7 +1993,7 @@ static int smack_sem_alloc_security(struct sem_array *sma)
1908{ 1993{
1909 struct kern_ipc_perm *isp = &sma->sem_perm; 1994 struct kern_ipc_perm *isp = &sma->sem_perm;
1910 1995
1911 isp->security = current_security(); 1996 isp->security = smk_of_current();
1912 return 0; 1997 return 0;
1913} 1998}
1914 1999
@@ -2026,7 +2111,7 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq)
2026{ 2111{
2027 struct kern_ipc_perm *kisp = &msq->q_perm; 2112 struct kern_ipc_perm *kisp = &msq->q_perm;
2028 2113
2029 kisp->security = current_security(); 2114 kisp->security = smk_of_current();
2030 return 0; 2115 return 0;
2031} 2116}
2032 2117
@@ -2198,9 +2283,11 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2198 struct super_block *sbp; 2283 struct super_block *sbp;
2199 struct superblock_smack *sbsp; 2284 struct superblock_smack *sbsp;
2200 struct inode_smack *isp; 2285 struct inode_smack *isp;
2201 char *csp = current_security(); 2286 char *csp = smk_of_current();
2202 char *fetched; 2287 char *fetched;
2203 char *final; 2288 char *final;
2289 char trattr[TRANS_TRUE_SIZE];
2290 int transflag = 0;
2204 struct dentry *dp; 2291 struct dentry *dp;
2205 2292
2206 if (inode == NULL) 2293 if (inode == NULL)
@@ -2267,9 +2354,10 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2267 break; 2354 break;
2268 case SOCKFS_MAGIC: 2355 case SOCKFS_MAGIC:
2269 /* 2356 /*
2270 * Casey says sockets get the smack of the task. 2357 * Socket access is controlled by the socket
2358 * structures associated with the task involved.
2271 */ 2359 */
2272 final = csp; 2360 final = smack_known_star.smk_known;
2273 break; 2361 break;
2274 case PROC_SUPER_MAGIC: 2362 case PROC_SUPER_MAGIC:
2275 /* 2363 /*
@@ -2296,7 +2384,16 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2296 /* 2384 /*
2297 * This isn't an understood special case. 2385 * This isn't an understood special case.
2298 * Get the value from the xattr. 2386 * Get the value from the xattr.
2299 * 2387 */
2388
2389 /*
2390 * UNIX domain sockets use lower level socket data.
2391 */
2392 if (S_ISSOCK(inode->i_mode)) {
2393 final = smack_known_star.smk_known;
2394 break;
2395 }
2396 /*
2300 * No xattr support means, alas, no SMACK label. 2397 * No xattr support means, alas, no SMACK label.
2301 * Use the aforeapplied default. 2398 * Use the aforeapplied default.
2302 * It would be curious if the label of the task 2399 * It would be curious if the label of the task
@@ -2308,9 +2405,21 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2308 * Get the dentry for xattr. 2405 * Get the dentry for xattr.
2309 */ 2406 */
2310 dp = dget(opt_dentry); 2407 dp = dget(opt_dentry);
2311 fetched = smk_fetch(inode, dp); 2408 fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp);
2312 if (fetched != NULL) 2409 if (fetched != NULL) {
2313 final = fetched; 2410 final = fetched;
2411 if (S_ISDIR(inode->i_mode)) {
2412 trattr[0] = '\0';
2413 inode->i_op->getxattr(dp,
2414 XATTR_NAME_SMACKTRANSMUTE,
2415 trattr, TRANS_TRUE_SIZE);
2416 if (strncmp(trattr, TRANS_TRUE,
2417 TRANS_TRUE_SIZE) == 0)
2418 transflag = SMK_INODE_TRANSMUTE;
2419 }
2420 }
2421 isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
2422
2314 dput(dp); 2423 dput(dp);
2315 break; 2424 break;
2316 } 2425 }
@@ -2320,7 +2429,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2320 else 2429 else
2321 isp->smk_inode = final; 2430 isp->smk_inode = final;
2322 2431
2323 isp->smk_flags |= SMK_INODE_INSTANT; 2432 isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
2324 2433
2325unlockandout: 2434unlockandout:
2326 mutex_unlock(&isp->smk_lock); 2435 mutex_unlock(&isp->smk_lock);
@@ -2345,7 +2454,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2345 if (strcmp(name, "current") != 0) 2454 if (strcmp(name, "current") != 0)
2346 return -EINVAL; 2455 return -EINVAL;
2347 2456
2348 cp = kstrdup(task_security(p), GFP_KERNEL); 2457 cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL);
2349 if (cp == NULL) 2458 if (cp == NULL)
2350 return -ENOMEM; 2459 return -ENOMEM;
2351 2460
@@ -2369,6 +2478,8 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
2369static int smack_setprocattr(struct task_struct *p, char *name, 2478static int smack_setprocattr(struct task_struct *p, char *name,
2370 void *value, size_t size) 2479 void *value, size_t size)
2371{ 2480{
2481 struct task_smack *tsp;
2482 struct task_smack *oldtsp;
2372 struct cred *new; 2483 struct cred *new;
2373 char *newsmack; 2484 char *newsmack;
2374 2485
@@ -2398,10 +2509,18 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2398 if (newsmack == smack_known_web.smk_known) 2509 if (newsmack == smack_known_web.smk_known)
2399 return -EPERM; 2510 return -EPERM;
2400 2511
2512 oldtsp = p->cred->security;
2401 new = prepare_creds(); 2513 new = prepare_creds();
2402 if (new == NULL) 2514 if (new == NULL)
2403 return -ENOMEM; 2515 return -ENOMEM;
2404 new->security = newsmack; 2516 tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL);
2517 if (tsp == NULL) {
2518 kfree(new);
2519 return -ENOMEM;
2520 }
2521 tsp->smk_task = newsmack;
2522 tsp->smk_forked = oldtsp->smk_forked;
2523 new->security = tsp;
2405 commit_creds(new); 2524 commit_creds(new);
2406 return size; 2525 return size;
2407} 2526}
@@ -2418,14 +2537,18 @@ static int smack_setprocattr(struct task_struct *p, char *name,
2418static int smack_unix_stream_connect(struct sock *sock, 2537static int smack_unix_stream_connect(struct sock *sock,
2419 struct sock *other, struct sock *newsk) 2538 struct sock *other, struct sock *newsk)
2420{ 2539{
2421 struct inode *sp = SOCK_INODE(sock->sk_socket); 2540 struct socket_smack *ssp = sock->sk_security;
2422 struct inode *op = SOCK_INODE(other->sk_socket); 2541 struct socket_smack *osp = other->sk_security;
2423 struct smk_audit_info ad; 2542 struct smk_audit_info ad;
2543 int rc = 0;
2424 2544
2425 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); 2545 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2426 smk_ad_setfield_u_net_sk(&ad, other); 2546 smk_ad_setfield_u_net_sk(&ad, other);
2427 return smk_access(smk_of_inode(sp), smk_of_inode(op), 2547
2428 MAY_READWRITE, &ad); 2548 if (!capable(CAP_MAC_OVERRIDE))
2549 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2550
2551 return rc;
2429} 2552}
2430 2553
2431/** 2554/**
@@ -2438,13 +2561,18 @@ static int smack_unix_stream_connect(struct sock *sock,
2438 */ 2561 */
2439static int smack_unix_may_send(struct socket *sock, struct socket *other) 2562static int smack_unix_may_send(struct socket *sock, struct socket *other)
2440{ 2563{
2441 struct inode *sp = SOCK_INODE(sock); 2564 struct socket_smack *ssp = sock->sk->sk_security;
2442 struct inode *op = SOCK_INODE(other); 2565 struct socket_smack *osp = other->sk->sk_security;
2443 struct smk_audit_info ad; 2566 struct smk_audit_info ad;
2567 int rc = 0;
2444 2568
2445 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); 2569 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2446 smk_ad_setfield_u_net_sk(&ad, other->sk); 2570 smk_ad_setfield_u_net_sk(&ad, other->sk);
2447 return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad); 2571
2572 if (!capable(CAP_MAC_OVERRIDE))
2573 rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
2574
2575 return rc;
2448} 2576}
2449 2577
2450/** 2578/**
@@ -2629,7 +2757,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
2629 2757
2630/** 2758/**
2631 * smack_socket_getpeersec_dgram - pull in packet label 2759 * smack_socket_getpeersec_dgram - pull in packet label
2632 * @sock: the socket 2760 * @sock: the peer socket
2633 * @skb: packet data 2761 * @skb: packet data
2634 * @secid: pointer to where to put the secid of the packet 2762 * @secid: pointer to where to put the secid of the packet
2635 * 2763 *
@@ -2640,41 +2768,39 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2640 2768
2641{ 2769{
2642 struct netlbl_lsm_secattr secattr; 2770 struct netlbl_lsm_secattr secattr;
2643 struct sock *sk; 2771 struct socket_smack *sp;
2644 char smack[SMK_LABELLEN]; 2772 char smack[SMK_LABELLEN];
2645 int family = PF_INET; 2773 int family = PF_UNSPEC;
2646 u32 s; 2774 u32 s = 0; /* 0 is the invalid secid */
2647 int rc; 2775 int rc;
2648 2776
2649 /* 2777 if (skb != NULL) {
2650 * Only works for families with packets. 2778 if (skb->protocol == htons(ETH_P_IP))
2651 */ 2779 family = PF_INET;
2652 if (sock != NULL) { 2780 else if (skb->protocol == htons(ETH_P_IPV6))
2653 sk = sock->sk; 2781 family = PF_INET6;
2654 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
2655 return 0;
2656 family = sk->sk_family;
2657 } 2782 }
2658 /* 2783 if (family == PF_UNSPEC && sock != NULL)
2659 * Translate what netlabel gave us. 2784 family = sock->sk->sk_family;
2660 */
2661 netlbl_secattr_init(&secattr);
2662 rc = netlbl_skbuff_getattr(skb, family, &secattr);
2663 if (rc == 0)
2664 smack_from_secattr(&secattr, smack);
2665 netlbl_secattr_destroy(&secattr);
2666 2785
2667 /* 2786 if (family == PF_UNIX) {
2668 * Give up if we couldn't get anything 2787 sp = sock->sk->sk_security;
2669 */ 2788 s = smack_to_secid(sp->smk_out);
2670 if (rc != 0) 2789 } else if (family == PF_INET || family == PF_INET6) {
2671 return rc; 2790 /*
2672 2791 * Translate what netlabel gave us.
2673 s = smack_to_secid(smack); 2792 */
2793 netlbl_secattr_init(&secattr);
2794 rc = netlbl_skbuff_getattr(skb, family, &secattr);
2795 if (rc == 0) {
2796 smack_from_secattr(&secattr, smack);
2797 s = smack_to_secid(smack);
2798 }
2799 netlbl_secattr_destroy(&secattr);
2800 }
2801 *secid = s;
2674 if (s == 0) 2802 if (s == 0)
2675 return -EINVAL; 2803 return -EINVAL;
2676
2677 *secid = s;
2678 return 0; 2804 return 0;
2679} 2805}
2680 2806
@@ -2695,7 +2821,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
2695 return; 2821 return;
2696 2822
2697 ssp = sk->sk_security; 2823 ssp = sk->sk_security;
2698 ssp->smk_in = ssp->smk_out = current_security(); 2824 ssp->smk_in = ssp->smk_out = smk_of_current();
2699 /* cssp->smk_packet is already set in smack_inet_csk_clone() */ 2825 /* cssp->smk_packet is already set in smack_inet_csk_clone() */
2700} 2826}
2701 2827
@@ -2816,7 +2942,7 @@ static void smack_inet_csk_clone(struct sock *sk,
2816static int smack_key_alloc(struct key *key, const struct cred *cred, 2942static int smack_key_alloc(struct key *key, const struct cred *cred,
2817 unsigned long flags) 2943 unsigned long flags)
2818{ 2944{
2819 key->security = cred->security; 2945 key->security = smk_of_task(cred->security);
2820 return 0; 2946 return 0;
2821} 2947}
2822 2948
@@ -2845,6 +2971,7 @@ static int smack_key_permission(key_ref_t key_ref,
2845{ 2971{
2846 struct key *keyp; 2972 struct key *keyp;
2847 struct smk_audit_info ad; 2973 struct smk_audit_info ad;
2974 char *tsp = smk_of_task(cred->security);
2848 2975
2849 keyp = key_ref_to_ptr(key_ref); 2976 keyp = key_ref_to_ptr(key_ref);
2850 if (keyp == NULL) 2977 if (keyp == NULL)
@@ -2858,14 +2985,14 @@ static int smack_key_permission(key_ref_t key_ref,
2858 /* 2985 /*
2859 * This should not occur 2986 * This should not occur
2860 */ 2987 */
2861 if (cred->security == NULL) 2988 if (tsp == NULL)
2862 return -EACCES; 2989 return -EACCES;
2863#ifdef CONFIG_AUDIT 2990#ifdef CONFIG_AUDIT
2864 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); 2991 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
2865 ad.a.u.key_struct.key = keyp->serial; 2992 ad.a.u.key_struct.key = keyp->serial;
2866 ad.a.u.key_struct.key_desc = keyp->description; 2993 ad.a.u.key_struct.key_desc = keyp->description;
2867#endif 2994#endif
2868 return smk_access(cred->security, keyp->security, 2995 return smk_access(tsp, keyp->security,
2869 MAY_READWRITE, &ad); 2996 MAY_READWRITE, &ad);
2870} 2997}
2871#endif /* CONFIG_KEYS */ 2998#endif /* CONFIG_KEYS */
@@ -3067,6 +3194,8 @@ struct security_operations smack_ops = {
3067 .sb_mount = smack_sb_mount, 3194 .sb_mount = smack_sb_mount,
3068 .sb_umount = smack_sb_umount, 3195 .sb_umount = smack_sb_umount,
3069 3196
3197 .bprm_set_creds = smack_bprm_set_creds,
3198
3070 .inode_alloc_security = smack_inode_alloc_security, 3199 .inode_alloc_security = smack_inode_alloc_security,
3071 .inode_free_security = smack_inode_free_security, 3200 .inode_free_security = smack_inode_free_security,
3072 .inode_init_security = smack_inode_init_security, 3201 .inode_init_security = smack_inode_init_security,
@@ -3203,9 +3332,16 @@ static __init void init_smack_know_list(void)
3203static __init int smack_init(void) 3332static __init int smack_init(void)
3204{ 3333{
3205 struct cred *cred; 3334 struct cred *cred;
3335 struct task_smack *tsp;
3206 3336
3207 if (!security_module_enable(&smack_ops)) 3337 tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL);
3338 if (tsp == NULL)
3339 return -ENOMEM;
3340
3341 if (!security_module_enable(&smack_ops)) {
3342 kfree(tsp);
3208 return 0; 3343 return 0;
3344 }
3209 3345
3210 printk(KERN_INFO "Smack: Initializing.\n"); 3346 printk(KERN_INFO "Smack: Initializing.\n");
3211 3347
@@ -3213,7 +3349,9 @@ static __init int smack_init(void)
3213 * Set the security state for the initial task. 3349 * Set the security state for the initial task.
3214 */ 3350 */
3215 cred = (struct cred *) current->cred; 3351 cred = (struct cred *) current->cred;
3216 cred->security = &smack_known_floor.smk_known; 3352 tsp->smk_forked = smack_known_floor.smk_known;
3353 tsp->smk_task = smack_known_floor.smk_known;
3354 cred->security = tsp;
3217 3355
3218 /* initialize the smack_know_list */ 3356 /* initialize the smack_know_list */
3219 init_smack_know_list(); 3357 init_smack_know_list();
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index dc1fd6239f24..362d5eda948b 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -109,9 +109,12 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION;
109 * SMK_ACCESSLEN: Maximum length for a rule access field 109 * SMK_ACCESSLEN: Maximum length for a rule access field
110 * SMK_LOADLEN: Smack rule length 110 * SMK_LOADLEN: Smack rule length
111 */ 111 */
112#define SMK_ACCESS "rwxa" 112#define SMK_OACCESS "rwxa"
113#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) 113#define SMK_ACCESS "rwxat"
114#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) 114#define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1)
115#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
116#define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
117#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
115 118
116/** 119/**
117 * smk_netlabel_audit_set - fill a netlbl_audit struct 120 * smk_netlabel_audit_set - fill a netlbl_audit struct
@@ -121,7 +124,7 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
121{ 124{
122 nap->loginuid = audit_get_loginuid(current); 125 nap->loginuid = audit_get_loginuid(current);
123 nap->sessionid = audit_get_sessionid(current); 126 nap->sessionid = audit_get_sessionid(current);
124 nap->secid = smack_to_secid(current_security()); 127 nap->secid = smack_to_secid(smk_of_current());
125} 128}
126 129
127/* 130/*
@@ -175,6 +178,8 @@ static int load_seq_show(struct seq_file *s, void *v)
175 seq_putc(s, 'x'); 178 seq_putc(s, 'x');
176 if (srp->smk_access & MAY_APPEND) 179 if (srp->smk_access & MAY_APPEND)
177 seq_putc(s, 'a'); 180 seq_putc(s, 'a');
181 if (srp->smk_access & MAY_TRANSMUTE)
182 seq_putc(s, 't');
178 if (srp->smk_access == 0) 183 if (srp->smk_access == 0)
179 seq_putc(s, '-'); 184 seq_putc(s, '-');
180 185
@@ -273,10 +278,15 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
273 if (!capable(CAP_MAC_ADMIN)) 278 if (!capable(CAP_MAC_ADMIN))
274 return -EPERM; 279 return -EPERM;
275 280
276 if (*ppos != 0 || count != SMK_LOADLEN) 281 if (*ppos != 0)
282 return -EINVAL;
283 /*
284 * Minor hack for backward compatability
285 */
286 if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN)
277 return -EINVAL; 287 return -EINVAL;
278 288
279 data = kzalloc(count, GFP_KERNEL); 289 data = kzalloc(SMK_LOADLEN, GFP_KERNEL);
280 if (data == NULL) 290 if (data == NULL)
281 return -ENOMEM; 291 return -ENOMEM;
282 292
@@ -285,6 +295,12 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
285 goto out; 295 goto out;
286 } 296 }
287 297
298 /*
299 * More on the minor hack for backward compatability
300 */
301 if (count == (SMK_OLOADLEN))
302 data[SMK_OLOADLEN] = '-';
303
288 rule = kzalloc(sizeof(*rule), GFP_KERNEL); 304 rule = kzalloc(sizeof(*rule), GFP_KERNEL);
289 if (rule == NULL) { 305 if (rule == NULL) {
290 rc = -ENOMEM; 306 rc = -ENOMEM;
@@ -345,6 +361,17 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
345 goto out_free_rule; 361 goto out_free_rule;
346 } 362 }
347 363
364 switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) {
365 case '-':
366 break;
367 case 't':
368 case 'T':
369 rule->smk_access |= MAY_TRANSMUTE;
370 break;
371 default:
372 goto out_free_rule;
373 }
374
348 rc = smk_set_access(rule); 375 rc = smk_set_access(rule);
349 376
350 if (!rc) 377 if (!rc)
@@ -1160,7 +1187,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1160 size_t count, loff_t *ppos) 1187 size_t count, loff_t *ppos)
1161{ 1188{
1162 char in[SMK_LABELLEN]; 1189 char in[SMK_LABELLEN];
1163 char *sp = current->cred->security; 1190 char *sp = smk_of_task(current->cred->security);
1164 1191
1165 if (!capable(CAP_MAC_ADMIN)) 1192 if (!capable(CAP_MAC_ADMIN))
1166 return -EPERM; 1193 return -EPERM;