Messages in this thread | | | Date | Fri, 11 Apr 2014 14:50:15 -0700 | From | Casey Schaufler <> | Subject | Re: [PATCH 3/3] Smack: adds smackfs/ptrace interface |
| |
On 3/11/2014 9:07 AM, Lukasz Pawelczyk wrote: > This allows to limit ptrace beyond the regular smack access rules. > It adds a smackfs/ptrace interface that allows smack to be configured > to require equal smack labels for PTRACE_MODE_ATTACH access. > See the changes in Documentation/security/Smack.txt below for details. > > Signed-off-by: Lukasz Pawelczyk <l.pawelczyk@partner.samsung.com> > Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
Acked-by: Casey Schaufler <casey@schaufler-ca.com>
Applied to git://git.gitorious.org/smack-next/kernel.git smack-for-3.16
> --- > Documentation/security/Smack.txt | 10 ++++++ > security/smack/smack.h | 9 +++++ > security/smack/smack_access.c | 5 ++- > security/smack/smack_lsm.c | 22 +++++++++++- > security/smack/smackfs.c | 74 ++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 118 insertions(+), 2 deletions(-) > > diff --git a/Documentation/security/Smack.txt b/Documentation/security/Smack.txt > index 7a2d30c..5597917 100644 > --- a/Documentation/security/Smack.txt > +++ b/Documentation/security/Smack.txt > @@ -204,6 +204,16 @@ onlycap > these capabilities are effective at for processes with any > label. The value is set by writing the desired label to the > 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 > Writing a Smack label here sets the access to '-' for all access > rules with that subject label. > diff --git a/security/smack/smack.h b/security/smack/smack.h > index b9dfc4e..fade085 100644 > --- a/security/smack/smack.h > +++ b/security/smack/smack.h > @@ -177,6 +177,14 @@ struct smk_port_label { > #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. > * It shouldn't be necessary to avoid conflicts with definitions > * in fs.h, but do so anyway. > @@ -245,6 +253,7 @@ extern struct smack_known *smack_net_ambient; > extern struct smack_known *smack_onlycap; > extern struct smack_known *smack_syslog_label; > extern const char *smack_cipso_option; > +extern int smack_ptrace_rule; > > extern struct smack_known smack_known_floor; > extern struct smack_known smack_known_hat; > diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c > index f161deb..c062e94 100644 > --- a/security/smack/smack_access.c > +++ b/security/smack/smack_access.c > @@ -304,7 +304,10 @@ static void smack_log_callback(struct audit_buffer *ab, void *a) > audit_log_untrustedstring(ab, sad->subject); > audit_log_format(ab, " object="); > audit_log_untrustedstring(ab, sad->object); > - audit_log_format(ab, " requested=%s", sad->request); > + if (sad->request[0] == '\0') > + audit_log_format(ab, " labels_differ"); > + else > + audit_log_format(ab, " requested=%s", sad->request); > } > > /** > diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c > index 3da13fd..1876bfc 100644 > --- a/security/smack/smack_lsm.c > +++ b/security/smack/smack_lsm.c > @@ -178,7 +178,8 @@ static inline unsigned int smk_ptrace_mode(unsigned int mode) > /** > * smk_ptrace_rule_check - helper for ptrace access > * @tracer: tracer process > - * @tracee_label: label of the process that's about to be traced > + * @tracee_label: label of the process that's about to be traced, > + * the pointer must originate from smack structures > * @mode: ptrace attachment mode (PTRACE_MODE_*) > * @func: name of the function that called us, used for audit > * > @@ -201,6 +202,25 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label, > tsp = task_security(tracer); > skp = smk_of_task(tsp); > > + if ((mode & PTRACE_MODE_ATTACH) && > + (smack_ptrace_rule == SMACK_PTRACE_EXACT || > + smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) { > + if (skp->smk_known == tracee_label) > + rc = 0; > + else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN) > + rc = -EACCES; > + else if (capable(CAP_SYS_PTRACE)) > + rc = 0; > + else > + rc = -EACCES; > + > + if (saip) > + smack_log(skp->smk_known, tracee_label, 0, rc, saip); > + > + return rc; > + } > + > + /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ > rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip); > return rc; > } > diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c > index 3198cfe..177d878 100644 > --- a/security/smack/smackfs.c > +++ b/security/smack/smackfs.c > @@ -53,6 +53,7 @@ enum smk_inos { > SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */ > SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ > SMK_SYSLOG = 20, /* change syslog label) */ > + SMK_PTRACE = 21, /* set ptrace rule */ > }; > > /* > @@ -101,6 +102,15 @@ struct smack_known *smack_onlycap; > 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. > * Packets are sent there unlabeled, but only from tasks that > * can write to the specified label. > @@ -2244,6 +2254,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 > * @sb: the empty superblock > * @data: unused > @@ -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}, > [SMK_SYSLOG] = { > "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, > + [SMK_PTRACE] = { > + "ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR}, > /* last one */ > {""} > };
| |