aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukasz Pawelczyk <l.pawelczyk@partner.samsung.com>2014-03-11 12:07:06 -0400
committerCasey Schaufler <casey@schaufler-ca.com>2014-04-11 17:34:35 -0400
commit668678185247303450e60df14569f94cf5775fea (patch)
tree2f2b77d7a2769745699e48685c9dbf26d8dd0c98
parent5663884caab166f87ab8c68ec7c62b1cce85a400 (diff)
Smack: adds smackfs/ptrace interface
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>
-rw-r--r--Documentation/security/Smack.txt10
-rw-r--r--security/smack/smack.h9
-rw-r--r--security/smack/smack_access.c5
-rw-r--r--security/smack/smack_lsm.c22
-rw-r--r--security/smack/smackfs.c74
5 files changed, 118 insertions, 2 deletions
diff --git a/Documentation/security/Smack.txt b/Documentation/security/Smack.txt
index 7a2d30c132e3..5597917703e0 100644
--- a/Documentation/security/Smack.txt
+++ b/Documentation/security/Smack.txt
@@ -204,6 +204,16 @@ onlycap
204 these capabilities are effective at for processes with any 204 these capabilities are effective at for processes with any
205 label. The value is set by writing the desired label to the 205 label. The value is set by writing the desired label to the
206 file or cleared by writing "-" to the file. 206 file or cleared by writing "-" to the file.
207ptrace
208 This is used to define the current ptrace policy
209 0 - default: this is the policy that relies on smack access rules.
210 For the PTRACE_READ a subject needs to have a read access on
211 object. For the PTRACE_ATTACH a read-write access is required.
212 1 - exact: this is the policy that limits PTRACE_ATTACH. Attach is
213 only allowed when subject's and object's labels are equal.
214 PTRACE_READ is not affected. Can be overriden with CAP_SYS_PTRACE.
215 2 - draconian: this policy behaves like the 'exact' above with an
216 exception that it can't be overriden with CAP_SYS_PTRACE.
207revoke-subject 217revoke-subject
208 Writing a Smack label here sets the access to '-' for all access 218 Writing a Smack label here sets the access to '-' for all access
209 rules with that subject label. 219 rules with that subject label.
diff --git a/security/smack/smack.h b/security/smack/smack.h
index b9dfc4e1d3e0..fade085b1128 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -177,6 +177,14 @@ struct smk_port_label {
177#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */ 177#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */
178 178
179/* 179/*
180 * Ptrace rules
181 */
182#define SMACK_PTRACE_DEFAULT 0
183#define SMACK_PTRACE_EXACT 1
184#define SMACK_PTRACE_DRACONIAN 2
185#define SMACK_PTRACE_MAX SMACK_PTRACE_DRACONIAN
186
187/*
180 * Flags for untraditional access modes. 188 * Flags for untraditional access modes.
181 * It shouldn't be necessary to avoid conflicts with definitions 189 * It shouldn't be necessary to avoid conflicts with definitions
182 * in fs.h, but do so anyway. 190 * in fs.h, but do so anyway.
@@ -245,6 +253,7 @@ extern struct smack_known *smack_net_ambient;
245extern struct smack_known *smack_onlycap; 253extern struct smack_known *smack_onlycap;
246extern struct smack_known *smack_syslog_label; 254extern struct smack_known *smack_syslog_label;
247extern const char *smack_cipso_option; 255extern const char *smack_cipso_option;
256extern int smack_ptrace_rule;
248 257
249extern struct smack_known smack_known_floor; 258extern struct smack_known smack_known_floor;
250extern struct smack_known smack_known_hat; 259extern struct smack_known smack_known_hat;
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index f161debed02b..c062e9467b62 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)
304 audit_log_untrustedstring(ab, sad->subject); 304 audit_log_untrustedstring(ab, sad->subject);
305 audit_log_format(ab, " object="); 305 audit_log_format(ab, " object=");
306 audit_log_untrustedstring(ab, sad->object); 306 audit_log_untrustedstring(ab, sad->object);
307 audit_log_format(ab, " requested=%s", sad->request); 307 if (sad->request[0] == '\0')
308 audit_log_format(ab, " labels_differ");
309 else
310 audit_log_format(ab, " requested=%s", sad->request);
308} 311}
309 312
310/** 313/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 4d6f37644baa..787dcf12f15c 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)
178/** 178/**
179 * smk_ptrace_rule_check - helper for ptrace access 179 * smk_ptrace_rule_check - helper for ptrace access
180 * @tracer: tracer process 180 * @tracer: tracer process
181 * @tracee_label: label of the process that's about to be traced 181 * @tracee_label: label of the process that's about to be traced,
182 * the pointer must originate from smack structures
182 * @mode: ptrace attachment mode (PTRACE_MODE_*) 183 * @mode: ptrace attachment mode (PTRACE_MODE_*)
183 * @func: name of the function that called us, used for audit 184 * @func: name of the function that called us, used for audit
184 * 185 *
@@ -201,6 +202,25 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label,
201 tsp = task_security(tracer); 202 tsp = task_security(tracer);
202 skp = smk_of_task(tsp); 203 skp = smk_of_task(tsp);
203 204
205 if ((mode & PTRACE_MODE_ATTACH) &&
206 (smack_ptrace_rule == SMACK_PTRACE_EXACT ||
207 smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) {
208 if (skp->smk_known == tracee_label)
209 rc = 0;
210 else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)
211 rc = -EACCES;
212 else if (capable(CAP_SYS_PTRACE))
213 rc = 0;
214 else
215 rc = -EACCES;
216
217 if (saip)
218 smack_log(skp->smk_known, tracee_label, 0, rc, saip);
219
220 return rc;
221 }
222
223 /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */
204 rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip); 224 rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip);
205 return rc; 225 return rc;
206} 226}
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 3198cfe1dcc6..177d87875394 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -53,6 +53,7 @@ enum smk_inos {
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 SMK_SYSLOG = 20, /* change syslog label) */
56 SMK_PTRACE = 21, /* set ptrace rule */
56}; 57};
57 58
58/* 59/*
@@ -101,6 +102,15 @@ struct smack_known *smack_onlycap;
101struct smack_known *smack_syslog_label; 102struct smack_known *smack_syslog_label;
102 103
103/* 104/*
105 * Ptrace current rule
106 * SMACK_PTRACE_DEFAULT regular smack ptrace rules (/proc based)
107 * SMACK_PTRACE_EXACT labels must match, but can be overriden with
108 * CAP_SYS_PTRACE
109 * SMACK_PTRACE_DRACONIAN lables must match, CAP_SYS_PTRACE has no effect
110 */
111int smack_ptrace_rule = SMACK_PTRACE_DEFAULT;
112
113/*
104 * Certain IP addresses may be designated as single label hosts. 114 * Certain IP addresses may be designated as single label hosts.
105 * Packets are sent there unlabeled, but only from tasks that 115 * Packets are sent there unlabeled, but only from tasks that
106 * can write to the specified label. 116 * can write to the specified label.
@@ -2244,6 +2254,68 @@ static const struct file_operations smk_syslog_ops = {
2244 2254
2245 2255
2246/** 2256/**
2257 * smk_read_ptrace - read() for /smack/ptrace
2258 * @filp: file pointer, not actually used
2259 * @buf: where to put the result
2260 * @count: maximum to send along
2261 * @ppos: where to start
2262 *
2263 * Returns number of bytes read or error code, as appropriate
2264 */
2265static ssize_t smk_read_ptrace(struct file *filp, char __user *buf,
2266 size_t count, loff_t *ppos)
2267{
2268 char temp[32];
2269 ssize_t rc;
2270
2271 if (*ppos != 0)
2272 return 0;
2273
2274 sprintf(temp, "%d\n", smack_ptrace_rule);
2275 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
2276 return rc;
2277}
2278
2279/**
2280 * smk_write_ptrace - write() for /smack/ptrace
2281 * @file: file pointer
2282 * @buf: data from user space
2283 * @count: bytes sent
2284 * @ppos: where to start - must be 0
2285 */
2286static ssize_t smk_write_ptrace(struct file *file, const char __user *buf,
2287 size_t count, loff_t *ppos)
2288{
2289 char temp[32];
2290 int i;
2291
2292 if (!smack_privileged(CAP_MAC_ADMIN))
2293 return -EPERM;
2294
2295 if (*ppos != 0 || count >= sizeof(temp) || count == 0)
2296 return -EINVAL;
2297
2298 if (copy_from_user(temp, buf, count) != 0)
2299 return -EFAULT;
2300
2301 temp[count] = '\0';
2302
2303 if (sscanf(temp, "%d", &i) != 1)
2304 return -EINVAL;
2305 if (i < SMACK_PTRACE_DEFAULT || i > SMACK_PTRACE_MAX)
2306 return -EINVAL;
2307 smack_ptrace_rule = i;
2308
2309 return count;
2310}
2311
2312static const struct file_operations smk_ptrace_ops = {
2313 .write = smk_write_ptrace,
2314 .read = smk_read_ptrace,
2315 .llseek = default_llseek,
2316};
2317
2318/**
2247 * smk_fill_super - fill the smackfs superblock 2319 * smk_fill_super - fill the smackfs superblock
2248 * @sb: the empty superblock 2320 * @sb: the empty superblock
2249 * @data: unused 2321 * @data: unused
@@ -2296,6 +2368,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
2296 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, 2368 "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
2297 [SMK_SYSLOG] = { 2369 [SMK_SYSLOG] = {
2298 "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, 2370 "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
2371 [SMK_PTRACE] = {
2372 "ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR},
2299 /* last one */ 2373 /* last one */
2300 {""} 2374 {""}
2301 }; 2375 };