Commit 2fd4e669 authored by James Morris's avatar James Morris

Merge branch 'smack-for-3.16' of git://git.gitorious.org/smack-next/kernel into next

parents fab71a90 ec554fa7
...@@ -204,6 +204,16 @@ onlycap ...@@ -204,6 +204,16 @@ onlycap
these capabilities are effective at for processes with any these capabilities are effective at for processes with any
label. The value is set by writing the desired label to the label. The value is set by writing the desired label to the
file or cleared by writing "-" to the file. file or cleared by writing "-" to the file.
ptrace
This is used to define the current ptrace policy
0 - default: this is the policy that relies on smack access rules.
For the PTRACE_READ a subject needs to have a read access on
object. For the PTRACE_ATTACH a read-write access is required.
1 - exact: this is the policy that limits PTRACE_ATTACH. Attach is
only allowed when subject's and object's labels are equal.
PTRACE_READ is not affected. Can be overriden with CAP_SYS_PTRACE.
2 - draconian: this policy behaves like the 'exact' above with an
exception that it can't be overriden with CAP_SYS_PTRACE.
revoke-subject revoke-subject
Writing a Smack label here sets the access to '-' for all access Writing a Smack label here sets the access to '-' for all access
rules with that subject label. rules with that subject label.
......
...@@ -80,8 +80,8 @@ struct superblock_smack { ...@@ -80,8 +80,8 @@ struct superblock_smack {
struct socket_smack { struct socket_smack {
struct smack_known *smk_out; /* outbound label */ struct smack_known *smk_out; /* outbound label */
char *smk_in; /* inbound label */ struct smack_known *smk_in; /* inbound label */
char *smk_packet; /* TCP peer label */ struct smack_known *smk_packet; /* TCP peer label */
}; };
/* /*
...@@ -133,7 +133,7 @@ struct smk_port_label { ...@@ -133,7 +133,7 @@ struct smk_port_label {
struct list_head list; struct list_head list;
struct sock *smk_sock; /* socket initialized on */ struct sock *smk_sock; /* socket initialized on */
unsigned short smk_port; /* the port number */ unsigned short smk_port; /* the port number */
char *smk_in; /* incoming label */ struct smack_known *smk_in; /* inbound label */
struct smack_known *smk_out; /* outgoing label */ struct smack_known *smk_out; /* outgoing label */
}; };
...@@ -176,6 +176,14 @@ struct smk_port_label { ...@@ -176,6 +176,14 @@ struct smk_port_label {
*/ */
#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */ #define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */
/*
* Ptrace rules
*/
#define SMACK_PTRACE_DEFAULT 0
#define SMACK_PTRACE_EXACT 1
#define SMACK_PTRACE_DRACONIAN 2
#define SMACK_PTRACE_MAX SMACK_PTRACE_DRACONIAN
/* /*
* Flags for untraditional access modes. * Flags for untraditional access modes.
* It shouldn't be necessary to avoid conflicts with definitions * It shouldn't be necessary to avoid conflicts with definitions
...@@ -225,6 +233,7 @@ struct inode_smack *new_inode_smack(char *); ...@@ -225,6 +233,7 @@ struct inode_smack *new_inode_smack(char *);
*/ */
int smk_access_entry(char *, char *, struct list_head *); int smk_access_entry(char *, char *, struct list_head *);
int smk_access(struct smack_known *, char *, int, struct smk_audit_info *); int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
int smk_tskacc(struct task_smack *, char *, u32, struct smk_audit_info *);
int smk_curacc(char *, u32, struct smk_audit_info *); int smk_curacc(char *, u32, struct smk_audit_info *);
struct smack_known *smack_from_secid(const u32); struct smack_known *smack_from_secid(const u32);
char *smk_parse_smack(const char *string, int len); char *smk_parse_smack(const char *string, int len);
...@@ -244,6 +253,7 @@ extern struct smack_known *smack_net_ambient; ...@@ -244,6 +253,7 @@ extern struct smack_known *smack_net_ambient;
extern struct smack_known *smack_onlycap; extern struct smack_known *smack_onlycap;
extern struct smack_known *smack_syslog_label; extern struct smack_known *smack_syslog_label;
extern const char *smack_cipso_option; extern const char *smack_cipso_option;
extern int smack_ptrace_rule;
extern struct smack_known smack_known_floor; extern struct smack_known smack_known_floor;
extern struct smack_known smack_known_hat; extern struct smack_known smack_known_hat;
......
...@@ -192,20 +192,21 @@ int smk_access(struct smack_known *subject_known, char *object_label, ...@@ -192,20 +192,21 @@ int smk_access(struct smack_known *subject_known, char *object_label,
} }
/** /**
* smk_curacc - determine if current has a specific access to an object * smk_tskacc - determine if a task has a specific access to an object
* @tsp: a pointer to the subject task
* @obj_label: a pointer to the object's Smack label * @obj_label: a pointer to the object's Smack label
* @mode: the access requested, in "MAY" format * @mode: the access requested, in "MAY" format
* @a : common audit data * @a : common audit data
* *
* This function checks the current subject label/object label pair * This function checks the subject task's label/object label pair
* in the access rule list and returns 0 if the access is permitted, * in the access rule list and returns 0 if the access is permitted,
* non zero otherwise. It allows that current may have the capability * non zero otherwise. It allows that the task may have the capability
* to override the rules. * to override the rules.
*/ */
int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) int smk_tskacc(struct task_smack *subject, char *obj_label,
u32 mode, struct smk_audit_info *a)
{ {
struct task_smack *tsp = current_security(); struct smack_known *skp = smk_of_task(subject);
struct smack_known *skp = smk_of_task(tsp);
int may; int may;
int rc; int rc;
...@@ -219,7 +220,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) ...@@ -219,7 +220,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
* it can further restrict access. * it can further restrict access.
*/ */
may = smk_access_entry(skp->smk_known, obj_label, may = smk_access_entry(skp->smk_known, obj_label,
&tsp->smk_rules); &subject->smk_rules);
if (may < 0) if (may < 0)
goto out_audit; goto out_audit;
if ((mode & may) == mode) if ((mode & may) == mode)
...@@ -241,6 +242,24 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) ...@@ -241,6 +242,24 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
return rc; return rc;
} }
/**
* smk_curacc - determine if current has a specific access to an object
* @obj_label: a pointer to the object's Smack label
* @mode: the access requested, in "MAY" format
* @a : common audit data
*
* This function checks the current subject label/object label pair
* in the access rule list and returns 0 if the access is permitted,
* non zero otherwise. It allows that current may have the capability
* to override the rules.
*/
int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
{
struct task_smack *tsp = current_security();
return smk_tskacc(tsp, obj_label, mode, a);
}
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
/** /**
* smack_str_from_perm : helper to transalate an int to a * smack_str_from_perm : helper to transalate an int to a
...@@ -285,6 +304,9 @@ static void smack_log_callback(struct audit_buffer *ab, void *a) ...@@ -285,6 +304,9 @@ static void smack_log_callback(struct audit_buffer *ab, void *a)
audit_log_untrustedstring(ab, sad->subject); audit_log_untrustedstring(ab, sad->subject);
audit_log_format(ab, " object="); audit_log_format(ab, " object=");
audit_log_untrustedstring(ab, sad->object); audit_log_untrustedstring(ab, sad->object);
if (sad->request[0] == '\0')
audit_log_format(ab, " labels_differ");
else
audit_log_format(ab, " requested=%s", sad->request); audit_log_format(ab, " requested=%s", sad->request);
} }
......
This diff is collapsed.
...@@ -53,6 +53,7 @@ enum smk_inos { ...@@ -53,6 +53,7 @@ enum smk_inos {
SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */ SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */
SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
SMK_SYSLOG = 20, /* change syslog label) */ SMK_SYSLOG = 20, /* change syslog label) */
SMK_PTRACE = 21, /* set ptrace rule */
}; };
/* /*
...@@ -100,6 +101,15 @@ struct smack_known *smack_onlycap; ...@@ -100,6 +101,15 @@ struct smack_known *smack_onlycap;
*/ */
struct smack_known *smack_syslog_label; struct smack_known *smack_syslog_label;
/*
* Ptrace current rule
* SMACK_PTRACE_DEFAULT regular smack ptrace rules (/proc based)
* SMACK_PTRACE_EXACT labels must match, but can be overriden with
* CAP_SYS_PTRACE
* SMACK_PTRACE_DRACONIAN lables must match, CAP_SYS_PTRACE has no effect
*/
int smack_ptrace_rule = SMACK_PTRACE_DEFAULT;
/* /*
* Certain IP addresses may be designated as single label hosts. * Certain IP addresses may be designated as single label hosts.
* Packets are sent there unlabeled, but only from tasks that * Packets are sent there unlabeled, but only from tasks that
...@@ -1183,7 +1193,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, ...@@ -1183,7 +1193,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
data[count] = '\0'; data[count] = '\0';
rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s", rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
&host[0], &host[1], &host[2], &host[3], &m, smack); &host[0], &host[1], &host[2], &host[3], &m, smack);
if (rc != 6) { if (rc != 6) {
rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
...@@ -2243,6 +2253,68 @@ static const struct file_operations smk_syslog_ops = { ...@@ -2243,6 +2253,68 @@ static const struct file_operations smk_syslog_ops = {
}; };
/**
* smk_read_ptrace - read() for /smack/ptrace
* @filp: file pointer, not actually used
* @buf: where to put the result
* @count: maximum to send along
* @ppos: where to start
*
* Returns number of bytes read or error code, as appropriate
*/
static ssize_t smk_read_ptrace(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
char temp[32];
ssize_t rc;
if (*ppos != 0)
return 0;
sprintf(temp, "%d\n", smack_ptrace_rule);
rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
return rc;
}
/**
* smk_write_ptrace - write() for /smack/ptrace
* @file: file pointer
* @buf: data from user space
* @count: bytes sent
* @ppos: where to start - must be 0
*/
static ssize_t smk_write_ptrace(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
char temp[32];
int i;
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
if (*ppos != 0 || count >= sizeof(temp) || count == 0)
return -EINVAL;
if (copy_from_user(temp, buf, count) != 0)
return -EFAULT;
temp[count] = '\0';
if (sscanf(temp, "%d", &i) != 1)
return -EINVAL;
if (i < SMACK_PTRACE_DEFAULT || i > SMACK_PTRACE_MAX)
return -EINVAL;
smack_ptrace_rule = i;
return count;
}
static const struct file_operations smk_ptrace_ops = {
.write = smk_write_ptrace,
.read = smk_read_ptrace,
.llseek = default_llseek,
};
/** /**
* smk_fill_super - fill the smackfs superblock * smk_fill_super - fill the smackfs superblock
* @sb: the empty superblock * @sb: the empty superblock
...@@ -2296,6 +2368,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) ...@@ -2296,6 +2368,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
"change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
[SMK_SYSLOG] = { [SMK_SYSLOG] = {
"syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
[SMK_PTRACE] = {
"ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR},
/* last one */ /* last one */
{""} {""}
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment