aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/inode.c33
-rw-r--r--security/security.c8
-rw-r--r--security/selinux/hooks.c45
-rw-r--r--security/selinux/ss/avtab.c8
-rw-r--r--security/selinux/ss/conditional.c18
-rw-r--r--security/selinux/ss/conditional.h2
-rw-r--r--security/selinux/ss/ebitmap.c4
-rw-r--r--security/selinux/ss/hashtab.c6
-rw-r--r--security/selinux/ss/mls.c14
-rw-r--r--security/selinux/ss/policydb.c20
-rw-r--r--security/selinux/ss/services.c8
-rw-r--r--security/selinux/ss/sidtab.c12
-rw-r--r--security/smack/smack.h1
-rw-r--r--security/smack/smack_access.c10
-rw-r--r--security/smack/smackfs.c92
15 files changed, 193 insertions, 88 deletions
diff --git a/security/inode.c b/security/inode.c
index acc6cf0d7900..ca4958ebad8d 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -190,7 +190,7 @@ static int create_by_name(const char *name, mode_t mode,
190 * @name: a pointer to a string containing the name of the file to create. 190 * @name: a pointer to a string containing the name of the file to create.
191 * @mode: the permission that the file should have 191 * @mode: the permission that the file should have
192 * @parent: a pointer to the parent dentry for this file. This should be a 192 * @parent: a pointer to the parent dentry for this file. This should be a
193 * directory dentry if set. If this paramater is NULL, then the 193 * directory dentry if set. If this parameter is %NULL, then the
194 * file will be created in the root of the securityfs filesystem. 194 * file will be created in the root of the securityfs filesystem.
195 * @data: a pointer to something that the caller will want to get to later 195 * @data: a pointer to something that the caller will want to get to later
196 * on. The inode.i_private pointer will point to this value on 196 * on. The inode.i_private pointer will point to this value on
@@ -199,18 +199,18 @@ static int create_by_name(const char *name, mode_t mode,
199 * this file. 199 * this file.
200 * 200 *
201 * This is the basic "create a file" function for securityfs. It allows for a 201 * This is the basic "create a file" function for securityfs. It allows for a
202 * wide range of flexibility in createing a file, or a directory (if you 202 * wide range of flexibility in creating a file, or a directory (if you
203 * want to create a directory, the securityfs_create_dir() function is 203 * want to create a directory, the securityfs_create_dir() function is
204 * recommended to be used instead.) 204 * recommended to be used instead).
205 * 205 *
206 * This function will return a pointer to a dentry if it succeeds. This 206 * This function returns a pointer to a dentry if it succeeds. This
207 * pointer must be passed to the securityfs_remove() function when the file is 207 * pointer must be passed to the securityfs_remove() function when the file is
208 * to be removed (no automatic cleanup happens if your module is unloaded, 208 * to be removed (no automatic cleanup happens if your module is unloaded,
209 * you are responsible here.) If an error occurs, NULL will be returned. 209 * you are responsible here). If an error occurs, %NULL is returned.
210 * 210 *
211 * If securityfs is not enabled in the kernel, the value -ENODEV will be 211 * If securityfs is not enabled in the kernel, the value %-ENODEV is
212 * returned. It is not wise to check for this value, but rather, check for 212 * returned. It is not wise to check for this value, but rather, check for
213 * NULL or !NULL instead as to eliminate the need for #ifdef in the calling 213 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
214 * code. 214 * code.
215 */ 215 */
216struct dentry *securityfs_create_file(const char *name, mode_t mode, 216struct dentry *securityfs_create_file(const char *name, mode_t mode,
@@ -252,19 +252,19 @@ EXPORT_SYMBOL_GPL(securityfs_create_file);
252 * @name: a pointer to a string containing the name of the directory to 252 * @name: a pointer to a string containing the name of the directory to
253 * create. 253 * create.
254 * @parent: a pointer to the parent dentry for this file. This should be a 254 * @parent: a pointer to the parent dentry for this file. This should be a
255 * directory dentry if set. If this paramater is NULL, then the 255 * directory dentry if set. If this parameter is %NULL, then the
256 * directory will be created in the root of the securityfs filesystem. 256 * directory will be created in the root of the securityfs filesystem.
257 * 257 *
258 * This function creates a directory in securityfs with the given name. 258 * This function creates a directory in securityfs with the given @name.
259 * 259 *
260 * This function will return a pointer to a dentry if it succeeds. This 260 * This function returns a pointer to a dentry if it succeeds. This
261 * pointer must be passed to the securityfs_remove() function when the file is 261 * pointer must be passed to the securityfs_remove() function when the file is
262 * to be removed (no automatic cleanup happens if your module is unloaded, 262 * to be removed (no automatic cleanup happens if your module is unloaded,
263 * you are responsible here.) If an error occurs, NULL will be returned. 263 * you are responsible here). If an error occurs, %NULL will be returned.
264 * 264 *
265 * If securityfs is not enabled in the kernel, the value -ENODEV will be 265 * If securityfs is not enabled in the kernel, the value %-ENODEV is
266 * returned. It is not wise to check for this value, but rather, check for 266 * returned. It is not wise to check for this value, but rather, check for
267 * NULL or !NULL instead as to eliminate the need for #ifdef in the calling 267 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
268 * code. 268 * code.
269 */ 269 */
270struct dentry *securityfs_create_dir(const char *name, struct dentry *parent) 270struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
@@ -278,16 +278,15 @@ EXPORT_SYMBOL_GPL(securityfs_create_dir);
278/** 278/**
279 * securityfs_remove - removes a file or directory from the securityfs filesystem 279 * securityfs_remove - removes a file or directory from the securityfs filesystem
280 * 280 *
281 * @dentry: a pointer to a the dentry of the file or directory to be 281 * @dentry: a pointer to a the dentry of the file or directory to be removed.
282 * removed.
283 * 282 *
284 * This function removes a file or directory in securityfs that was previously 283 * This function removes a file or directory in securityfs that was previously
285 * created with a call to another securityfs function (like 284 * created with a call to another securityfs function (like
286 * securityfs_create_file() or variants thereof.) 285 * securityfs_create_file() or variants thereof.)
287 * 286 *
288 * This function is required to be called in order for the file to be 287 * This function is required to be called in order for the file to be
289 * removed, no automatic cleanup of files will happen when a module is 288 * removed. No automatic cleanup of files will happen when a module is
290 * removed, you are responsible here. 289 * removed; you are responsible here.
291 */ 290 */
292void securityfs_remove(struct dentry *dentry) 291void securityfs_remove(struct dentry *dentry)
293{ 292{
diff --git a/security/security.c b/security/security.c
index 3a4b4f55b33f..255b08559b2b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -82,8 +82,8 @@ __setup("security=", choose_lsm);
82 * 82 *
83 * Return true if: 83 * Return true if:
84 * -The passed LSM is the one chosen by user at boot time, 84 * -The passed LSM is the one chosen by user at boot time,
85 * -or user didsn't specify a specific LSM and we're the first to ask 85 * -or user didn't specify a specific LSM and we're the first to ask
86 * for registeration permissoin, 86 * for registration permission,
87 * -or the passed LSM is currently loaded. 87 * -or the passed LSM is currently loaded.
88 * Otherwise, return false. 88 * Otherwise, return false.
89 */ 89 */
@@ -101,13 +101,13 @@ int __init security_module_enable(struct security_operations *ops)
101 * register_security - registers a security framework with the kernel 101 * register_security - registers a security framework with the kernel
102 * @ops: a pointer to the struct security_options that is to be registered 102 * @ops: a pointer to the struct security_options that is to be registered
103 * 103 *
104 * This function is to allow a security module to register itself with the 104 * This function allows a security module to register itself with the
105 * kernel security subsystem. Some rudimentary checking is done on the @ops 105 * kernel security subsystem. Some rudimentary checking is done on the @ops
106 * value passed to this function. You'll need to check first if your LSM 106 * value passed to this function. You'll need to check first if your LSM
107 * is allowed to register its @ops by calling security_module_enable(@ops). 107 * is allowed to register its @ops by calling security_module_enable(@ops).
108 * 108 *
109 * If there is already a security module registered with the kernel, 109 * If there is already a security module registered with the kernel,
110 * an error will be returned. Otherwise 0 is returned on success. 110 * an error will be returned. Otherwise %0 is returned on success.
111 */ 111 */
112int register_security(struct security_operations *ops) 112int register_security(struct security_operations *ops)
113{ 113{
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 03fc6a81ae32..6b5790bba8f9 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -957,7 +957,8 @@ out_err:
957 return rc; 957 return rc;
958} 958}
959 959
960void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts) 960static void selinux_write_opts(struct seq_file *m,
961 struct security_mnt_opts *opts)
961{ 962{
962 int i; 963 int i;
963 char *prefix; 964 char *prefix;
@@ -3548,38 +3549,44 @@ out:
3548#endif /* IPV6 */ 3549#endif /* IPV6 */
3549 3550
3550static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, 3551static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
3551 char **addrp, int src, u8 *proto) 3552 char **_addrp, int src, u8 *proto)
3552{ 3553{
3553 int ret = 0; 3554 char *addrp;
3555 int ret;
3554 3556
3555 switch (ad->u.net.family) { 3557 switch (ad->u.net.family) {
3556 case PF_INET: 3558 case PF_INET:
3557 ret = selinux_parse_skb_ipv4(skb, ad, proto); 3559 ret = selinux_parse_skb_ipv4(skb, ad, proto);
3558 if (ret || !addrp) 3560 if (ret)
3559 break; 3561 goto parse_error;
3560 *addrp = (char *)(src ? &ad->u.net.v4info.saddr : 3562 addrp = (char *)(src ? &ad->u.net.v4info.saddr :
3561 &ad->u.net.v4info.daddr); 3563 &ad->u.net.v4info.daddr);
3562 break; 3564 goto okay;
3563 3565
3564#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 3566#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3565 case PF_INET6: 3567 case PF_INET6:
3566 ret = selinux_parse_skb_ipv6(skb, ad, proto); 3568 ret = selinux_parse_skb_ipv6(skb, ad, proto);
3567 if (ret || !addrp) 3569 if (ret)
3568 break; 3570 goto parse_error;
3569 *addrp = (char *)(src ? &ad->u.net.v6info.saddr : 3571 addrp = (char *)(src ? &ad->u.net.v6info.saddr :
3570 &ad->u.net.v6info.daddr); 3572 &ad->u.net.v6info.daddr);
3571 break; 3573 goto okay;
3572#endif /* IPV6 */ 3574#endif /* IPV6 */
3573 default: 3575 default:
3574 break; 3576 addrp = NULL;
3577 goto okay;
3575 } 3578 }
3576 3579
3577 if (unlikely(ret)) 3580parse_error:
3578 printk(KERN_WARNING 3581 printk(KERN_WARNING
3579 "SELinux: failure in selinux_parse_skb()," 3582 "SELinux: failure in selinux_parse_skb(),"
3580 " unable to parse packet\n"); 3583 " unable to parse packet\n");
3581
3582 return ret; 3584 return ret;
3585
3586okay:
3587 if (_addrp)
3588 *_addrp = addrp;
3589 return 0;
3583} 3590}
3584 3591
3585/** 3592/**
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index a1be97f8beea..1215b8e47dba 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -98,7 +98,7 @@ struct avtab_node *
98avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datum *datum) 98avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datum *datum)
99{ 99{
100 int hvalue; 100 int hvalue;
101 struct avtab_node *prev, *cur, *newnode; 101 struct avtab_node *prev, *cur;
102 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD); 102 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
103 103
104 if (!h || !h->htable) 104 if (!h || !h->htable)
@@ -122,9 +122,7 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu
122 key->target_class < cur->key.target_class) 122 key->target_class < cur->key.target_class)
123 break; 123 break;
124 } 124 }
125 newnode = avtab_insert_node(h, hvalue, prev, cur, key, datum); 125 return avtab_insert_node(h, hvalue, prev, cur, key, datum);
126
127 return newnode;
128} 126}
129 127
130struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key) 128struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
@@ -231,7 +229,7 @@ void avtab_destroy(struct avtab *h)
231 229
232 for (i = 0; i < h->nslot; i++) { 230 for (i = 0; i < h->nslot; i++) {
233 cur = h->htable[i]; 231 cur = h->htable[i];
234 while (cur != NULL) { 232 while (cur) {
235 temp = cur; 233 temp = cur;
236 cur = cur->next; 234 cur = cur->next;
237 kmem_cache_free(avtab_node_cachep, temp); 235 kmem_cache_free(avtab_node_cachep, temp);
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index fb4efe4f4bc8..4a4e35cac22b 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -29,7 +29,7 @@ static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr)
29 int s[COND_EXPR_MAXDEPTH]; 29 int s[COND_EXPR_MAXDEPTH];
30 int sp = -1; 30 int sp = -1;
31 31
32 for (cur = expr; cur != NULL; cur = cur->next) { 32 for (cur = expr; cur; cur = cur->next) {
33 switch (cur->expr_type) { 33 switch (cur->expr_type) {
34 case COND_BOOL: 34 case COND_BOOL:
35 if (sp == (COND_EXPR_MAXDEPTH - 1)) 35 if (sp == (COND_EXPR_MAXDEPTH - 1))
@@ -97,14 +97,14 @@ int evaluate_cond_node(struct policydb *p, struct cond_node *node)
97 if (new_state == -1) 97 if (new_state == -1)
98 printk(KERN_ERR "SELinux: expression result was undefined - disabling all rules.\n"); 98 printk(KERN_ERR "SELinux: expression result was undefined - disabling all rules.\n");
99 /* turn the rules on or off */ 99 /* turn the rules on or off */
100 for (cur = node->true_list; cur != NULL; cur = cur->next) { 100 for (cur = node->true_list; cur; cur = cur->next) {
101 if (new_state <= 0) 101 if (new_state <= 0)
102 cur->node->key.specified &= ~AVTAB_ENABLED; 102 cur->node->key.specified &= ~AVTAB_ENABLED;
103 else 103 else
104 cur->node->key.specified |= AVTAB_ENABLED; 104 cur->node->key.specified |= AVTAB_ENABLED;
105 } 105 }
106 106
107 for (cur = node->false_list; cur != NULL; cur = cur->next) { 107 for (cur = node->false_list; cur; cur = cur->next) {
108 /* -1 or 1 */ 108 /* -1 or 1 */
109 if (new_state) 109 if (new_state)
110 cur->node->key.specified &= ~AVTAB_ENABLED; 110 cur->node->key.specified &= ~AVTAB_ENABLED;
@@ -128,7 +128,7 @@ int cond_policydb_init(struct policydb *p)
128static void cond_av_list_destroy(struct cond_av_list *list) 128static void cond_av_list_destroy(struct cond_av_list *list)
129{ 129{
130 struct cond_av_list *cur, *next; 130 struct cond_av_list *cur, *next;
131 for (cur = list; cur != NULL; cur = next) { 131 for (cur = list; cur; cur = next) {
132 next = cur->next; 132 next = cur->next;
133 /* the avtab_ptr_t node is destroy by the avtab */ 133 /* the avtab_ptr_t node is destroy by the avtab */
134 kfree(cur); 134 kfree(cur);
@@ -139,7 +139,7 @@ static void cond_node_destroy(struct cond_node *node)
139{ 139{
140 struct cond_expr *cur_expr, *next_expr; 140 struct cond_expr *cur_expr, *next_expr;
141 141
142 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = next_expr) { 142 for (cur_expr = node->expr; cur_expr; cur_expr = next_expr) {
143 next_expr = cur_expr->next; 143 next_expr = cur_expr->next;
144 kfree(cur_expr); 144 kfree(cur_expr);
145 } 145 }
@@ -155,7 +155,7 @@ static void cond_list_destroy(struct cond_node *list)
155 if (list == NULL) 155 if (list == NULL)
156 return; 156 return;
157 157
158 for (cur = list; cur != NULL; cur = next) { 158 for (cur = list; cur; cur = next) {
159 next = cur->next; 159 next = cur->next;
160 cond_node_destroy(cur); 160 cond_node_destroy(cur);
161 } 161 }
@@ -239,7 +239,7 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
239 rc = next_entry(key, fp, len); 239 rc = next_entry(key, fp, len);
240 if (rc < 0) 240 if (rc < 0)
241 goto err; 241 goto err;
242 key[len] = 0; 242 key[len] = '\0';
243 if (hashtab_insert(h, key, booldatum)) 243 if (hashtab_insert(h, key, booldatum))
244 goto err; 244 goto err;
245 245
@@ -291,7 +291,7 @@ static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum
291 goto err; 291 goto err;
292 } 292 }
293 found = 0; 293 found = 0;
294 for (cur = other; cur != NULL; cur = cur->next) { 294 for (cur = other; cur; cur = cur->next) {
295 if (cur->node == node_ptr) { 295 if (cur->node == node_ptr) {
296 found = 1; 296 found = 1;
297 break; 297 break;
@@ -485,7 +485,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decisi
485 if (!ctab || !key || !avd) 485 if (!ctab || !key || !avd)
486 return; 486 return;
487 487
488 for (node = avtab_search_node(ctab, key); node != NULL; 488 for (node = avtab_search_node(ctab, key); node;
489 node = avtab_search_node_next(node, key->specified)) { 489 node = avtab_search_node_next(node, key->specified)) {
490 if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) == 490 if ((u16)(AVTAB_ALLOWED|AVTAB_ENABLED) ==
491 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) 491 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED)))
diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h
index 65b9f8366e9c..53ddb013ae57 100644
--- a/security/selinux/ss/conditional.h
+++ b/security/selinux/ss/conditional.h
@@ -28,7 +28,7 @@ struct cond_expr {
28#define COND_XOR 5 /* bool ^ bool */ 28#define COND_XOR 5 /* bool ^ bool */
29#define COND_EQ 6 /* bool == bool */ 29#define COND_EQ 6 /* bool == bool */
30#define COND_NEQ 7 /* bool != bool */ 30#define COND_NEQ 7 /* bool != bool */
31#define COND_LAST 8 31#define COND_LAST COND_NEQ
32 __u32 expr_type; 32 __u32 expr_type;
33 __u32 bool; 33 __u32 bool;
34 struct cond_expr *next; 34 struct cond_expr *next;
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index ddc275490af8..68c7348d1acc 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -109,7 +109,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
109 *catmap = c_iter; 109 *catmap = c_iter;
110 c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1); 110 c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1);
111 111
112 while (e_iter != NULL) { 112 while (e_iter) {
113 for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { 113 for (i = 0; i < EBITMAP_UNIT_NUMS; i++) {
114 unsigned int delta, e_startbit, c_endbit; 114 unsigned int delta, e_startbit, c_endbit;
115 115
@@ -197,7 +197,7 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap,
197 } 197 }
198 } 198 }
199 c_iter = c_iter->next; 199 c_iter = c_iter->next;
200 } while (c_iter != NULL); 200 } while (c_iter);
201 if (e_iter != NULL) 201 if (e_iter != NULL)
202 ebmap->highbit = e_iter->startbit + EBITMAP_SIZE; 202 ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
203 else 203 else
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c
index 2e7788e13213..933e735bb185 100644
--- a/security/selinux/ss/hashtab.c
+++ b/security/selinux/ss/hashtab.c
@@ -81,7 +81,7 @@ void *hashtab_search(struct hashtab *h, const void *key)
81 81
82 hvalue = h->hash_value(h, key); 82 hvalue = h->hash_value(h, key);
83 cur = h->htable[hvalue]; 83 cur = h->htable[hvalue];
84 while (cur != NULL && h->keycmp(h, key, cur->key) > 0) 84 while (cur && h->keycmp(h, key, cur->key) > 0)
85 cur = cur->next; 85 cur = cur->next;
86 86
87 if (cur == NULL || (h->keycmp(h, key, cur->key) != 0)) 87 if (cur == NULL || (h->keycmp(h, key, cur->key) != 0))
@@ -100,7 +100,7 @@ void hashtab_destroy(struct hashtab *h)
100 100
101 for (i = 0; i < h->size; i++) { 101 for (i = 0; i < h->size; i++) {
102 cur = h->htable[i]; 102 cur = h->htable[i];
103 while (cur != NULL) { 103 while (cur) {
104 temp = cur; 104 temp = cur;
105 cur = cur->next; 105 cur = cur->next;
106 kfree(temp); 106 kfree(temp);
@@ -127,7 +127,7 @@ int hashtab_map(struct hashtab *h,
127 127
128 for (i = 0; i < h->size; i++) { 128 for (i = 0; i < h->size; i++) {
129 cur = h->htable[i]; 129 cur = h->htable[i];
130 while (cur != NULL) { 130 while (cur) {
131 ret = apply(cur->key, cur->datum, args); 131 ret = apply(cur->key, cur->datum, args);
132 if (ret) 132 if (ret)
133 return ret; 133 return ret;
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 77d745da48bb..b5407f16c2a4 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -283,8 +283,8 @@ int mls_context_to_sid(struct policydb *pol,
283 p++; 283 p++;
284 284
285 delim = *p; 285 delim = *p;
286 if (delim != 0) 286 if (delim != '\0')
287 *p++ = 0; 287 *p++ = '\0';
288 288
289 for (l = 0; l < 2; l++) { 289 for (l = 0; l < 2; l++) {
290 levdatum = hashtab_search(pol->p_levels.table, scontextp); 290 levdatum = hashtab_search(pol->p_levels.table, scontextp);
@@ -302,14 +302,14 @@ int mls_context_to_sid(struct policydb *pol,
302 while (*p && *p != ',' && *p != '-') 302 while (*p && *p != ',' && *p != '-')
303 p++; 303 p++;
304 delim = *p; 304 delim = *p;
305 if (delim != 0) 305 if (delim != '\0')
306 *p++ = 0; 306 *p++ = '\0';
307 307
308 /* Separate into range if exists */ 308 /* Separate into range if exists */
309 rngptr = strchr(scontextp, '.'); 309 rngptr = strchr(scontextp, '.');
310 if (rngptr != NULL) { 310 if (rngptr != NULL) {
311 /* Remove '.' */ 311 /* Remove '.' */
312 *rngptr++ = 0; 312 *rngptr++ = '\0';
313 } 313 }
314 314
315 catdatum = hashtab_search(pol->p_cats.table, 315 catdatum = hashtab_search(pol->p_cats.table,
@@ -357,8 +357,8 @@ int mls_context_to_sid(struct policydb *pol,
357 p++; 357 p++;
358 358
359 delim = *p; 359 delim = *p;
360 if (delim != 0) 360 if (delim != '\0')
361 *p++ = 0; 361 *p++ = '\0';
362 } else 362 } else
363 break; 363 break;
364 } 364 }
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 2391761ae422..26646305dc0e 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -932,7 +932,7 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
932 rc = next_entry(key, fp, len); 932 rc = next_entry(key, fp, len);
933 if (rc < 0) 933 if (rc < 0)
934 goto bad; 934 goto bad;
935 key[len] = 0; 935 key[len] = '\0';
936 936
937 rc = hashtab_insert(h, key, perdatum); 937 rc = hashtab_insert(h, key, perdatum);
938 if (rc) 938 if (rc)
@@ -979,7 +979,7 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
979 rc = next_entry(key, fp, len); 979 rc = next_entry(key, fp, len);
980 if (rc < 0) 980 if (rc < 0)
981 goto bad; 981 goto bad;
982 key[len] = 0; 982 key[len] = '\0';
983 983
984 for (i = 0; i < nel; i++) { 984 for (i = 0; i < nel; i++) {
985 rc = perm_read(p, comdatum->permissions.table, fp); 985 rc = perm_read(p, comdatum->permissions.table, fp);
@@ -1117,7 +1117,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1117 rc = next_entry(key, fp, len); 1117 rc = next_entry(key, fp, len);
1118 if (rc < 0) 1118 if (rc < 0)
1119 goto bad; 1119 goto bad;
1120 key[len] = 0; 1120 key[len] = '\0';
1121 1121
1122 if (len2) { 1122 if (len2) {
1123 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); 1123 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
@@ -1128,7 +1128,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1128 rc = next_entry(cladatum->comkey, fp, len2); 1128 rc = next_entry(cladatum->comkey, fp, len2);
1129 if (rc < 0) 1129 if (rc < 0)
1130 goto bad; 1130 goto bad;
1131 cladatum->comkey[len2] = 0; 1131 cladatum->comkey[len2] = '\0';
1132 1132
1133 cladatum->comdatum = hashtab_search(p->p_commons.table, 1133 cladatum->comdatum = hashtab_search(p->p_commons.table,
1134 cladatum->comkey); 1134 cladatum->comkey);
@@ -1201,7 +1201,7 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1201 rc = next_entry(key, fp, len); 1201 rc = next_entry(key, fp, len);
1202 if (rc < 0) 1202 if (rc < 0)
1203 goto bad; 1203 goto bad;
1204 key[len] = 0; 1204 key[len] = '\0';
1205 1205
1206 rc = ebitmap_read(&role->dominates, fp); 1206 rc = ebitmap_read(&role->dominates, fp);
1207 if (rc) 1207 if (rc)
@@ -1262,7 +1262,7 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1262 rc = next_entry(key, fp, len); 1262 rc = next_entry(key, fp, len);
1263 if (rc < 0) 1263 if (rc < 0)
1264 goto bad; 1264 goto bad;
1265 key[len] = 0; 1265 key[len] = '\0';
1266 1266
1267 rc = hashtab_insert(h, key, typdatum); 1267 rc = hashtab_insert(h, key, typdatum);
1268 if (rc) 1268 if (rc)
@@ -1334,7 +1334,7 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1334 rc = next_entry(key, fp, len); 1334 rc = next_entry(key, fp, len);
1335 if (rc < 0) 1335 if (rc < 0)
1336 goto bad; 1336 goto bad;
1337 key[len] = 0; 1337 key[len] = '\0';
1338 1338
1339 rc = ebitmap_read(&usrdatum->roles, fp); 1339 rc = ebitmap_read(&usrdatum->roles, fp);
1340 if (rc) 1340 if (rc)
@@ -1388,7 +1388,7 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1388 rc = next_entry(key, fp, len); 1388 rc = next_entry(key, fp, len);
1389 if (rc < 0) 1389 if (rc < 0)
1390 goto bad; 1390 goto bad;
1391 key[len] = 0; 1391 key[len] = '\0';
1392 1392
1393 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); 1393 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
1394 if (!levdatum->level) { 1394 if (!levdatum->level) {
@@ -1440,7 +1440,7 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1440 rc = next_entry(key, fp, len); 1440 rc = next_entry(key, fp, len);
1441 if (rc < 0) 1441 if (rc < 0)
1442 goto bad; 1442 goto bad;
1443 key[len] = 0; 1443 key[len] = '\0';
1444 1444
1445 rc = hashtab_insert(h, key, catdatum); 1445 rc = hashtab_insert(h, key, catdatum);
1446 if (rc) 1446 if (rc)
@@ -1523,7 +1523,7 @@ int policydb_read(struct policydb *p, void *fp)
1523 kfree(policydb_str); 1523 kfree(policydb_str);
1524 goto bad; 1524 goto bad;
1525 } 1525 }
1526 policydb_str[len] = 0; 1526 policydb_str[len] = '\0';
1527 if (strcmp(policydb_str, POLICYDB_STRING)) { 1527 if (strcmp(policydb_str, POLICYDB_STRING)) {
1528 printk(KERN_ERR "SELinux: policydb string %s does not match " 1528 printk(KERN_ERR "SELinux: policydb string %s does not match "
1529 "my string %s\n", policydb_str, POLICYDB_STRING); 1529 "my string %s\n", policydb_str, POLICYDB_STRING);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b52f923ce680..5a0536bddc63 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -356,7 +356,7 @@ static int context_struct_compute_av(struct context *scontext,
356 avkey.source_type = i + 1; 356 avkey.source_type = i + 1;
357 avkey.target_type = j + 1; 357 avkey.target_type = j + 1;
358 for (node = avtab_search_node(&policydb.te_avtab, &avkey); 358 for (node = avtab_search_node(&policydb.te_avtab, &avkey);
359 node != NULL; 359 node;
360 node = avtab_search_node_next(node, avkey.specified)) { 360 node = avtab_search_node_next(node, avkey.specified)) {
361 if (node->key.specified == AVTAB_ALLOWED) 361 if (node->key.specified == AVTAB_ALLOWED)
362 avd->allowed |= node->datum.data; 362 avd->allowed |= node->datum.data;
@@ -1037,7 +1037,7 @@ static int security_compute_sid(u32 ssid,
1037 /* If no permanent rule, also check for enabled conditional rules */ 1037 /* If no permanent rule, also check for enabled conditional rules */
1038 if (!avdatum) { 1038 if (!avdatum) {
1039 node = avtab_search_node(&policydb.te_cond_avtab, &avkey); 1039 node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
1040 for (; node != NULL; node = avtab_search_node_next(node, specified)) { 1040 for (; node; node = avtab_search_node_next(node, specified)) {
1041 if (node->key.specified & AVTAB_ENABLED) { 1041 if (node->key.specified & AVTAB_ENABLED) {
1042 avdatum = &node->datum; 1042 avdatum = &node->datum;
1043 break; 1043 break;
@@ -2050,7 +2050,7 @@ int security_set_bools(int len, int *values)
2050 policydb.bool_val_to_struct[i]->state = 0; 2050 policydb.bool_val_to_struct[i]->state = 0;
2051 } 2051 }
2052 2052
2053 for (cur = policydb.cond_list; cur != NULL; cur = cur->next) { 2053 for (cur = policydb.cond_list; cur; cur = cur->next) {
2054 rc = evaluate_cond_node(&policydb, cur); 2054 rc = evaluate_cond_node(&policydb, cur);
2055 if (rc) 2055 if (rc)
2056 goto out; 2056 goto out;
@@ -2102,7 +2102,7 @@ static int security_preserve_bools(struct policydb *p)
2102 if (booldatum) 2102 if (booldatum)
2103 booldatum->state = bvalues[i]; 2103 booldatum->state = bvalues[i];
2104 } 2104 }
2105 for (cur = p->cond_list; cur != NULL; cur = cur->next) { 2105 for (cur = p->cond_list; cur; cur = cur->next) {
2106 rc = evaluate_cond_node(p, cur); 2106 rc = evaluate_cond_node(p, cur);
2107 if (rc) 2107 if (rc)
2108 goto out; 2108 goto out;
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index a81ded104129..e817989764cd 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -43,7 +43,7 @@ int sidtab_insert(struct sidtab *s, u32 sid, struct context *context)
43 hvalue = SIDTAB_HASH(sid); 43 hvalue = SIDTAB_HASH(sid);
44 prev = NULL; 44 prev = NULL;
45 cur = s->htable[hvalue]; 45 cur = s->htable[hvalue];
46 while (cur != NULL && sid > cur->sid) { 46 while (cur && sid > cur->sid) {
47 prev = cur; 47 prev = cur;
48 cur = cur->next; 48 cur = cur->next;
49 } 49 }
@@ -92,7 +92,7 @@ static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force)
92 92
93 hvalue = SIDTAB_HASH(sid); 93 hvalue = SIDTAB_HASH(sid);
94 cur = s->htable[hvalue]; 94 cur = s->htable[hvalue];
95 while (cur != NULL && sid > cur->sid) 95 while (cur && sid > cur->sid)
96 cur = cur->next; 96 cur = cur->next;
97 97
98 if (force && cur && sid == cur->sid && cur->context.len) 98 if (force && cur && sid == cur->sid && cur->context.len)
@@ -103,7 +103,7 @@ static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force)
103 sid = SECINITSID_UNLABELED; 103 sid = SECINITSID_UNLABELED;
104 hvalue = SIDTAB_HASH(sid); 104 hvalue = SIDTAB_HASH(sid);
105 cur = s->htable[hvalue]; 105 cur = s->htable[hvalue];
106 while (cur != NULL && sid > cur->sid) 106 while (cur && sid > cur->sid)
107 cur = cur->next; 107 cur = cur->next;
108 if (!cur || sid != cur->sid) 108 if (!cur || sid != cur->sid)
109 return NULL; 109 return NULL;
@@ -136,7 +136,7 @@ int sidtab_map(struct sidtab *s,
136 136
137 for (i = 0; i < SIDTAB_SIZE; i++) { 137 for (i = 0; i < SIDTAB_SIZE; i++) {
138 cur = s->htable[i]; 138 cur = s->htable[i];
139 while (cur != NULL) { 139 while (cur) {
140 rc = apply(cur->sid, &cur->context, args); 140 rc = apply(cur->sid, &cur->context, args);
141 if (rc) 141 if (rc)
142 goto out; 142 goto out;
@@ -155,7 +155,7 @@ static inline u32 sidtab_search_context(struct sidtab *s,
155 155
156 for (i = 0; i < SIDTAB_SIZE; i++) { 156 for (i = 0; i < SIDTAB_SIZE; i++) {
157 cur = s->htable[i]; 157 cur = s->htable[i];
158 while (cur != NULL) { 158 while (cur) {
159 if (context_cmp(&cur->context, context)) 159 if (context_cmp(&cur->context, context))
160 return cur->sid; 160 return cur->sid;
161 cur = cur->next; 161 cur = cur->next;
@@ -242,7 +242,7 @@ void sidtab_destroy(struct sidtab *s)
242 242
243 for (i = 0; i < SIDTAB_SIZE; i++) { 243 for (i = 0; i < SIDTAB_SIZE; i++) {
244 cur = s->htable[i]; 244 cur = s->htable[i];
245 while (cur != NULL) { 245 while (cur) {
246 temp = cur; 246 temp = cur;
247 cur = cur->next; 247 cur = cur->next;
248 context_destroy(&temp->context); 248 context_destroy(&temp->context);
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 4a4477f5afdc..31dce559595a 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -178,6 +178,7 @@ u32 smack_to_secid(const char *);
178extern int smack_cipso_direct; 178extern int smack_cipso_direct;
179extern int smack_net_nltype; 179extern int smack_net_nltype;
180extern char *smack_net_ambient; 180extern char *smack_net_ambient;
181extern char *smack_onlycap;
181 182
182extern struct smack_known *smack_known; 183extern struct smack_known *smack_known;
183extern struct smack_known smack_known_floor; 184extern struct smack_known smack_known_floor;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index f6b5f6eed6dd..79ff21ed4c3b 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -157,7 +157,7 @@ int smk_access(char *subject_label, char *object_label, int request)
157 * 157 *
158 * This function checks the current subject label/object label pair 158 * This function checks the current subject label/object label pair
159 * in the access rule list and returns 0 if the access is permitted, 159 * in the access rule list and returns 0 if the access is permitted,
160 * non zero otherwise. It allows that current my have the capability 160 * non zero otherwise. It allows that current may have the capability
161 * to override the rules. 161 * to override the rules.
162 */ 162 */
163int smk_curacc(char *obj_label, u32 mode) 163int smk_curacc(char *obj_label, u32 mode)
@@ -168,6 +168,14 @@ int smk_curacc(char *obj_label, u32 mode)
168 if (rc == 0) 168 if (rc == 0)
169 return 0; 169 return 0;
170 170
171 /*
172 * Return if a specific label has been designated as the
173 * only one that gets privilege and current does not
174 * have that label.
175 */
176 if (smack_onlycap != NULL && smack_onlycap != current->security)
177 return rc;
178
171 if (capable(CAP_MAC_OVERRIDE)) 179 if (capable(CAP_MAC_OVERRIDE))
172 return 0; 180 return 0;
173 181
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 271a835fbbe3..e7c642458ec9 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -39,6 +39,7 @@ enum smk_inos {
39 SMK_DIRECT = 6, /* CIPSO level indicating direct label */ 39 SMK_DIRECT = 6, /* CIPSO level indicating direct label */
40 SMK_AMBIENT = 7, /* internet ambient label */ 40 SMK_AMBIENT = 7, /* internet ambient label */
41 SMK_NLTYPE = 8, /* label scheme to use by default */ 41 SMK_NLTYPE = 8, /* label scheme to use by default */
42 SMK_ONLYCAP = 9, /* the only "capable" label */
42}; 43};
43 44
44/* 45/*
@@ -68,6 +69,16 @@ int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4;
68 */ 69 */
69int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT; 70int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
70 71
72/*
73 * Unless a process is running with this label even
74 * having CAP_MAC_OVERRIDE isn't enough to grant
75 * privilege to violate MAC policy. If no label is
76 * designated (the NULL case) capabilities apply to
77 * everyone. It is expected that the hat (^) label
78 * will be used if any label is used.
79 */
80char *smack_onlycap;
81
71static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; 82static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
72struct smk_list_entry *smack_list; 83struct smk_list_entry *smack_list;
73 84
@@ -787,6 +798,85 @@ static const struct file_operations smk_ambient_ops = {
787 .write = smk_write_ambient, 798 .write = smk_write_ambient,
788}; 799};
789 800
801/**
802 * smk_read_onlycap - read() for /smack/onlycap
803 * @filp: file pointer, not actually used
804 * @buf: where to put the result
805 * @cn: maximum to send along
806 * @ppos: where to start
807 *
808 * Returns number of bytes read or error code, as appropriate
809 */
810static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
811 size_t cn, loff_t *ppos)
812{
813 char *smack = "";
814 ssize_t rc = -EINVAL;
815 int asize;
816
817 if (*ppos != 0)
818 return 0;
819
820 if (smack_onlycap != NULL)
821 smack = smack_onlycap;
822
823 asize = strlen(smack) + 1;
824
825 if (cn >= asize)
826 rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
827
828 return rc;
829}
830
831/**
832 * smk_write_onlycap - write() for /smack/onlycap
833 * @filp: file pointer, not actually used
834 * @buf: where to get the data from
835 * @count: bytes sent
836 * @ppos: where to start
837 *
838 * Returns number of bytes written or error code, as appropriate
839 */
840static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
841 size_t count, loff_t *ppos)
842{
843 char in[SMK_LABELLEN];
844 char *sp = current->security;
845
846 if (!capable(CAP_MAC_ADMIN))
847 return -EPERM;
848
849 /*
850 * This can be done using smk_access() but is done
851 * explicitly for clarity. The smk_access() implementation
852 * would use smk_access(smack_onlycap, MAY_WRITE)
853 */
854 if (smack_onlycap != NULL && smack_onlycap != sp)
855 return -EPERM;
856
857 if (count >= SMK_LABELLEN)
858 return -EINVAL;
859
860 if (copy_from_user(in, buf, count) != 0)
861 return -EFAULT;
862
863 /*
864 * Should the null string be passed in unset the onlycap value.
865 * This seems like something to be careful with as usually
866 * smk_import only expects to return NULL for errors. It
867 * is usually the case that a nullstring or "\n" would be
868 * bad to pass to smk_import but in fact this is useful here.
869 */
870 smack_onlycap = smk_import(in, count);
871
872 return count;
873}
874
875static const struct file_operations smk_onlycap_ops = {
876 .read = smk_read_onlycap,
877 .write = smk_write_onlycap,
878};
879
790struct option_names { 880struct option_names {
791 int o_number; 881 int o_number;
792 char *o_name; 882 char *o_name;
@@ -919,6 +1009,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
919 {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, 1009 {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
920 [SMK_NLTYPE] = 1010 [SMK_NLTYPE] =
921 {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR}, 1011 {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR},
1012 [SMK_ONLYCAP] =
1013 {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
922 /* last one */ {""} 1014 /* last one */ {""}
923 }; 1015 };
924 1016