summaryrefslogtreecommitdiff
path: root/security/smack
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/smack.h21
-rw-r--r--security/smack/smack_access.c16
-rw-r--r--security/smack/smack_lsm.c110
-rw-r--r--security/smack/smackfs.c55
4 files changed, 88 insertions, 114 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index dbf8d7226eb5..bf6a6ed3946c 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -42,7 +42,7 @@
/*
* This is the repository for labels seen so that it is
- * not necessary to keep allocating tiny chuncks of memory
+ * not necessary to keep allocating tiny chunks of memory
* and so that they can be shared.
*
* Labels are never modified in place. Anytime a label
@@ -152,6 +152,7 @@ struct smk_net4addr {
struct smack_known *smk_label; /* label */
};
+#if IS_ENABLED(CONFIG_IPV6)
/*
* An entry in the table identifying IPv6 hosts.
*/
@@ -162,7 +163,9 @@ struct smk_net6addr {
int smk_masks; /* mask size */
struct smack_known *smk_label; /* label */
};
+#endif /* CONFIG_IPV6 */
+#ifdef SMACK_IPV6_PORT_LABELING
/*
* An entry in the table identifying ports.
*/
@@ -175,6 +178,7 @@ struct smk_port_label {
short smk_sock_type; /* Socket type */
short smk_can_reuse;
};
+#endif /* SMACK_IPV6_PORT_LABELING */
struct smack_known_list_elem {
struct list_head list;
@@ -280,6 +284,7 @@ int smk_access(struct smack_known *, struct smack_known *,
int smk_tskacc(struct task_smack *, struct smack_known *,
u32, struct smk_audit_info *);
int smk_curacc(struct smack_known *, u32, struct smk_audit_info *);
+int smack_str_from_perm(char *string, int access);
struct smack_known *smack_from_secid(const u32);
char *smk_parse_smack(const char *string, int len);
int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int);
@@ -314,7 +319,9 @@ extern struct smack_known smack_known_web;
extern struct mutex smack_known_lock;
extern struct list_head smack_known_list;
extern struct list_head smk_net4addr_list;
+#if IS_ENABLED(CONFIG_IPV6)
extern struct list_head smk_net6addr_list;
+#endif /* CONFIG_IPV6 */
extern struct mutex smack_onlycap_lock;
extern struct list_head smack_onlycap_list;
@@ -425,6 +432,12 @@ static inline struct smack_known *smk_of_current(void)
return smk_of_task(smack_cred(current_cred()));
}
+void smack_log(char *subject_label, char *object_label,
+ int request,
+ int result, struct smk_audit_info *auditdata);
+
+#ifdef CONFIG_AUDIT
+
/*
* logging functions
*/
@@ -432,12 +445,6 @@ static inline struct smack_known *smk_of_current(void)
#define SMACK_AUDIT_ACCEPT 0x2
extern int log_policy;
-void smack_log(char *subject_label, char *object_label,
- int request,
- int result, struct smk_audit_info *auditdata);
-
-#ifdef CONFIG_AUDIT
-
/*
* some inline functions to set up audit data
* they do nothing if CONFIG_AUDIT is not set
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 585e5e35710b..2e4a0cb22782 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -45,11 +45,13 @@ LIST_HEAD(smack_known_list);
*/
static u32 smack_next_secid = 10;
+#ifdef CONFIG_AUDIT
/*
* what events do we log
* can be overwritten at run-time by /smack/logging
*/
int log_policy = SMACK_AUDIT_DENIED;
+#endif /* CONFIG_AUDIT */
/**
* smk_access_entry - look up matching access rule
@@ -242,7 +244,7 @@ int smk_tskacc(struct task_smack *tsp, struct smack_known *obj_known,
}
/*
- * Allow for priviliged to override policy.
+ * Allow for privileged to override policy.
*/
if (rc != 0 && smack_privileged(CAP_MAC_OVERRIDE))
rc = 0;
@@ -275,15 +277,14 @@ int smk_curacc(struct smack_known *obj_known,
return smk_tskacc(tsp, obj_known, mode, a);
}
-#ifdef CONFIG_AUDIT
/**
- * smack_str_from_perm : helper to transalate an int to a
+ * smack_str_from_perm : helper to translate an int to a
* readable string
* @string : the string to fill
* @access : the int
*
*/
-static inline void smack_str_from_perm(char *string, int access)
+int smack_str_from_perm(char *string, int access)
{
int i = 0;
@@ -299,8 +300,15 @@ static inline void smack_str_from_perm(char *string, int access)
string[i++] = 't';
if (access & MAY_LOCK)
string[i++] = 'l';
+ if (access & MAY_BRINGUP)
+ string[i++] = 'b';
+ if (i == 0)
+ string[i++] = '-';
string[i] = '\0';
+ return i;
}
+
+#ifdef CONFIG_AUDIT
/**
* smack_log_callback - SMACK specific information
* will be called by generic audit code
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 0c476282e279..99833168604e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -107,23 +107,7 @@ static char *smk_bu_mess[] = {
static void smk_bu_mode(int mode, char *s)
{
- int i = 0;
-
- if (mode & MAY_READ)
- s[i++] = 'r';
- if (mode & MAY_WRITE)
- s[i++] = 'w';
- if (mode & MAY_EXEC)
- s[i++] = 'x';
- if (mode & MAY_APPEND)
- s[i++] = 'a';
- if (mode & MAY_TRANSMUTE)
- s[i++] = 't';
- if (mode & MAY_LOCK)
- s[i++] = 'l';
- if (i == 0)
- s[i++] = '-';
- s[i] = '\0';
+ smack_str_from_perm(s, mode);
}
#endif
@@ -1950,7 +1934,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk,
*/
file = fown->file;
- /* we don't log here as rc can be overriden */
+ /* we don't log here as rc can be overridden */
blob = smack_file(file);
skp = *blob;
rc = smk_access(skp, tkp, MAY_DELIVER, NULL);
@@ -2508,6 +2492,7 @@ static struct smack_known *smack_ipv4host_label(struct sockaddr_in *sip)
return NULL;
}
+#if IS_ENABLED(CONFIG_IPV6)
/*
* smk_ipv6_localhost - Check for local ipv6 host address
* @sip: the address
@@ -2575,6 +2560,7 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
return NULL;
}
+#endif /* CONFIG_IPV6 */
/**
* smack_netlbl_add - Set the secattr on a socket
@@ -2679,6 +2665,7 @@ static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap)
return rc;
}
+#if IS_ENABLED(CONFIG_IPV6)
/**
* smk_ipv6_check - check Smack access
* @subject: subject Smack label
@@ -2711,6 +2698,7 @@ static int smk_ipv6_check(struct smack_known *subject,
rc = smk_bu_note("IPv6 check", subject, object, MAY_WRITE, rc);
return rc;
}
+#endif /* CONFIG_IPV6 */
#ifdef SMACK_IPV6_PORT_LABELING
/**
@@ -3043,7 +3031,9 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
return 0;
if (addrlen < offsetofend(struct sockaddr, sa_family))
return 0;
- if (IS_ENABLED(CONFIG_IPV6) && sap->sa_family == AF_INET6) {
+
+#if IS_ENABLED(CONFIG_IPV6)
+ if (sap->sa_family == AF_INET6) {
struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
struct smack_known *rsp = NULL;
@@ -3063,6 +3053,8 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
return rc;
}
+#endif /* CONFIG_IPV6 */
+
if (sap->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
return 0;
rc = smk_ipv4_check(sock->sk, (struct sockaddr_in *)sap);
@@ -4211,7 +4203,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
/*
* Receiving a packet requires that the other end
* be able to write here. Read access is not required.
- * This is the simplist possible security model
+ * This is the simplest possible security model
* for networking.
*/
rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
@@ -4359,29 +4351,6 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
}
/**
- * smack_sock_graft - Initialize a newly created socket with an existing sock
- * @sk: child sock
- * @parent: parent socket
- *
- * Set the smk_{in,out} state of an existing sock based on the process that
- * is creating the new socket.
- */
-static void smack_sock_graft(struct sock *sk, struct socket *parent)
-{
- struct socket_smack *ssp;
- struct smack_known *skp = smk_of_current();
-
- if (sk == NULL ||
- (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
- return;
-
- ssp = smack_sock(sk);
- ssp->smk_in = skp;
- ssp->smk_out = skp;
- /* cssp->smk_packet is already set in smack_inet_csk_clone() */
-}
-
-/**
* smack_inet_conn_request - Smack access check on connect
* @sk: socket involved
* @skb: packet
@@ -4717,7 +4686,7 @@ static int smack_post_notification(const struct cred *w_cred,
* @gfp: type of the memory for the allocation
*
* Prepare to audit cases where (@field @op @rulestr) is true.
- * The label to be audited is created if necessay.
+ * The label to be audited is created if necessary.
*/
static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
gfp_t gfp)
@@ -4818,40 +4787,47 @@ static int smack_ismaclabel(const char *name)
}
/**
+ * smack_to_secctx - fill a lsm_context
+ * @skp: Smack label
+ * @cp: destination
+ *
+ * Fill the passed @cp and return the length of the string
+ */
+static int smack_to_secctx(struct smack_known *skp, struct lsm_context *cp)
+{
+ int len = strlen(skp->smk_known);
+
+ if (cp) {
+ cp->context = skp->smk_known;
+ cp->len = len;
+ cp->id = LSM_ID_SMACK;
+ }
+ return len;
+}
+
+/**
* smack_secid_to_secctx - return the smack label for a secid
* @secid: incoming integer
- * @secdata: destination
- * @seclen: how long it is
+ * @cp: destination
*
* Exists for networking code.
*/
-static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+static int smack_secid_to_secctx(u32 secid, struct lsm_context *cp)
{
- struct smack_known *skp = smack_from_secid(secid);
-
- if (secdata)
- *secdata = skp->smk_known;
- *seclen = strlen(skp->smk_known);
- return 0;
+ return smack_to_secctx(smack_from_secid(secid), cp);
}
/**
* smack_lsmprop_to_secctx - return the smack label
* @prop: includes incoming Smack data
- * @secdata: destination
- * @seclen: how long it is
+ * @cp: destination
*
* Exists for audit code.
*/
-static int smack_lsmprop_to_secctx(struct lsm_prop *prop, char **secdata,
- u32 *seclen)
+static int smack_lsmprop_to_secctx(struct lsm_prop *prop,
+ struct lsm_context *cp)
{
- struct smack_known *skp = prop->smack.skp;
-
- if (secdata)
- *secdata = skp->smk_known;
- *seclen = strlen(skp->smk_known);
- return 0;
+ return smack_to_secctx(prop->smack.skp, cp);
}
/**
@@ -4891,12 +4867,13 @@ static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
ctx, ctxlen, 0, NULL);
}
-static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
+static int smack_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
{
struct smack_known *skp = smk_of_inode(inode);
- *ctx = skp->smk_known;
- *ctxlen = strlen(skp->smk_known);
+ cp->context = skp->smk_known;
+ cp->len = strlen(skp->smk_known);
+ cp->id = LSM_ID_SMACK;
return 0;
}
@@ -5187,7 +5164,6 @@ static struct security_hook_list smack_hooks[] __ro_after_init = {
LSM_HOOK_INIT(sk_free_security, smack_sk_free_security),
#endif
LSM_HOOK_INIT(sk_clone_security, smack_sk_clone_security),
- LSM_HOOK_INIT(sock_graft, smack_sock_graft),
LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request),
LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone),
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 1401412fd794..90a67e410808 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -41,7 +41,9 @@ enum smk_inos {
SMK_AMBIENT = 7, /* internet ambient label */
SMK_NET4ADDR = 8, /* single label hosts */
SMK_ONLYCAP = 9, /* the only "capable" label */
+#ifdef CONFIG_AUDIT
SMK_LOGGING = 10, /* logging */
+#endif /* CONFIG_AUDIT */
SMK_LOAD_SELF = 11, /* task specific rules */
SMK_ACCESSES = 12, /* access policy */
SMK_MAPPED = 13, /* CIPSO level indicating mapped label */
@@ -165,7 +167,7 @@ static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
/*
- * Stricly for CIPSO level manipulation.
+ * Strictly for CIPSO level manipulation.
* Set the category bit number in a smack label sized buffer.
*/
static inline void smack_catset_bit(unsigned int cat, char *catsetp)
@@ -562,6 +564,7 @@ static void smk_seq_stop(struct seq_file *s, void *v)
static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
{
+ char acc[SMK_NUM_ACCESS_TYPE + 1];
/*
* Don't show any rules with label names too long for
* interface file (/smack/load or /smack/load2)
@@ -575,28 +578,11 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
if (srp->smk_access == 0)
return;
- seq_printf(s, "%s %s",
+ smack_str_from_perm(acc, srp->smk_access);
+ seq_printf(s, "%s %s %s\n",
srp->smk_subject->smk_known,
- srp->smk_object->smk_known);
-
- seq_putc(s, ' ');
-
- if (srp->smk_access & MAY_READ)
- seq_putc(s, 'r');
- if (srp->smk_access & MAY_WRITE)
- seq_putc(s, 'w');
- if (srp->smk_access & MAY_EXEC)
- seq_putc(s, 'x');
- if (srp->smk_access & MAY_APPEND)
- seq_putc(s, 'a');
- if (srp->smk_access & MAY_TRANSMUTE)
- seq_putc(s, 't');
- if (srp->smk_access & MAY_LOCK)
- seq_putc(s, 'l');
- if (srp->smk_access & MAY_BRINGUP)
- seq_putc(s, 'b');
-
- seq_putc(s, '\n');
+ srp->smk_object->smk_known,
+ acc);
}
/*
@@ -828,7 +814,7 @@ static int smk_open_cipso(struct inode *inode, struct file *file)
static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
size_t count, loff_t *ppos, int format)
{
- struct netlbl_lsm_catmap *old_cat, *new_cat = NULL;
+ struct netlbl_lsm_catmap *old_cat;
struct smack_known *skp;
struct netlbl_lsm_secattr ncats;
char mapcatset[SMK_CIPSOLEN];
@@ -915,22 +901,15 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
smack_catset_bit(cat, mapcatset);
}
- ncats.flags = 0;
- if (catlen == 0) {
- ncats.attr.mls.cat = NULL;
- ncats.attr.mls.lvl = maplevel;
- new_cat = netlbl_catmap_alloc(GFP_ATOMIC);
- if (new_cat)
- new_cat->next = ncats.attr.mls.cat;
- ncats.attr.mls.cat = new_cat;
- skp->smk_netlabel.flags &= ~(1U << 3);
- rc = 0;
- } else {
- rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
- }
+
+ rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
if (rc >= 0) {
old_cat = skp->smk_netlabel.attr.mls.cat;
rcu_assign_pointer(skp->smk_netlabel.attr.mls.cat, ncats.attr.mls.cat);
+ if (ncats.attr.mls.cat)
+ skp->smk_netlabel.flags |= NETLBL_SECATTR_MLS_CAT;
+ else
+ skp->smk_netlabel.flags &= ~(u32)NETLBL_SECATTR_MLS_CAT;
skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
synchronize_rcu();
netlbl_catmap_free(old_cat);
@@ -2149,6 +2128,7 @@ static const struct file_operations smk_unconfined_ops = {
};
#endif /* CONFIG_SECURITY_SMACK_BRINGUP */
+#ifdef CONFIG_AUDIT
/**
* smk_read_logging - read() for /smack/logging
* @filp: file pointer, not actually used
@@ -2213,6 +2193,7 @@ static const struct file_operations smk_logging_ops = {
.write = smk_write_logging,
.llseek = default_llseek,
};
+#endif /* CONFIG_AUDIT */
/*
* Seq_file read operations for /smack/load-self
@@ -2899,8 +2880,10 @@ static int smk_fill_super(struct super_block *sb, struct fs_context *fc)
"netlabel", &smk_net4addr_ops, S_IRUGO|S_IWUSR},
[SMK_ONLYCAP] = {
"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
+#ifdef CONFIG_AUDIT
[SMK_LOGGING] = {
"logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
+#endif /* CONFIG_AUDIT */
[SMK_LOAD_SELF] = {
"load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
[SMK_ACCESSES] = {