aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/security/Smack.txt10
-rw-r--r--security/smack/smack.h16
-rw-r--r--security/smack/smack_access.c38
-rw-r--r--security/smack/smack_lsm.c240
-rw-r--r--security/smack/smackfs.c76
5 files changed, 307 insertions, 73 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 d072fd32212d..020307ef0972 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -80,8 +80,8 @@ struct superblock_smack {
80 80
81struct socket_smack { 81struct socket_smack {
82 struct smack_known *smk_out; /* outbound label */ 82 struct smack_known *smk_out; /* outbound label */
83 char *smk_in; /* inbound label */ 83 struct smack_known *smk_in; /* inbound label */
84 char *smk_packet; /* TCP peer label */ 84 struct smack_known *smk_packet; /* TCP peer label */
85}; 85};
86 86
87/* 87/*
@@ -133,7 +133,7 @@ struct smk_port_label {
133 struct list_head list; 133 struct list_head list;
134 struct sock *smk_sock; /* socket initialized on */ 134 struct sock *smk_sock; /* socket initialized on */
135 unsigned short smk_port; /* the port number */ 135 unsigned short smk_port; /* the port number */
136 char *smk_in; /* incoming label */ 136 struct smack_known *smk_in; /* inbound label */
137 struct smack_known *smk_out; /* outgoing label */ 137 struct smack_known *smk_out; /* outgoing label */
138}; 138};
139 139
@@ -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.
@@ -225,6 +233,7 @@ struct inode_smack *new_inode_smack(char *);
225 */ 233 */
226int smk_access_entry(char *, char *, struct list_head *); 234int smk_access_entry(char *, char *, struct list_head *);
227int smk_access(struct smack_known *, char *, int, struct smk_audit_info *); 235int smk_access(struct smack_known *, char *, int, struct smk_audit_info *);
236int smk_tskacc(struct task_smack *, char *, u32, struct smk_audit_info *);
228int smk_curacc(char *, u32, struct smk_audit_info *); 237int smk_curacc(char *, u32, struct smk_audit_info *);
229struct smack_known *smack_from_secid(const u32); 238struct smack_known *smack_from_secid(const u32);
230char *smk_parse_smack(const char *string, int len); 239char *smk_parse_smack(const char *string, int len);
@@ -244,6 +253,7 @@ extern struct smack_known *smack_net_ambient;
244extern struct smack_known *smack_onlycap; 253extern struct smack_known *smack_onlycap;
245extern struct smack_known *smack_syslog_label; 254extern struct smack_known *smack_syslog_label;
246extern const char *smack_cipso_option; 255extern const char *smack_cipso_option;
256extern int smack_ptrace_rule;
247 257
248extern struct smack_known smack_known_floor; 258extern struct smack_known smack_known_floor;
249extern 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 14293cd9b1e5..c062e9467b62 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -192,20 +192,21 @@ out_audit:
192} 192}
193 193
194/** 194/**
195 * smk_curacc - determine if current has a specific access to an object 195 * smk_tskacc - determine if a task has a specific access to an object
196 * @tsp: a pointer to the subject task
196 * @obj_label: a pointer to the object's Smack label 197 * @obj_label: a pointer to the object's Smack label
197 * @mode: the access requested, in "MAY" format 198 * @mode: the access requested, in "MAY" format
198 * @a : common audit data 199 * @a : common audit data
199 * 200 *
200 * This function checks the current subject label/object label pair 201 * This function checks the subject task's label/object label pair
201 * in the access rule list and returns 0 if the access is permitted, 202 * in the access rule list and returns 0 if the access is permitted,
202 * non zero otherwise. It allows that current may have the capability 203 * non zero otherwise. It allows that the task may have the capability
203 * to override the rules. 204 * to override the rules.
204 */ 205 */
205int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) 206int smk_tskacc(struct task_smack *subject, char *obj_label,
207 u32 mode, struct smk_audit_info *a)
206{ 208{
207 struct task_smack *tsp = current_security(); 209 struct smack_known *skp = smk_of_task(subject);
208 struct smack_known *skp = smk_of_task(tsp);
209 int may; 210 int may;
210 int rc; 211 int rc;
211 212
@@ -219,7 +220,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
219 * it can further restrict access. 220 * it can further restrict access.
220 */ 221 */
221 may = smk_access_entry(skp->smk_known, obj_label, 222 may = smk_access_entry(skp->smk_known, obj_label,
222 &tsp->smk_rules); 223 &subject->smk_rules);
223 if (may < 0) 224 if (may < 0)
224 goto out_audit; 225 goto out_audit;
225 if ((mode & may) == mode) 226 if ((mode & may) == mode)
@@ -241,6 +242,24 @@ out_audit:
241 return rc; 242 return rc;
242} 243}
243 244
245/**
246 * smk_curacc - determine if current has a specific access to an object
247 * @obj_label: a pointer to the object's Smack label
248 * @mode: the access requested, in "MAY" format
249 * @a : common audit data
250 *
251 * This function checks the current subject label/object label pair
252 * in the access rule list and returns 0 if the access is permitted,
253 * non zero otherwise. It allows that current may have the capability
254 * to override the rules.
255 */
256int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a)
257{
258 struct task_smack *tsp = current_security();
259
260 return smk_tskacc(tsp, obj_label, mode, a);
261}
262
244#ifdef CONFIG_AUDIT 263#ifdef CONFIG_AUDIT
245/** 264/**
246 * smack_str_from_perm : helper to transalate an int to a 265 * smack_str_from_perm : helper to transalate an int to a
@@ -285,7 +304,10 @@ static void smack_log_callback(struct audit_buffer *ab, void *a)
285 audit_log_untrustedstring(ab, sad->subject); 304 audit_log_untrustedstring(ab, sad->subject);
286 audit_log_format(ab, " object="); 305 audit_log_format(ab, " object=");
287 audit_log_untrustedstring(ab, sad->object); 306 audit_log_untrustedstring(ab, sad->object);
288 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);
289} 311}
290 312
291/** 313/**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 8177e7df8c2d..f2c30801ce41 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -157,6 +157,74 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
157 return rc; 157 return rc;
158} 158}
159 159
160/**
161 * smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
162 * @mode - input mode in form of PTRACE_MODE_*
163 *
164 * Returns a converted MAY_* mode usable by smack rules
165 */
166static inline unsigned int smk_ptrace_mode(unsigned int mode)
167{
168 switch (mode) {
169 case PTRACE_MODE_READ:
170 return MAY_READ;
171 case PTRACE_MODE_ATTACH:
172 return MAY_READWRITE;
173 }
174
175 return 0;
176}
177
178/**
179 * smk_ptrace_rule_check - helper for ptrace access
180 * @tracer: tracer process
181 * @tracee_label: label of the process that's about to be traced,
182 * the pointer must originate from smack structures
183 * @mode: ptrace attachment mode (PTRACE_MODE_*)
184 * @func: name of the function that called us, used for audit
185 *
186 * Returns 0 on access granted, -error on error
187 */
188static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label,
189 unsigned int mode, const char *func)
190{
191 int rc;
192 struct smk_audit_info ad, *saip = NULL;
193 struct task_smack *tsp;
194 struct smack_known *skp;
195
196 if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
197 smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
198 smk_ad_setfield_u_tsk(&ad, tracer);
199 saip = &ad;
200 }
201
202 tsp = task_security(tracer);
203 skp = smk_of_task(tsp);
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 */
224 rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip);
225 return rc;
226}
227
160/* 228/*
161 * LSM hooks. 229 * LSM hooks.
162 * We he, that is fun! 230 * We he, that is fun!
@@ -165,16 +233,15 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
165/** 233/**
166 * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH 234 * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
167 * @ctp: child task pointer 235 * @ctp: child task pointer
168 * @mode: ptrace attachment mode 236 * @mode: ptrace attachment mode (PTRACE_MODE_*)
169 * 237 *
170 * Returns 0 if access is OK, an error code otherwise 238 * Returns 0 if access is OK, an error code otherwise
171 * 239 *
172 * Do the capability checks, and require read and write. 240 * Do the capability checks.
173 */ 241 */
174static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) 242static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
175{ 243{
176 int rc; 244 int rc;
177 struct smk_audit_info ad;
178 struct smack_known *skp; 245 struct smack_known *skp;
179 246
180 rc = cap_ptrace_access_check(ctp, mode); 247 rc = cap_ptrace_access_check(ctp, mode);
@@ -182,10 +249,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
182 return rc; 249 return rc;
183 250
184 skp = smk_of_task(task_security(ctp)); 251 skp = smk_of_task(task_security(ctp));
185 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
186 smk_ad_setfield_u_tsk(&ad, ctp);
187 252
188 rc = smk_curacc(skp->smk_known, mode, &ad); 253 rc = smk_ptrace_rule_check(current, skp->smk_known, mode, __func__);
189 return rc; 254 return rc;
190} 255}
191 256
@@ -195,23 +260,21 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
195 * 260 *
196 * Returns 0 if access is OK, an error code otherwise 261 * Returns 0 if access is OK, an error code otherwise
197 * 262 *
198 * Do the capability checks, and require read and write. 263 * Do the capability checks, and require PTRACE_MODE_ATTACH.
199 */ 264 */
200static int smack_ptrace_traceme(struct task_struct *ptp) 265static int smack_ptrace_traceme(struct task_struct *ptp)
201{ 266{
202 int rc; 267 int rc;
203 struct smk_audit_info ad;
204 struct smack_known *skp; 268 struct smack_known *skp;
205 269
206 rc = cap_ptrace_traceme(ptp); 270 rc = cap_ptrace_traceme(ptp);
207 if (rc != 0) 271 if (rc != 0)
208 return rc; 272 return rc;
209 273
210 skp = smk_of_task(task_security(ptp)); 274 skp = smk_of_task(current_security());
211 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
212 smk_ad_setfield_u_tsk(&ad, ptp);
213 275
214 rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad); 276 rc = smk_ptrace_rule_check(ptp, skp->smk_known,
277 PTRACE_MODE_ATTACH, __func__);
215 return rc; 278 return rc;
216} 279}
217 280
@@ -413,9 +476,11 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
413 * Initialize the root inode. 476 * Initialize the root inode.
414 */ 477 */
415 isp = inode->i_security; 478 isp = inode->i_security;
416 if (inode->i_security == NULL) { 479 if (isp == NULL) {
417 inode->i_security = new_inode_smack(sp->smk_root); 480 isp = new_inode_smack(sp->smk_root);
418 isp = inode->i_security; 481 if (isp == NULL)
482 return -ENOMEM;
483 inode->i_security = isp;
419 } else 484 } else
420 isp->smk_inode = sp->smk_root; 485 isp->smk_inode = sp->smk_root;
421 486
@@ -453,7 +518,7 @@ static int smack_sb_statfs(struct dentry *dentry)
453 * smack_bprm_set_creds - set creds for exec 518 * smack_bprm_set_creds - set creds for exec
454 * @bprm: the exec information 519 * @bprm: the exec information
455 * 520 *
456 * Returns 0 if it gets a blob, -ENOMEM otherwise 521 * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
457 */ 522 */
458static int smack_bprm_set_creds(struct linux_binprm *bprm) 523static int smack_bprm_set_creds(struct linux_binprm *bprm)
459{ 524{
@@ -473,7 +538,22 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
473 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task) 538 if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
474 return 0; 539 return 0;
475 540
476 if (bprm->unsafe) 541 if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
542 struct task_struct *tracer;
543 rc = 0;
544
545 rcu_read_lock();
546 tracer = ptrace_parent(current);
547 if (likely(tracer != NULL))
548 rc = smk_ptrace_rule_check(tracer,
549 isp->smk_task->smk_known,
550 PTRACE_MODE_ATTACH,
551 __func__);
552 rcu_read_unlock();
553
554 if (rc != 0)
555 return rc;
556 } else if (bprm->unsafe)
477 return -EPERM; 557 return -EPERM;
478 558
479 bsp->smk_task = isp->smk_task; 559 bsp->smk_task = isp->smk_task;
@@ -880,18 +960,20 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
880 return; 960 return;
881 } 961 }
882 962
883 skp = smk_import_entry(value, size);
884 if (strcmp(name, XATTR_NAME_SMACK) == 0) { 963 if (strcmp(name, XATTR_NAME_SMACK) == 0) {
964 skp = smk_import_entry(value, size);
885 if (skp != NULL) 965 if (skp != NULL)
886 isp->smk_inode = skp->smk_known; 966 isp->smk_inode = skp->smk_known;
887 else 967 else
888 isp->smk_inode = smack_known_invalid.smk_known; 968 isp->smk_inode = smack_known_invalid.smk_known;
889 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { 969 } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
970 skp = smk_import_entry(value, size);
890 if (skp != NULL) 971 if (skp != NULL)
891 isp->smk_task = skp; 972 isp->smk_task = skp;
892 else 973 else
893 isp->smk_task = &smack_known_invalid; 974 isp->smk_task = &smack_known_invalid;
894 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { 975 } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
976 skp = smk_import_entry(value, size);
895 if (skp != NULL) 977 if (skp != NULL)
896 isp->smk_mmap = skp; 978 isp->smk_mmap = skp;
897 else 979 else
@@ -938,24 +1020,37 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
938 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || 1020 strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
939 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || 1021 strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
940 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || 1022 strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
941 strcmp(name, XATTR_NAME_SMACKMMAP)) { 1023 strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
942 if (!smack_privileged(CAP_MAC_ADMIN)) 1024 if (!smack_privileged(CAP_MAC_ADMIN))
943 rc = -EPERM; 1025 rc = -EPERM;
944 } else 1026 } else
945 rc = cap_inode_removexattr(dentry, name); 1027 rc = cap_inode_removexattr(dentry, name);
946 1028
1029 if (rc != 0)
1030 return rc;
1031
947 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); 1032 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
948 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 1033 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
949 if (rc == 0)
950 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
951 1034
952 if (rc == 0) { 1035 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
953 isp = dentry->d_inode->i_security; 1036 if (rc != 0)
1037 return rc;
1038
1039 isp = dentry->d_inode->i_security;
1040 /*
1041 * Don't do anything special for these.
1042 * XATTR_NAME_SMACKIPIN
1043 * XATTR_NAME_SMACKIPOUT
1044 * XATTR_NAME_SMACKEXEC
1045 */
1046 if (strcmp(name, XATTR_NAME_SMACK) == 0)
954 isp->smk_task = NULL; 1047 isp->smk_task = NULL;
1048 else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
955 isp->smk_mmap = NULL; 1049 isp->smk_mmap = NULL;
956 } 1050 else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
1051 isp->smk_flags &= ~SMK_INODE_TRANSMUTE;
957 1052
958 return rc; 1053 return 0;
959} 1054}
960 1055
961/** 1056/**
@@ -1000,7 +1095,7 @@ static int smack_inode_getsecurity(const struct inode *inode,
1000 ssp = sock->sk->sk_security; 1095 ssp = sock->sk->sk_security;
1001 1096
1002 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 1097 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
1003 isp = ssp->smk_in; 1098 isp = ssp->smk_in->smk_known;
1004 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) 1099 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
1005 isp = ssp->smk_out->smk_known; 1100 isp = ssp->smk_out->smk_known;
1006 else 1101 else
@@ -1367,19 +1462,32 @@ static int smack_file_receive(struct file *file)
1367/** 1462/**
1368 * smack_file_open - Smack dentry open processing 1463 * smack_file_open - Smack dentry open processing
1369 * @file: the object 1464 * @file: the object
1370 * @cred: unused 1465 * @cred: task credential
1371 * 1466 *
1372 * Set the security blob in the file structure. 1467 * Set the security blob in the file structure.
1468 * Allow the open only if the task has read access. There are
1469 * many read operations (e.g. fstat) that you can do with an
1470 * fd even if you have the file open write-only.
1373 * 1471 *
1374 * Returns 0 1472 * Returns 0
1375 */ 1473 */
1376static int smack_file_open(struct file *file, const struct cred *cred) 1474static int smack_file_open(struct file *file, const struct cred *cred)
1377{ 1475{
1476 struct task_smack *tsp = cred->security;
1378 struct inode_smack *isp = file_inode(file)->i_security; 1477 struct inode_smack *isp = file_inode(file)->i_security;
1478 struct smk_audit_info ad;
1479 int rc;
1379 1480
1380 file->f_security = isp->smk_inode; 1481 if (smack_privileged(CAP_MAC_OVERRIDE))
1482 return 0;
1381 1483
1382 return 0; 1484 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1485 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1486 rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad);
1487 if (rc == 0)
1488 file->f_security = isp->smk_inode;
1489
1490 return rc;
1383} 1491}
1384 1492
1385/* 1493/*
@@ -1764,7 +1872,7 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1764 if (ssp == NULL) 1872 if (ssp == NULL)
1765 return -ENOMEM; 1873 return -ENOMEM;
1766 1874
1767 ssp->smk_in = skp->smk_known; 1875 ssp->smk_in = skp;
1768 ssp->smk_out = skp; 1876 ssp->smk_out = skp;
1769 ssp->smk_packet = NULL; 1877 ssp->smk_packet = NULL;
1770 1878
@@ -2004,7 +2112,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
2004 2112
2005 if (act == SMK_RECEIVING) { 2113 if (act == SMK_RECEIVING) {
2006 skp = smack_net_ambient; 2114 skp = smack_net_ambient;
2007 object = ssp->smk_in; 2115 object = ssp->smk_in->smk_known;
2008 } else { 2116 } else {
2009 skp = ssp->smk_out; 2117 skp = ssp->smk_out;
2010 object = smack_net_ambient->smk_known; 2118 object = smack_net_ambient->smk_known;
@@ -2034,9 +2142,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
2034 list_for_each_entry(spp, &smk_ipv6_port_list, list) { 2142 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
2035 if (spp->smk_port != port) 2143 if (spp->smk_port != port)
2036 continue; 2144 continue;
2037 object = spp->smk_in; 2145 object = spp->smk_in->smk_known;
2038 if (act == SMK_CONNECTING) 2146 if (act == SMK_CONNECTING)
2039 ssp->smk_packet = spp->smk_out->smk_known; 2147 ssp->smk_packet = spp->smk_out;
2040 break; 2148 break;
2041 } 2149 }
2042 2150
@@ -2076,7 +2184,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2076 int rc = 0; 2184 int rc = 0;
2077 2185
2078 if (value == NULL || size > SMK_LONGLABEL || size == 0) 2186 if (value == NULL || size > SMK_LONGLABEL || size == 0)
2079 return -EACCES; 2187 return -EINVAL;
2080 2188
2081 skp = smk_import_entry(value, size); 2189 skp = smk_import_entry(value, size);
2082 if (skp == NULL) 2190 if (skp == NULL)
@@ -2100,7 +2208,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2100 ssp = sock->sk->sk_security; 2208 ssp = sock->sk->sk_security;
2101 2209
2102 if (strcmp(name, XATTR_SMACK_IPIN) == 0) 2210 if (strcmp(name, XATTR_SMACK_IPIN) == 0)
2103 ssp->smk_in = skp->smk_known; 2211 ssp->smk_in = skp;
2104 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 2212 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
2105 ssp->smk_out = skp; 2213 ssp->smk_out = skp;
2106 if (sock->sk->sk_family == PF_INET) { 2214 if (sock->sk->sk_family == PF_INET) {
@@ -2713,6 +2821,15 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2713 * of the superblock. 2821 * of the superblock.
2714 */ 2822 */
2715 if (opt_dentry->d_parent == opt_dentry) { 2823 if (opt_dentry->d_parent == opt_dentry) {
2824 if (sbp->s_magic == CGROUP_SUPER_MAGIC) {
2825 /*
2826 * The cgroup filesystem is never mounted,
2827 * so there's no opportunity to set the mount
2828 * options.
2829 */
2830 sbsp->smk_root = smack_known_star.smk_known;
2831 sbsp->smk_default = smack_known_star.smk_known;
2832 }
2716 isp->smk_inode = sbsp->smk_root; 2833 isp->smk_inode = sbsp->smk_root;
2717 isp->smk_flags |= SMK_INODE_INSTANT; 2834 isp->smk_flags |= SMK_INODE_INSTANT;
2718 goto unlockandout; 2835 goto unlockandout;
@@ -2726,16 +2843,20 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2726 */ 2843 */
2727 switch (sbp->s_magic) { 2844 switch (sbp->s_magic) {
2728 case SMACK_MAGIC: 2845 case SMACK_MAGIC:
2846 case PIPEFS_MAGIC:
2847 case SOCKFS_MAGIC:
2848 case CGROUP_SUPER_MAGIC:
2729 /* 2849 /*
2730 * Casey says that it's a little embarrassing 2850 * Casey says that it's a little embarrassing
2731 * that the smack file system doesn't do 2851 * that the smack file system doesn't do
2732 * extended attributes. 2852 * extended attributes.
2733 */ 2853 *
2734 final = smack_known_star.smk_known;
2735 break;
2736 case PIPEFS_MAGIC:
2737 /*
2738 * Casey says pipes are easy (?) 2854 * Casey says pipes are easy (?)
2855 *
2856 * Socket access is controlled by the socket
2857 * structures associated with the task involved.
2858 *
2859 * Cgroupfs is special
2739 */ 2860 */
2740 final = smack_known_star.smk_known; 2861 final = smack_known_star.smk_known;
2741 break; 2862 break;
@@ -2747,13 +2868,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
2747 */ 2868 */
2748 final = ckp->smk_known; 2869 final = ckp->smk_known;
2749 break; 2870 break;
2750 case SOCKFS_MAGIC:
2751 /*
2752 * Socket access is controlled by the socket
2753 * structures associated with the task involved.
2754 */
2755 final = smack_known_star.smk_known;
2756 break;
2757 case PROC_SUPER_MAGIC: 2871 case PROC_SUPER_MAGIC:
2758 /* 2872 /*
2759 * Casey says procfs appears not to care. 2873 * Casey says procfs appears not to care.
@@ -2959,30 +3073,34 @@ static int smack_unix_stream_connect(struct sock *sock,
2959 struct sock *other, struct sock *newsk) 3073 struct sock *other, struct sock *newsk)
2960{ 3074{
2961 struct smack_known *skp; 3075 struct smack_known *skp;
3076 struct smack_known *okp;
2962 struct socket_smack *ssp = sock->sk_security; 3077 struct socket_smack *ssp = sock->sk_security;
2963 struct socket_smack *osp = other->sk_security; 3078 struct socket_smack *osp = other->sk_security;
2964 struct socket_smack *nsp = newsk->sk_security; 3079 struct socket_smack *nsp = newsk->sk_security;
2965 struct smk_audit_info ad; 3080 struct smk_audit_info ad;
2966 int rc = 0; 3081 int rc = 0;
2967
2968#ifdef CONFIG_AUDIT 3082#ifdef CONFIG_AUDIT
2969 struct lsm_network_audit net; 3083 struct lsm_network_audit net;
2970
2971 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2972 smk_ad_setfield_u_net_sk(&ad, other);
2973#endif 3084#endif
2974 3085
2975 if (!smack_privileged(CAP_MAC_OVERRIDE)) { 3086 if (!smack_privileged(CAP_MAC_OVERRIDE)) {
2976 skp = ssp->smk_out; 3087 skp = ssp->smk_out;
2977 rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad); 3088 okp = osp->smk_out;
3089#ifdef CONFIG_AUDIT
3090 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
3091 smk_ad_setfield_u_net_sk(&ad, other);
3092#endif
3093 rc = smk_access(skp, okp->smk_known, MAY_WRITE, &ad);
3094 if (rc == 0)
3095 rc = smk_access(okp, okp->smk_known, MAY_WRITE, NULL);
2978 } 3096 }
2979 3097
2980 /* 3098 /*
2981 * Cross reference the peer labels for SO_PEERSEC. 3099 * Cross reference the peer labels for SO_PEERSEC.
2982 */ 3100 */
2983 if (rc == 0) { 3101 if (rc == 0) {
2984 nsp->smk_packet = ssp->smk_out->smk_known; 3102 nsp->smk_packet = ssp->smk_out;
2985 ssp->smk_packet = osp->smk_out->smk_known; 3103 ssp->smk_packet = osp->smk_out;
2986 } 3104 }
2987 3105
2988 return rc; 3106 return rc;
@@ -3014,7 +3132,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
3014 return 0; 3132 return 0;
3015 3133
3016 skp = ssp->smk_out; 3134 skp = ssp->smk_out;
3017 return smk_access(skp, osp->smk_in, MAY_WRITE, &ad); 3135 return smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad);
3018} 3136}
3019 3137
3020/** 3138/**
@@ -3109,7 +3227,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3109 if (found) 3227 if (found)
3110 return skp; 3228 return skp;
3111 3229
3112 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) 3230 if (ssp != NULL && ssp->smk_in == &smack_known_star)
3113 return &smack_known_web; 3231 return &smack_known_web;
3114 return &smack_known_star; 3232 return &smack_known_star;
3115 } 3233 }
@@ -3228,7 +3346,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3228 * This is the simplist possible security model 3346 * This is the simplist possible security model
3229 * for networking. 3347 * for networking.
3230 */ 3348 */
3231 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); 3349 rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad);
3232 if (rc != 0) 3350 if (rc != 0)
3233 netlbl_skbuff_err(skb, rc, 0); 3351 netlbl_skbuff_err(skb, rc, 0);
3234 break; 3352 break;
@@ -3263,7 +3381,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
3263 3381
3264 ssp = sock->sk->sk_security; 3382 ssp = sock->sk->sk_security;
3265 if (ssp->smk_packet != NULL) { 3383 if (ssp->smk_packet != NULL) {
3266 rcp = ssp->smk_packet; 3384 rcp = ssp->smk_packet->smk_known;
3267 slen = strlen(rcp) + 1; 3385 slen = strlen(rcp) + 1;
3268 } 3386 }
3269 3387
@@ -3348,7 +3466,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent)
3348 return; 3466 return;
3349 3467
3350 ssp = sk->sk_security; 3468 ssp = sk->sk_security;
3351 ssp->smk_in = skp->smk_known; 3469 ssp->smk_in = skp;
3352 ssp->smk_out = skp; 3470 ssp->smk_out = skp;
3353 /* cssp->smk_packet is already set in smack_inet_csk_clone() */ 3471 /* cssp->smk_packet is already set in smack_inet_csk_clone() */
3354} 3472}
@@ -3408,7 +3526,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3408 * Receiving a packet requires that the other end be able to write 3526 * Receiving a packet requires that the other end be able to write
3409 * here. Read access is not required. 3527 * here. Read access is not required.
3410 */ 3528 */
3411 rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); 3529 rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad);
3412 if (rc != 0) 3530 if (rc != 0)
3413 return rc; 3531 return rc;
3414 3532
@@ -3452,7 +3570,7 @@ static void smack_inet_csk_clone(struct sock *sk,
3452 3570
3453 if (req->peer_secid != 0) { 3571 if (req->peer_secid != 0) {
3454 skp = smack_from_secid(req->peer_secid); 3572 skp = smack_from_secid(req->peer_secid);
3455 ssp->smk_packet = skp->smk_known; 3573 ssp->smk_packet = skp;
3456 } else 3574 } else
3457 ssp->smk_packet = NULL; 3575 ssp->smk_packet = NULL;
3458} 3576}
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 3198cfe1dcc6..32b248820840 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.
@@ -1183,7 +1193,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
1183 1193
1184 data[count] = '\0'; 1194 data[count] = '\0';
1185 1195
1186 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s", 1196 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
1187 &host[0], &host[1], &host[2], &host[3], &m, smack); 1197 &host[0], &host[1], &host[2], &host[3], &m, smack);
1188 if (rc != 6) { 1198 if (rc != 6) {
1189 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", 1199 rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
@@ -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 };