aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-21 12:06:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-21 12:06:02 -0500
commitfb2e2c85375a0380d6818f153ffa2ae9ebbd055f (patch)
treecf8498a01357c220e4d664ff67125f60146f0da3 /security
parentec513b16c480c6cdda1e3d597e611eafca05227b (diff)
parent923b49ff69fcbffe6f8b2739de218c45544392a7 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security layer updates from James Morris: "Changes for this kernel include maintenance updates for Smack, SELinux (and several networking fixes), IMA and TPM" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (39 commits) SELinux: Fix memory leak upon loading policy tpm/tpm-sysfs: active_show() can be static tpm: tpm_tis: Fix compile problems with CONFIG_PM_SLEEP/CONFIG_PNP tpm: Make tpm-dev allocate a per-file structure tpm: Use the ops structure instead of a copy in tpm_vendor_specific tpm: Create a tpm_class_ops structure and use it in the drivers tpm: Pull all driver sysfs code into tpm-sysfs.c tpm: Move sysfs functions from tpm-interface to tpm-sysfs tpm: Pull everything related to /dev/tpmX into tpm-dev.c char: tpm: nuvoton: remove unused variable tpm: MAINTAINERS: Cleanup TPM Maintainers file tpm/tpm_i2c_atmel: fix coccinelle warnings tpm/tpm_ibmvtpm: fix unreachable code warning (smatch warning) tpm/tpm_i2c_stm_st33: Check return code of get_burstcount tpm/tpm_ppi: Check return value of acpi_get_name tpm/tpm_ppi: Do not compare strcmp(a,b) == -1 ima: remove unneeded size_limit argument from ima_eventdigest_init_common() ima: update IMA-templates.txt documentation ima: pass HASH_ALGO__LAST as hash algo in ima_eventdigest_init() ima: change the default hash algorithm to SHA1 in ima_eventdigest_ng_init() ...
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima_template_lib.c18
-rw-r--r--security/selinux/hooks.c7
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/netlabel.c31
-rw-r--r--security/selinux/ss/constraint.h1
-rw-r--r--security/selinux/ss/policydb.c110
-rw-r--r--security/selinux/ss/policydb.h11
-rw-r--r--security/selinux/ss/services.c54
-rw-r--r--security/smack/smack.h5
-rw-r--r--security/smack/smack_lsm.c140
-rw-r--r--security/smack/smackfs.c134
11 files changed, 366 insertions, 148 deletions
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index c38adcc910fb..1683bbf289a4 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -162,8 +162,7 @@ void ima_show_template_sig(struct seq_file *m, enum ima_show_type show,
162} 162}
163 163
164static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo, 164static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
165 struct ima_field_data *field_data, 165 struct ima_field_data *field_data)
166 bool size_limit)
167{ 166{
168 /* 167 /*
169 * digest formats: 168 * digest formats:
@@ -176,11 +175,10 @@ static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo,
176 enum data_formats fmt = DATA_FMT_DIGEST; 175 enum data_formats fmt = DATA_FMT_DIGEST;
177 u32 offset = 0; 176 u32 offset = 0;
178 177
179 if (!size_limit) { 178 if (hash_algo < HASH_ALGO__LAST) {
180 fmt = DATA_FMT_DIGEST_WITH_ALGO; 179 fmt = DATA_FMT_DIGEST_WITH_ALGO;
181 if (hash_algo < HASH_ALGO__LAST) 180 offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, "%s",
182 offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, 181 hash_algo_name[hash_algo]);
183 "%s", hash_algo_name[hash_algo]);
184 buffer[offset] = ':'; 182 buffer[offset] = ':';
185 offset += 2; 183 offset += 2;
186 } 184 }
@@ -243,8 +241,8 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file,
243 cur_digest = hash.hdr.digest; 241 cur_digest = hash.hdr.digest;
244 cur_digestsize = hash.hdr.length; 242 cur_digestsize = hash.hdr.length;
245out: 243out:
246 return ima_eventdigest_init_common(cur_digest, cur_digestsize, -1, 244 return ima_eventdigest_init_common(cur_digest, cur_digestsize,
247 field_data, true); 245 HASH_ALGO__LAST, field_data);
248} 246}
249 247
250/* 248/*
@@ -255,7 +253,7 @@ int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
255 struct evm_ima_xattr_data *xattr_value, 253 struct evm_ima_xattr_data *xattr_value,
256 int xattr_len, struct ima_field_data *field_data) 254 int xattr_len, struct ima_field_data *field_data)
257{ 255{
258 u8 *cur_digest = NULL, hash_algo = HASH_ALGO__LAST; 256 u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1;
259 u32 cur_digestsize = 0; 257 u32 cur_digestsize = 0;
260 258
261 /* If iint is NULL, we are recording a violation. */ 259 /* If iint is NULL, we are recording a violation. */
@@ -268,7 +266,7 @@ int ima_eventdigest_ng_init(struct integrity_iint_cache *iint,
268 hash_algo = iint->ima_hash->algo; 266 hash_algo = iint->ima_hash->algo;
269out: 267out:
270 return ima_eventdigest_init_common(cur_digest, cur_digestsize, 268 return ima_eventdigest_init_common(cur_digest, cur_digestsize,
271 hash_algo, field_data, false); 269 hash_algo, field_data);
272} 270}
273 271
274static int ima_eventname_init_common(struct integrity_iint_cache *iint, 272static int ima_eventname_init_common(struct integrity_iint_cache *iint,
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 57b0b49f4e6e..4b34847208cc 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -82,7 +82,6 @@
82#include <linux/syslog.h> 82#include <linux/syslog.h>
83#include <linux/user_namespace.h> 83#include <linux/user_namespace.h>
84#include <linux/export.h> 84#include <linux/export.h>
85#include <linux/security.h>
86#include <linux/msg.h> 85#include <linux/msg.h>
87#include <linux/shm.h> 86#include <linux/shm.h>
88 87
@@ -4490,14 +4489,10 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4490{ 4489{
4491 struct sk_security_struct *sksec = sk->sk_security; 4490 struct sk_security_struct *sksec = sk->sk_security;
4492 int err; 4491 int err;
4493 u16 family = sk->sk_family; 4492 u16 family = req->rsk_ops->family;
4494 u32 connsid; 4493 u32 connsid;
4495 u32 peersid; 4494 u32 peersid;
4496 4495
4497 /* handle mapped IPv4 packets arriving via IPv6 sockets */
4498 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
4499 family = PF_INET;
4500
4501 err = selinux_skb_peerlbl_sid(skb, family, &peersid); 4496 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
4502 if (err) 4497 if (err)
4503 return err; 4498 return err;
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index fe341ae37004..8ed8daf7f1ee 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -33,13 +33,14 @@
33#define POLICYDB_VERSION_ROLETRANS 26 33#define POLICYDB_VERSION_ROLETRANS 26
34#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 34#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27
35#define POLICYDB_VERSION_DEFAULT_TYPE 28 35#define POLICYDB_VERSION_DEFAULT_TYPE 28
36#define POLICYDB_VERSION_CONSTRAINT_NAMES 29
36 37
37/* Range of policy versions we understand*/ 38/* Range of policy versions we understand*/
38#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 39#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
39#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 40#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
40#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 41#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
41#else 42#else
42#define POLICYDB_VERSION_MAX POLICYDB_VERSION_DEFAULT_TYPE 43#define POLICYDB_VERSION_MAX POLICYDB_VERSION_CONSTRAINT_NAMES
43#endif 44#endif
44 45
45/* Mask for just the mount related flags */ 46/* Mask for just the mount related flags */
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 6235d052338b..0364120d1ec8 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -101,6 +101,32 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
101} 101}
102 102
103/** 103/**
104 * selinux_netlbl_sock_getattr - Get the cached NetLabel secattr
105 * @sk: the socket
106 * @sid: the SID
107 *
108 * Query the socket's cached secattr and if the SID matches the cached value
109 * return the cache, otherwise return NULL.
110 *
111 */
112static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr(
113 const struct sock *sk,
114 u32 sid)
115{
116 struct sk_security_struct *sksec = sk->sk_security;
117 struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr;
118
119 if (secattr == NULL)
120 return NULL;
121
122 if ((secattr->flags & NETLBL_SECATTR_SECID) &&
123 (secattr->attr.secid == sid))
124 return secattr;
125
126 return NULL;
127}
128
129/**
104 * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache 130 * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache
105 * 131 *
106 * Description: 132 * Description:
@@ -224,7 +250,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
224 struct sk_security_struct *sksec = sk->sk_security; 250 struct sk_security_struct *sksec = sk->sk_security;
225 if (sksec->nlbl_state != NLBL_REQSKB) 251 if (sksec->nlbl_state != NLBL_REQSKB)
226 return 0; 252 return 0;
227 secattr = sksec->nlbl_secattr; 253 secattr = selinux_netlbl_sock_getattr(sk, sid);
228 } 254 }
229 if (secattr == NULL) { 255 if (secattr == NULL) {
230 secattr = &secattr_storage; 256 secattr = &secattr_storage;
@@ -410,6 +436,9 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,
410 sksec->nlbl_state == NLBL_CONNLABELED)) { 436 sksec->nlbl_state == NLBL_CONNLABELED)) {
411 netlbl_secattr_init(&secattr); 437 netlbl_secattr_init(&secattr);
412 lock_sock(sk); 438 lock_sock(sk);
439 /* call the netlabel function directly as we want to see the
440 * on-the-wire label that is assigned via the socket's options
441 * and not the cached netlabel/lsm attributes */
413 rc = netlbl_sock_getattr(sk, &secattr); 442 rc = netlbl_sock_getattr(sk, &secattr);
414 release_sock(sk); 443 release_sock(sk);
415 if (rc == 0) 444 if (rc == 0)
diff --git a/security/selinux/ss/constraint.h b/security/selinux/ss/constraint.h
index 149dda731fd3..96fd947c494b 100644
--- a/security/selinux/ss/constraint.h
+++ b/security/selinux/ss/constraint.h
@@ -48,6 +48,7 @@ struct constraint_expr {
48 u32 op; /* operator */ 48 u32 op; /* operator */
49 49
50 struct ebitmap names; /* names */ 50 struct ebitmap names; /* names */
51 struct type_set *type_names;
51 52
52 struct constraint_expr *next; /* next expression */ 53 struct constraint_expr *next; /* next expression */
53}; 54};
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index f6195ebde3c9..c0f498842129 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -143,6 +143,11 @@ static struct policydb_compat_info policydb_compat[] = {
143 .sym_num = SYM_NUM, 143 .sym_num = SYM_NUM,
144 .ocon_num = OCON_NUM, 144 .ocon_num = OCON_NUM,
145 }, 145 },
146 {
147 .version = POLICYDB_VERSION_CONSTRAINT_NAMES,
148 .sym_num = SYM_NUM,
149 .ocon_num = OCON_NUM,
150 },
146}; 151};
147 152
148static struct policydb_compat_info *policydb_lookup_compat(int version) 153static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -613,6 +618,19 @@ static int common_destroy(void *key, void *datum, void *p)
613 return 0; 618 return 0;
614} 619}
615 620
621static void constraint_expr_destroy(struct constraint_expr *expr)
622{
623 if (expr) {
624 ebitmap_destroy(&expr->names);
625 if (expr->type_names) {
626 ebitmap_destroy(&expr->type_names->types);
627 ebitmap_destroy(&expr->type_names->negset);
628 kfree(expr->type_names);
629 }
630 kfree(expr);
631 }
632}
633
616static int cls_destroy(void *key, void *datum, void *p) 634static int cls_destroy(void *key, void *datum, void *p)
617{ 635{
618 struct class_datum *cladatum; 636 struct class_datum *cladatum;
@@ -628,10 +646,9 @@ static int cls_destroy(void *key, void *datum, void *p)
628 while (constraint) { 646 while (constraint) {
629 e = constraint->expr; 647 e = constraint->expr;
630 while (e) { 648 while (e) {
631 ebitmap_destroy(&e->names);
632 etmp = e; 649 etmp = e;
633 e = e->next; 650 e = e->next;
634 kfree(etmp); 651 constraint_expr_destroy(etmp);
635 } 652 }
636 ctemp = constraint; 653 ctemp = constraint;
637 constraint = constraint->next; 654 constraint = constraint->next;
@@ -642,16 +659,14 @@ static int cls_destroy(void *key, void *datum, void *p)
642 while (constraint) { 659 while (constraint) {
643 e = constraint->expr; 660 e = constraint->expr;
644 while (e) { 661 while (e) {
645 ebitmap_destroy(&e->names);
646 etmp = e; 662 etmp = e;
647 e = e->next; 663 e = e->next;
648 kfree(etmp); 664 constraint_expr_destroy(etmp);
649 } 665 }
650 ctemp = constraint; 666 ctemp = constraint;
651 constraint = constraint->next; 667 constraint = constraint->next;
652 kfree(ctemp); 668 kfree(ctemp);
653 } 669 }
654
655 kfree(cladatum->comkey); 670 kfree(cladatum->comkey);
656 } 671 }
657 kfree(datum); 672 kfree(datum);
@@ -1156,8 +1171,34 @@ bad:
1156 return rc; 1171 return rc;
1157} 1172}
1158 1173
1159static int read_cons_helper(struct constraint_node **nodep, int ncons, 1174static void type_set_init(struct type_set *t)
1160 int allowxtarget, void *fp) 1175{
1176 ebitmap_init(&t->types);
1177 ebitmap_init(&t->negset);
1178}
1179
1180static int type_set_read(struct type_set *t, void *fp)
1181{
1182 __le32 buf[1];
1183 int rc;
1184
1185 if (ebitmap_read(&t->types, fp))
1186 return -EINVAL;
1187 if (ebitmap_read(&t->negset, fp))
1188 return -EINVAL;
1189
1190 rc = next_entry(buf, fp, sizeof(u32));
1191 if (rc < 0)
1192 return -EINVAL;
1193 t->flags = le32_to_cpu(buf[0]);
1194
1195 return 0;
1196}
1197
1198
1199static int read_cons_helper(struct policydb *p,
1200 struct constraint_node **nodep,
1201 int ncons, int allowxtarget, void *fp)
1161{ 1202{
1162 struct constraint_node *c, *lc; 1203 struct constraint_node *c, *lc;
1163 struct constraint_expr *e, *le; 1204 struct constraint_expr *e, *le;
@@ -1225,6 +1266,18 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1225 rc = ebitmap_read(&e->names, fp); 1266 rc = ebitmap_read(&e->names, fp);
1226 if (rc) 1267 if (rc)
1227 return rc; 1268 return rc;
1269 if (p->policyvers >=
1270 POLICYDB_VERSION_CONSTRAINT_NAMES) {
1271 e->type_names = kzalloc(sizeof
1272 (*e->type_names),
1273 GFP_KERNEL);
1274 if (!e->type_names)
1275 return -ENOMEM;
1276 type_set_init(e->type_names);
1277 rc = type_set_read(e->type_names, fp);
1278 if (rc)
1279 return rc;
1280 }
1228 break; 1281 break;
1229 default: 1282 default:
1230 return -EINVAL; 1283 return -EINVAL;
@@ -1301,7 +1354,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1301 goto bad; 1354 goto bad;
1302 } 1355 }
1303 1356
1304 rc = read_cons_helper(&cladatum->constraints, ncons, 0, fp); 1357 rc = read_cons_helper(p, &cladatum->constraints, ncons, 0, fp);
1305 if (rc) 1358 if (rc)
1306 goto bad; 1359 goto bad;
1307 1360
@@ -1311,7 +1364,8 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1311 if (rc) 1364 if (rc)
1312 goto bad; 1365 goto bad;
1313 ncons = le32_to_cpu(buf[0]); 1366 ncons = le32_to_cpu(buf[0]);
1314 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); 1367 rc = read_cons_helper(p, &cladatum->validatetrans,
1368 ncons, 1, fp);
1315 if (rc) 1369 if (rc)
1316 goto bad; 1370 goto bad;
1317 } 1371 }
@@ -1941,7 +1995,19 @@ static int filename_trans_read(struct policydb *p, void *fp)
1941 if (rc) 1995 if (rc)
1942 goto out; 1996 goto out;
1943 1997
1944 hashtab_insert(p->filename_trans, ft, otype); 1998 rc = hashtab_insert(p->filename_trans, ft, otype);
1999 if (rc) {
2000 /*
2001 * Do not return -EEXIST to the caller, or the system
2002 * will not boot.
2003 */
2004 if (rc != -EEXIST)
2005 goto out;
2006 /* But free memory to avoid memory leak. */
2007 kfree(ft);
2008 kfree(name);
2009 kfree(otype);
2010 }
1945 } 2011 }
1946 hash_eval(p->filename_trans, "filenametr"); 2012 hash_eval(p->filename_trans, "filenametr");
1947 return 0; 2013 return 0;
@@ -2753,6 +2819,24 @@ static int common_write(void *vkey, void *datum, void *ptr)
2753 return 0; 2819 return 0;
2754} 2820}
2755 2821
2822static int type_set_write(struct type_set *t, void *fp)
2823{
2824 int rc;
2825 __le32 buf[1];
2826
2827 if (ebitmap_write(&t->types, fp))
2828 return -EINVAL;
2829 if (ebitmap_write(&t->negset, fp))
2830 return -EINVAL;
2831
2832 buf[0] = cpu_to_le32(t->flags);
2833 rc = put_entry(buf, sizeof(u32), 1, fp);
2834 if (rc)
2835 return -EINVAL;
2836
2837 return 0;
2838}
2839
2756static int write_cons_helper(struct policydb *p, struct constraint_node *node, 2840static int write_cons_helper(struct policydb *p, struct constraint_node *node,
2757 void *fp) 2841 void *fp)
2758{ 2842{
@@ -2784,6 +2868,12 @@ static int write_cons_helper(struct policydb *p, struct constraint_node *node,
2784 rc = ebitmap_write(&e->names, fp); 2868 rc = ebitmap_write(&e->names, fp);
2785 if (rc) 2869 if (rc)
2786 return rc; 2870 return rc;
2871 if (p->policyvers >=
2872 POLICYDB_VERSION_CONSTRAINT_NAMES) {
2873 rc = type_set_write(e->type_names, fp);
2874 if (rc)
2875 return rc;
2876 }
2787 break; 2877 break;
2788 default: 2878 default:
2789 break; 2879 break;
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index da637471d4ce..725d5945a97e 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -154,6 +154,17 @@ struct cond_bool_datum {
154struct cond_node; 154struct cond_node;
155 155
156/* 156/*
157 * type set preserves data needed to determine constraint info from
158 * policy source. This is not used by the kernel policy but allows
159 * utilities such as audit2allow to determine constraint denials.
160 */
161struct type_set {
162 struct ebitmap types;
163 struct ebitmap negset;
164 u32 flags;
165};
166
167/*
157 * The configuration data includes security contexts for 168 * The configuration data includes security contexts for
158 * initial SIDs, unlabeled file systems, TCP and UDP port numbers, 169 * initial SIDs, unlabeled file systems, TCP and UDP port numbers,
159 * network interfaces, and nodes. This structure stores the 170 * network interfaces, and nodes. This structure stores the
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index d106733ad987..fc5a63a05a1c 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1831,7 +1831,7 @@ static int security_preserve_bools(struct policydb *p);
1831 */ 1831 */
1832int security_load_policy(void *data, size_t len) 1832int security_load_policy(void *data, size_t len)
1833{ 1833{
1834 struct policydb oldpolicydb, newpolicydb; 1834 struct policydb *oldpolicydb, *newpolicydb;
1835 struct sidtab oldsidtab, newsidtab; 1835 struct sidtab oldsidtab, newsidtab;
1836 struct selinux_mapping *oldmap, *map = NULL; 1836 struct selinux_mapping *oldmap, *map = NULL;
1837 struct convert_context_args args; 1837 struct convert_context_args args;
@@ -1840,12 +1840,19 @@ int security_load_policy(void *data, size_t len)
1840 int rc = 0; 1840 int rc = 0;
1841 struct policy_file file = { data, len }, *fp = &file; 1841 struct policy_file file = { data, len }, *fp = &file;
1842 1842
1843 oldpolicydb = kzalloc(2 * sizeof(*oldpolicydb), GFP_KERNEL);
1844 if (!oldpolicydb) {
1845 rc = -ENOMEM;
1846 goto out;
1847 }
1848 newpolicydb = oldpolicydb + 1;
1849
1843 if (!ss_initialized) { 1850 if (!ss_initialized) {
1844 avtab_cache_init(); 1851 avtab_cache_init();
1845 rc = policydb_read(&policydb, fp); 1852 rc = policydb_read(&policydb, fp);
1846 if (rc) { 1853 if (rc) {
1847 avtab_cache_destroy(); 1854 avtab_cache_destroy();
1848 return rc; 1855 goto out;
1849 } 1856 }
1850 1857
1851 policydb.len = len; 1858 policydb.len = len;
@@ -1855,14 +1862,14 @@ int security_load_policy(void *data, size_t len)
1855 if (rc) { 1862 if (rc) {
1856 policydb_destroy(&policydb); 1863 policydb_destroy(&policydb);
1857 avtab_cache_destroy(); 1864 avtab_cache_destroy();
1858 return rc; 1865 goto out;
1859 } 1866 }
1860 1867
1861 rc = policydb_load_isids(&policydb, &sidtab); 1868 rc = policydb_load_isids(&policydb, &sidtab);
1862 if (rc) { 1869 if (rc) {
1863 policydb_destroy(&policydb); 1870 policydb_destroy(&policydb);
1864 avtab_cache_destroy(); 1871 avtab_cache_destroy();
1865 return rc; 1872 goto out;
1866 } 1873 }
1867 1874
1868 security_load_policycaps(); 1875 security_load_policycaps();
@@ -1874,36 +1881,36 @@ int security_load_policy(void *data, size_t len)
1874 selinux_status_update_policyload(seqno); 1881 selinux_status_update_policyload(seqno);
1875 selinux_netlbl_cache_invalidate(); 1882 selinux_netlbl_cache_invalidate();
1876 selinux_xfrm_notify_policyload(); 1883 selinux_xfrm_notify_policyload();
1877 return 0; 1884 goto out;
1878 } 1885 }
1879 1886
1880#if 0 1887#if 0
1881 sidtab_hash_eval(&sidtab, "sids"); 1888 sidtab_hash_eval(&sidtab, "sids");
1882#endif 1889#endif
1883 1890
1884 rc = policydb_read(&newpolicydb, fp); 1891 rc = policydb_read(newpolicydb, fp);
1885 if (rc) 1892 if (rc)
1886 return rc; 1893 goto out;
1887 1894
1888 newpolicydb.len = len; 1895 newpolicydb->len = len;
1889 /* If switching between different policy types, log MLS status */ 1896 /* If switching between different policy types, log MLS status */
1890 if (policydb.mls_enabled && !newpolicydb.mls_enabled) 1897 if (policydb.mls_enabled && !newpolicydb->mls_enabled)
1891 printk(KERN_INFO "SELinux: Disabling MLS support...\n"); 1898 printk(KERN_INFO "SELinux: Disabling MLS support...\n");
1892 else if (!policydb.mls_enabled && newpolicydb.mls_enabled) 1899 else if (!policydb.mls_enabled && newpolicydb->mls_enabled)
1893 printk(KERN_INFO "SELinux: Enabling MLS support...\n"); 1900 printk(KERN_INFO "SELinux: Enabling MLS support...\n");
1894 1901
1895 rc = policydb_load_isids(&newpolicydb, &newsidtab); 1902 rc = policydb_load_isids(newpolicydb, &newsidtab);
1896 if (rc) { 1903 if (rc) {
1897 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n"); 1904 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n");
1898 policydb_destroy(&newpolicydb); 1905 policydb_destroy(newpolicydb);
1899 return rc; 1906 goto out;
1900 } 1907 }
1901 1908
1902 rc = selinux_set_mapping(&newpolicydb, secclass_map, &map, &map_size); 1909 rc = selinux_set_mapping(newpolicydb, secclass_map, &map, &map_size);
1903 if (rc) 1910 if (rc)
1904 goto err; 1911 goto err;
1905 1912
1906 rc = security_preserve_bools(&newpolicydb); 1913 rc = security_preserve_bools(newpolicydb);
1907 if (rc) { 1914 if (rc) {
1908 printk(KERN_ERR "SELinux: unable to preserve booleans\n"); 1915 printk(KERN_ERR "SELinux: unable to preserve booleans\n");
1909 goto err; 1916 goto err;
@@ -1921,7 +1928,7 @@ int security_load_policy(void *data, size_t len)
1921 * in the new SID table. 1928 * in the new SID table.
1922 */ 1929 */
1923 args.oldp = &policydb; 1930 args.oldp = &policydb;
1924 args.newp = &newpolicydb; 1931 args.newp = newpolicydb;
1925 rc = sidtab_map(&newsidtab, convert_context, &args); 1932 rc = sidtab_map(&newsidtab, convert_context, &args);
1926 if (rc) { 1933 if (rc) {
1927 printk(KERN_ERR "SELinux: unable to convert the internal" 1934 printk(KERN_ERR "SELinux: unable to convert the internal"
@@ -1931,12 +1938,12 @@ int security_load_policy(void *data, size_t len)
1931 } 1938 }
1932 1939
1933 /* Save the old policydb and SID table to free later. */ 1940 /* Save the old policydb and SID table to free later. */
1934 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1941 memcpy(oldpolicydb, &policydb, sizeof(policydb));
1935 sidtab_set(&oldsidtab, &sidtab); 1942 sidtab_set(&oldsidtab, &sidtab);
1936 1943
1937 /* Install the new policydb and SID table. */ 1944 /* Install the new policydb and SID table. */
1938 write_lock_irq(&policy_rwlock); 1945 write_lock_irq(&policy_rwlock);
1939 memcpy(&policydb, &newpolicydb, sizeof policydb); 1946 memcpy(&policydb, newpolicydb, sizeof(policydb));
1940 sidtab_set(&sidtab, &newsidtab); 1947 sidtab_set(&sidtab, &newsidtab);
1941 security_load_policycaps(); 1948 security_load_policycaps();
1942 oldmap = current_mapping; 1949 oldmap = current_mapping;
@@ -1946,7 +1953,7 @@ int security_load_policy(void *data, size_t len)
1946 write_unlock_irq(&policy_rwlock); 1953 write_unlock_irq(&policy_rwlock);
1947 1954
1948 /* Free the old policydb and SID table. */ 1955 /* Free the old policydb and SID table. */
1949 policydb_destroy(&oldpolicydb); 1956 policydb_destroy(oldpolicydb);
1950 sidtab_destroy(&oldsidtab); 1957 sidtab_destroy(&oldsidtab);
1951 kfree(oldmap); 1958 kfree(oldmap);
1952 1959
@@ -1956,14 +1963,17 @@ int security_load_policy(void *data, size_t len)
1956 selinux_netlbl_cache_invalidate(); 1963 selinux_netlbl_cache_invalidate();
1957 selinux_xfrm_notify_policyload(); 1964 selinux_xfrm_notify_policyload();
1958 1965
1959 return 0; 1966 rc = 0;
1967 goto out;
1960 1968
1961err: 1969err:
1962 kfree(map); 1970 kfree(map);
1963 sidtab_destroy(&newsidtab); 1971 sidtab_destroy(&newsidtab);
1964 policydb_destroy(&newpolicydb); 1972 policydb_destroy(newpolicydb);
1965 return rc;
1966 1973
1974out:
1975 kfree(oldpolicydb);
1976 return rc;
1967} 1977}
1968 1978
1969size_t security_policydb_len(void) 1979size_t security_policydb_len(void)
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 364cc64fce71..d072fd32212d 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -241,7 +241,8 @@ u32 smack_to_secid(const char *);
241extern int smack_cipso_direct; 241extern int smack_cipso_direct;
242extern int smack_cipso_mapped; 242extern int smack_cipso_mapped;
243extern struct smack_known *smack_net_ambient; 243extern struct smack_known *smack_net_ambient;
244extern char *smack_onlycap; 244extern struct smack_known *smack_onlycap;
245extern struct smack_known *smack_syslog_label;
245extern const char *smack_cipso_option; 246extern const char *smack_cipso_option;
246 247
247extern struct smack_known smack_known_floor; 248extern struct smack_known smack_known_floor;
@@ -312,7 +313,7 @@ static inline int smack_privileged(int cap)
312 313
313 if (!capable(cap)) 314 if (!capable(cap))
314 return 0; 315 return 0;
315 if (smack_onlycap == NULL || smack_onlycap == skp->smk_known) 316 if (smack_onlycap == NULL || smack_onlycap == skp)
316 return 1; 317 return 1;
317 return 0; 318 return 0;
318} 319}
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index b0be893ad44d..d814e35987be 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -219,8 +219,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
219 * smack_syslog - Smack approval on syslog 219 * smack_syslog - Smack approval on syslog
220 * @type: message type 220 * @type: message type
221 * 221 *
222 * Require that the task has the floor label
223 *
224 * Returns 0 on success, error code otherwise. 222 * Returns 0 on success, error code otherwise.
225 */ 223 */
226static int smack_syslog(int typefrom_file) 224static int smack_syslog(int typefrom_file)
@@ -231,7 +229,7 @@ static int smack_syslog(int typefrom_file)
231 if (smack_privileged(CAP_MAC_OVERRIDE)) 229 if (smack_privileged(CAP_MAC_OVERRIDE))
232 return 0; 230 return 0;
233 231
234 if (skp != &smack_known_floor) 232 if (smack_syslog_label != NULL && smack_syslog_label != skp)
235 rc = -EACCES; 233 rc = -EACCES;
236 234
237 return rc; 235 return rc;
@@ -341,10 +339,12 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
341 struct inode *inode = root->d_inode; 339 struct inode *inode = root->d_inode;
342 struct superblock_smack *sp = sb->s_security; 340 struct superblock_smack *sp = sb->s_security;
343 struct inode_smack *isp; 341 struct inode_smack *isp;
342 struct smack_known *skp;
344 char *op; 343 char *op;
345 char *commap; 344 char *commap;
346 char *nsp; 345 char *nsp;
347 int transmute = 0; 346 int transmute = 0;
347 int specified = 0;
348 348
349 if (sp->smk_initialized) 349 if (sp->smk_initialized)
350 return 0; 350 return 0;
@@ -359,34 +359,56 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
359 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { 359 if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
360 op += strlen(SMK_FSHAT); 360 op += strlen(SMK_FSHAT);
361 nsp = smk_import(op, 0); 361 nsp = smk_import(op, 0);
362 if (nsp != NULL) 362 if (nsp != NULL) {
363 sp->smk_hat = nsp; 363 sp->smk_hat = nsp;
364 specified = 1;
365 }
364 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { 366 } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) {
365 op += strlen(SMK_FSFLOOR); 367 op += strlen(SMK_FSFLOOR);
366 nsp = smk_import(op, 0); 368 nsp = smk_import(op, 0);
367 if (nsp != NULL) 369 if (nsp != NULL) {
368 sp->smk_floor = nsp; 370 sp->smk_floor = nsp;
371 specified = 1;
372 }
369 } else if (strncmp(op, SMK_FSDEFAULT, 373 } else if (strncmp(op, SMK_FSDEFAULT,
370 strlen(SMK_FSDEFAULT)) == 0) { 374 strlen(SMK_FSDEFAULT)) == 0) {
371 op += strlen(SMK_FSDEFAULT); 375 op += strlen(SMK_FSDEFAULT);
372 nsp = smk_import(op, 0); 376 nsp = smk_import(op, 0);
373 if (nsp != NULL) 377 if (nsp != NULL) {
374 sp->smk_default = nsp; 378 sp->smk_default = nsp;
379 specified = 1;
380 }
375 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { 381 } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) {
376 op += strlen(SMK_FSROOT); 382 op += strlen(SMK_FSROOT);
377 nsp = smk_import(op, 0); 383 nsp = smk_import(op, 0);
378 if (nsp != NULL) 384 if (nsp != NULL) {
379 sp->smk_root = nsp; 385 sp->smk_root = nsp;
386 specified = 1;
387 }
380 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { 388 } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) {
381 op += strlen(SMK_FSTRANS); 389 op += strlen(SMK_FSTRANS);
382 nsp = smk_import(op, 0); 390 nsp = smk_import(op, 0);
383 if (nsp != NULL) { 391 if (nsp != NULL) {
384 sp->smk_root = nsp; 392 sp->smk_root = nsp;
385 transmute = 1; 393 transmute = 1;
394 specified = 1;
386 } 395 }
387 } 396 }
388 } 397 }
389 398
399 if (!smack_privileged(CAP_MAC_ADMIN)) {
400 /*
401 * Unprivileged mounts don't get to specify Smack values.
402 */
403 if (specified)
404 return -EPERM;
405 /*
406 * Unprivileged mounts get root and default from the caller.
407 */
408 skp = smk_of_current();
409 sp->smk_root = skp->smk_known;
410 sp->smk_default = skp->smk_known;
411 }
390 /* 412 /*
391 * Initialize the root inode. 413 * Initialize the root inode.
392 */ 414 */
@@ -423,53 +445,6 @@ static int smack_sb_statfs(struct dentry *dentry)
423 return rc; 445 return rc;
424} 446}
425 447
426/**
427 * smack_sb_mount - Smack check for mounting
428 * @dev_name: unused
429 * @path: mount point
430 * @type: unused
431 * @flags: unused
432 * @data: unused
433 *
434 * Returns 0 if current can write the floor of the filesystem
435 * being mounted on, an error code otherwise.
436 */
437static int smack_sb_mount(const char *dev_name, struct path *path,
438 const char *type, unsigned long flags, void *data)
439{
440 struct superblock_smack *sbp = path->dentry->d_sb->s_security;
441 struct smk_audit_info ad;
442
443 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
444 smk_ad_setfield_u_fs_path(&ad, *path);
445
446 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
447}
448
449/**
450 * smack_sb_umount - Smack check for unmounting
451 * @mnt: file system to unmount
452 * @flags: unused
453 *
454 * Returns 0 if current can write the floor of the filesystem
455 * being unmounted, an error code otherwise.
456 */
457static int smack_sb_umount(struct vfsmount *mnt, int flags)
458{
459 struct superblock_smack *sbp;
460 struct smk_audit_info ad;
461 struct path path;
462
463 path.dentry = mnt->mnt_root;
464 path.mnt = mnt;
465
466 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
467 smk_ad_setfield_u_fs_path(&ad, path);
468
469 sbp = path.dentry->d_sb->s_security;
470 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
471}
472
473/* 448/*
474 * BPRM hooks 449 * BPRM hooks
475 */ 450 */
@@ -837,31 +812,43 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
837 const void *value, size_t size, int flags) 812 const void *value, size_t size, int flags)
838{ 813{
839 struct smk_audit_info ad; 814 struct smk_audit_info ad;
815 struct smack_known *skp;
816 int check_priv = 0;
817 int check_import = 0;
818 int check_star = 0;
840 int rc = 0; 819 int rc = 0;
841 820
821 /*
822 * Check label validity here so import won't fail in post_setxattr
823 */
842 if (strcmp(name, XATTR_NAME_SMACK) == 0 || 824 if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
843 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || 825 strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
844 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || 826 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
845 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 827 check_priv = 1;
846 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 828 check_import = 1;
847 if (!smack_privileged(CAP_MAC_ADMIN)) 829 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
848 rc = -EPERM; 830 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
849 /* 831 check_priv = 1;
850 * check label validity here so import wont fail on 832 check_import = 1;
851 * post_setxattr 833 check_star = 1;
852 */
853 if (size == 0 || size >= SMK_LONGLABEL ||
854 smk_import(value, size) == NULL)
855 rc = -EINVAL;
856 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { 834 } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
857 if (!smack_privileged(CAP_MAC_ADMIN)) 835 check_priv = 1;
858 rc = -EPERM;
859 if (size != TRANS_TRUE_SIZE || 836 if (size != TRANS_TRUE_SIZE ||
860 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) 837 strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
861 rc = -EINVAL; 838 rc = -EINVAL;
862 } else 839 } else
863 rc = cap_inode_setxattr(dentry, name, value, size, flags); 840 rc = cap_inode_setxattr(dentry, name, value, size, flags);
864 841
842 if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
843 rc = -EPERM;
844
845 if (rc == 0 && check_import) {
846 skp = smk_import_entry(value, size);
847 if (skp == NULL || (check_star &&
848 (skp == &smack_known_star || skp == &smack_known_web)))
849 rc = -EINVAL;
850 }
851
865 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); 852 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
866 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 853 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
867 854
@@ -1364,7 +1351,7 @@ static int smack_file_receive(struct file *file)
1364 int may = 0; 1351 int may = 0;
1365 struct smk_audit_info ad; 1352 struct smk_audit_info ad;
1366 1353
1367 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); 1354 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1368 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1355 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1369 /* 1356 /*
1370 * This code relies on bitmasks. 1357 * This code relies on bitmasks.
@@ -2847,8 +2834,17 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2847 if (rc >= 0) 2834 if (rc >= 0)
2848 transflag = SMK_INODE_TRANSMUTE; 2835 transflag = SMK_INODE_TRANSMUTE;
2849 } 2836 }
2850 isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); 2837 /*
2851 isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); 2838 * Don't let the exec or mmap label be "*" or "@".
2839 */
2840 skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
2841 if (skp == &smack_known_star || skp == &smack_known_web)
2842 skp = NULL;
2843 isp->smk_task = skp;
2844 skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
2845 if (skp == &smack_known_star || skp == &smack_known_web)
2846 skp = NULL;
2847 isp->smk_mmap = skp;
2852 2848
2853 dput(dp); 2849 dput(dp);
2854 break; 2850 break;
@@ -3743,8 +3739,6 @@ struct security_operations smack_ops = {
3743 .sb_copy_data = smack_sb_copy_data, 3739 .sb_copy_data = smack_sb_copy_data,
3744 .sb_kern_mount = smack_sb_kern_mount, 3740 .sb_kern_mount = smack_sb_kern_mount,
3745 .sb_statfs = smack_sb_statfs, 3741 .sb_statfs = smack_sb_statfs,
3746 .sb_mount = smack_sb_mount,
3747 .sb_umount = smack_sb_umount,
3748 3742
3749 .bprm_set_creds = smack_bprm_set_creds, 3743 .bprm_set_creds = smack_bprm_set_creds,
3750 .bprm_committing_creds = smack_bprm_committing_creds, 3744 .bprm_committing_creds = smack_bprm_committing_creds,
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 160aa08e3cd5..3198cfe1dcc6 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -52,6 +52,7 @@ enum smk_inos {
52 SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */ 52 SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */
53 SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */ 53 SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */
54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ 54 SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
55 SMK_SYSLOG = 20, /* change syslog label) */
55}; 56};
56 57
57/* 58/*
@@ -59,6 +60,7 @@ enum smk_inos {
59 */ 60 */
60static DEFINE_MUTEX(smack_cipso_lock); 61static DEFINE_MUTEX(smack_cipso_lock);
61static DEFINE_MUTEX(smack_ambient_lock); 62static DEFINE_MUTEX(smack_ambient_lock);
63static DEFINE_MUTEX(smack_syslog_lock);
62static DEFINE_MUTEX(smk_netlbladdr_lock); 64static DEFINE_MUTEX(smk_netlbladdr_lock);
63 65
64/* 66/*
@@ -90,7 +92,13 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
90 * everyone. It is expected that the hat (^) label 92 * everyone. It is expected that the hat (^) label
91 * will be used if any label is used. 93 * will be used if any label is used.
92 */ 94 */
93char *smack_onlycap; 95struct smack_known *smack_onlycap;
96
97/*
98 * If this value is set restrict syslog use to the label specified.
99 * It can be reset via smackfs/syslog
100 */
101struct smack_known *smack_syslog_label;
94 102
95/* 103/*
96 * Certain IP addresses may be designated as single label hosts. 104 * Certain IP addresses may be designated as single label hosts.
@@ -301,7 +309,8 @@ static int smk_perm_from_str(const char *string)
301 * @import: if non-zero, import labels 309 * @import: if non-zero, import labels
302 * @len: label length limit 310 * @len: label length limit
303 * 311 *
304 * Returns 0 on success, -1 on failure 312 * Returns 0 on success, -EINVAL on failure and -ENOENT when either subject
313 * or object is missing.
305 */ 314 */
306static int smk_fill_rule(const char *subject, const char *object, 315static int smk_fill_rule(const char *subject, const char *object,
307 const char *access1, const char *access2, 316 const char *access1, const char *access2,
@@ -314,28 +323,28 @@ static int smk_fill_rule(const char *subject, const char *object,
314 if (import) { 323 if (import) {
315 rule->smk_subject = smk_import_entry(subject, len); 324 rule->smk_subject = smk_import_entry(subject, len);
316 if (rule->smk_subject == NULL) 325 if (rule->smk_subject == NULL)
317 return -1; 326 return -EINVAL;
318 327
319 rule->smk_object = smk_import(object, len); 328 rule->smk_object = smk_import(object, len);
320 if (rule->smk_object == NULL) 329 if (rule->smk_object == NULL)
321 return -1; 330 return -EINVAL;
322 } else { 331 } else {
323 cp = smk_parse_smack(subject, len); 332 cp = smk_parse_smack(subject, len);
324 if (cp == NULL) 333 if (cp == NULL)
325 return -1; 334 return -EINVAL;
326 skp = smk_find_entry(cp); 335 skp = smk_find_entry(cp);
327 kfree(cp); 336 kfree(cp);
328 if (skp == NULL) 337 if (skp == NULL)
329 return -1; 338 return -ENOENT;
330 rule->smk_subject = skp; 339 rule->smk_subject = skp;
331 340
332 cp = smk_parse_smack(object, len); 341 cp = smk_parse_smack(object, len);
333 if (cp == NULL) 342 if (cp == NULL)
334 return -1; 343 return -EINVAL;
335 skp = smk_find_entry(cp); 344 skp = smk_find_entry(cp);
336 kfree(cp); 345 kfree(cp);
337 if (skp == NULL) 346 if (skp == NULL)
338 return -1; 347 return -ENOENT;
339 rule->smk_object = skp->smk_known; 348 rule->smk_object = skp->smk_known;
340 } 349 }
341 350
@@ -381,6 +390,7 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
381{ 390{
382 ssize_t cnt = 0; 391 ssize_t cnt = 0;
383 char *tok[4]; 392 char *tok[4];
393 int rc;
384 int i; 394 int i;
385 395
386 /* 396 /*
@@ -405,10 +415,8 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule,
405 while (i < 4) 415 while (i < 4)
406 tok[i++] = NULL; 416 tok[i++] = NULL;
407 417
408 if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0)) 418 rc = smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0);
409 return -1; 419 return rc == 0 ? cnt : rc;
410
411 return cnt;
412} 420}
413 421
414#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */ 422#define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */
@@ -1603,7 +1611,7 @@ static const struct file_operations smk_ambient_ops = {
1603}; 1611};
1604 1612
1605/** 1613/**
1606 * smk_read_onlycap - read() for /smack/onlycap 1614 * smk_read_onlycap - read() for smackfs/onlycap
1607 * @filp: file pointer, not actually used 1615 * @filp: file pointer, not actually used
1608 * @buf: where to put the result 1616 * @buf: where to put the result
1609 * @cn: maximum to send along 1617 * @cn: maximum to send along
@@ -1622,7 +1630,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1622 return 0; 1630 return 0;
1623 1631
1624 if (smack_onlycap != NULL) 1632 if (smack_onlycap != NULL)
1625 smack = smack_onlycap; 1633 smack = smack_onlycap->smk_known;
1626 1634
1627 asize = strlen(smack) + 1; 1635 asize = strlen(smack) + 1;
1628 1636
@@ -1633,7 +1641,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1633} 1641}
1634 1642
1635/** 1643/**
1636 * smk_write_onlycap - write() for /smack/onlycap 1644 * smk_write_onlycap - write() for smackfs/onlycap
1637 * @file: file pointer, not actually used 1645 * @file: file pointer, not actually used
1638 * @buf: where to get the data from 1646 * @buf: where to get the data from
1639 * @count: bytes sent 1647 * @count: bytes sent
@@ -1656,7 +1664,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1656 * explicitly for clarity. The smk_access() implementation 1664 * explicitly for clarity. The smk_access() implementation
1657 * would use smk_access(smack_onlycap, MAY_WRITE) 1665 * would use smk_access(smack_onlycap, MAY_WRITE)
1658 */ 1666 */
1659 if (smack_onlycap != NULL && smack_onlycap != skp->smk_known) 1667 if (smack_onlycap != NULL && smack_onlycap != skp)
1660 return -EPERM; 1668 return -EPERM;
1661 1669
1662 data = kzalloc(count, GFP_KERNEL); 1670 data = kzalloc(count, GFP_KERNEL);
@@ -1676,7 +1684,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1676 if (copy_from_user(data, buf, count) != 0) 1684 if (copy_from_user(data, buf, count) != 0)
1677 rc = -EFAULT; 1685 rc = -EFAULT;
1678 else 1686 else
1679 smack_onlycap = smk_import(data, count); 1687 smack_onlycap = smk_import_entry(data, count);
1680 1688
1681 kfree(data); 1689 kfree(data);
1682 return rc; 1690 return rc;
@@ -1856,11 +1864,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf,
1856 res = smk_parse_long_rule(data, &rule, 0, 3); 1864 res = smk_parse_long_rule(data, &rule, 0, 3);
1857 } 1865 }
1858 1866
1859 if (res < 0) 1867 if (res >= 0)
1868 res = smk_access(rule.smk_subject, rule.smk_object,
1869 rule.smk_access1, NULL);
1870 else if (res != -ENOENT)
1860 return -EINVAL; 1871 return -EINVAL;
1861 1872
1862 res = smk_access(rule.smk_subject, rule.smk_object,
1863 rule.smk_access1, NULL);
1864 data[0] = res == 0 ? '1' : '0'; 1873 data[0] = res == 0 ? '1' : '0';
1865 data[1] = '\0'; 1874 data[1] = '\0';
1866 1875
@@ -2143,7 +2152,7 @@ static ssize_t smk_write_change_rule(struct file *file, const char __user *buf,
2143 /* 2152 /*
2144 * Must have privilege. 2153 * Must have privilege.
2145 */ 2154 */
2146 if (!capable(CAP_MAC_ADMIN)) 2155 if (!smack_privileged(CAP_MAC_ADMIN))
2147 return -EPERM; 2156 return -EPERM;
2148 2157
2149 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, 2158 return smk_write_rules_list(file, buf, count, ppos, NULL, NULL,
@@ -2158,12 +2167,89 @@ static const struct file_operations smk_change_rule_ops = {
2158}; 2167};
2159 2168
2160/** 2169/**
2161 * smk_fill_super - fill the /smackfs superblock 2170 * smk_read_syslog - read() for smackfs/syslog
2171 * @filp: file pointer, not actually used
2172 * @buf: where to put the result
2173 * @cn: maximum to send along
2174 * @ppos: where to start
2175 *
2176 * Returns number of bytes read or error code, as appropriate
2177 */
2178static ssize_t smk_read_syslog(struct file *filp, char __user *buf,
2179 size_t cn, loff_t *ppos)
2180{
2181 struct smack_known *skp;
2182 ssize_t rc = -EINVAL;
2183 int asize;
2184
2185 if (*ppos != 0)
2186 return 0;
2187
2188 if (smack_syslog_label == NULL)
2189 skp = &smack_known_star;
2190 else
2191 skp = smack_syslog_label;
2192
2193 asize = strlen(skp->smk_known) + 1;
2194
2195 if (cn >= asize)
2196 rc = simple_read_from_buffer(buf, cn, ppos, skp->smk_known,
2197 asize);
2198
2199 return rc;
2200}
2201
2202/**
2203 * smk_write_syslog - write() for smackfs/syslog
2204 * @file: file pointer, not actually used
2205 * @buf: where to get the data from
2206 * @count: bytes sent
2207 * @ppos: where to start
2208 *
2209 * Returns number of bytes written or error code, as appropriate
2210 */
2211static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
2212 size_t count, loff_t *ppos)
2213{
2214 char *data;
2215 struct smack_known *skp;
2216 int rc = count;
2217
2218 if (!smack_privileged(CAP_MAC_ADMIN))
2219 return -EPERM;
2220
2221 data = kzalloc(count, GFP_KERNEL);
2222 if (data == NULL)
2223 return -ENOMEM;
2224
2225 if (copy_from_user(data, buf, count) != 0)
2226 rc = -EFAULT;
2227 else {
2228 skp = smk_import_entry(data, count);
2229 if (skp == NULL)
2230 rc = -EINVAL;
2231 else
2232 smack_syslog_label = smk_import_entry(data, count);
2233 }
2234
2235 kfree(data);
2236 return rc;
2237}
2238
2239static const struct file_operations smk_syslog_ops = {
2240 .read = smk_read_syslog,
2241 .write = smk_write_syslog,
2242 .llseek = default_llseek,
2243};
2244
2245
2246/**
2247 * smk_fill_super - fill the smackfs superblock
2162 * @sb: the empty superblock 2248 * @sb: the empty superblock
2163 * @data: unused 2249 * @data: unused
2164 * @silent: unused 2250 * @silent: unused
2165 * 2251 *
2166 * Fill in the well known entries for /smack 2252 * Fill in the well known entries for the smack filesystem
2167 * 2253 *
2168 * Returns 0 on success, an error code on failure 2254 * Returns 0 on success, an error code on failure
2169 */ 2255 */
@@ -2208,6 +2294,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2208 S_IRUGO|S_IWUSR}, 2294 S_IRUGO|S_IWUSR},
2209 [SMK_CHANGE_RULE] = { 2295 [SMK_CHANGE_RULE] = {
2210 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, 2296 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
2297 [SMK_SYSLOG] = {
2298 "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
2211 /* last one */ 2299 /* last one */
2212 {""} 2300 {""}
2213 }; 2301 };