Blame view

security/smack/smack_lsm.c 116 KB
e114e4737   Casey Schaufler   Smack: Simplified...
1
2
3
4
5
  /*
   *  Simplified MAC Kernel (smack) security module
   *
   *  This file contains the smack hook function implementations.
   *
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
6
   *  Authors:
e114e4737   Casey Schaufler   Smack: Simplified...
7
   *	Casey Schaufler <casey@schaufler-ca.com>
84088ba23   Jarkko Sakkinen   Smack: domain tra...
8
   *	Jarkko Sakkinen <jarkko.sakkinen@intel.com>
e114e4737   Casey Schaufler   Smack: Simplified...
9
10
   *
   *  Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
07feee8f8   Paul Moore   netlabel: Cleanup...
11
   *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
82c21bfab   Paul Moore   doc: Update the e...
12
   *                Paul Moore <paul@paul-moore.com>
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
13
   *  Copyright (C) 2010 Nokia Corporation
84088ba23   Jarkko Sakkinen   Smack: domain tra...
14
   *  Copyright (C) 2011 Intel Corporation.
e114e4737   Casey Schaufler   Smack: Simplified...
15
16
17
18
19
20
21
22
23
24
   *
   *	This program is free software; you can redistribute it and/or modify
   *	it under the terms of the GNU General Public License version 2,
   *      as published by the Free Software Foundation.
   */
  
  #include <linux/xattr.h>
  #include <linux/pagemap.h>
  #include <linux/mount.h>
  #include <linux/stat.h>
e114e4737   Casey Schaufler   Smack: Simplified...
25
26
  #include <linux/kd.h>
  #include <asm/ioctls.h>
07feee8f8   Paul Moore   netlabel: Cleanup...
27
  #include <linux/ip.h>
e114e4737   Casey Schaufler   Smack: Simplified...
28
29
  #include <linux/tcp.h>
  #include <linux/udp.h>
c67394434   Casey Schaufler   Smack: Local IPv6...
30
  #include <linux/dccp.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
31
  #include <linux/slab.h>
e114e4737   Casey Schaufler   Smack: Simplified...
32
33
  #include <linux/mutex.h>
  #include <linux/pipe_fs_i.h>
e114e4737   Casey Schaufler   Smack: Simplified...
34
  #include <net/cipso_ipv4.h>
c67394434   Casey Schaufler   Smack: Local IPv6...
35
36
  #include <net/ip.h>
  #include <net/ipv6.h>
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
37
  #include <linux/audit.h>
1fd7317d0   Nick Black   Move magic number...
38
  #include <linux/magic.h>
2a7dba391   Eric Paris   fs/vfs/security: ...
39
  #include <linux/dcache.h>
16014d875   Jarkko Sakkinen   Smack: compilatio...
40
  #include <linux/personality.h>
404015308   Al Viro   security: trim se...
41
42
43
  #include <linux/msg.h>
  #include <linux/shm.h>
  #include <linux/binfmts.h>
3bf2789ca   Vivek Trivedi   smack: allow moun...
44
  #include <linux/parser.h>
e114e4737   Casey Schaufler   Smack: Simplified...
45
  #include "smack.h"
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
46
47
  #define TRANS_TRUE	"TRUE"
  #define TRANS_TRUE_SIZE	4
c67394434   Casey Schaufler   Smack: Local IPv6...
48
49
50
  #define SMK_CONNECTING	0
  #define SMK_RECEIVING	1
  #define SMK_SENDING	2
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
51
  #ifdef SMACK_IPV6_PORT_LABELING
8b549ef42   Geliang Tang   smack: smk_ipv6_p...
52
  static LIST_HEAD(smk_ipv6_port_list);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
53
  #endif
1a5b472bd   Rohit   Security: smack: ...
54
  static struct kmem_cache *smack_inode_cache;
69f287ae6   Casey Schaufler   Smack: secmark su...
55
  int smack_enabled;
c67394434   Casey Schaufler   Smack: Local IPv6...
56

3d04c9240   Casey Schaufler   Smack - Fix build...
57
  static const match_table_t smk_mount_tokens = {
3bf2789ca   Vivek Trivedi   smack: allow moun...
58
59
60
61
62
63
64
  	{Opt_fsdefault, SMK_FSDEFAULT "%s"},
  	{Opt_fsfloor, SMK_FSFLOOR "%s"},
  	{Opt_fshat, SMK_FSHAT "%s"},
  	{Opt_fsroot, SMK_FSROOT "%s"},
  	{Opt_fstransmute, SMK_FSTRANS "%s"},
  	{Opt_error, NULL},
  };
3d04c9240   Casey Schaufler   Smack - Fix build...
65
66
67
68
69
70
71
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static char *smk_bu_mess[] = {
  	"Bringup Error",	/* Unused */
  	"Bringup",		/* SMACK_BRINGUP_ALLOW */
  	"Unconfined Subject",	/* SMACK_UNCONFINED_SUBJECT */
  	"Unconfined Object",	/* SMACK_UNCONFINED_OBJECT */
  };
d166c8024   Casey Schaufler   Smack: Bring-up a...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  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';
  }
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
95
96
  static int smk_bu_note(char *note, struct smack_known *sskp,
  		       struct smack_known *oskp, int mode, int rc)
d166c8024   Casey Schaufler   Smack: Bring-up a...
97
98
99
100
101
  {
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
  
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
102
103
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
104
105
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
106
107
  	pr_info("Smack %s: (%s %s %s) %s
  ", smk_bu_mess[rc],
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
108
  		sskp->smk_known, oskp->smk_known, acc, note);
d166c8024   Casey Schaufler   Smack: Bring-up a...
109
110
111
  	return 0;
  }
  #else
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
112
  #define smk_bu_note(note, sskp, oskp, mode, RC) (RC)
d166c8024   Casey Schaufler   Smack: Bring-up a...
113
114
115
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
116
117
  static int smk_bu_current(char *note, struct smack_known *oskp,
  			  int mode, int rc)
d166c8024   Casey Schaufler   Smack: Bring-up a...
118
119
120
121
122
123
  {
  	struct task_smack *tsp = current_security();
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
  
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
124
125
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
126
127
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
128
129
  	pr_info("Smack %s: (%s %s %s) %s %s
  ", smk_bu_mess[rc],
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
130
131
  		tsp->smk_task->smk_known, oskp->smk_known,
  		acc, current->comm, note);
d166c8024   Casey Schaufler   Smack: Bring-up a...
132
133
134
  	return 0;
  }
  #else
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
135
  #define smk_bu_current(note, oskp, mode, RC) (RC)
d166c8024   Casey Schaufler   Smack: Bring-up a...
136
137
138
139
140
141
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static int smk_bu_task(struct task_struct *otp, int mode, int rc)
  {
  	struct task_smack *tsp = current_security();
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
142
  	struct smack_known *smk_task = smk_of_task_struct(otp);
d166c8024   Casey Schaufler   Smack: Bring-up a...
143
144
145
146
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
  
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
147
148
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
149
150
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
151
152
  	pr_info("Smack %s: (%s %s %s) %s to %s
  ", smk_bu_mess[rc],
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
153
  		tsp->smk_task->smk_known, smk_task->smk_known, acc,
d166c8024   Casey Schaufler   Smack: Bring-up a...
154
155
156
157
158
159
160
161
162
163
164
  		current->comm, otp->comm);
  	return 0;
  }
  #else
  #define smk_bu_task(otp, mode, RC) (RC)
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static int smk_bu_inode(struct inode *inode, int mode, int rc)
  {
  	struct task_smack *tsp = current_security();
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
165
  	struct inode_smack *isp = inode->i_security;
d166c8024   Casey Schaufler   Smack: Bring-up a...
166
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
167
168
169
170
  	if (isp->smk_flags & SMK_INODE_IMPURE)
  		pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s
  ",
  			inode->i_sb->s_id, inode->i_ino, current->comm);
d166c8024   Casey Schaufler   Smack: Bring-up a...
171
172
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
173
174
175
176
177
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
  	if (rc == SMACK_UNCONFINED_SUBJECT &&
  	    (mode & (MAY_WRITE | MAY_APPEND)))
  		isp->smk_flags |= SMK_INODE_IMPURE;
d166c8024   Casey Schaufler   Smack: Bring-up a...
178
179
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
180
181
182
183
  
  	pr_info("Smack %s: (%s %s %s) inode=(%s %ld) %s
  ", smk_bu_mess[rc],
  		tsp->smk_task->smk_known, isp->smk_inode->smk_known, acc,
d166c8024   Casey Schaufler   Smack: Bring-up a...
184
185
186
187
188
189
190
191
192
193
194
195
  		inode->i_sb->s_id, inode->i_ino, current->comm);
  	return 0;
  }
  #else
  #define smk_bu_inode(inode, mode, RC) (RC)
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static int smk_bu_file(struct file *file, int mode, int rc)
  {
  	struct task_smack *tsp = current_security();
  	struct smack_known *sskp = tsp->smk_task;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
196
  	struct inode *inode = file_inode(file);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
197
  	struct inode_smack *isp = inode->i_security;
d166c8024   Casey Schaufler   Smack: Bring-up a...
198
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
199
200
201
202
  	if (isp->smk_flags & SMK_INODE_IMPURE)
  		pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s
  ",
  			inode->i_sb->s_id, inode->i_ino, current->comm);
d166c8024   Casey Schaufler   Smack: Bring-up a...
203
204
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
205
206
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
207
208
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
209
210
  	pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s
  ", smk_bu_mess[rc],
5e7270a6d   Casey Schaufler   Smack: Rework fil...
211
  		sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
a455589f1   Al Viro   assorted conversi...
212
  		inode->i_sb->s_id, inode->i_ino, file,
d166c8024   Casey Schaufler   Smack: Bring-up a...
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  		current->comm);
  	return 0;
  }
  #else
  #define smk_bu_file(file, mode, RC) (RC)
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static int smk_bu_credfile(const struct cred *cred, struct file *file,
  				int mode, int rc)
  {
  	struct task_smack *tsp = cred->security;
  	struct smack_known *sskp = tsp->smk_task;
  	struct inode *inode = file->f_inode;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
227
  	struct inode_smack *isp = inode->i_security;
d166c8024   Casey Schaufler   Smack: Bring-up a...
228
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
229
230
231
232
  	if (isp->smk_flags & SMK_INODE_IMPURE)
  		pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s
  ",
  			inode->i_sb->s_id, inode->i_ino, current->comm);
d166c8024   Casey Schaufler   Smack: Bring-up a...
233
234
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
235
236
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
237
238
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
239
240
  	pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s
  ", smk_bu_mess[rc],
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
241
  		sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
a455589f1   Al Viro   assorted conversi...
242
  		inode->i_sb->s_id, inode->i_ino, file,
d166c8024   Casey Schaufler   Smack: Bring-up a...
243
244
245
246
247
248
  		current->comm);
  	return 0;
  }
  #else
  #define smk_bu_credfile(cred, file, mode, RC) (RC)
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
249
250
  /**
   * smk_fetch - Fetch the smack label from a file.
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
251
   * @name: type of the label (attribute)
e114e4737   Casey Schaufler   Smack: Simplified...
252
253
254
   * @ip: a pointer to the inode
   * @dp: a pointer to the dentry
   *
e774ad683   Lukasz Pawelczyk   smack: pass error...
255
256
   * Returns a pointer to the master list entry for the Smack label,
   * NULL if there was no label to fetch, or an error code.
e114e4737   Casey Schaufler   Smack: Simplified...
257
   */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
258
259
  static struct smack_known *smk_fetch(const char *name, struct inode *ip,
  					struct dentry *dp)
e114e4737   Casey Schaufler   Smack: Simplified...
260
261
  {
  	int rc;
f7112e6c9   Casey Schaufler   Smack: allow for ...
262
  	char *buffer;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
263
  	struct smack_known *skp = NULL;
e114e4737   Casey Schaufler   Smack: Simplified...
264

5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
265
  	if (!(ip->i_opflags & IOP_XATTR))
e774ad683   Lukasz Pawelczyk   smack: pass error...
266
  		return ERR_PTR(-EOPNOTSUPP);
e114e4737   Casey Schaufler   Smack: Simplified...
267

f7112e6c9   Casey Schaufler   Smack: allow for ...
268
269
  	buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL);
  	if (buffer == NULL)
e774ad683   Lukasz Pawelczyk   smack: pass error...
270
  		return ERR_PTR(-ENOMEM);
e114e4737   Casey Schaufler   Smack: Simplified...
271

5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
272
  	rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL);
e774ad683   Lukasz Pawelczyk   smack: pass error...
273
274
275
276
277
  	if (rc < 0)
  		skp = ERR_PTR(rc);
  	else if (rc == 0)
  		skp = NULL;
  	else
2f823ff8b   Casey Schaufler   Smack: Improve ac...
278
  		skp = smk_import_entry(buffer, rc);
f7112e6c9   Casey Schaufler   Smack: allow for ...
279
280
  
  	kfree(buffer);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
281
  	return skp;
e114e4737   Casey Schaufler   Smack: Simplified...
282
283
284
285
  }
  
  /**
   * new_inode_smack - allocate an inode security blob
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
286
   * @skp: a pointer to the Smack label entry to use in the blob
e114e4737   Casey Schaufler   Smack: Simplified...
287
288
289
   *
   * Returns the new blob or NULL if there's no memory available
   */
1eddfe8ed   Casey Schaufler   Smack: Three symb...
290
  static struct inode_smack *new_inode_smack(struct smack_known *skp)
e114e4737   Casey Schaufler   Smack: Simplified...
291
292
  {
  	struct inode_smack *isp;
1a5b472bd   Rohit   Security: smack: ...
293
  	isp = kmem_cache_zalloc(smack_inode_cache, GFP_NOFS);
e114e4737   Casey Schaufler   Smack: Simplified...
294
295
  	if (isp == NULL)
  		return NULL;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
296
  	isp->smk_inode = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
297
298
299
300
301
  	isp->smk_flags = 0;
  	mutex_init(&isp->smk_lock);
  
  	return isp;
  }
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
302
303
  /**
   * new_task_smack - allocate a task security blob
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
304
305
306
   * @task: a pointer to the Smack label for the running task
   * @forked: a pointer to the Smack label for the forked task
   * @gfp: type of the memory for the allocation
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
307
308
309
   *
   * Returns the new blob or NULL if there's no memory available
   */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
310
311
  static struct task_smack *new_task_smack(struct smack_known *task,
  					struct smack_known *forked, gfp_t gfp)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
312
313
314
315
316
317
318
319
320
321
  {
  	struct task_smack *tsp;
  
  	tsp = kzalloc(sizeof(struct task_smack), gfp);
  	if (tsp == NULL)
  		return NULL;
  
  	tsp->smk_task = task;
  	tsp->smk_forked = forked;
  	INIT_LIST_HEAD(&tsp->smk_rules);
38416e539   Zbigniew Jasinski   Smack: limited ca...
322
  	INIT_LIST_HEAD(&tsp->smk_relabel);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
323
324
325
326
327
328
329
  	mutex_init(&tsp->smk_rules_lock);
  
  	return tsp;
  }
  
  /**
   * smk_copy_rules - copy a rule set
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
330
331
332
   * @nhead: new rules header pointer
   * @ohead: old rules header pointer
   * @gfp: type of the memory for the allocation
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
   *
   * Returns 0 on success, -ENOMEM on error
   */
  static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
  				gfp_t gfp)
  {
  	struct smack_rule *nrp;
  	struct smack_rule *orp;
  	int rc = 0;
  
  	INIT_LIST_HEAD(nhead);
  
  	list_for_each_entry_rcu(orp, ohead, list) {
  		nrp = kzalloc(sizeof(struct smack_rule), gfp);
  		if (nrp == NULL) {
  			rc = -ENOMEM;
  			break;
  		}
  		*nrp = *orp;
  		list_add_rcu(&nrp->list, nhead);
  	}
  	return rc;
  }
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
356
  /**
38416e539   Zbigniew Jasinski   Smack: limited ca...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
   * smk_copy_relabel - copy smk_relabel labels list
   * @nhead: new rules header pointer
   * @ohead: old rules header pointer
   * @gfp: type of the memory for the allocation
   *
   * Returns 0 on success, -ENOMEM on error
   */
  static int smk_copy_relabel(struct list_head *nhead, struct list_head *ohead,
  				gfp_t gfp)
  {
  	struct smack_known_list_elem *nklep;
  	struct smack_known_list_elem *oklep;
  
  	INIT_LIST_HEAD(nhead);
  
  	list_for_each_entry(oklep, ohead, list) {
  		nklep = kzalloc(sizeof(struct smack_known_list_elem), gfp);
  		if (nklep == NULL) {
  			smk_destroy_label_list(nhead);
  			return -ENOMEM;
  		}
  		nklep->smk_label = oklep->smk_label;
  		list_add(&nklep->list, nhead);
  	}
  
  	return 0;
  }
  
  /**
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
386
387
388
389
390
391
392
   * smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_*
   * @mode - input mode in form of PTRACE_MODE_*
   *
   * Returns a converted MAY_* mode usable by smack rules
   */
  static inline unsigned int smk_ptrace_mode(unsigned int mode)
  {
3dfb7d8cd   Jann Horn   security: let sec...
393
  	if (mode & PTRACE_MODE_ATTACH)
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
394
  		return MAY_READWRITE;
3dfb7d8cd   Jann Horn   security: let sec...
395
396
  	if (mode & PTRACE_MODE_READ)
  		return MAY_READ;
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
397
398
399
400
401
402
403
  
  	return 0;
  }
  
  /**
   * smk_ptrace_rule_check - helper for ptrace access
   * @tracer: tracer process
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
404
   * @tracee_known: label entry of the process that's about to be traced
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
405
406
407
408
409
   * @mode: ptrace attachment mode (PTRACE_MODE_*)
   * @func: name of the function that called us, used for audit
   *
   * Returns 0 on access granted, -error on error
   */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
410
411
  static int smk_ptrace_rule_check(struct task_struct *tracer,
  				 struct smack_known *tracee_known,
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
412
413
414
415
416
  				 unsigned int mode, const char *func)
  {
  	int rc;
  	struct smk_audit_info ad, *saip = NULL;
  	struct task_smack *tsp;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
417
  	struct smack_known *tracer_known;
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
418
419
420
421
422
423
  
  	if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
  		smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK);
  		smk_ad_setfield_u_tsk(&ad, tracer);
  		saip = &ad;
  	}
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
424
425
  	rcu_read_lock();
  	tsp = __task_cred(tracer)->security;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
426
  	tracer_known = smk_of_task(tsp);
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
427

668678185   Lukasz Pawelczyk   Smack: adds smack...
428
429
430
  	if ((mode & PTRACE_MODE_ATTACH) &&
  	    (smack_ptrace_rule == SMACK_PTRACE_EXACT ||
  	     smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
431
  		if (tracer_known->smk_known == tracee_known->smk_known)
668678185   Lukasz Pawelczyk   Smack: adds smack...
432
433
434
435
436
437
438
439
440
  			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)
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
441
442
443
  			smack_log(tracer_known->smk_known,
  				  tracee_known->smk_known,
  				  0, rc, saip);
668678185   Lukasz Pawelczyk   Smack: adds smack...
444

6d1cff2a8   Andrey Ryabinin   smack: fix possib...
445
  		rcu_read_unlock();
668678185   Lukasz Pawelczyk   Smack: adds smack...
446
447
448
449
  		return rc;
  	}
  
  	/* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
450
  	rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip);
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
451
452
  
  	rcu_read_unlock();
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
453
454
  	return rc;
  }
e114e4737   Casey Schaufler   Smack: Simplified...
455
456
457
458
459
460
  /*
   * LSM hooks.
   * We he, that is fun!
   */
  
  /**
9e48858f7   Ingo Molnar   security: rename ...
461
   * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH
e114e4737   Casey Schaufler   Smack: Simplified...
462
   * @ctp: child task pointer
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
463
   * @mode: ptrace attachment mode (PTRACE_MODE_*)
e114e4737   Casey Schaufler   Smack: Simplified...
464
465
466
   *
   * Returns 0 if access is OK, an error code otherwise
   *
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
467
   * Do the capability checks.
e114e4737   Casey Schaufler   Smack: Simplified...
468
   */
9e48858f7   Ingo Molnar   security: rename ...
469
  static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
e114e4737   Casey Schaufler   Smack: Simplified...
470
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
471
  	struct smack_known *skp;
e114e4737   Casey Schaufler   Smack: Simplified...
472

6d1cff2a8   Andrey Ryabinin   smack: fix possib...
473
  	skp = smk_of_task_struct(ctp);
ecfcc53fe   Etienne Basset   smack: implement ...
474

b1d9e6b06   Casey Schaufler   LSM: Switch to li...
475
  	return smk_ptrace_rule_check(current, skp, mode, __func__);
5cd9c58fb   David Howells   security: Fix set...
476
477
478
479
480
481
482
483
  }
  
  /**
   * smack_ptrace_traceme - Smack approval on PTRACE_TRACEME
   * @ptp: parent task pointer
   *
   * Returns 0 if access is OK, an error code otherwise
   *
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
484
   * Do the capability checks, and require PTRACE_MODE_ATTACH.
5cd9c58fb   David Howells   security: Fix set...
485
486
487
488
   */
  static int smack_ptrace_traceme(struct task_struct *ptp)
  {
  	int rc;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
489
  	struct smack_known *skp;
5cd9c58fb   David Howells   security: Fix set...
490

959e6c7f1   Lukasz Pawelczyk   Smack: fix the su...
491
  	skp = smk_of_task(current_security());
ecfcc53fe   Etienne Basset   smack: implement ...
492

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
493
  	rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
494
495
496
497
498
499
500
  	return rc;
  }
  
  /**
   * smack_syslog - Smack approval on syslog
   * @type: message type
   *
e114e4737   Casey Schaufler   Smack: Simplified...
501
502
   * Returns 0 on success, error code otherwise.
   */
12b3052c3   Eric Paris   capabilities/sysl...
503
  static int smack_syslog(int typefrom_file)
e114e4737   Casey Schaufler   Smack: Simplified...
504
  {
12b3052c3   Eric Paris   capabilities/sysl...
505
  	int rc = 0;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
506
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
507

1880eff77   Casey Schaufler   Smack: onlycap li...
508
  	if (smack_privileged(CAP_MAC_OVERRIDE))
e114e4737   Casey Schaufler   Smack: Simplified...
509
  		return 0;
24ea1b6ef   Casey Schaufler   Smack: Rationaliz...
510
  	if (smack_syslog_label != NULL && smack_syslog_label != skp)
e114e4737   Casey Schaufler   Smack: Simplified...
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
  		rc = -EACCES;
  
  	return rc;
  }
  
  
  /*
   * Superblock Hooks.
   */
  
  /**
   * smack_sb_alloc_security - allocate a superblock blob
   * @sb: the superblock getting the blob
   *
   * Returns 0 on success or -ENOMEM on error.
   */
  static int smack_sb_alloc_security(struct super_block *sb)
  {
  	struct superblock_smack *sbsp;
  
  	sbsp = kzalloc(sizeof(struct superblock_smack), GFP_KERNEL);
  
  	if (sbsp == NULL)
  		return -ENOMEM;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
535
536
537
538
  	sbsp->smk_root = &smack_known_floor;
  	sbsp->smk_default = &smack_known_floor;
  	sbsp->smk_floor = &smack_known_floor;
  	sbsp->smk_hat = &smack_known_hat;
e830b3941   Casey Schaufler   Smack: Add smkfst...
539
  	/*
9f50eda2a   Seth Forshee   Smack: Add suppor...
540
  	 * SMK_SB_INITIALIZED will be zero from kzalloc.
e830b3941   Casey Schaufler   Smack: Add smkfst...
541
  	 */
e114e4737   Casey Schaufler   Smack: Simplified...
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
  	sb->s_security = sbsp;
  
  	return 0;
  }
  
  /**
   * smack_sb_free_security - free a superblock blob
   * @sb: the superblock getting the blob
   *
   */
  static void smack_sb_free_security(struct super_block *sb)
  {
  	kfree(sb->s_security);
  	sb->s_security = NULL;
  }
  
  /**
   * smack_sb_copy_data - copy mount options data for processing
e114e4737   Casey Schaufler   Smack: Simplified...
560
   * @orig: where to start
251a2a958   Randy Dunlap   smack: fix lots o...
561
   * @smackopts: mount options string
e114e4737   Casey Schaufler   Smack: Simplified...
562
563
564
565
566
567
   *
   * Returns 0 on success or -ENOMEM on error.
   *
   * Copy the Smack specific mount options out of the mount
   * options list.
   */
e00075298   Eric Paris   LSM/SELinux: Inte...
568
  static int smack_sb_copy_data(char *orig, char *smackopts)
e114e4737   Casey Schaufler   Smack: Simplified...
569
570
  {
  	char *cp, *commap, *otheropts, *dp;
e114e4737   Casey Schaufler   Smack: Simplified...
571
572
573
574
575
576
577
578
579
580
581
582
583
  	otheropts = (char *)get_zeroed_page(GFP_KERNEL);
  	if (otheropts == NULL)
  		return -ENOMEM;
  
  	for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) {
  		if (strstr(cp, SMK_FSDEFAULT) == cp)
  			dp = smackopts;
  		else if (strstr(cp, SMK_FSFLOOR) == cp)
  			dp = smackopts;
  		else if (strstr(cp, SMK_FSHAT) == cp)
  			dp = smackopts;
  		else if (strstr(cp, SMK_FSROOT) == cp)
  			dp = smackopts;
e830b3941   Casey Schaufler   Smack: Add smkfst...
584
585
  		else if (strstr(cp, SMK_FSTRANS) == cp)
  			dp = smackopts;
e114e4737   Casey Schaufler   Smack: Simplified...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
  		else
  			dp = otheropts;
  
  		commap = strchr(cp, ',');
  		if (commap != NULL)
  			*commap = '\0';
  
  		if (*dp != '\0')
  			strcat(dp, ",");
  		strcat(dp, cp);
  	}
  
  	strcpy(orig, otheropts);
  	free_page((unsigned long)otheropts);
  
  	return 0;
  }
  
  /**
3bf2789ca   Vivek Trivedi   smack: allow moun...
605
606
607
608
609
610
611
612
613
614
615
616
   * smack_parse_opts_str - parse Smack specific mount options
   * @options: mount options string
   * @opts: where to store converted mount opts
   *
   * Returns 0 on success or -ENOMEM on error.
   *
   * converts Smack specific mount options to generic security option format
   */
  static int smack_parse_opts_str(char *options,
  		struct security_mnt_opts *opts)
  {
  	char *p;
3d04c9240   Casey Schaufler   Smack - Fix build...
617
618
619
620
621
622
623
624
  	char *fsdefault = NULL;
  	char *fsfloor = NULL;
  	char *fshat = NULL;
  	char *fsroot = NULL;
  	char *fstransmute = NULL;
  	int rc = -ENOMEM;
  	int num_mnt_opts = 0;
  	int token;
3bf2789ca   Vivek Trivedi   smack: allow moun...
625
626
627
628
629
630
631
  
  	opts->num_mnt_opts = 0;
  
  	if (!options)
  		return 0;
  
  	while ((p = strsep(&options, ",")) != NULL) {
3bf2789ca   Vivek Trivedi   smack: allow moun...
632
633
634
635
  		substring_t args[MAX_OPT_ARGS];
  
  		if (!*p)
  			continue;
3d04c9240   Casey Schaufler   Smack - Fix build...
636
  		token = match_token(p, smk_mount_tokens, args);
3bf2789ca   Vivek Trivedi   smack: allow moun...
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
  
  		switch (token) {
  		case Opt_fsdefault:
  			if (fsdefault)
  				goto out_opt_err;
  			fsdefault = match_strdup(&args[0]);
  			if (!fsdefault)
  				goto out_err;
  			break;
  		case Opt_fsfloor:
  			if (fsfloor)
  				goto out_opt_err;
  			fsfloor = match_strdup(&args[0]);
  			if (!fsfloor)
  				goto out_err;
  			break;
  		case Opt_fshat:
  			if (fshat)
  				goto out_opt_err;
  			fshat = match_strdup(&args[0]);
  			if (!fshat)
  				goto out_err;
  			break;
  		case Opt_fsroot:
  			if (fsroot)
  				goto out_opt_err;
  			fsroot = match_strdup(&args[0]);
  			if (!fsroot)
  				goto out_err;
  			break;
  		case Opt_fstransmute:
  			if (fstransmute)
  				goto out_opt_err;
  			fstransmute = match_strdup(&args[0]);
  			if (!fstransmute)
  				goto out_err;
  			break;
  		default:
  			rc = -EINVAL;
  			pr_warn("Smack:  unknown mount option
  ");
  			goto out_err;
  		}
  	}
  
  	opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_ATOMIC);
  	if (!opts->mnt_opts)
  		goto out_err;
  
  	opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int),
  			GFP_ATOMIC);
  	if (!opts->mnt_opts_flags) {
  		kfree(opts->mnt_opts);
  		goto out_err;
  	}
  
  	if (fsdefault) {
  		opts->mnt_opts[num_mnt_opts] = fsdefault;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSDEFAULT_MNT;
  	}
  	if (fsfloor) {
  		opts->mnt_opts[num_mnt_opts] = fsfloor;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSFLOOR_MNT;
  	}
  	if (fshat) {
  		opts->mnt_opts[num_mnt_opts] = fshat;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSHAT_MNT;
  	}
  	if (fsroot) {
  		opts->mnt_opts[num_mnt_opts] = fsroot;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSROOT_MNT;
  	}
  	if (fstransmute) {
  		opts->mnt_opts[num_mnt_opts] = fstransmute;
  		opts->mnt_opts_flags[num_mnt_opts++] = FSTRANS_MNT;
  	}
  
  	opts->num_mnt_opts = num_mnt_opts;
  	return 0;
  
  out_opt_err:
  	rc = -EINVAL;
  	pr_warn("Smack: duplicate mount options
  ");
  
  out_err:
  	kfree(fsdefault);
  	kfree(fsfloor);
  	kfree(fshat);
  	kfree(fsroot);
  	kfree(fstransmute);
  	return rc;
  }
  
  /**
   * smack_set_mnt_opts - set Smack specific mount options
e114e4737   Casey Schaufler   Smack: Simplified...
733
   * @sb: the file system superblock
3bf2789ca   Vivek Trivedi   smack: allow moun...
734
735
736
   * @opts: Smack mount options
   * @kern_flags: mount option from kernel space or user space
   * @set_kern_flags: where to store converted mount opts
e114e4737   Casey Schaufler   Smack: Simplified...
737
738
   *
   * Returns 0 on success, an error code on failure
3bf2789ca   Vivek Trivedi   smack: allow moun...
739
740
741
   *
   * Allow filesystems with binary mount data to explicitly set Smack mount
   * labels.
e114e4737   Casey Schaufler   Smack: Simplified...
742
   */
3bf2789ca   Vivek Trivedi   smack: allow moun...
743
744
745
746
  static int smack_set_mnt_opts(struct super_block *sb,
  		struct security_mnt_opts *opts,
  		unsigned long kern_flags,
  		unsigned long *set_kern_flags)
e114e4737   Casey Schaufler   Smack: Simplified...
747
748
  {
  	struct dentry *root = sb->s_root;
c6f493d63   David Howells   VFS: security/: d...
749
  	struct inode *inode = d_backing_inode(root);
e114e4737   Casey Schaufler   Smack: Simplified...
750
751
  	struct superblock_smack *sp = sb->s_security;
  	struct inode_smack *isp;
24ea1b6ef   Casey Schaufler   Smack: Rationaliz...
752
  	struct smack_known *skp;
3bf2789ca   Vivek Trivedi   smack: allow moun...
753
754
  	int i;
  	int num_opts = opts->num_mnt_opts;
e830b3941   Casey Schaufler   Smack: Add smkfst...
755
  	int transmute = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
756

9f50eda2a   Seth Forshee   Smack: Add suppor...
757
  	if (sp->smk_flags & SMK_SB_INITIALIZED)
e114e4737   Casey Schaufler   Smack: Simplified...
758
  		return 0;
eb982cb4c   Casey Schaufler   Smack: fix smack_...
759

9f50eda2a   Seth Forshee   Smack: Add suppor...
760
  	sp->smk_flags |= SMK_SB_INITIALIZED;
e114e4737   Casey Schaufler   Smack: Simplified...
761

3bf2789ca   Vivek Trivedi   smack: allow moun...
762
763
764
765
  	for (i = 0; i < num_opts; i++) {
  		switch (opts->mnt_opts_flags[i]) {
  		case FSDEFAULT_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
766
767
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
3bf2789ca   Vivek Trivedi   smack: allow moun...
768
769
770
771
  			sp->smk_default = skp;
  			break;
  		case FSFLOOR_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
772
773
774
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
  			sp->smk_floor = skp;
3bf2789ca   Vivek Trivedi   smack: allow moun...
775
776
777
  			break;
  		case FSHAT_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
778
779
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
3bf2789ca   Vivek Trivedi   smack: allow moun...
780
781
782
783
  			sp->smk_hat = skp;
  			break;
  		case FSROOT_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
784
785
786
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
  			sp->smk_root = skp;
3bf2789ca   Vivek Trivedi   smack: allow moun...
787
788
789
  			break;
  		case FSTRANS_MNT:
  			skp = smk_import_entry(opts->mnt_opts[i], 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
790
791
792
793
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
  			sp->smk_root = skp;
  			transmute = 1;
3bf2789ca   Vivek Trivedi   smack: allow moun...
794
795
796
  			break;
  		default:
  			break;
e114e4737   Casey Schaufler   Smack: Simplified...
797
798
  		}
  	}
24ea1b6ef   Casey Schaufler   Smack: Rationaliz...
799
800
801
802
  	if (!smack_privileged(CAP_MAC_ADMIN)) {
  		/*
  		 * Unprivileged mounts don't get to specify Smack values.
  		 */
3bf2789ca   Vivek Trivedi   smack: allow moun...
803
  		if (num_opts)
24ea1b6ef   Casey Schaufler   Smack: Rationaliz...
804
805
806
807
808
  			return -EPERM;
  		/*
  		 * Unprivileged mounts get root and default from the caller.
  		 */
  		skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
809
810
  		sp->smk_root = skp;
  		sp->smk_default = skp;
9f50eda2a   Seth Forshee   Smack: Add suppor...
811
812
813
814
815
816
817
818
819
820
821
  		/*
  		 * For a handful of fs types with no user-controlled
  		 * backing store it's okay to trust security labels
  		 * in the filesystem. The rest are untrusted.
  		 */
  		if (sb->s_user_ns != &init_user_ns &&
  		    sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC &&
  		    sb->s_magic != RAMFS_MAGIC) {
  			transmute = 1;
  			sp->smk_flags |= SMK_SB_UNTRUSTED;
  		}
24ea1b6ef   Casey Schaufler   Smack: Rationaliz...
822
  	}
3bf2789ca   Vivek Trivedi   smack: allow moun...
823

e114e4737   Casey Schaufler   Smack: Simplified...
824
825
826
827
  	/*
  	 * Initialize the root inode.
  	 */
  	isp = inode->i_security;
55dfc5da1   José Bollo   Minor improvement...
828
829
830
831
832
  	if (isp == NULL) {
  		isp = new_inode_smack(sp->smk_root);
  		if (isp == NULL)
  			return -ENOMEM;
  		inode->i_security = isp;
e830b3941   Casey Schaufler   Smack: Add smkfst...
833
  	} else
e114e4737   Casey Schaufler   Smack: Simplified...
834
  		isp->smk_inode = sp->smk_root;
e830b3941   Casey Schaufler   Smack: Add smkfst...
835
836
  	if (transmute)
  		isp->smk_flags |= SMK_INODE_TRANSMUTE;
e114e4737   Casey Schaufler   Smack: Simplified...
837
838
839
840
  	return 0;
  }
  
  /**
3bf2789ca   Vivek Trivedi   smack: allow moun...
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
   * smack_sb_kern_mount - Smack specific mount processing
   * @sb: the file system superblock
   * @flags: the mount flags
   * @data: the smack mount options
   *
   * Returns 0 on success, an error code on failure
   */
  static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data)
  {
  	int rc = 0;
  	char *options = data;
  	struct security_mnt_opts opts;
  
  	security_init_mnt_opts(&opts);
  
  	if (!options)
  		goto out;
  
  	rc = smack_parse_opts_str(options, &opts);
  	if (rc)
  		goto out_err;
  
  out:
  	rc = smack_set_mnt_opts(sb, &opts, 0, NULL);
  
  out_err:
  	security_free_mnt_opts(&opts);
  	return rc;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
872
873
874
875
876
877
878
879
880
   * smack_sb_statfs - Smack check on statfs
   * @dentry: identifies the file system in question
   *
   * Returns 0 if current can read the floor of the filesystem,
   * and error code otherwise
   */
  static int smack_sb_statfs(struct dentry *dentry)
  {
  	struct superblock_smack *sbp = dentry->d_sb->s_security;
ecfcc53fe   Etienne Basset   smack: implement ...
881
882
  	int rc;
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
883
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
884
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
885

ecfcc53fe   Etienne Basset   smack: implement ...
886
  	rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
887
  	rc = smk_bu_current("statfs", sbp->smk_floor, MAY_READ, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
888
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
889
  }
e114e4737   Casey Schaufler   Smack: Simplified...
890
  /*
676dac4b1   Casey Schaufler   This patch adds a...
891
892
   * BPRM hooks
   */
ce8a43219   Casey Schaufler   Smack: Clean up c...
893
894
895
896
  /**
   * smack_bprm_set_creds - set creds for exec
   * @bprm: the exec information
   *
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
897
   * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
ce8a43219   Casey Schaufler   Smack: Clean up c...
898
   */
676dac4b1   Casey Schaufler   This patch adds a...
899
900
  static int smack_bprm_set_creds(struct linux_binprm *bprm)
  {
496ad9aa8   Al Viro   new helper: file_...
901
  	struct inode *inode = file_inode(bprm->file);
84088ba23   Jarkko Sakkinen   Smack: domain tra...
902
  	struct task_smack *bsp = bprm->cred->security;
676dac4b1   Casey Schaufler   This patch adds a...
903
  	struct inode_smack *isp;
809c02e09   Seth Forshee   Smack: Handle lab...
904
  	struct superblock_smack *sbsp;
676dac4b1   Casey Schaufler   This patch adds a...
905
  	int rc;
676dac4b1   Casey Schaufler   This patch adds a...
906
907
  	if (bprm->cred_prepared)
  		return 0;
84088ba23   Jarkko Sakkinen   Smack: domain tra...
908
909
  	isp = inode->i_security;
  	if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
676dac4b1   Casey Schaufler   This patch adds a...
910
  		return 0;
809c02e09   Seth Forshee   Smack: Handle lab...
911
912
913
914
  	sbsp = inode->i_sb->s_security;
  	if ((sbsp->smk_flags & SMK_SB_UNTRUSTED) &&
  	    isp->smk_task != sbsp->smk_root)
  		return 0;
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
915
916
917
918
919
920
921
922
  	if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
  		struct task_struct *tracer;
  		rc = 0;
  
  		rcu_read_lock();
  		tracer = ptrace_parent(current);
  		if (likely(tracer != NULL))
  			rc = smk_ptrace_rule_check(tracer,
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
923
  						   isp->smk_task,
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
924
925
926
927
928
929
930
  						   PTRACE_MODE_ATTACH,
  						   __func__);
  		rcu_read_unlock();
  
  		if (rc != 0)
  			return rc;
  	} else if (bprm->unsafe)
84088ba23   Jarkko Sakkinen   Smack: domain tra...
931
  		return -EPERM;
676dac4b1   Casey Schaufler   This patch adds a...
932

84088ba23   Jarkko Sakkinen   Smack: domain tra...
933
934
  	bsp->smk_task = isp->smk_task;
  	bprm->per_clear |= PER_CLEAR_ON_SETID;
676dac4b1   Casey Schaufler   This patch adds a...
935

84088ba23   Jarkko Sakkinen   Smack: domain tra...
936
937
  	return 0;
  }
676dac4b1   Casey Schaufler   This patch adds a...
938

84088ba23   Jarkko Sakkinen   Smack: domain tra...
939
940
941
942
943
944
945
946
947
  /**
   * smack_bprm_committing_creds - Prepare to install the new credentials
   * from bprm.
   *
   * @bprm: binprm for exec
   */
  static void smack_bprm_committing_creds(struct linux_binprm *bprm)
  {
  	struct task_smack *bsp = bprm->cred->security;
676dac4b1   Casey Schaufler   This patch adds a...
948

84088ba23   Jarkko Sakkinen   Smack: domain tra...
949
950
951
952
953
954
955
956
957
958
959
960
961
  	if (bsp->smk_task != bsp->smk_forked)
  		current->pdeath_signal = 0;
  }
  
  /**
   * smack_bprm_secureexec - Return the decision to use secureexec.
   * @bprm: binprm for exec
   *
   * Returns 0 on success.
   */
  static int smack_bprm_secureexec(struct linux_binprm *bprm)
  {
  	struct task_smack *tsp = current_security();
84088ba23   Jarkko Sakkinen   Smack: domain tra...
962

b1d9e6b06   Casey Schaufler   LSM: Switch to li...
963
964
  	if (tsp->smk_task != tsp->smk_forked)
  		return 1;
84088ba23   Jarkko Sakkinen   Smack: domain tra...
965

b1d9e6b06   Casey Schaufler   LSM: Switch to li...
966
  	return 0;
676dac4b1   Casey Schaufler   This patch adds a...
967
968
969
  }
  
  /*
e114e4737   Casey Schaufler   Smack: Simplified...
970
971
972
973
974
   * Inode hooks
   */
  
  /**
   * smack_inode_alloc_security - allocate an inode blob
251a2a958   Randy Dunlap   smack: fix lots o...
975
   * @inode: the inode in need of a blob
e114e4737   Casey Schaufler   Smack: Simplified...
976
977
978
979
980
   *
   * Returns 0 if it gets a blob, -ENOMEM otherwise
   */
  static int smack_inode_alloc_security(struct inode *inode)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
981
  	struct smack_known *skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
982
  	inode->i_security = new_inode_smack(skp);
e114e4737   Casey Schaufler   Smack: Simplified...
983
984
985
986
987
988
989
  	if (inode->i_security == NULL)
  		return -ENOMEM;
  	return 0;
  }
  
  /**
   * smack_inode_free_security - free an inode blob
251a2a958   Randy Dunlap   smack: fix lots o...
990
   * @inode: the inode with a blob
e114e4737   Casey Schaufler   Smack: Simplified...
991
992
993
994
995
   *
   * Clears the blob pointer in inode
   */
  static void smack_inode_free_security(struct inode *inode)
  {
1a5b472bd   Rohit   Security: smack: ...
996
  	kmem_cache_free(smack_inode_cache, inode->i_security);
e114e4737   Casey Schaufler   Smack: Simplified...
997
998
999
1000
1001
  	inode->i_security = NULL;
  }
  
  /**
   * smack_inode_init_security - copy out the smack from an inode
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
1002
1003
   * @inode: the newly created inode
   * @dir: containing directory object
2a7dba391   Eric Paris   fs/vfs/security: ...
1004
   * @qstr: unused
e114e4737   Casey Schaufler   Smack: Simplified...
1005
1006
1007
1008
1009
1010
1011
   * @name: where to put the attribute name
   * @value: where to put the attribute value
   * @len: where to put the length of the attribute
   *
   * Returns 0 if it all works out, -ENOMEM if there's no memory
   */
  static int smack_inode_init_security(struct inode *inode, struct inode *dir,
9548906b2   Tetsuo Handa   xattr: Constify -...
1012
  				     const struct qstr *qstr, const char **name,
2a7dba391   Eric Paris   fs/vfs/security: ...
1013
  				     void **value, size_t *len)
e114e4737   Casey Schaufler   Smack: Simplified...
1014
  {
2267b13a7   Casey Schaufler   Smack: recursive ...
1015
  	struct inode_smack *issp = inode->i_security;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1016
  	struct smack_known *skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1017
1018
  	struct smack_known *isp = smk_of_inode(inode);
  	struct smack_known *dsp = smk_of_inode(dir);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1019
  	int may;
e114e4737   Casey Schaufler   Smack: Simplified...
1020

9548906b2   Tetsuo Handa   xattr: Constify -...
1021
1022
  	if (name)
  		*name = XATTR_SMACK_SUFFIX;
e114e4737   Casey Schaufler   Smack: Simplified...
1023

68390ccf8   Lukasz Pawelczyk   smack: fix logic ...
1024
  	if (value && len) {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1025
  		rcu_read_lock();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1026
1027
  		may = smk_access_entry(skp->smk_known, dsp->smk_known,
  				       &skp->smk_rules);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1028
  		rcu_read_unlock();
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1029
1030
1031
1032
1033
  
  		/*
  		 * If the access rule allows transmutation and
  		 * the directory requests transmutation then
  		 * by all means transmute.
2267b13a7   Casey Schaufler   Smack: recursive ...
1034
  		 * Mark the inode as changed.
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1035
  		 */
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1036
  		if (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
2267b13a7   Casey Schaufler   Smack: recursive ...
1037
  		    smk_inode_transmutable(dir)) {
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1038
  			isp = dsp;
2267b13a7   Casey Schaufler   Smack: recursive ...
1039
1040
  			issp->smk_flags |= SMK_INODE_CHANGED;
  		}
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1041

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1042
  		*value = kstrdup(isp->smk_known, GFP_NOFS);
e114e4737   Casey Schaufler   Smack: Simplified...
1043
1044
  		if (*value == NULL)
  			return -ENOMEM;
e114e4737   Casey Schaufler   Smack: Simplified...
1045

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1046
  		*len = strlen(isp->smk_known);
68390ccf8   Lukasz Pawelczyk   smack: fix logic ...
1047
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
  
  	return 0;
  }
  
  /**
   * smack_inode_link - Smack check on link
   * @old_dentry: the existing object
   * @dir: unused
   * @new_dentry: the new object
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
  static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
  			    struct dentry *new_dentry)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1063
  	struct smack_known *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
1064
1065
  	struct smk_audit_info ad;
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
1066
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1067
  	smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1068

c6f493d63   David Howells   VFS: security/: d...
1069
  	isp = smk_of_inode(d_backing_inode(old_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1070
  	rc = smk_curacc(isp, MAY_WRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1071
  	rc = smk_bu_inode(d_backing_inode(old_dentry), MAY_WRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1072

8802565b6   David Howells   Smack: Use d_is_p...
1073
  	if (rc == 0 && d_is_positive(new_dentry)) {
c6f493d63   David Howells   VFS: security/: d...
1074
  		isp = smk_of_inode(d_backing_inode(new_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1075
1076
  		smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
  		rc = smk_curacc(isp, MAY_WRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1077
  		rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_WRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
  	}
  
  	return rc;
  }
  
  /**
   * smack_inode_unlink - Smack check on inode deletion
   * @dir: containing directory object
   * @dentry: file to unlink
   *
   * Returns 0 if current can write the containing directory
   * and the object, error code otherwise
   */
  static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
  {
c6f493d63   David Howells   VFS: security/: d...
1093
  	struct inode *ip = d_backing_inode(dentry);
ecfcc53fe   Etienne Basset   smack: implement ...
1094
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1095
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
1096
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1097
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1098
1099
1100
  	/*
  	 * You need write access to the thing you're unlinking
  	 */
ecfcc53fe   Etienne Basset   smack: implement ...
1101
  	rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1102
  	rc = smk_bu_inode(ip, MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1103
  	if (rc == 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
1104
1105
1106
  		/*
  		 * You also need write access to the containing directory
  		 */
cdb56b608   Igor Zhbanov   Fix NULL pointer ...
1107
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
1108
1109
  		smk_ad_setfield_u_fs_inode(&ad, dir);
  		rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1110
  		rc = smk_bu_inode(dir, MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1111
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
  	return rc;
  }
  
  /**
   * smack_inode_rmdir - Smack check on directory deletion
   * @dir: containing directory object
   * @dentry: directory to unlink
   *
   * Returns 0 if current can write the containing directory
   * and the directory, error code otherwise
   */
  static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1125
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1126
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
1127
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1128
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1129
1130
1131
  	/*
  	 * You need write access to the thing you're removing
  	 */
c6f493d63   David Howells   VFS: security/: d...
1132
1133
  	rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
  	rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1134
  	if (rc == 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
1135
1136
1137
  		/*
  		 * You also need write access to the containing directory
  		 */
cdb56b608   Igor Zhbanov   Fix NULL pointer ...
1138
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
1139
1140
  		smk_ad_setfield_u_fs_inode(&ad, dir);
  		rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1141
  		rc = smk_bu_inode(dir, MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1142
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1143
1144
1145
1146
1147
1148
  
  	return rc;
  }
  
  /**
   * smack_inode_rename - Smack check on rename
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
1149
1150
1151
1152
   * @old_inode: unused
   * @old_dentry: the old object
   * @new_inode: unused
   * @new_dentry: the new object
e114e4737   Casey Schaufler   Smack: Simplified...
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
   *
   * Read and write access is required on both the old and
   * new directories.
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
  static int smack_inode_rename(struct inode *old_inode,
  			      struct dentry *old_dentry,
  			      struct inode *new_inode,
  			      struct dentry *new_dentry)
  {
  	int rc;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1165
  	struct smack_known *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
1166
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
1167
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1168
  	smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1169

c6f493d63   David Howells   VFS: security/: d...
1170
  	isp = smk_of_inode(d_backing_inode(old_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1171
  	rc = smk_curacc(isp, MAY_READWRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1172
  	rc = smk_bu_inode(d_backing_inode(old_dentry), MAY_READWRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1173

8802565b6   David Howells   Smack: Use d_is_p...
1174
  	if (rc == 0 && d_is_positive(new_dentry)) {
c6f493d63   David Howells   VFS: security/: d...
1175
  		isp = smk_of_inode(d_backing_inode(new_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1176
1177
  		smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
  		rc = smk_curacc(isp, MAY_READWRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1178
  		rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_READWRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1179
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1180
1181
1182
1183
1184
1185
1186
  	return rc;
  }
  
  /**
   * smack_inode_permission - Smack version of permission()
   * @inode: the inode in question
   * @mask: the access requested
e114e4737   Casey Schaufler   Smack: Simplified...
1187
1188
1189
1190
1191
   *
   * This is the important Smack hook.
   *
   * Returns 0 if access is permitted, -EACCES otherwise
   */
e74f71eb7   Al Viro   ->permission() sa...
1192
  static int smack_inode_permission(struct inode *inode, int mask)
e114e4737   Casey Schaufler   Smack: Simplified...
1193
  {
9f50eda2a   Seth Forshee   Smack: Add suppor...
1194
  	struct superblock_smack *sbsp = inode->i_sb->s_security;
ecfcc53fe   Etienne Basset   smack: implement ...
1195
  	struct smk_audit_info ad;
e74f71eb7   Al Viro   ->permission() sa...
1196
  	int no_block = mask & MAY_NOT_BLOCK;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1197
  	int rc;
d09ca7397   Eric Paris   security: make LS...
1198
1199
  
  	mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
e114e4737   Casey Schaufler   Smack: Simplified...
1200
1201
1202
1203
1204
  	/*
  	 * No permission to check. Existence test. Yup, it's there.
  	 */
  	if (mask == 0)
  		return 0;
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
1205

9f50eda2a   Seth Forshee   Smack: Add suppor...
1206
1207
1208
1209
  	if (sbsp->smk_flags & SMK_SB_UNTRUSTED) {
  		if (smk_of_inode(inode) != sbsp->smk_root)
  			return -EACCES;
  	}
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
1210
  	/* May be droppable after audit */
e74f71eb7   Al Viro   ->permission() sa...
1211
  	if (no_block)
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
1212
  		return -ECHILD;
f48b73998   Eric Paris   LSM: split LSM_AU...
1213
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
1214
  	smk_ad_setfield_u_fs_inode(&ad, inode);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1215
1216
1217
  	rc = smk_curacc(smk_of_inode(inode), mask, &ad);
  	rc = smk_bu_inode(inode, mask, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
  }
  
  /**
   * smack_inode_setattr - Smack check for setting attributes
   * @dentry: the object
   * @iattr: for the force flag
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
  static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1229
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1230
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1231
1232
1233
1234
1235
  	/*
  	 * Need to allow for clearing the setuid bit.
  	 */
  	if (iattr->ia_valid & ATTR_FORCE)
  		return 0;
a269434d2   Eric Paris   LSM: separate LSM...
1236
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1237
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1238

c6f493d63   David Howells   VFS: security/: d...
1239
1240
  	rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
  	rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1241
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1242
1243
1244
1245
  }
  
  /**
   * smack_inode_getattr - Smack check for getting attributes
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
1246
   * @mnt: vfsmount of the object
e114e4737   Casey Schaufler   Smack: Simplified...
1247
1248
1249
1250
   * @dentry: the object
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
3f7036a07   Al Viro   switch security_i...
1251
  static int smack_inode_getattr(const struct path *path)
e114e4737   Casey Schaufler   Smack: Simplified...
1252
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1253
  	struct smk_audit_info ad;
c6f493d63   David Howells   VFS: security/: d...
1254
  	struct inode *inode = d_backing_inode(path->dentry);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1255
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1256

f48b73998   Eric Paris   LSM: split LSM_AU...
1257
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
3f7036a07   Al Viro   switch security_i...
1258
1259
1260
  	smk_ad_setfield_u_fs_path(&ad, *path);
  	rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad);
  	rc = smk_bu_inode(inode, MAY_READ, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1261
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1262
1263
1264
1265
1266
1267
  }
  
  /**
   * smack_inode_setxattr - Smack check for setting xattrs
   * @dentry: the object
   * @name: name of the attribute
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
1268
1269
   * @value: value of the attribute
   * @size: size of the value
e114e4737   Casey Schaufler   Smack: Simplified...
1270
1271
1272
1273
1274
1275
   * @flags: unused
   *
   * This protects the Smack attribute explicitly.
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
8f0cfa52a   David Howells   xattr: add missin...
1276
1277
  static int smack_inode_setxattr(struct dentry *dentry, const char *name,
  				const void *value, size_t size, int flags)
e114e4737   Casey Schaufler   Smack: Simplified...
1278
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1279
  	struct smk_audit_info ad;
19760ad03   Casey Schaufler   Smack: Prevent th...
1280
1281
1282
1283
  	struct smack_known *skp;
  	int check_priv = 0;
  	int check_import = 0;
  	int check_star = 0;
bcdca225b   Casey Schaufler   Smack: update for...
1284
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1285

19760ad03   Casey Schaufler   Smack: Prevent th...
1286
1287
1288
  	/*
  	 * Check label validity here so import won't fail in post_setxattr
  	 */
bcdca225b   Casey Schaufler   Smack: update for...
1289
1290
  	if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
19760ad03   Casey Schaufler   Smack: Prevent th...
1291
1292
1293
1294
1295
1296
1297
1298
  	    strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
  		check_priv = 1;
  		check_import = 1;
  	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
  		   strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
  		check_priv = 1;
  		check_import = 1;
  		check_star = 1;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1299
  	} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
19760ad03   Casey Schaufler   Smack: Prevent th...
1300
  		check_priv = 1;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1301
1302
1303
  		if (size != TRANS_TRUE_SIZE ||
  		    strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
  			rc = -EINVAL;
bcdca225b   Casey Schaufler   Smack: update for...
1304
1305
  	} else
  		rc = cap_inode_setxattr(dentry, name, value, size, flags);
19760ad03   Casey Schaufler   Smack: Prevent th...
1306
1307
1308
1309
  	if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
  		rc = -EPERM;
  
  	if (rc == 0 && check_import) {
b862e561b   Konstantin Khlebnikov   Smack: handle zer...
1310
  		skp = size ? smk_import_entry(value, size) : NULL;
e774ad683   Lukasz Pawelczyk   smack: pass error...
1311
1312
1313
  		if (IS_ERR(skp))
  			rc = PTR_ERR(skp);
  		else if (skp == NULL || (check_star &&
19760ad03   Casey Schaufler   Smack: Prevent th...
1314
1315
1316
  		    (skp == &smack_known_star || skp == &smack_known_web)))
  			rc = -EINVAL;
  	}
a269434d2   Eric Paris   LSM: separate LSM...
1317
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1318
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1319
  	if (rc == 0) {
c6f493d63   David Howells   VFS: security/: d...
1320
1321
  		rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
  		rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1322
  	}
bcdca225b   Casey Schaufler   Smack: update for...
1323
1324
  
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
  }
  
  /**
   * smack_inode_post_setxattr - Apply the Smack update approved above
   * @dentry: object
   * @name: attribute name
   * @value: attribute value
   * @size: attribute size
   * @flags: unused
   *
   * Set the pointer in the inode blob to the entry found
   * in the master label list.
   */
8f0cfa52a   David Howells   xattr: add missin...
1338
1339
  static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
  				      const void *value, size_t size, int flags)
e114e4737   Casey Schaufler   Smack: Simplified...
1340
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1341
  	struct smack_known *skp;
c6f493d63   David Howells   VFS: security/: d...
1342
  	struct inode_smack *isp = d_backing_inode(dentry)->i_security;
676dac4b1   Casey Schaufler   This patch adds a...
1343

2f823ff8b   Casey Schaufler   Smack: Improve ac...
1344
1345
1346
1347
  	if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
  		isp->smk_flags |= SMK_INODE_TRANSMUTE;
  		return;
  	}
676dac4b1   Casey Schaufler   This patch adds a...
1348
  	if (strcmp(name, XATTR_NAME_SMACK) == 0) {
9598f4c9e   José Bollo   SMACK: Fix handli...
1349
  		skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
1350
  		if (!IS_ERR(skp))
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1351
  			isp->smk_inode = skp;
676dac4b1   Casey Schaufler   This patch adds a...
1352
  		else
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1353
  			isp->smk_inode = &smack_known_invalid;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1354
  	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
9598f4c9e   José Bollo   SMACK: Fix handli...
1355
  		skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
1356
  		if (!IS_ERR(skp))
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1357
  			isp->smk_task = skp;
676dac4b1   Casey Schaufler   This patch adds a...
1358
  		else
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1359
  			isp->smk_task = &smack_known_invalid;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1360
  	} else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
9598f4c9e   José Bollo   SMACK: Fix handli...
1361
  		skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
1362
  		if (!IS_ERR(skp))
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1363
  			isp->smk_mmap = skp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1364
  		else
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1365
1366
  			isp->smk_mmap = &smack_known_invalid;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1367
1368
1369
  
  	return;
  }
ce8a43219   Casey Schaufler   Smack: Clean up c...
1370
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1371
1372
1373
1374
1375
1376
   * smack_inode_getxattr - Smack check on getxattr
   * @dentry: the object
   * @name: unused
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
8f0cfa52a   David Howells   xattr: add missin...
1377
  static int smack_inode_getxattr(struct dentry *dentry, const char *name)
e114e4737   Casey Schaufler   Smack: Simplified...
1378
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1379
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1380
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1381

a269434d2   Eric Paris   LSM: separate LSM...
1382
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1383
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
c6f493d63   David Howells   VFS: security/: d...
1384
1385
  	rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_READ, &ad);
  	rc = smk_bu_inode(d_backing_inode(dentry), MAY_READ, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1386
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1387
  }
ce8a43219   Casey Schaufler   Smack: Clean up c...
1388
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1389
1390
1391
1392
1393
1394
1395
1396
   * smack_inode_removexattr - Smack check on removexattr
   * @dentry: the object
   * @name: name of the attribute
   *
   * Removing the Smack attribute requires CAP_MAC_ADMIN
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
8f0cfa52a   David Howells   xattr: add missin...
1397
  static int smack_inode_removexattr(struct dentry *dentry, const char *name)
e114e4737   Casey Schaufler   Smack: Simplified...
1398
  {
676dac4b1   Casey Schaufler   This patch adds a...
1399
  	struct inode_smack *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
1400
  	struct smk_audit_info ad;
bcdca225b   Casey Schaufler   Smack: update for...
1401
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1402

bcdca225b   Casey Schaufler   Smack: update for...
1403
1404
  	if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
676dac4b1   Casey Schaufler   This patch adds a...
1405
  	    strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1406
  	    strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1407
  	    strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
5e9ab593c   Pankaj Kumar   bugfix patch for ...
1408
  	    strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
1880eff77   Casey Schaufler   Smack: onlycap li...
1409
  		if (!smack_privileged(CAP_MAC_ADMIN))
bcdca225b   Casey Schaufler   Smack: update for...
1410
1411
1412
  			rc = -EPERM;
  	} else
  		rc = cap_inode_removexattr(dentry, name);
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1413
1414
  	if (rc != 0)
  		return rc;
a269434d2   Eric Paris   LSM: separate LSM...
1415
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1416
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
bcdca225b   Casey Schaufler   Smack: update for...
1417

c6f493d63   David Howells   VFS: security/: d...
1418
1419
  	rc = smk_curacc(smk_of_inode(d_backing_inode(dentry)), MAY_WRITE, &ad);
  	rc = smk_bu_inode(d_backing_inode(dentry), MAY_WRITE, rc);
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1420
1421
  	if (rc != 0)
  		return rc;
c6f493d63   David Howells   VFS: security/: d...
1422
  	isp = d_backing_inode(dentry)->i_security;
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1423
1424
1425
1426
  	/*
  	 * Don't do anything special for these.
  	 *	XATTR_NAME_SMACKIPIN
  	 *	XATTR_NAME_SMACKIPOUT
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1427
  	 */
8012495e1   José Bollo   smack: fix cache ...
1428
  	if (strcmp(name, XATTR_NAME_SMACK) == 0) {
fc64005c9   Al Viro   don't bother with...
1429
  		struct super_block *sbp = dentry->d_sb;
8012495e1   José Bollo   smack: fix cache ...
1430
1431
1432
1433
  		struct superblock_smack *sbsp = sbp->s_security;
  
  		isp->smk_inode = sbsp->smk_default;
  	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0)
676dac4b1   Casey Schaufler   This patch adds a...
1434
  		isp->smk_task = NULL;
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1435
  	else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1436
  		isp->smk_mmap = NULL;
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1437
1438
  	else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
  		isp->smk_flags &= ~SMK_INODE_TRANSMUTE;
676dac4b1   Casey Schaufler   This patch adds a...
1439

f59bdfba3   Casey Schaufler   Smack: Correctly ...
1440
  	return 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1441
1442
1443
1444
1445
1446
1447
  }
  
  /**
   * smack_inode_getsecurity - get smack xattrs
   * @inode: the object
   * @name: attribute name
   * @buffer: where to put the result
251a2a958   Randy Dunlap   smack: fix lots o...
1448
   * @alloc: unused
e114e4737   Casey Schaufler   Smack: Simplified...
1449
1450
1451
   *
   * Returns the size of the attribute or an error code
   */
ea861dfd9   Andreas Gruenbacher   security: Make in...
1452
  static int smack_inode_getsecurity(struct inode *inode,
e114e4737   Casey Schaufler   Smack: Simplified...
1453
1454
1455
1456
1457
1458
1459
  				   const char *name, void **buffer,
  				   bool alloc)
  {
  	struct socket_smack *ssp;
  	struct socket *sock;
  	struct super_block *sbp;
  	struct inode *ip = (struct inode *)inode;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1460
  	struct smack_known *isp;
e114e4737   Casey Schaufler   Smack: Simplified...
1461
1462
1463
1464
1465
  	int ilen;
  	int rc = 0;
  
  	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
  		isp = smk_of_inode(inode);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1466
1467
  		ilen = strlen(isp->smk_known);
  		*buffer = isp->smk_known;
e114e4737   Casey Schaufler   Smack: Simplified...
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
  		return ilen;
  	}
  
  	/*
  	 * The rest of the Smack xattrs are only on sockets.
  	 */
  	sbp = ip->i_sb;
  	if (sbp->s_magic != SOCKFS_MAGIC)
  		return -EOPNOTSUPP;
  
  	sock = SOCKET_I(ip);
2e1d146a1   Ahmed S. Darwish   Smack: check for ...
1479
  	if (sock == NULL || sock->sk == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
1480
1481
1482
1483
1484
  		return -EOPNOTSUPP;
  
  	ssp = sock->sk->sk_security;
  
  	if (strcmp(name, XATTR_SMACK_IPIN) == 0)
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1485
  		isp = ssp->smk_in;
e114e4737   Casey Schaufler   Smack: Simplified...
1486
  	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1487
  		isp = ssp->smk_out;
e114e4737   Casey Schaufler   Smack: Simplified...
1488
1489
  	else
  		return -EOPNOTSUPP;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1490
  	ilen = strlen(isp->smk_known);
e114e4737   Casey Schaufler   Smack: Simplified...
1491
  	if (rc == 0) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1492
  		*buffer = isp->smk_known;
e114e4737   Casey Schaufler   Smack: Simplified...
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
  		rc = ilen;
  	}
  
  	return rc;
  }
  
  
  /**
   * smack_inode_listsecurity - list the Smack attributes
   * @inode: the object
   * @buffer: where they go
   * @buffer_size: size of buffer
e114e4737   Casey Schaufler   Smack: Simplified...
1505
1506
1507
1508
   */
  static int smack_inode_listsecurity(struct inode *inode, char *buffer,
  				    size_t buffer_size)
  {
fd5c9d230   Konstantin Khlebnikov   Smack: fix behavi...
1509
  	int len = sizeof(XATTR_NAME_SMACK);
e114e4737   Casey Schaufler   Smack: Simplified...
1510

fd5c9d230   Konstantin Khlebnikov   Smack: fix behavi...
1511
  	if (buffer != NULL && len <= buffer_size)
e114e4737   Casey Schaufler   Smack: Simplified...
1512
  		memcpy(buffer, XATTR_NAME_SMACK, len);
fd5c9d230   Konstantin Khlebnikov   Smack: fix behavi...
1513
1514
  
  	return len;
e114e4737   Casey Schaufler   Smack: Simplified...
1515
  }
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1516
1517
1518
1519
1520
  /**
   * smack_inode_getsecid - Extract inode's security id
   * @inode: inode to extract the info from
   * @secid: where result will be saved
   */
d6335d77a   Andreas Gruenbacher   security: Make in...
1521
  static void smack_inode_getsecid(struct inode *inode, u32 *secid)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1522
1523
  {
  	struct inode_smack *isp = inode->i_security;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1524
  	*secid = isp->smk_inode->smk_secid;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1525
  }
e114e4737   Casey Schaufler   Smack: Simplified...
1526
1527
1528
  /*
   * File Hooks
   */
491a0b08d   Casey Schaufler   Smack: Remove poi...
1529
1530
  /*
   * There is no smack_file_permission hook
e114e4737   Casey Schaufler   Smack: Simplified...
1531
1532
1533
1534
1535
1536
1537
1538
   *
   * Should access checks be done on each read or write?
   * UNICOS and SELinux say yes.
   * Trusted Solaris, Trusted Irix, and just about everyone else says no.
   *
   * I'll say no for now. Smack does not do the frequent
   * label changing that SELinux does.
   */
e114e4737   Casey Schaufler   Smack: Simplified...
1539
1540
1541
1542
1543
1544
1545
1546
  
  /**
   * smack_file_alloc_security - assign a file security blob
   * @file: the object
   *
   * The security blob for a file is a pointer to the master
   * label list, so no allocation is done.
   *
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1547
1548
1549
   * f_security is the owner security information. It
   * isn't used on file access checks, it's for send_sigio.
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1550
1551
1552
1553
   * Returns 0
   */
  static int smack_file_alloc_security(struct file *file)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1554
  	struct smack_known *skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1555
  	file->f_security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
  	return 0;
  }
  
  /**
   * smack_file_free_security - clear a file security blob
   * @file: the object
   *
   * The security blob for a file is a pointer to the master
   * label list, so no memory is freed.
   */
  static void smack_file_free_security(struct file *file)
  {
  	file->f_security = NULL;
  }
  
  /**
   * smack_file_ioctl - Smack check on ioctls
   * @file: the object
   * @cmd: what to do
   * @arg: unused
   *
   * Relies heavily on the correct use of the ioctl command conventions.
   *
   * Returns 0 if allowed, error code otherwise
   */
  static int smack_file_ioctl(struct file *file, unsigned int cmd,
  			    unsigned long arg)
  {
  	int rc = 0;
ecfcc53fe   Etienne Basset   smack: implement ...
1585
  	struct smk_audit_info ad;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1586
  	struct inode *inode = file_inode(file);
ecfcc53fe   Etienne Basset   smack: implement ...
1587

f48b73998   Eric Paris   LSM: split LSM_AU...
1588
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
ecfcc53fe   Etienne Basset   smack: implement ...
1589
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
e114e4737   Casey Schaufler   Smack: Simplified...
1590

d166c8024   Casey Schaufler   Smack: Bring-up a...
1591
  	if (_IOC_DIR(cmd) & _IOC_WRITE) {
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1592
  		rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1593
1594
  		rc = smk_bu_file(file, MAY_WRITE, rc);
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1595

d166c8024   Casey Schaufler   Smack: Bring-up a...
1596
  	if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) {
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1597
  		rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1598
1599
  		rc = smk_bu_file(file, MAY_READ, rc);
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1600
1601
1602
1603
1604
1605
1606
  
  	return rc;
  }
  
  /**
   * smack_file_lock - Smack check on file locking
   * @file: the object
251a2a958   Randy Dunlap   smack: fix lots o...
1607
   * @cmd: unused
e114e4737   Casey Schaufler   Smack: Simplified...
1608
   *
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1609
   * Returns 0 if current has lock access, error code otherwise
e114e4737   Casey Schaufler   Smack: Simplified...
1610
1611
1612
   */
  static int smack_file_lock(struct file *file, unsigned int cmd)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1613
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1614
  	int rc;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1615
  	struct inode *inode = file_inode(file);
ecfcc53fe   Etienne Basset   smack: implement ...
1616

92f425090   Eric Paris   SMACK: smack_file...
1617
1618
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1619
  	rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1620
1621
  	rc = smk_bu_file(file, MAY_LOCK, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1622
1623
1624
1625
1626
1627
1628
1629
  }
  
  /**
   * smack_file_fcntl - Smack check on fcntl
   * @file: the object
   * @cmd: what action to check
   * @arg: unused
   *
531f1d453   Casey Schaufler   Smack: Repair pro...
1630
1631
1632
1633
   * Generally these operations are harmless.
   * File locking operations present an obvious mechanism
   * for passing information, so they require write access.
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1634
1635
1636
1637
1638
   * Returns 0 if current has access, error code otherwise
   */
  static int smack_file_fcntl(struct file *file, unsigned int cmd,
  			    unsigned long arg)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1639
  	struct smk_audit_info ad;
531f1d453   Casey Schaufler   Smack: Repair pro...
1640
  	int rc = 0;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1641
  	struct inode *inode = file_inode(file);
ecfcc53fe   Etienne Basset   smack: implement ...
1642

e114e4737   Casey Schaufler   Smack: Simplified...
1643
  	switch (cmd) {
e114e4737   Casey Schaufler   Smack: Simplified...
1644
  	case F_GETLK:
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1645
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1646
1647
  	case F_SETLK:
  	case F_SETLKW:
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1648
1649
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  		smk_ad_setfield_u_fs_path(&ad, file->f_path);
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1650
  		rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1651
  		rc = smk_bu_file(file, MAY_LOCK, rc);
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1652
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1653
1654
  	case F_SETOWN:
  	case F_SETSIG:
531f1d453   Casey Schaufler   Smack: Repair pro...
1655
1656
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  		smk_ad_setfield_u_fs_path(&ad, file->f_path);
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1657
  		rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1658
  		rc = smk_bu_file(file, MAY_WRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1659
1660
  		break;
  	default:
531f1d453   Casey Schaufler   Smack: Repair pro...
1661
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1662
1663
1664
1665
1666
1667
  	}
  
  	return rc;
  }
  
  /**
e5467859f   Al Viro   split ->file_mmap...
1668
   * smack_mmap_file :
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1669
1670
1671
1672
1673
1674
1675
1676
   * Check permissions for a mmap operation.  The @file may be NULL, e.g.
   * if mapping anonymous memory.
   * @file contains the file structure for file to map (may be NULL).
   * @reqprot contains the protection requested by the application.
   * @prot contains the protection that will be applied by the kernel.
   * @flags contains the operational flags.
   * Return 0 if permission is granted.
   */
e5467859f   Al Viro   split ->file_mmap...
1677
  static int smack_mmap_file(struct file *file,
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1678
  			   unsigned long reqprot, unsigned long prot,
e5467859f   Al Viro   split ->file_mmap...
1679
  			   unsigned long flags)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1680
  {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1681
  	struct smack_known *skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1682
  	struct smack_known *mkp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1683
1684
  	struct smack_rule *srp;
  	struct task_smack *tsp;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1685
  	struct smack_known *okp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1686
  	struct inode_smack *isp;
809c02e09   Seth Forshee   Smack: Handle lab...
1687
  	struct superblock_smack *sbsp;
0e0a070d3   Casey Schaufler   Smack: correct be...
1688
1689
1690
  	int may;
  	int mmay;
  	int tmay;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1691
  	int rc;
496ad9aa8   Al Viro   new helper: file_...
1692
  	if (file == NULL)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1693
  		return 0;
496ad9aa8   Al Viro   new helper: file_...
1694
  	isp = file_inode(file)->i_security;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1695
1696
  	if (isp->smk_mmap == NULL)
  		return 0;
809c02e09   Seth Forshee   Smack: Handle lab...
1697
1698
1699
1700
  	sbsp = file_inode(file)->i_sb->s_security;
  	if (sbsp->smk_flags & SMK_SB_UNTRUSTED &&
  	    isp->smk_mmap != sbsp->smk_root)
  		return -EACCES;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1701
  	mkp = isp->smk_mmap;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1702
1703
  
  	tsp = current_security();
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1704
  	skp = smk_of_current();
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1705
1706
1707
1708
1709
1710
1711
  	rc = 0;
  
  	rcu_read_lock();
  	/*
  	 * For each Smack rule associated with the subject
  	 * label verify that the SMACK64MMAP also has access
  	 * to that rule's object label.
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1712
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1713
  	list_for_each_entry_rcu(srp, &skp->smk_rules, list) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1714
  		okp = srp->smk_object;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1715
1716
1717
  		/*
  		 * Matching labels always allows access.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1718
  		if (mkp->smk_known == okp->smk_known)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1719
  			continue;
0e0a070d3   Casey Schaufler   Smack: correct be...
1720
1721
1722
1723
  		/*
  		 * If there is a matching local rule take
  		 * that into account as well.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1724
1725
1726
  		may = smk_access_entry(srp->smk_subject->smk_known,
  				       okp->smk_known,
  				       &tsp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
  		if (may == -ENOENT)
  			may = srp->smk_access;
  		else
  			may &= srp->smk_access;
  		/*
  		 * If may is zero the SMACK64MMAP subject can't
  		 * possibly have less access.
  		 */
  		if (may == 0)
  			continue;
  
  		/*
  		 * Fetch the global list entry.
  		 * If there isn't one a SMACK64MMAP subject
  		 * can't have as much access as current.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1743
1744
  		mmay = smk_access_entry(mkp->smk_known, okp->smk_known,
  					&mkp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1745
1746
1747
1748
1749
1750
1751
1752
  		if (mmay == -ENOENT) {
  			rc = -EACCES;
  			break;
  		}
  		/*
  		 * If there is a local entry it modifies the
  		 * potential access, too.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1753
1754
  		tmay = smk_access_entry(mkp->smk_known, okp->smk_known,
  					&tsp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1755
1756
  		if (tmay != -ENOENT)
  			mmay &= tmay;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1757

0e0a070d3   Casey Schaufler   Smack: correct be...
1758
1759
1760
1761
1762
  		/*
  		 * If there is any access available to current that is
  		 * not available to a SMACK64MMAP subject
  		 * deny access.
  		 */
75a25637b   Casey Schaufler   Smack: correct fi...
1763
  		if ((may | mmay) != mmay) {
0e0a070d3   Casey Schaufler   Smack: correct be...
1764
  			rc = -EACCES;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1765
  			break;
0e0a070d3   Casey Schaufler   Smack: correct be...
1766
  		}
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1767
1768
1769
1770
1771
1772
1773
1774
  	}
  
  	rcu_read_unlock();
  
  	return rc;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1775
1776
1777
   * smack_file_set_fowner - set the file security blob value
   * @file: object in question
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1778
   */
e0b93eddf   Jeff Layton   security: make se...
1779
  static void smack_file_set_fowner(struct file *file)
e114e4737   Casey Schaufler   Smack: Simplified...
1780
  {
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1781
  	file->f_security = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
  }
  
  /**
   * smack_file_send_sigiotask - Smack on sigio
   * @tsk: The target task
   * @fown: the object the signal come from
   * @signum: unused
   *
   * Allow a privileged task to get signals even if it shouldn't
   *
   * Returns 0 if a subject with the object's smack could
   * write to the task, an error code otherwise.
   */
  static int smack_file_send_sigiotask(struct task_struct *tsk,
  				     struct fown_struct *fown, int signum)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1798
1799
  	struct smack_known *skp;
  	struct smack_known *tkp = smk_of_task(tsk->cred->security);
e114e4737   Casey Schaufler   Smack: Simplified...
1800
1801
  	struct file *file;
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1802
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1803
1804
1805
1806
1807
  
  	/*
  	 * struct fown_struct is never outside the context of a struct file
  	 */
  	file = container_of(fown, struct file, f_owner);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1808

ecfcc53fe   Etienne Basset   smack: implement ...
1809
  	/* we don't log here as rc can be overriden */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1810
  	skp = file->f_security;
c60b90667   Casey Schaufler   Smack: Signal del...
1811
1812
  	rc = smk_access(skp, tkp, MAY_DELIVER, NULL);
  	rc = smk_bu_note("sigiotask", skp, tkp, MAY_DELIVER, rc);
5cd9c58fb   David Howells   security: Fix set...
1813
  	if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE))
ecfcc53fe   Etienne Basset   smack: implement ...
1814
1815
1816
1817
  		rc = 0;
  
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, tsk);
c60b90667   Casey Schaufler   Smack: Signal del...
1818
  	smack_log(skp->smk_known, tkp->smk_known, MAY_DELIVER, rc, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
  	return rc;
  }
  
  /**
   * smack_file_receive - Smack file receive check
   * @file: the object
   *
   * Returns 0 if current has access, error code otherwise
   */
  static int smack_file_receive(struct file *file)
  {
d166c8024   Casey Schaufler   Smack: Bring-up a...
1830
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1831
  	int may = 0;
ecfcc53fe   Etienne Basset   smack: implement ...
1832
  	struct smk_audit_info ad;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1833
  	struct inode *inode = file_inode(file);
79be09350   Casey Schaufler   Smack: File recei...
1834
1835
1836
  	struct socket *sock;
  	struct task_smack *tsp;
  	struct socket_smack *ssp;
e114e4737   Casey Schaufler   Smack: Simplified...
1837

9777582e8   Seung-Woo Kim   Smack: ignore pri...
1838
1839
  	if (unlikely(IS_PRIVATE(inode)))
  		return 0;
4482a44f6   Casey Schaufler   Smack: File recei...
1840
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
ecfcc53fe   Etienne Basset   smack: implement ...
1841
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
79be09350   Casey Schaufler   Smack: File recei...
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
  
  	if (S_ISSOCK(inode->i_mode)) {
  		sock = SOCKET_I(inode);
  		ssp = sock->sk->sk_security;
  		tsp = current_security();
  		/*
  		 * If the receiving process can't write to the
  		 * passed socket or if the passed socket can't
  		 * write to the receiving process don't accept
  		 * the passed socket.
  		 */
  		rc = smk_access(tsp->smk_task, ssp->smk_out, MAY_WRITE, &ad);
  		rc = smk_bu_file(file, may, rc);
  		if (rc < 0)
  			return rc;
  		rc = smk_access(ssp->smk_in, tsp->smk_task, MAY_WRITE, &ad);
  		rc = smk_bu_file(file, may, rc);
  		return rc;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1861
1862
1863
1864
1865
1866
1867
  	/*
  	 * This code relies on bitmasks.
  	 */
  	if (file->f_mode & FMODE_READ)
  		may = MAY_READ;
  	if (file->f_mode & FMODE_WRITE)
  		may |= MAY_WRITE;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1868
  	rc = smk_curacc(smk_of_inode(inode), may, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1869
1870
  	rc = smk_bu_file(file, may, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1871
  }
531f1d453   Casey Schaufler   Smack: Repair pro...
1872
  /**
83d498569   Eric Paris   SELinux: rename d...
1873
   * smack_file_open - Smack dentry open processing
531f1d453   Casey Schaufler   Smack: Repair pro...
1874
   * @file: the object
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1875
   * @cred: task credential
531f1d453   Casey Schaufler   Smack: Repair pro...
1876
1877
   *
   * Set the security blob in the file structure.
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1878
1879
1880
   * Allow the open only if the task has read access. There are
   * many read operations (e.g. fstat) that you can do with an
   * fd even if you have the file open write-only.
531f1d453   Casey Schaufler   Smack: Repair pro...
1881
1882
1883
   *
   * Returns 0
   */
83d498569   Eric Paris   SELinux: rename d...
1884
  static int smack_file_open(struct file *file, const struct cred *cred)
531f1d453   Casey Schaufler   Smack: Repair pro...
1885
  {
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1886
  	struct task_smack *tsp = cred->security;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1887
  	struct inode *inode = file_inode(file);
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1888
1889
  	struct smk_audit_info ad;
  	int rc;
531f1d453   Casey Schaufler   Smack: Repair pro...
1890

5e7270a6d   Casey Schaufler   Smack: Rework fil...
1891
  	if (smack_privileged(CAP_MAC_OVERRIDE))
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1892
  		return 0;
531f1d453   Casey Schaufler   Smack: Repair pro...
1893

a6834c0b9   Casey Schaufler   Smack: Verify rea...
1894
1895
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1896
  	rc = smk_access(tsp->smk_task, smk_of_inode(inode), MAY_READ, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1897
  	rc = smk_bu_credfile(cred, file, MAY_READ, rc);
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1898
1899
  
  	return rc;
531f1d453   Casey Schaufler   Smack: Repair pro...
1900
  }
e114e4737   Casey Schaufler   Smack: Simplified...
1901
1902
1903
1904
1905
  /*
   * Task hooks
   */
  
  /**
ee18d64c1   David Howells   KEYS: Add a keyct...
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
   * smack_cred_alloc_blank - "allocate" blank task-level security credentials
   * @new: the new credentials
   * @gfp: the atomicity of any memory allocations
   *
   * Prepare a blank set of credentials for modification.  This must allocate all
   * the memory the LSM module might require such that cred_transfer() can
   * complete without error.
   */
  static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
  {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1916
1917
1918
1919
  	struct task_smack *tsp;
  
  	tsp = new_task_smack(NULL, NULL, gfp);
  	if (tsp == NULL)
676dac4b1   Casey Schaufler   This patch adds a...
1920
  		return -ENOMEM;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1921
1922
  
  	cred->security = tsp;
ee18d64c1   David Howells   KEYS: Add a keyct...
1923
1924
1925
1926
1927
  	return 0;
  }
  
  
  /**
f1752eec6   David Howells   CRED: Detach the ...
1928
1929
   * smack_cred_free - "free" task-level security credentials
   * @cred: the credentials in question
e114e4737   Casey Schaufler   Smack: Simplified...
1930
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1931
   */
f1752eec6   David Howells   CRED: Detach the ...
1932
  static void smack_cred_free(struct cred *cred)
e114e4737   Casey Schaufler   Smack: Simplified...
1933
  {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1934
1935
1936
1937
1938
1939
1940
1941
  	struct task_smack *tsp = cred->security;
  	struct smack_rule *rp;
  	struct list_head *l;
  	struct list_head *n;
  
  	if (tsp == NULL)
  		return;
  	cred->security = NULL;
38416e539   Zbigniew Jasinski   Smack: limited ca...
1942
  	smk_destroy_label_list(&tsp->smk_relabel);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1943
1944
1945
1946
1947
1948
  	list_for_each_safe(l, n, &tsp->smk_rules) {
  		rp = list_entry(l, struct smack_rule, list);
  		list_del(&rp->list);
  		kfree(rp);
  	}
  	kfree(tsp);
e114e4737   Casey Schaufler   Smack: Simplified...
1949
1950
1951
  }
  
  /**
d84f4f992   David Howells   CRED: Inaugurate ...
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
   * smack_cred_prepare - prepare new set of credentials for modification
   * @new: the new credentials
   * @old: the original credentials
   * @gfp: the atomicity of any memory allocations
   *
   * Prepare a new set of credentials for modification.
   */
  static int smack_cred_prepare(struct cred *new, const struct cred *old,
  			      gfp_t gfp)
  {
676dac4b1   Casey Schaufler   This patch adds a...
1962
1963
  	struct task_smack *old_tsp = old->security;
  	struct task_smack *new_tsp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1964
  	int rc;
676dac4b1   Casey Schaufler   This patch adds a...
1965

7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1966
  	new_tsp = new_task_smack(old_tsp->smk_task, old_tsp->smk_task, gfp);
676dac4b1   Casey Schaufler   This patch adds a...
1967
1968
  	if (new_tsp == NULL)
  		return -ENOMEM;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1969
1970
1971
  	rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
  	if (rc != 0)
  		return rc;
38416e539   Zbigniew Jasinski   Smack: limited ca...
1972
1973
1974
1975
  	rc = smk_copy_relabel(&new_tsp->smk_relabel, &old_tsp->smk_relabel,
  				gfp);
  	if (rc != 0)
  		return rc;
676dac4b1   Casey Schaufler   This patch adds a...
1976
  	new->security = new_tsp;
d84f4f992   David Howells   CRED: Inaugurate ...
1977
1978
  	return 0;
  }
251a2a958   Randy Dunlap   smack: fix lots o...
1979
  /**
ee18d64c1   David Howells   KEYS: Add a keyct...
1980
1981
1982
1983
1984
1985
1986
1987
   * smack_cred_transfer - Transfer the old credentials to the new credentials
   * @new: the new credentials
   * @old: the original credentials
   *
   * Fill in a set of blank credentials from another set of credentials.
   */
  static void smack_cred_transfer(struct cred *new, const struct cred *old)
  {
676dac4b1   Casey Schaufler   This patch adds a...
1988
1989
1990
1991
1992
  	struct task_smack *old_tsp = old->security;
  	struct task_smack *new_tsp = new->security;
  
  	new_tsp->smk_task = old_tsp->smk_task;
  	new_tsp->smk_forked = old_tsp->smk_task;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1993
1994
1995
1996
1997
  	mutex_init(&new_tsp->smk_rules_lock);
  	INIT_LIST_HEAD(&new_tsp->smk_rules);
  
  
  	/* cbs copy rule list */
ee18d64c1   David Howells   KEYS: Add a keyct...
1998
1999
2000
  }
  
  /**
3a3b7ce93   David Howells   CRED: Allow kerne...
2001
   * smack_kernel_act_as - Set the subjective context in a set of credentials
251a2a958   Randy Dunlap   smack: fix lots o...
2002
2003
   * @new: points to the set of credentials to be modified.
   * @secid: specifies the security ID to be set
3a3b7ce93   David Howells   CRED: Allow kerne...
2004
2005
2006
2007
2008
   *
   * Set the security data for a kernel service.
   */
  static int smack_kernel_act_as(struct cred *new, u32 secid)
  {
676dac4b1   Casey Schaufler   This patch adds a...
2009
  	struct task_smack *new_tsp = new->security;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2010
  	struct smack_known *skp = smack_from_secid(secid);
3a3b7ce93   David Howells   CRED: Allow kerne...
2011

2f823ff8b   Casey Schaufler   Smack: Improve ac...
2012
  	if (skp == NULL)
3a3b7ce93   David Howells   CRED: Allow kerne...
2013
  		return -EINVAL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2014
  	new_tsp->smk_task = skp;
3a3b7ce93   David Howells   CRED: Allow kerne...
2015
2016
2017
2018
2019
  	return 0;
  }
  
  /**
   * smack_kernel_create_files_as - Set the file creation label in a set of creds
251a2a958   Randy Dunlap   smack: fix lots o...
2020
2021
   * @new: points to the set of credentials to be modified
   * @inode: points to the inode to use as a reference
3a3b7ce93   David Howells   CRED: Allow kerne...
2022
2023
2024
2025
2026
2027
2028
2029
   *
   * Set the file creation context in a set of credentials to the same
   * as the objective context of the specified inode
   */
  static int smack_kernel_create_files_as(struct cred *new,
  					struct inode *inode)
  {
  	struct inode_smack *isp = inode->i_security;
676dac4b1   Casey Schaufler   This patch adds a...
2030
  	struct task_smack *tsp = new->security;
3a3b7ce93   David Howells   CRED: Allow kerne...
2031

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2032
  	tsp->smk_forked = isp->smk_inode;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2033
  	tsp->smk_task = tsp->smk_forked;
3a3b7ce93   David Howells   CRED: Allow kerne...
2034
2035
2036
2037
  	return 0;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
2038
2039
   * smk_curacc_on_task - helper to log task related access
   * @p: the task object
531f1d453   Casey Schaufler   Smack: Repair pro...
2040
2041
   * @access: the access requested
   * @caller: name of the calling function for audit
ecfcc53fe   Etienne Basset   smack: implement ...
2042
2043
2044
   *
   * Return 0 if access is permitted
   */
531f1d453   Casey Schaufler   Smack: Repair pro...
2045
2046
  static int smk_curacc_on_task(struct task_struct *p, int access,
  				const char *caller)
ecfcc53fe   Etienne Basset   smack: implement ...
2047
2048
  {
  	struct smk_audit_info ad;
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2049
  	struct smack_known *skp = smk_of_task_struct(p);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2050
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2051

531f1d453   Casey Schaufler   Smack: Repair pro...
2052
  	smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
ecfcc53fe   Etienne Basset   smack: implement ...
2053
  	smk_ad_setfield_u_tsk(&ad, p);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2054
  	rc = smk_curacc(skp, access, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2055
2056
  	rc = smk_bu_task(p, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2057
2058
2059
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2060
2061
2062
2063
2064
2065
2066
2067
   * smack_task_setpgid - Smack check on setting pgid
   * @p: the task object
   * @pgid: unused
   *
   * Return 0 if write access is permitted
   */
  static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
2068
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
  }
  
  /**
   * smack_task_getpgid - Smack access check for getpgid
   * @p: the object task
   *
   * Returns 0 if current can read the object task, error code otherwise
   */
  static int smack_task_getpgid(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
2079
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
  }
  
  /**
   * smack_task_getsid - Smack access check for getsid
   * @p: the object task
   *
   * Returns 0 if current can read the object task, error code otherwise
   */
  static int smack_task_getsid(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
2090
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
  }
  
  /**
   * smack_task_getsecid - get the secid of the task
   * @p: the object task
   * @secid: where to put the result
   *
   * Sets the secid to contain a u32 version of the smack label.
   */
  static void smack_task_getsecid(struct task_struct *p, u32 *secid)
  {
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2102
  	struct smack_known *skp = smk_of_task_struct(p);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2103
2104
  
  	*secid = skp->smk_secid;
e114e4737   Casey Schaufler   Smack: Simplified...
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
  }
  
  /**
   * smack_task_setnice - Smack check on setting nice
   * @p: the task object
   * @nice: unused
   *
   * Return 0 if write access is permitted
   */
  static int smack_task_setnice(struct task_struct *p, int nice)
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
2116
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
  }
  
  /**
   * smack_task_setioprio - Smack check on setting ioprio
   * @p: the task object
   * @ioprio: unused
   *
   * Return 0 if write access is permitted
   */
  static int smack_task_setioprio(struct task_struct *p, int ioprio)
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
2128
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
  }
  
  /**
   * smack_task_getioprio - Smack check on reading ioprio
   * @p: the task object
   *
   * Return 0 if read access is permitted
   */
  static int smack_task_getioprio(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
2139
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
  }
  
  /**
   * smack_task_setscheduler - Smack check on setting scheduler
   * @p: the task object
   * @policy: unused
   * @lp: unused
   *
   * Return 0 if read access is permitted
   */
b0ae19811   KOSAKI Motohiro   security: remove ...
2150
  static int smack_task_setscheduler(struct task_struct *p)
e114e4737   Casey Schaufler   Smack: Simplified...
2151
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
2152
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
  }
  
  /**
   * smack_task_getscheduler - Smack check on reading scheduler
   * @p: the task object
   *
   * Return 0 if read access is permitted
   */
  static int smack_task_getscheduler(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
2163
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
  }
  
  /**
   * smack_task_movememory - Smack check on moving memory
   * @p: the task object
   *
   * Return 0 if write access is permitted
   */
  static int smack_task_movememory(struct task_struct *p)
  {
531f1d453   Casey Schaufler   Smack: Repair pro...
2174
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
  }
  
  /**
   * smack_task_kill - Smack check on signal delivery
   * @p: the task object
   * @info: unused
   * @sig: unused
   * @secid: identifies the smack to use in lieu of current's
   *
   * Return 0 if write access is permitted
   *
   * The secid behavior is an artifact of an SELinux hack
   * in the USB code. Someday it may go away.
   */
  static int smack_task_kill(struct task_struct *p, struct siginfo *info,
  			   int sig, u32 secid)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
2192
  	struct smk_audit_info ad;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2193
  	struct smack_known *skp;
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2194
  	struct smack_known *tkp = smk_of_task_struct(p);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2195
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2196

18d872f77   Rafal Krypa   Smack: ignore nul...
2197
2198
  	if (!sig)
  		return 0; /* null signal; existence test */
ecfcc53fe   Etienne Basset   smack: implement ...
2199
2200
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, p);
e114e4737   Casey Schaufler   Smack: Simplified...
2201
  	/*
e114e4737   Casey Schaufler   Smack: Simplified...
2202
2203
2204
  	 * Sending a signal requires that the sender
  	 * can write the receiver.
  	 */
d166c8024   Casey Schaufler   Smack: Bring-up a...
2205
  	if (secid == 0) {
c60b90667   Casey Schaufler   Smack: Signal del...
2206
2207
  		rc = smk_curacc(tkp, MAY_DELIVER, &ad);
  		rc = smk_bu_task(p, MAY_DELIVER, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2208
2209
  		return rc;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
2210
2211
2212
2213
2214
  	/*
  	 * If the secid isn't 0 we're dealing with some USB IO
  	 * specific behavior. This is not clean. For one thing
  	 * we can't take privilege into account.
  	 */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2215
  	skp = smack_from_secid(secid);
c60b90667   Casey Schaufler   Smack: Signal del...
2216
2217
  	rc = smk_access(skp, tkp, MAY_DELIVER, &ad);
  	rc = smk_bu_note("USB signal", skp, tkp, MAY_DELIVER, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2218
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2219
2220
2221
2222
2223
2224
  }
  
  /**
   * smack_task_wait - Smack access check for waiting
   * @p: task to wait for
   *
c00bedb36   Casey Schaufler   Smack: remove tas...
2225
   * Returns 0
e114e4737   Casey Schaufler   Smack: Simplified...
2226
2227
2228
   */
  static int smack_task_wait(struct task_struct *p)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2229
  	/*
c00bedb36   Casey Schaufler   Smack: remove tas...
2230
2231
2232
2233
2234
2235
  	 * Allow the operation to succeed.
  	 * Zombies are bad.
  	 * In userless environments (e.g. phones) programs
  	 * get marked with SMACK64EXEC and even if the parent
  	 * and child shouldn't be talking the parent still
  	 * may expect to know when the child exits.
e114e4737   Casey Schaufler   Smack: Simplified...
2236
  	 */
c00bedb36   Casey Schaufler   Smack: remove tas...
2237
  	return 0;
e114e4737   Casey Schaufler   Smack: Simplified...
2238
2239
2240
2241
2242
  }
  
  /**
   * smack_task_to_inode - copy task smack into the inode blob
   * @p: task to copy from
251a2a958   Randy Dunlap   smack: fix lots o...
2243
   * @inode: inode to copy to
e114e4737   Casey Schaufler   Smack: Simplified...
2244
2245
2246
2247
2248
2249
   *
   * Sets the smack pointer in the inode security blob
   */
  static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
  {
  	struct inode_smack *isp = inode->i_security;
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2250
  	struct smack_known *skp = smk_of_task_struct(p);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2251

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2252
  	isp->smk_inode = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
  }
  
  /*
   * Socket hooks.
   */
  
  /**
   * smack_sk_alloc_security - Allocate a socket blob
   * @sk: the socket
   * @family: unused
251a2a958   Randy Dunlap   smack: fix lots o...
2263
   * @gfp_flags: memory allocation flags
e114e4737   Casey Schaufler   Smack: Simplified...
2264
2265
2266
2267
2268
2269
2270
   *
   * Assign Smack pointers to current
   *
   * Returns 0 on success, -ENOMEM is there's no memory
   */
  static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2271
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2272
2273
2274
2275
2276
  	struct socket_smack *ssp;
  
  	ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
  	if (ssp == NULL)
  		return -ENOMEM;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
2277
  	ssp->smk_in = skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2278
  	ssp->smk_out = skp;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2279
  	ssp->smk_packet = NULL;
e114e4737   Casey Schaufler   Smack: Simplified...
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
  
  	sk->sk_security = ssp;
  
  	return 0;
  }
  
  /**
   * smack_sk_free_security - Free a socket blob
   * @sk: the socket
   *
   * Clears the blob pointer
   */
  static void smack_sk_free_security(struct sock *sk)
  {
  	kfree(sk->sk_security);
  }
  
  /**
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2298
  * smack_ipv4host_label - check host based restrictions
07feee8f8   Paul Moore   netlabel: Cleanup...
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
  * @sip: the object end
  *
  * looks for host based access restrictions
  *
  * This version will only be appropriate for really small sets of single label
  * hosts.  The caller is responsible for ensuring that the RCU read lock is
  * taken before calling this function.
  *
  * Returns the label of the far end or NULL if it's not special.
  */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2309
  static struct smack_known *smack_ipv4host_label(struct sockaddr_in *sip)
07feee8f8   Paul Moore   netlabel: Cleanup...
2310
  {
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2311
  	struct smk_net4addr *snp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2312
2313
2314
2315
  	struct in_addr *siap = &sip->sin_addr;
  
  	if (siap->s_addr == 0)
  		return NULL;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
  	list_for_each_entry_rcu(snp, &smk_net4addr_list, list)
  		/*
  		 * we break after finding the first match because
  		 * the list is sorted from longest to shortest mask
  		 * so we have found the most specific match
  		 */
  		if (snp->smk_host.s_addr ==
  		    (siap->s_addr & snp->smk_mask.s_addr))
  			return snp->smk_label;
  
  	return NULL;
  }
  
  #if IS_ENABLED(CONFIG_IPV6)
  /*
   * smk_ipv6_localhost - Check for local ipv6 host address
   * @sip: the address
   *
   * Returns boolean true if this is the localhost address
   */
  static bool smk_ipv6_localhost(struct sockaddr_in6 *sip)
  {
  	__be16 *be16p = (__be16 *)&sip->sin6_addr;
  	__be32 *be32p = (__be32 *)&sip->sin6_addr;
  
  	if (be32p[0] == 0 && be32p[1] == 0 && be32p[2] == 0 && be16p[6] == 0 &&
  	    ntohs(be16p[7]) == 1)
  		return true;
  	return false;
  }
  
  /**
  * smack_ipv6host_label - check host based restrictions
  * @sip: the object end
  *
  * looks for host based access restrictions
  *
  * This version will only be appropriate for really small sets of single label
  * hosts.  The caller is responsible for ensuring that the RCU read lock is
  * taken before calling this function.
  *
  * Returns the label of the far end or NULL if it's not special.
  */
  static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip)
  {
  	struct smk_net6addr *snp;
  	struct in6_addr *sap = &sip->sin6_addr;
  	int i;
  	int found = 0;
  
  	/*
  	 * It's local. Don't look for a host label.
  	 */
  	if (smk_ipv6_localhost(sip))
  		return NULL;
  
  	list_for_each_entry_rcu(snp, &smk_net6addr_list, list) {
07feee8f8   Paul Moore   netlabel: Cleanup...
2373
2374
2375
2376
2377
  		/*
  		* we break after finding the first match because
  		* the list is sorted from longest to shortest mask
  		* so we have found the most specific match
  		*/
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
  		for (found = 1, i = 0; i < 8; i++) {
  			/*
  			 * If the label is NULL the entry has
  			 * been renounced. Ignore it.
  			 */
  			if (snp->smk_label == NULL)
  				continue;
  			if ((sap->s6_addr16[i] & snp->smk_mask.s6_addr16[i]) !=
  			    snp->smk_host.s6_addr16[i]) {
  				found = 0;
  				break;
  			}
4303154e8   Etienne Basset   smack: Add a new ...
2390
  		}
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2391
2392
2393
  		if (found)
  			return snp->smk_label;
  	}
07feee8f8   Paul Moore   netlabel: Cleanup...
2394
2395
2396
  
  	return NULL;
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2397
  #endif /* CONFIG_IPV6 */
07feee8f8   Paul Moore   netlabel: Cleanup...
2398
2399
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2400
2401
   * smack_netlabel - Set the secattr on a socket
   * @sk: the socket
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2402
   * @labeled: socket label scheme
e114e4737   Casey Schaufler   Smack: Simplified...
2403
2404
2405
2406
2407
2408
   *
   * Convert the outbound smack value (smk_out) to a
   * secattr and attach it to the socket.
   *
   * Returns 0 on success or an error code
   */
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2409
  static int smack_netlabel(struct sock *sk, int labeled)
e114e4737   Casey Schaufler   Smack: Simplified...
2410
  {
f7112e6c9   Casey Schaufler   Smack: allow for ...
2411
  	struct smack_known *skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2412
  	struct socket_smack *ssp = sk->sk_security;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2413
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
2414

6d3dc07cb   Casey Schaufler   smack: Add suppor...
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
  	/*
  	 * Usually the netlabel code will handle changing the
  	 * packet labeling based on the label.
  	 * The case of a single label host is different, because
  	 * a single label host should never get a labeled packet
  	 * even though the label is usually associated with a packet
  	 * label.
  	 */
  	local_bh_disable();
  	bh_lock_sock_nested(sk);
  
  	if (ssp->smk_out == smack_net_ambient ||
  	    labeled == SMACK_UNLABELED_SOCKET)
  		netlbl_sock_delattr(sk);
  	else {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2430
  		skp = ssp->smk_out;
f7112e6c9   Casey Schaufler   Smack: allow for ...
2431
  		rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2432
2433
2434
2435
  	}
  
  	bh_unlock_sock(sk);
  	local_bh_enable();
4bc87e627   Casey Schaufler   Smack: unlabeled ...
2436

e114e4737   Casey Schaufler   Smack: Simplified...
2437
2438
2439
2440
  	return rc;
  }
  
  /**
07feee8f8   Paul Moore   netlabel: Cleanup...
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
   * smack_netlbel_send - Set the secattr on a socket and perform access checks
   * @sk: the socket
   * @sap: the destination address
   *
   * Set the correct secattr for the given socket based on the destination
   * address and perform any outbound access checks needed.
   *
   * Returns 0 on success or an error code.
   *
   */
  static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2453
  	struct smack_known *skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2454
2455
  	int rc;
  	int sk_lbl;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2456
  	struct smack_known *hkp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2457
  	struct socket_smack *ssp = sk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
2458
  	struct smk_audit_info ad;
07feee8f8   Paul Moore   netlabel: Cleanup...
2459
2460
  
  	rcu_read_lock();
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2461
  	hkp = smack_ipv4host_label(sap);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2462
  	if (hkp != NULL) {
ecfcc53fe   Etienne Basset   smack: implement ...
2463
  #ifdef CONFIG_AUDIT
923e9a139   Kees Cook   Smack: build when...
2464
  		struct lsm_network_audit net;
48c62af68   Eric Paris   LSM: shrink the c...
2465
2466
2467
2468
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
  		ad.a.u.net->family = sap->sin_family;
  		ad.a.u.net->dport = sap->sin_port;
  		ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
ecfcc53fe   Etienne Basset   smack: implement ...
2469
  #endif
923e9a139   Kees Cook   Smack: build when...
2470
  		sk_lbl = SMACK_UNLABELED_SOCKET;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2471
  		skp = ssp->smk_out;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2472
2473
  		rc = smk_access(skp, hkp, MAY_WRITE, &ad);
  		rc = smk_bu_note("IPv4 host check", skp, hkp, MAY_WRITE, rc);
07feee8f8   Paul Moore   netlabel: Cleanup...
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
  	} else {
  		sk_lbl = SMACK_CIPSO_SOCKET;
  		rc = 0;
  	}
  	rcu_read_unlock();
  	if (rc != 0)
  		return rc;
  
  	return smack_netlabel(sk, sk_lbl);
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
  #if IS_ENABLED(CONFIG_IPV6)
  /**
   * smk_ipv6_check - check Smack access
   * @subject: subject Smack label
   * @object: object Smack label
   * @address: address
   * @act: the action being taken
   *
   * Check an IPv6 access
   */
  static int smk_ipv6_check(struct smack_known *subject,
  				struct smack_known *object,
  				struct sockaddr_in6 *address, int act)
  {
  #ifdef CONFIG_AUDIT
  	struct lsm_network_audit net;
  #endif
  	struct smk_audit_info ad;
  	int rc;
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
  	ad.a.u.net->family = PF_INET6;
  	ad.a.u.net->dport = ntohs(address->sin6_port);
  	if (act == SMK_RECEIVING)
  		ad.a.u.net->v6info.saddr = address->sin6_addr;
  	else
  		ad.a.u.net->v6info.daddr = address->sin6_addr;
  #endif
  	rc = smk_access(subject, object, MAY_WRITE, &ad);
  	rc = smk_bu_note("IPv6 check", subject, object, MAY_WRITE, rc);
  	return rc;
  }
  #endif /* CONFIG_IPV6 */
  
  #ifdef SMACK_IPV6_PORT_LABELING
07feee8f8   Paul Moore   netlabel: Cleanup...
2520
  /**
c67394434   Casey Schaufler   Smack: Local IPv6...
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
   * smk_ipv6_port_label - Smack port access table management
   * @sock: socket
   * @address: address
   *
   * Create or update the port list entry
   */
  static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
  {
  	struct sock *sk = sock->sk;
  	struct sockaddr_in6 *addr6;
  	struct socket_smack *ssp = sock->sk->sk_security;
  	struct smk_port_label *spp;
  	unsigned short port = 0;
  
  	if (address == NULL) {
  		/*
  		 * This operation is changing the Smack information
  		 * on the bound socket. Take the changes to the port
  		 * as well.
  		 */
  		list_for_each_entry(spp, &smk_ipv6_port_list, list) {
  			if (sk != spp->smk_sock)
  				continue;
  			spp->smk_in = ssp->smk_in;
  			spp->smk_out = ssp->smk_out;
  			return;
  		}
  		/*
  		 * A NULL address is only used for updating existing
  		 * bound entries. If there isn't one, it's OK.
  		 */
  		return;
  	}
  
  	addr6 = (struct sockaddr_in6 *)address;
  	port = ntohs(addr6->sin6_port);
  	/*
  	 * This is a special case that is safely ignored.
  	 */
  	if (port == 0)
  		return;
  
  	/*
  	 * Look for an existing port list entry.
  	 * This is an indication that a port is getting reused.
  	 */
  	list_for_each_entry(spp, &smk_ipv6_port_list, list) {
  		if (spp->smk_port != port)
  			continue;
  		spp->smk_port = port;
  		spp->smk_sock = sk;
  		spp->smk_in = ssp->smk_in;
  		spp->smk_out = ssp->smk_out;
  		return;
  	}
  
  	/*
  	 * A new port entry is required.
  	 */
  	spp = kzalloc(sizeof(*spp), GFP_KERNEL);
  	if (spp == NULL)
  		return;
  
  	spp->smk_port = port;
  	spp->smk_sock = sk;
  	spp->smk_in = ssp->smk_in;
  	spp->smk_out = ssp->smk_out;
  
  	list_add(&spp->list, &smk_ipv6_port_list);
  	return;
  }
  
  /**
   * smk_ipv6_port_check - check Smack port access
   * @sock: socket
   * @address: address
   *
   * Create or update the port list entry
   */
6ea062475   Casey Schaufler   Smack: IPv6 casti...
2600
  static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
c67394434   Casey Schaufler   Smack: Local IPv6...
2601
2602
  				int act)
  {
c67394434   Casey Schaufler   Smack: Local IPv6...
2603
2604
  	struct smk_port_label *spp;
  	struct socket_smack *ssp = sk->sk_security;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2605
2606
  	struct smack_known *skp = NULL;
  	unsigned short port;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2607
  	struct smack_known *object;
c67394434   Casey Schaufler   Smack: Local IPv6...
2608
2609
  
  	if (act == SMK_RECEIVING) {
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2610
  		skp = smack_ipv6host_label(address);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2611
  		object = ssp->smk_in;
c67394434   Casey Schaufler   Smack: Local IPv6...
2612
  	} else {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2613
  		skp = ssp->smk_out;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2614
  		object = smack_ipv6host_label(address);
c67394434   Casey Schaufler   Smack: Local IPv6...
2615
2616
2617
  	}
  
  	/*
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2618
  	 * The other end is a single label host.
c67394434   Casey Schaufler   Smack: Local IPv6...
2619
  	 */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2620
2621
2622
2623
2624
2625
  	if (skp != NULL && object != NULL)
  		return smk_ipv6_check(skp, object, address, act);
  	if (skp == NULL)
  		skp = smack_net_ambient;
  	if (object == NULL)
  		object = smack_net_ambient;
c67394434   Casey Schaufler   Smack: Local IPv6...
2626
2627
2628
2629
  
  	/*
  	 * It's remote, so port lookup does no good.
  	 */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2630
2631
  	if (!smk_ipv6_localhost(address))
  		return smk_ipv6_check(skp, object, address, act);
c67394434   Casey Schaufler   Smack: Local IPv6...
2632
2633
2634
2635
  
  	/*
  	 * It's local so the send check has to have passed.
  	 */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2636
2637
  	if (act == SMK_RECEIVING)
  		return 0;
c67394434   Casey Schaufler   Smack: Local IPv6...
2638

21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2639
  	port = ntohs(address->sin6_port);
c67394434   Casey Schaufler   Smack: Local IPv6...
2640
2641
2642
  	list_for_each_entry(spp, &smk_ipv6_port_list, list) {
  		if (spp->smk_port != port)
  			continue;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2643
  		object = spp->smk_in;
c67394434   Casey Schaufler   Smack: Local IPv6...
2644
  		if (act == SMK_CONNECTING)
54e70ec5e   Casey Schaufler   Smack: bidirectio...
2645
  			ssp->smk_packet = spp->smk_out;
c67394434   Casey Schaufler   Smack: Local IPv6...
2646
2647
  		break;
  	}
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2648
  	return smk_ipv6_check(skp, object, address, act);
c67394434   Casey Schaufler   Smack: Local IPv6...
2649
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2650
  #endif /* SMACK_IPV6_PORT_LABELING */
c67394434   Casey Schaufler   Smack: Local IPv6...
2651
2652
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
   * smack_inode_setsecurity - set smack xattrs
   * @inode: the object
   * @name: attribute name
   * @value: attribute value
   * @size: size of the attribute
   * @flags: unused
   *
   * Sets the named attribute in the appropriate blob
   *
   * Returns 0 on success, or an error code
   */
  static int smack_inode_setsecurity(struct inode *inode, const char *name,
  				   const void *value, size_t size, int flags)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2667
  	struct smack_known *skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2668
2669
2670
  	struct inode_smack *nsp = inode->i_security;
  	struct socket_smack *ssp;
  	struct socket *sock;
4bc87e627   Casey Schaufler   Smack: unlabeled ...
2671
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
2672

f7112e6c9   Casey Schaufler   Smack: allow for ...
2673
  	if (value == NULL || size > SMK_LONGLABEL || size == 0)
5e9ab593c   Pankaj Kumar   bugfix patch for ...
2674
  		return -EINVAL;
e114e4737   Casey Schaufler   Smack: Simplified...
2675

2f823ff8b   Casey Schaufler   Smack: Improve ac...
2676
  	skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
2677
2678
  	if (IS_ERR(skp))
  		return PTR_ERR(skp);
e114e4737   Casey Schaufler   Smack: Simplified...
2679
2680
  
  	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2681
  		nsp->smk_inode = skp;
ddd29ec65   David P. Quigley   sysfs: Add labeli...
2682
  		nsp->smk_flags |= SMK_INODE_INSTANT;
e114e4737   Casey Schaufler   Smack: Simplified...
2683
2684
2685
2686
2687
2688
2689
2690
2691
  		return 0;
  	}
  	/*
  	 * The rest of the Smack xattrs are only on sockets.
  	 */
  	if (inode->i_sb->s_magic != SOCKFS_MAGIC)
  		return -EOPNOTSUPP;
  
  	sock = SOCKET_I(inode);
2e1d146a1   Ahmed S. Darwish   Smack: check for ...
2692
  	if (sock == NULL || sock->sk == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
2693
2694
2695
2696
2697
  		return -EOPNOTSUPP;
  
  	ssp = sock->sk->sk_security;
  
  	if (strcmp(name, XATTR_SMACK_IPIN) == 0)
54e70ec5e   Casey Schaufler   Smack: bidirectio...
2698
  		ssp->smk_in = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2699
  	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2700
  		ssp->smk_out = skp;
c67394434   Casey Schaufler   Smack: Local IPv6...
2701
  		if (sock->sk->sk_family == PF_INET) {
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2702
2703
2704
2705
2706
2707
2708
  			rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
  			if (rc != 0)
  				printk(KERN_WARNING
  					"Smack: \"%s\" netlbl error %d.
  ",
  					__func__, -rc);
  		}
e114e4737   Casey Schaufler   Smack: Simplified...
2709
2710
  	} else
  		return -EOPNOTSUPP;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2711
  #ifdef SMACK_IPV6_PORT_LABELING
c67394434   Casey Schaufler   Smack: Local IPv6...
2712
2713
  	if (sock->sk->sk_family == PF_INET6)
  		smk_ipv6_port_label(sock, NULL);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2714
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
2715

e114e4737   Casey Schaufler   Smack: Simplified...
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
  	return 0;
  }
  
  /**
   * smack_socket_post_create - finish socket setup
   * @sock: the socket
   * @family: protocol family
   * @type: unused
   * @protocol: unused
   * @kern: unused
   *
   * Sets the netlabel information on the socket
   *
   * Returns 0 on success, and error code otherwise
   */
  static int smack_socket_post_create(struct socket *sock, int family,
  				    int type, int protocol, int kern)
  {
7412301b7   Marcin Lis   Smack: Assign sma...
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
  	struct socket_smack *ssp;
  
  	if (sock->sk == NULL)
  		return 0;
  
  	/*
  	 * Sockets created by kernel threads receive web label.
  	 */
  	if (unlikely(current->flags & PF_KTHREAD)) {
  		ssp = sock->sk->sk_security;
  		ssp->smk_in = &smack_known_web;
  		ssp->smk_out = &smack_known_web;
  	}
  
  	if (family != PF_INET)
e114e4737   Casey Schaufler   Smack: Simplified...
2749
2750
2751
2752
  		return 0;
  	/*
  	 * Set the outbound netlbl.
  	 */
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2753
2754
  	return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2755
  #ifdef SMACK_IPV6_PORT_LABELING
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2756
  /**
c67394434   Casey Schaufler   Smack: Local IPv6...
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
   * smack_socket_bind - record port binding information.
   * @sock: the socket
   * @address: the port address
   * @addrlen: size of the address
   *
   * Records the label bound to a port.
   *
   * Returns 0
   */
  static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
  				int addrlen)
  {
  	if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
  		smk_ipv6_port_label(sock, address);
c67394434   Casey Schaufler   Smack: Local IPv6...
2771
2772
  	return 0;
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2773
  #endif /* SMACK_IPV6_PORT_LABELING */
c67394434   Casey Schaufler   Smack: Local IPv6...
2774
2775
  
  /**
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
   * smack_socket_connect - connect access check
   * @sock: the socket
   * @sap: the other end
   * @addrlen: size of sap
   *
   * Verifies that a connection may be possible
   *
   * Returns 0 on success, and error code otherwise
   */
  static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
  				int addrlen)
  {
c67394434   Casey Schaufler   Smack: Local IPv6...
2788
  	int rc = 0;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2789
2790
2791
2792
2793
2794
2795
  #if IS_ENABLED(CONFIG_IPV6)
  	struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
  #endif
  #ifdef SMACK_IPV6_SECMARK_LABELING
  	struct smack_known *rsp;
  	struct socket_smack *ssp = sock->sk->sk_security;
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
2796
2797
  
  	if (sock->sk == NULL)
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2798
  		return 0;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2799

c67394434   Casey Schaufler   Smack: Local IPv6...
2800
2801
2802
2803
2804
2805
2806
2807
2808
  	switch (sock->sk->sk_family) {
  	case PF_INET:
  		if (addrlen < sizeof(struct sockaddr_in))
  			return -EINVAL;
  		rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
  		break;
  	case PF_INET6:
  		if (addrlen < sizeof(struct sockaddr_in6))
  			return -EINVAL;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2809
2810
2811
2812
  #ifdef SMACK_IPV6_SECMARK_LABELING
  		rsp = smack_ipv6host_label(sip);
  		if (rsp != NULL)
  			rc = smk_ipv6_check(ssp->smk_out, rsp, sip,
6ea062475   Casey Schaufler   Smack: IPv6 casti...
2813
  						SMK_CONNECTING);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2814
2815
2816
2817
  #endif
  #ifdef SMACK_IPV6_PORT_LABELING
  		rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
2818
2819
2820
  		break;
  	}
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
  }
  
  /**
   * smack_flags_to_may - convert S_ to MAY_ values
   * @flags: the S_ value
   *
   * Returns the equivalent MAY_ value
   */
  static int smack_flags_to_may(int flags)
  {
  	int may = 0;
  
  	if (flags & S_IRUGO)
  		may |= MAY_READ;
  	if (flags & S_IWUGO)
  		may |= MAY_WRITE;
  	if (flags & S_IXUGO)
  		may |= MAY_EXEC;
  
  	return may;
  }
  
  /**
   * smack_msg_msg_alloc_security - Set the security blob for msg_msg
   * @msg: the object
   *
   * Returns 0
   */
  static int smack_msg_msg_alloc_security(struct msg_msg *msg)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2851
  	struct smack_known *skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2852
  	msg->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
  	return 0;
  }
  
  /**
   * smack_msg_msg_free_security - Clear the security blob for msg_msg
   * @msg: the object
   *
   * Clears the blob pointer
   */
  static void smack_msg_msg_free_security(struct msg_msg *msg)
  {
  	msg->security = NULL;
  }
  
  /**
   * smack_of_shm - the smack pointer for the shm
   * @shp: the object
   *
   * Returns a pointer to the smack value
   */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2873
  static struct smack_known *smack_of_shm(struct shmid_kernel *shp)
e114e4737   Casey Schaufler   Smack: Simplified...
2874
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2875
  	return (struct smack_known *)shp->shm_perm.security;
e114e4737   Casey Schaufler   Smack: Simplified...
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
  }
  
  /**
   * smack_shm_alloc_security - Set the security blob for shm
   * @shp: the object
   *
   * Returns 0
   */
  static int smack_shm_alloc_security(struct shmid_kernel *shp)
  {
  	struct kern_ipc_perm *isp = &shp->shm_perm;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2887
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2888

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2889
  	isp->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
  	return 0;
  }
  
  /**
   * smack_shm_free_security - Clear the security blob for shm
   * @shp: the object
   *
   * Clears the blob pointer
   */
  static void smack_shm_free_security(struct shmid_kernel *shp)
  {
  	struct kern_ipc_perm *isp = &shp->shm_perm;
  
  	isp->security = NULL;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
2907
2908
2909
2910
2911
2912
2913
2914
   * smk_curacc_shm : check if current has access on shm
   * @shp : the object
   * @access : access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smk_curacc_shm(struct shmid_kernel *shp, int access)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2915
  	struct smack_known *ssp = smack_of_shm(shp);
ecfcc53fe   Etienne Basset   smack: implement ...
2916
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
2917
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2918
2919
2920
2921
2922
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = shp->shm_perm.id;
  #endif
d166c8024   Casey Schaufler   Smack: Bring-up a...
2923
2924
2925
  	rc = smk_curacc(ssp, access, &ad);
  	rc = smk_bu_current("shm", ssp, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2926
2927
2928
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2929
2930
2931
2932
2933
2934
2935
2936
   * smack_shm_associate - Smack access check for shm
   * @shp: the object
   * @shmflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_shm_associate(struct shmid_kernel *shp, int shmflg)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2937
2938
2939
  	int may;
  
  	may = smack_flags_to_may(shmflg);
ecfcc53fe   Etienne Basset   smack: implement ...
2940
  	return smk_curacc_shm(shp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
  }
  
  /**
   * smack_shm_shmctl - Smack access check for shm
   * @shp: the object
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
  	int may;
  
  	switch (cmd) {
  	case IPC_STAT:
  	case SHM_STAT:
  		may = MAY_READ;
  		break;
  	case IPC_SET:
  	case SHM_LOCK:
  	case SHM_UNLOCK:
  	case IPC_RMID:
  		may = MAY_READWRITE;
  		break;
  	case IPC_INFO:
  	case SHM_INFO:
  		/*
  		 * System level information.
  		 */
  		return 0;
  	default:
  		return -EINVAL;
  	}
ecfcc53fe   Etienne Basset   smack: implement ...
2974
  	return smk_curacc_shm(shp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
  }
  
  /**
   * smack_shm_shmat - Smack access for shmat
   * @shp: the object
   * @shmaddr: unused
   * @shmflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
  			   int shmflg)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2988
2989
2990
  	int may;
  
  	may = smack_flags_to_may(shmflg);
ecfcc53fe   Etienne Basset   smack: implement ...
2991
  	return smk_curacc_shm(shp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2992
2993
2994
2995
2996
2997
2998
2999
  }
  
  /**
   * smack_of_sem - the smack pointer for the sem
   * @sma: the object
   *
   * Returns a pointer to the smack value
   */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3000
  static struct smack_known *smack_of_sem(struct sem_array *sma)
e114e4737   Casey Schaufler   Smack: Simplified...
3001
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3002
  	return (struct smack_known *)sma->sem_perm.security;
e114e4737   Casey Schaufler   Smack: Simplified...
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
  }
  
  /**
   * smack_sem_alloc_security - Set the security blob for sem
   * @sma: the object
   *
   * Returns 0
   */
  static int smack_sem_alloc_security(struct sem_array *sma)
  {
  	struct kern_ipc_perm *isp = &sma->sem_perm;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3014
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
3015

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3016
  	isp->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
  	return 0;
  }
  
  /**
   * smack_sem_free_security - Clear the security blob for sem
   * @sma: the object
   *
   * Clears the blob pointer
   */
  static void smack_sem_free_security(struct sem_array *sma)
  {
  	struct kern_ipc_perm *isp = &sma->sem_perm;
  
  	isp->security = NULL;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
3034
3035
3036
3037
3038
3039
3040
3041
   * smk_curacc_sem : check if current has access on sem
   * @sma : the object
   * @access : access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smk_curacc_sem(struct sem_array *sma, int access)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3042
  	struct smack_known *ssp = smack_of_sem(sma);
ecfcc53fe   Etienne Basset   smack: implement ...
3043
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3044
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3045
3046
3047
3048
3049
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = sma->sem_perm.id;
  #endif
d166c8024   Casey Schaufler   Smack: Bring-up a...
3050
3051
3052
  	rc = smk_curacc(ssp, access, &ad);
  	rc = smk_bu_current("sem", ssp, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3053
3054
3055
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
3056
3057
3058
3059
3060
3061
3062
3063
   * smack_sem_associate - Smack access check for sem
   * @sma: the object
   * @semflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_sem_associate(struct sem_array *sma, int semflg)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
3064
3065
3066
  	int may;
  
  	may = smack_flags_to_may(semflg);
ecfcc53fe   Etienne Basset   smack: implement ...
3067
  	return smk_curacc_sem(sma, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
  }
  
  /**
   * smack_sem_shmctl - Smack access check for sem
   * @sma: the object
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_sem_semctl(struct sem_array *sma, int cmd)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
  	int may;
  
  	switch (cmd) {
  	case GETPID:
  	case GETNCNT:
  	case GETZCNT:
  	case GETVAL:
  	case GETALL:
  	case IPC_STAT:
  	case SEM_STAT:
  		may = MAY_READ;
  		break;
  	case SETVAL:
  	case SETALL:
  	case IPC_RMID:
  	case IPC_SET:
  		may = MAY_READWRITE;
  		break;
  	case IPC_INFO:
  	case SEM_INFO:
  		/*
  		 * System level information
  		 */
  		return 0;
  	default:
  		return -EINVAL;
  	}
ecfcc53fe   Etienne Basset   smack: implement ...
3106
  	return smk_curacc_sem(sma, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
  }
  
  /**
   * smack_sem_semop - Smack checks of semaphore operations
   * @sma: the object
   * @sops: unused
   * @nsops: unused
   * @alter: unused
   *
   * Treated as read and write in all cases.
   *
   * Returns 0 if access is allowed, error code otherwise
   */
  static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops,
  			   unsigned nsops, int alter)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
3123
  	return smk_curacc_sem(sma, MAY_READWRITE);
e114e4737   Casey Schaufler   Smack: Simplified...
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
  }
  
  /**
   * smack_msg_alloc_security - Set the security blob for msg
   * @msq: the object
   *
   * Returns 0
   */
  static int smack_msg_queue_alloc_security(struct msg_queue *msq)
  {
  	struct kern_ipc_perm *kisp = &msq->q_perm;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3135
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
3136

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3137
  	kisp->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
  	return 0;
  }
  
  /**
   * smack_msg_free_security - Clear the security blob for msg
   * @msq: the object
   *
   * Clears the blob pointer
   */
  static void smack_msg_queue_free_security(struct msg_queue *msq)
  {
  	struct kern_ipc_perm *kisp = &msq->q_perm;
  
  	kisp->security = NULL;
  }
  
  /**
   * smack_of_msq - the smack pointer for the msq
   * @msq: the object
   *
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3158
   * Returns a pointer to the smack label entry
e114e4737   Casey Schaufler   Smack: Simplified...
3159
   */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3160
  static struct smack_known *smack_of_msq(struct msg_queue *msq)
e114e4737   Casey Schaufler   Smack: Simplified...
3161
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3162
  	return (struct smack_known *)msq->q_perm.security;
e114e4737   Casey Schaufler   Smack: Simplified...
3163
3164
3165
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
3166
3167
3168
3169
3170
3171
3172
3173
   * smk_curacc_msq : helper to check if current has access on msq
   * @msq : the msq
   * @access : access requested
   *
   * return 0 if current has access, error otherwise
   */
  static int smk_curacc_msq(struct msg_queue *msq, int access)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3174
  	struct smack_known *msp = smack_of_msq(msq);
ecfcc53fe   Etienne Basset   smack: implement ...
3175
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3176
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3177
3178
3179
3180
3181
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = msq->q_perm.id;
  #endif
d166c8024   Casey Schaufler   Smack: Bring-up a...
3182
3183
3184
  	rc = smk_curacc(msp, access, &ad);
  	rc = smk_bu_current("msq", msp, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3185
3186
3187
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
3188
3189
3190
3191
3192
3193
3194
3195
   * smack_msg_queue_associate - Smack access check for msg_queue
   * @msq: the object
   * @msqflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
3196
3197
3198
  	int may;
  
  	may = smack_flags_to_may(msqflg);
ecfcc53fe   Etienne Basset   smack: implement ...
3199
  	return smk_curacc_msq(msq, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
  }
  
  /**
   * smack_msg_queue_msgctl - Smack access check for msg_queue
   * @msq: the object
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
  	int may;
  
  	switch (cmd) {
  	case IPC_STAT:
  	case MSG_STAT:
  		may = MAY_READ;
  		break;
  	case IPC_SET:
  	case IPC_RMID:
  		may = MAY_READWRITE;
  		break;
  	case IPC_INFO:
  	case MSG_INFO:
  		/*
  		 * System level information
  		 */
  		return 0;
  	default:
  		return -EINVAL;
  	}
ecfcc53fe   Etienne Basset   smack: implement ...
3231
  	return smk_curacc_msq(msq, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
  }
  
  /**
   * smack_msg_queue_msgsnd - Smack access check for msg_queue
   * @msq: the object
   * @msg: unused
   * @msqflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
  static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
  				  int msqflg)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
3245
  	int may;
e114e4737   Casey Schaufler   Smack: Simplified...
3246

ecfcc53fe   Etienne Basset   smack: implement ...
3247
3248
  	may = smack_flags_to_may(msqflg);
  	return smk_curacc_msq(msq, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
  }
  
  /**
   * smack_msg_queue_msgsnd - Smack access check for msg_queue
   * @msq: the object
   * @msg: unused
   * @target: unused
   * @type: unused
   * @mode: unused
   *
   * Returns 0 if current has read and write access, error code otherwise
   */
  static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
  			struct task_struct *target, long type, int mode)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
3264
  	return smk_curacc_msq(msq, MAY_READWRITE);
e114e4737   Casey Schaufler   Smack: Simplified...
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
  }
  
  /**
   * smack_ipc_permission - Smack access for ipc_permission()
   * @ipp: the object permissions
   * @flag: access requested
   *
   * Returns 0 if current has read and write access, error code otherwise
   */
  static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3276
  	struct smack_known *iskp = ipp->security;
ecfcc53fe   Etienne Basset   smack: implement ...
3277
3278
  	int may = smack_flags_to_may(flag);
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3279
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3280

ecfcc53fe   Etienne Basset   smack: implement ...
3281
3282
3283
3284
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
  	ad.a.u.ipc_id = ipp->id;
  #endif
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3285
3286
  	rc = smk_curacc(iskp, may, &ad);
  	rc = smk_bu_current("svipc", iskp, may, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
3287
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3288
  }
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3289
3290
  /**
   * smack_ipc_getsecid - Extract smack security id
251a2a958   Randy Dunlap   smack: fix lots o...
3291
   * @ipp: the object permissions
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3292
3293
3294
3295
   * @secid: where result will be saved
   */
  static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3296
  	struct smack_known *iskp = ipp->security;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3297

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3298
  	*secid = iskp->smk_secid;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3299
  }
e114e4737   Casey Schaufler   Smack: Simplified...
3300
3301
  /**
   * smack_d_instantiate - Make sure the blob is correct on an inode
3e62cbb84   Dan Carpenter   smack: opt_dentry...
3302
   * @opt_dentry: dentry where inode will be attached
e114e4737   Casey Schaufler   Smack: Simplified...
3303
3304
3305
3306
3307
3308
3309
3310
3311
   * @inode: the object
   *
   * Set the inode's security blob if it hasn't been done already.
   */
  static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
  {
  	struct super_block *sbp;
  	struct superblock_smack *sbsp;
  	struct inode_smack *isp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3312
3313
  	struct smack_known *skp;
  	struct smack_known *ckp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3314
  	struct smack_known *final;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3315
3316
  	char trattr[TRANS_TRUE_SIZE];
  	int transflag = 0;
2267b13a7   Casey Schaufler   Smack: recursive ...
3317
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
  	struct dentry *dp;
  
  	if (inode == NULL)
  		return;
  
  	isp = inode->i_security;
  
  	mutex_lock(&isp->smk_lock);
  	/*
  	 * If the inode is already instantiated
  	 * take the quick way out
  	 */
  	if (isp->smk_flags & SMK_INODE_INSTANT)
  		goto unlockandout;
  
  	sbp = inode->i_sb;
  	sbsp = sbp->s_security;
  	/*
  	 * We're going to use the superblock default label
  	 * if there's no label on the file.
  	 */
  	final = sbsp->smk_default;
  
  	/*
e97dcb0ea   Casey Schaufler   Smack: fuse mount...
3342
3343
3344
3345
3346
3347
  	 * If this is the root inode the superblock
  	 * may be in the process of initialization.
  	 * If that is the case use the root value out
  	 * of the superblock.
  	 */
  	if (opt_dentry->d_parent == opt_dentry) {
1d8c2326a   Łukasz Stelmach   smack: introduce ...
3348
3349
  		switch (sbp->s_magic) {
  		case CGROUP_SUPER_MAGIC:
36ea735b5   Casey Schaufler   Smack: Label cgro...
3350
3351
3352
3353
3354
  			/*
  			 * The cgroup filesystem is never mounted,
  			 * so there's no opportunity to set the mount
  			 * options.
  			 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3355
3356
  			sbsp->smk_root = &smack_known_star;
  			sbsp->smk_default = &smack_known_star;
1d8c2326a   Łukasz Stelmach   smack: introduce ...
3357
3358
3359
3360
3361
3362
3363
3364
3365
  			isp->smk_inode = sbsp->smk_root;
  			break;
  		case TMPFS_MAGIC:
  			/*
  			 * What about shmem/tmpfs anonymous files with dentry
  			 * obtained from d_alloc_pseudo()?
  			 */
  			isp->smk_inode = smk_of_current();
  			break;
8da4aba5b   Roman Kubiak   Smack: pipefs fix...
3366
3367
3368
  		case PIPEFS_MAGIC:
  			isp->smk_inode = smk_of_current();
  			break;
1d8c2326a   Łukasz Stelmach   smack: introduce ...
3369
3370
3371
  		default:
  			isp->smk_inode = sbsp->smk_root;
  			break;
36ea735b5   Casey Schaufler   Smack: Label cgro...
3372
  		}
e97dcb0ea   Casey Schaufler   Smack: fuse mount...
3373
3374
3375
3376
3377
  		isp->smk_flags |= SMK_INODE_INSTANT;
  		goto unlockandout;
  	}
  
  	/*
e114e4737   Casey Schaufler   Smack: Simplified...
3378
3379
3380
3381
3382
3383
3384
  	 * This is pretty hackish.
  	 * Casey says that we shouldn't have to do
  	 * file system specific code, but it does help
  	 * with keeping it simple.
  	 */
  	switch (sbp->s_magic) {
  	case SMACK_MAGIC:
36ea735b5   Casey Schaufler   Smack: Label cgro...
3385
3386
3387
  	case PIPEFS_MAGIC:
  	case SOCKFS_MAGIC:
  	case CGROUP_SUPER_MAGIC:
e114e4737   Casey Schaufler   Smack: Simplified...
3388
  		/*
25985edce   Lucas De Marchi   Fix common misspe...
3389
  		 * Casey says that it's a little embarrassing
e114e4737   Casey Schaufler   Smack: Simplified...
3390
3391
  		 * that the smack file system doesn't do
  		 * extended attributes.
36ea735b5   Casey Schaufler   Smack: Label cgro...
3392
  		 *
e114e4737   Casey Schaufler   Smack: Simplified...
3393
  		 * Casey says pipes are easy (?)
36ea735b5   Casey Schaufler   Smack: Label cgro...
3394
3395
3396
3397
3398
  		 *
  		 * Socket access is controlled by the socket
  		 * structures associated with the task involved.
  		 *
  		 * Cgroupfs is special
e114e4737   Casey Schaufler   Smack: Simplified...
3399
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3400
  		final = &smack_known_star;
e114e4737   Casey Schaufler   Smack: Simplified...
3401
3402
3403
3404
3405
3406
3407
  		break;
  	case DEVPTS_SUPER_MAGIC:
  		/*
  		 * devpts seems content with the label of the task.
  		 * Programs that change smack have to treat the
  		 * pty with respect.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3408
  		final = ckp;
e114e4737   Casey Schaufler   Smack: Simplified...
3409
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
  	case PROC_SUPER_MAGIC:
  		/*
  		 * Casey says procfs appears not to care.
  		 * The superblock default suffices.
  		 */
  		break;
  	case TMPFS_MAGIC:
  		/*
  		 * Device labels should come from the filesystem,
  		 * but watch out, because they're volitile,
  		 * getting recreated on every reboot.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3422
  		final = &smack_known_star;
e114e4737   Casey Schaufler   Smack: Simplified...
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
  		/*
  		 * No break.
  		 *
  		 * If a smack value has been set we want to use it,
  		 * but since tmpfs isn't giving us the opportunity
  		 * to set mount options simulate setting the
  		 * superblock default.
  		 */
  	default:
  		/*
  		 * This isn't an understood special case.
  		 * Get the value from the xattr.
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3435
3436
3437
3438
3439
3440
  		 */
  
  		/*
  		 * UNIX domain sockets use lower level socket data.
  		 */
  		if (S_ISSOCK(inode->i_mode)) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3441
  			final = &smack_known_star;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3442
3443
3444
  			break;
  		}
  		/*
e114e4737   Casey Schaufler   Smack: Simplified...
3445
3446
3447
3448
3449
  		 * No xattr support means, alas, no SMACK label.
  		 * Use the aforeapplied default.
  		 * It would be curious if the label of the task
  		 * does not match that assigned.
  		 */
5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
3450
3451
  		if (!(inode->i_opflags & IOP_XATTR))
  		        break;
e114e4737   Casey Schaufler   Smack: Simplified...
3452
3453
3454
  		/*
  		 * Get the dentry for xattr.
  		 */
3e62cbb84   Dan Carpenter   smack: opt_dentry...
3455
  		dp = dget(opt_dentry);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3456
  		skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
e774ad683   Lukasz Pawelczyk   smack: pass error...
3457
  		if (!IS_ERR_OR_NULL(skp))
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3458
  			final = skp;
2267b13a7   Casey Schaufler   Smack: recursive ...
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
  
  		/*
  		 * Transmuting directory
  		 */
  		if (S_ISDIR(inode->i_mode)) {
  			/*
  			 * If this is a new directory and the label was
  			 * transmuted when the inode was initialized
  			 * set the transmute attribute on the directory
  			 * and mark the inode.
  			 *
  			 * If there is a transmute attribute on the
  			 * directory mark the inode.
  			 */
  			if (isp->smk_flags & SMK_INODE_CHANGED) {
  				isp->smk_flags &= ~SMK_INODE_CHANGED;
5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
3475
  				rc = __vfs_setxattr(dp, inode,
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3476
  					XATTR_NAME_SMACKTRANSMUTE,
2267b13a7   Casey Schaufler   Smack: recursive ...
3477
3478
3479
  					TRANS_TRUE, TRANS_TRUE_SIZE,
  					0);
  			} else {
5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
3480
  				rc = __vfs_getxattr(dp, inode,
2267b13a7   Casey Schaufler   Smack: recursive ...
3481
3482
3483
3484
3485
  					XATTR_NAME_SMACKTRANSMUTE, trattr,
  					TRANS_TRUE_SIZE);
  				if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
  						       TRANS_TRUE_SIZE) != 0)
  					rc = -EINVAL;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3486
  			}
2267b13a7   Casey Schaufler   Smack: recursive ...
3487
3488
  			if (rc >= 0)
  				transflag = SMK_INODE_TRANSMUTE;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3489
  		}
809c02e09   Seth Forshee   Smack: Handle lab...
3490
3491
3492
3493
3494
3495
3496
3497
  		/*
  		 * Don't let the exec or mmap label be "*" or "@".
  		 */
  		skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
  		if (IS_ERR(skp) || skp == &smack_known_star ||
  		    skp == &smack_known_web)
  			skp = NULL;
  		isp->smk_task = skp;
e774ad683   Lukasz Pawelczyk   smack: pass error...
3498

19760ad03   Casey Schaufler   Smack: Prevent th...
3499
  		skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
e774ad683   Lukasz Pawelczyk   smack: pass error...
3500
3501
  		if (IS_ERR(skp) || skp == &smack_known_star ||
  		    skp == &smack_known_web)
19760ad03   Casey Schaufler   Smack: Prevent th...
3502
3503
  			skp = NULL;
  		isp->smk_mmap = skp;
676dac4b1   Casey Schaufler   This patch adds a...
3504

e114e4737   Casey Schaufler   Smack: Simplified...
3505
3506
3507
3508
3509
  		dput(dp);
  		break;
  	}
  
  	if (final == NULL)
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3510
  		isp->smk_inode = ckp;
e114e4737   Casey Schaufler   Smack: Simplified...
3511
3512
  	else
  		isp->smk_inode = final;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3513
  	isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
e114e4737   Casey Schaufler   Smack: Simplified...
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
  
  unlockandout:
  	mutex_unlock(&isp->smk_lock);
  	return;
  }
  
  /**
   * smack_getprocattr - Smack process attribute access
   * @p: the object task
   * @name: the name of the attribute in /proc/.../attr
   * @value: where to put the result
   *
   * Places a copy of the task Smack into value
   *
   * Returns the length of the smack label or an error code
   */
  static int smack_getprocattr(struct task_struct *p, char *name, char **value)
  {
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
3532
  	struct smack_known *skp = smk_of_task_struct(p);
e114e4737   Casey Schaufler   Smack: Simplified...
3533
3534
3535
3536
3537
  	char *cp;
  	int slen;
  
  	if (strcmp(name, "current") != 0)
  		return -EINVAL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3538
  	cp = kstrdup(skp->smk_known, GFP_KERNEL);
e114e4737   Casey Schaufler   Smack: Simplified...
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
  	if (cp == NULL)
  		return -ENOMEM;
  
  	slen = strlen(cp);
  	*value = cp;
  	return slen;
  }
  
  /**
   * smack_setprocattr - Smack process attribute setting
   * @p: the object task
   * @name: the name of the attribute in /proc/.../attr
   * @value: the value to set
   * @size: the size of the value
   *
   * Sets the Smack value of the task. Only setting self
   * is permitted and only with privilege
   *
   * Returns the length of the smack label or an error code
   */
  static int smack_setprocattr(struct task_struct *p, char *name,
  			     void *value, size_t size)
  {
38416e539   Zbigniew Jasinski   Smack: limited ca...
3562
  	struct task_smack *tsp = current_security();
d84f4f992   David Howells   CRED: Inaugurate ...
3563
  	struct cred *new;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3564
  	struct smack_known *skp;
38416e539   Zbigniew Jasinski   Smack: limited ca...
3565
3566
  	struct smack_known_list_elem *sklep;
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3567

e114e4737   Casey Schaufler   Smack: Simplified...
3568
3569
3570
3571
3572
3573
  	/*
  	 * Changing another process' Smack value is too dangerous
  	 * and supports no sane use case.
  	 */
  	if (p != current)
  		return -EPERM;
38416e539   Zbigniew Jasinski   Smack: limited ca...
3574
  	if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel))
5cd9c58fb   David Howells   security: Fix set...
3575
  		return -EPERM;
f7112e6c9   Casey Schaufler   Smack: allow for ...
3576
  	if (value == NULL || size == 0 || size >= SMK_LONGLABEL)
e114e4737   Casey Schaufler   Smack: Simplified...
3577
3578
3579
3580
  		return -EINVAL;
  
  	if (strcmp(name, "current") != 0)
  		return -EINVAL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3581
  	skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
3582
3583
  	if (IS_ERR(skp))
  		return PTR_ERR(skp);
e114e4737   Casey Schaufler   Smack: Simplified...
3584

6d3dc07cb   Casey Schaufler   smack: Add suppor...
3585
3586
3587
  	/*
  	 * No process is ever allowed the web ("@") label.
  	 */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3588
  	if (skp == &smack_known_web)
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3589
  		return -EPERM;
38416e539   Zbigniew Jasinski   Smack: limited ca...
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
  	if (!smack_privileged(CAP_MAC_ADMIN)) {
  		rc = -EPERM;
  		list_for_each_entry(sklep, &tsp->smk_relabel, list)
  			if (sklep->smk_label == skp) {
  				rc = 0;
  				break;
  			}
  		if (rc)
  			return rc;
  	}
d84f4f992   David Howells   CRED: Inaugurate ...
3600
  	new = prepare_creds();
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3601
  	if (new == NULL)
d84f4f992   David Howells   CRED: Inaugurate ...
3602
  		return -ENOMEM;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
3603

46a2f3b9e   Casey Schaufler   Smack: setprocatt...
3604
  	tsp = new->security;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3605
  	tsp->smk_task = skp;
38416e539   Zbigniew Jasinski   Smack: limited ca...
3606
3607
3608
3609
  	/*
  	 * process can change its label only once
  	 */
  	smk_destroy_label_list(&tsp->smk_relabel);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
3610

d84f4f992   David Howells   CRED: Inaugurate ...
3611
  	commit_creds(new);
e114e4737   Casey Schaufler   Smack: Simplified...
3612
3613
3614
3615
3616
  	return size;
  }
  
  /**
   * smack_unix_stream_connect - Smack access on UDS
3610cda53   David S. Miller   af_unix: Avoid so...
3617
3618
   * @sock: one sock
   * @other: the other sock
e114e4737   Casey Schaufler   Smack: Simplified...
3619
3620
3621
3622
3623
   * @newsk: unused
   *
   * Return 0 if a subject with the smack of sock could access
   * an object with the smack of other, otherwise an error code
   */
3610cda53   David S. Miller   af_unix: Avoid so...
3624
3625
  static int smack_unix_stream_connect(struct sock *sock,
  				     struct sock *other, struct sock *newsk)
e114e4737   Casey Schaufler   Smack: Simplified...
3626
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3627
  	struct smack_known *skp;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3628
  	struct smack_known *okp;
d2e7ad192   James Morris   Merge branch 'mas...
3629
3630
  	struct socket_smack *ssp = sock->sk_security;
  	struct socket_smack *osp = other->sk_security;
975d5e55c   Casey Schaufler   Smack: Provide in...
3631
  	struct socket_smack *nsp = newsk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
3632
  	struct smk_audit_info ad;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3633
  	int rc = 0;
923e9a139   Kees Cook   Smack: build when...
3634
3635
  #ifdef CONFIG_AUDIT
  	struct lsm_network_audit net;
923e9a139   Kees Cook   Smack: build when...
3636
  #endif
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3637

2f823ff8b   Casey Schaufler   Smack: Improve ac...
3638
3639
  	if (!smack_privileged(CAP_MAC_OVERRIDE)) {
  		skp = ssp->smk_out;
96be7b542   Zbigniew Jasinski   smack: Fix a bidi...
3640
  		okp = osp->smk_in;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3641
3642
3643
3644
  #ifdef CONFIG_AUDIT
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
  		smk_ad_setfield_u_net_sk(&ad, other);
  #endif
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3645
3646
  		rc = smk_access(skp, okp, MAY_WRITE, &ad);
  		rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
3647
  		if (rc == 0) {
96be7b542   Zbigniew Jasinski   smack: Fix a bidi...
3648
3649
  			okp = osp->smk_out;
  			skp = ssp->smk_in;
138a868f0   Rafal Krypa   smack: Add missin...
3650
  			rc = smk_access(okp, skp, MAY_WRITE, &ad);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3651
  			rc = smk_bu_note("UDS connect", okp, skp,
d166c8024   Casey Schaufler   Smack: Bring-up a...
3652
3653
  						MAY_WRITE, rc);
  		}
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3654
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3655

975d5e55c   Casey Schaufler   Smack: Provide in...
3656
3657
3658
3659
  	/*
  	 * Cross reference the peer labels for SO_PEERSEC.
  	 */
  	if (rc == 0) {
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3660
3661
  		nsp->smk_packet = ssp->smk_out;
  		ssp->smk_packet = osp->smk_out;
975d5e55c   Casey Schaufler   Smack: Provide in...
3662
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3663
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
  }
  
  /**
   * smack_unix_may_send - Smack access on UDS
   * @sock: one socket
   * @other: the other socket
   *
   * Return 0 if a subject with the smack of sock could access
   * an object with the smack of other, otherwise an error code
   */
  static int smack_unix_may_send(struct socket *sock, struct socket *other)
  {
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3676
3677
  	struct socket_smack *ssp = sock->sk->sk_security;
  	struct socket_smack *osp = other->sk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
3678
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3679
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3680

923e9a139   Kees Cook   Smack: build when...
3681
3682
  #ifdef CONFIG_AUDIT
  	struct lsm_network_audit net;
48c62af68   Eric Paris   LSM: shrink the c...
3683
  	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
ecfcc53fe   Etienne Basset   smack: implement ...
3684
  	smk_ad_setfield_u_net_sk(&ad, other->sk);
923e9a139   Kees Cook   Smack: build when...
3685
  #endif
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3686

2f823ff8b   Casey Schaufler   Smack: Improve ac...
3687
3688
  	if (smack_privileged(CAP_MAC_OVERRIDE))
  		return 0;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3689

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3690
3691
  	rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
  	rc = smk_bu_note("UDS send", ssp->smk_out, osp->smk_in, MAY_WRITE, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
3692
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3693
3694
3695
  }
  
  /**
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3696
3697
   * smack_socket_sendmsg - Smack check based on destination host
   * @sock: the socket
251a2a958   Randy Dunlap   smack: fix lots o...
3698
   * @msg: the message
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3699
3700
   * @size: the size of the message
   *
c67394434   Casey Schaufler   Smack: Local IPv6...
3701
3702
3703
   * Return 0 if the current subject can write to the destination host.
   * For IPv4 this is only a question if the destination is a single label host.
   * For IPv6 this is a check against the label of the port.
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3704
3705
3706
3707
3708
   */
  static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
  				int size)
  {
  	struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3709
  #if IS_ENABLED(CONFIG_IPV6)
6ea062475   Casey Schaufler   Smack: IPv6 casti...
3710
  	struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3711
3712
3713
3714
3715
  #endif
  #ifdef SMACK_IPV6_SECMARK_LABELING
  	struct socket_smack *ssp = sock->sk->sk_security;
  	struct smack_known *rsp;
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
3716
  	int rc = 0;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3717
3718
3719
3720
  
  	/*
  	 * Perfectly reasonable for this to be NULL
  	 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3721
  	if (sip == NULL)
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3722
  		return 0;
81bd0d562   Roman Kubiak   Smack: type confu...
3723
  	switch (sock->sk->sk_family) {
c67394434   Casey Schaufler   Smack: Local IPv6...
3724
3725
3726
3727
  	case AF_INET:
  		rc = smack_netlabel_send(sock->sk, sip);
  		break;
  	case AF_INET6:
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3728
3729
3730
3731
3732
3733
3734
  #ifdef SMACK_IPV6_SECMARK_LABELING
  		rsp = smack_ipv6host_label(sap);
  		if (rsp != NULL)
  			rc = smk_ipv6_check(ssp->smk_out, rsp, sap,
  						SMK_CONNECTING);
  #endif
  #ifdef SMACK_IPV6_PORT_LABELING
c67394434   Casey Schaufler   Smack: Local IPv6...
3735
  		rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3736
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
3737
3738
3739
  		break;
  	}
  	return rc;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3740
  }
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3741
  /**
251a2a958   Randy Dunlap   smack: fix lots o...
3742
   * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
e114e4737   Casey Schaufler   Smack: Simplified...
3743
   * @sap: netlabel secattr
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3744
   * @ssp: socket security information
e114e4737   Casey Schaufler   Smack: Simplified...
3745
   *
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3746
   * Returns a pointer to a Smack label entry found on the label list.
e114e4737   Casey Schaufler   Smack: Simplified...
3747
   */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3748
3749
  static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
  						struct socket_smack *ssp)
e114e4737   Casey Schaufler   Smack: Simplified...
3750
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3751
  	struct smack_known *skp;
f7112e6c9   Casey Schaufler   Smack: allow for ...
3752
  	int found = 0;
677264e8f   Casey Schaufler   Smack: network la...
3753
3754
  	int acat;
  	int kcat;
e114e4737   Casey Schaufler   Smack: Simplified...
3755

6d3dc07cb   Casey Schaufler   smack: Add suppor...
3756
  	if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
3757
  		/*
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3758
  		 * Looks like a CIPSO packet.
e114e4737   Casey Schaufler   Smack: Simplified...
3759
3760
3761
  		 * If there are flags but no level netlabel isn't
  		 * behaving the way we expect it to.
  		 *
f7112e6c9   Casey Schaufler   Smack: allow for ...
3762
  		 * Look it up in the label table
e114e4737   Casey Schaufler   Smack: Simplified...
3763
3764
3765
3766
  		 * Without guidance regarding the smack value
  		 * for the packet fall back on the network
  		 * ambient value.
  		 */
f7112e6c9   Casey Schaufler   Smack: allow for ...
3767
  		rcu_read_lock();
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3768
3769
  		list_for_each_entry(skp, &smack_known_list, list) {
  			if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
f7112e6c9   Casey Schaufler   Smack: allow for ...
3770
  				continue;
677264e8f   Casey Schaufler   Smack: network la...
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
  			/*
  			 * Compare the catsets. Use the netlbl APIs.
  			 */
  			if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) {
  				if ((skp->smk_netlabel.flags &
  				     NETLBL_SECATTR_MLS_CAT) == 0)
  					found = 1;
  				break;
  			}
  			for (acat = -1, kcat = -1; acat == kcat; ) {
4fbe63d1c   Paul Moore   netlabel: shorter...
3781
3782
3783
  				acat = netlbl_catmap_walk(sap->attr.mls.cat,
  							  acat + 1);
  				kcat = netlbl_catmap_walk(
677264e8f   Casey Schaufler   Smack: network la...
3784
3785
3786
3787
3788
3789
3790
3791
3792
  					skp->smk_netlabel.attr.mls.cat,
  					kcat + 1);
  				if (acat < 0 || kcat < 0)
  					break;
  			}
  			if (acat == kcat) {
  				found = 1;
  				break;
  			}
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3793
  		}
f7112e6c9   Casey Schaufler   Smack: allow for ...
3794
3795
3796
  		rcu_read_unlock();
  
  		if (found)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3797
  			return skp;
f7112e6c9   Casey Schaufler   Smack: allow for ...
3798

54e70ec5e   Casey Schaufler   Smack: bidirectio...
3799
  		if (ssp != NULL && ssp->smk_in == &smack_known_star)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3800
3801
  			return &smack_known_web;
  		return &smack_known_star;
e114e4737   Casey Schaufler   Smack: Simplified...
3802
  	}
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3803
3804
3805
3806
  	if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
  		/*
  		 * Looks like a fallback, which gives us a secid.
  		 */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3807
  		skp = smack_from_secid(sap->attr.secid);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3808
3809
3810
3811
3812
3813
3814
  		/*
  		 * This has got to be a bug because it is
  		 * impossible to specify a fallback without
  		 * specifying the label, which will ensure
  		 * it has a secid, and the only way to get a
  		 * secid is from a fallback.
  		 */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3815
3816
  		BUG_ON(skp == NULL);
  		return skp;
e114e4737   Casey Schaufler   Smack: Simplified...
3817
3818
  	}
  	/*
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3819
3820
3821
  	 * Without guidance regarding the smack value
  	 * for the packet fall back on the network
  	 * ambient value.
e114e4737   Casey Schaufler   Smack: Simplified...
3822
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3823
  	return smack_net_ambient;
e114e4737   Casey Schaufler   Smack: Simplified...
3824
  }
69f287ae6   Casey Schaufler   Smack: secmark su...
3825
  #if IS_ENABLED(CONFIG_IPV6)
6ea062475   Casey Schaufler   Smack: IPv6 casti...
3826
  static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
c67394434   Casey Schaufler   Smack: Local IPv6...
3827
  {
c67394434   Casey Schaufler   Smack: Local IPv6...
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
  	u8 nexthdr;
  	int offset;
  	int proto = -EINVAL;
  	struct ipv6hdr _ipv6h;
  	struct ipv6hdr *ip6;
  	__be16 frag_off;
  	struct tcphdr _tcph, *th;
  	struct udphdr _udph, *uh;
  	struct dccp_hdr _dccph, *dh;
  
  	sip->sin6_port = 0;
  
  	offset = skb_network_offset(skb);
  	ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
  	if (ip6 == NULL)
  		return -EINVAL;
  	sip->sin6_addr = ip6->saddr;
  
  	nexthdr = ip6->nexthdr;
  	offset += sizeof(_ipv6h);
  	offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
  	if (offset < 0)
  		return -EINVAL;
  
  	proto = nexthdr;
  	switch (proto) {
  	case IPPROTO_TCP:
  		th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
  		if (th != NULL)
  			sip->sin6_port = th->source;
  		break;
  	case IPPROTO_UDP:
  		uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
  		if (uh != NULL)
  			sip->sin6_port = uh->source;
  		break;
  	case IPPROTO_DCCP:
  		dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
  		if (dh != NULL)
  			sip->sin6_port = dh->dccph_sport;
  		break;
  	}
  	return proto;
  }
69f287ae6   Casey Schaufler   Smack: secmark su...
3872
  #endif /* CONFIG_IPV6 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3873

e114e4737   Casey Schaufler   Smack: Simplified...
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
  /**
   * smack_socket_sock_rcv_skb - Smack packet delivery access check
   * @sk: socket
   * @skb: packet
   *
   * Returns 0 if the packet should be delivered, an error code otherwise
   */
  static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
  {
  	struct netlbl_lsm_secattr secattr;
  	struct socket_smack *ssp = sk->sk_security;
69f287ae6   Casey Schaufler   Smack: secmark su...
3885
  	struct smack_known *skp = NULL;
c67394434   Casey Schaufler   Smack: Local IPv6...
3886
  	int rc = 0;
ecfcc53fe   Etienne Basset   smack: implement ...
3887
  	struct smk_audit_info ad;
923e9a139   Kees Cook   Smack: build when...
3888
  #ifdef CONFIG_AUDIT
48c62af68   Eric Paris   LSM: shrink the c...
3889
  	struct lsm_network_audit net;
923e9a139   Kees Cook   Smack: build when...
3890
  #endif
69f287ae6   Casey Schaufler   Smack: secmark su...
3891
3892
3893
3894
  #if IS_ENABLED(CONFIG_IPV6)
  	struct sockaddr_in6 sadd;
  	int proto;
  #endif /* CONFIG_IPV6 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3895
3896
  	switch (sk->sk_family) {
  	case PF_INET:
69f287ae6   Casey Schaufler   Smack: secmark su...
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  		/*
  		 * If there is a secmark use it rather than the CIPSO label.
  		 * If there is no secmark fall back to CIPSO.
  		 * The secmark is assumed to reflect policy better.
  		 */
  		if (skb && skb->secmark != 0) {
  			skp = smack_from_secid(skb->secmark);
  			goto access_check;
  		}
  #endif /* CONFIG_SECURITY_SMACK_NETFILTER */
c67394434   Casey Schaufler   Smack: Local IPv6...
3908
3909
3910
3911
  		/*
  		 * Translate what netlabel gave us.
  		 */
  		netlbl_secattr_init(&secattr);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3912

c67394434   Casey Schaufler   Smack: Local IPv6...
3913
3914
  		rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
  		if (rc == 0)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3915
  			skp = smack_from_secattr(&secattr, ssp);
c67394434   Casey Schaufler   Smack: Local IPv6...
3916
  		else
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3917
  			skp = smack_net_ambient;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3918

c67394434   Casey Schaufler   Smack: Local IPv6...
3919
  		netlbl_secattr_destroy(&secattr);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3920

69f287ae6   Casey Schaufler   Smack: secmark su...
3921
3922
3923
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  access_check:
  #endif
ecfcc53fe   Etienne Basset   smack: implement ...
3924
  #ifdef CONFIG_AUDIT
c67394434   Casey Schaufler   Smack: Local IPv6...
3925
3926
3927
3928
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
  		ad.a.u.net->family = sk->sk_family;
  		ad.a.u.net->netif = skb->skb_iif;
  		ipv4_skb_to_auditdata(skb, &ad.a, NULL);
ecfcc53fe   Etienne Basset   smack: implement ...
3929
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
3930
3931
3932
3933
3934
3935
  		/*
  		 * 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
  		 * for networking.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3936
3937
  		rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
  		rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in,
d166c8024   Casey Schaufler   Smack: Bring-up a...
3938
  					MAY_WRITE, rc);
c67394434   Casey Schaufler   Smack: Local IPv6...
3939
  		if (rc != 0)
a04e71f63   Huw Davies   netlabel: Pass a ...
3940
  			netlbl_skbuff_err(skb, sk->sk_family, rc, 0);
c67394434   Casey Schaufler   Smack: Local IPv6...
3941
  		break;
69f287ae6   Casey Schaufler   Smack: secmark su...
3942
  #if IS_ENABLED(CONFIG_IPV6)
c67394434   Casey Schaufler   Smack: Local IPv6...
3943
  	case PF_INET6:
69f287ae6   Casey Schaufler   Smack: secmark su...
3944
3945
3946
  		proto = smk_skb_to_addr_ipv6(skb, &sadd);
  		if (proto != IPPROTO_UDP && proto != IPPROTO_TCP)
  			break;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3947
  #ifdef SMACK_IPV6_SECMARK_LABELING
69f287ae6   Casey Schaufler   Smack: secmark su...
3948
3949
  		if (skb && skb->secmark != 0)
  			skp = smack_from_secid(skb->secmark);
c67394434   Casey Schaufler   Smack: Local IPv6...
3950
  		else
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3951
3952
  			skp = smack_ipv6host_label(&sadd);
  		if (skp == NULL)
69f287ae6   Casey Schaufler   Smack: secmark su...
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
  			skp = smack_net_ambient;
  #ifdef CONFIG_AUDIT
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
  		ad.a.u.net->family = sk->sk_family;
  		ad.a.u.net->netif = skb->skb_iif;
  		ipv6_skb_to_auditdata(skb, &ad.a, NULL);
  #endif /* CONFIG_AUDIT */
  		rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
  		rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in,
  					MAY_WRITE, rc);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3963
3964
  #endif /* SMACK_IPV6_SECMARK_LABELING */
  #ifdef SMACK_IPV6_PORT_LABELING
69f287ae6   Casey Schaufler   Smack: secmark su...
3965
  		rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3966
  #endif /* SMACK_IPV6_PORT_LABELING */
c67394434   Casey Schaufler   Smack: Local IPv6...
3967
  		break;
69f287ae6   Casey Schaufler   Smack: secmark su...
3968
  #endif /* CONFIG_IPV6 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3969
  	}
69f287ae6   Casey Schaufler   Smack: secmark su...
3970

a8134296b   Paul Moore   smack: Fix missin...
3971
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3972
3973
3974
3975
3976
3977
3978
  }
  
  /**
   * smack_socket_getpeersec_stream - pull in packet label
   * @sock: the socket
   * @optval: user's destination
   * @optlen: size thereof
251a2a958   Randy Dunlap   smack: fix lots o...
3979
   * @len: max thereof
e114e4737   Casey Schaufler   Smack: Simplified...
3980
3981
3982
3983
3984
3985
3986
3987
   *
   * returns zero on success, an error code otherwise
   */
  static int smack_socket_getpeersec_stream(struct socket *sock,
  					  char __user *optval,
  					  int __user *optlen, unsigned len)
  {
  	struct socket_smack *ssp;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3988
3989
  	char *rcp = "";
  	int slen = 1;
e114e4737   Casey Schaufler   Smack: Simplified...
3990
3991
3992
  	int rc = 0;
  
  	ssp = sock->sk->sk_security;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3993
  	if (ssp->smk_packet != NULL) {
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3994
  		rcp = ssp->smk_packet->smk_known;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3995
3996
  		slen = strlen(rcp) + 1;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
3997
3998
3999
  
  	if (slen > len)
  		rc = -ERANGE;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
4000
  	else if (copy_to_user(optval, rcp, slen) != 0)
e114e4737   Casey Schaufler   Smack: Simplified...
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
  		rc = -EFAULT;
  
  	if (put_user(slen, optlen) != 0)
  		rc = -EFAULT;
  
  	return rc;
  }
  
  
  /**
   * smack_socket_getpeersec_dgram - pull in packet label
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4012
   * @sock: the peer socket
e114e4737   Casey Schaufler   Smack: Simplified...
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
   * @skb: packet data
   * @secid: pointer to where to put the secid of the packet
   *
   * Sets the netlabel socket state on sk from parent
   */
  static int smack_socket_getpeersec_dgram(struct socket *sock,
  					 struct sk_buff *skb, u32 *secid)
  
  {
  	struct netlbl_lsm_secattr secattr;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
4023
  	struct socket_smack *ssp = NULL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4024
  	struct smack_known *skp;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4025
4026
  	int family = PF_UNSPEC;
  	u32 s = 0;	/* 0 is the invalid secid */
e114e4737   Casey Schaufler   Smack: Simplified...
4027
  	int rc;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4028
4029
4030
  	if (skb != NULL) {
  		if (skb->protocol == htons(ETH_P_IP))
  			family = PF_INET;
69f287ae6   Casey Schaufler   Smack: secmark su...
4031
  #if IS_ENABLED(CONFIG_IPV6)
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4032
4033
  		else if (skb->protocol == htons(ETH_P_IPV6))
  			family = PF_INET6;
69f287ae6   Casey Schaufler   Smack: secmark su...
4034
  #endif /* CONFIG_IPV6 */
e114e4737   Casey Schaufler   Smack: Simplified...
4035
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4036
4037
  	if (family == PF_UNSPEC && sock != NULL)
  		family = sock->sk->sk_family;
e114e4737   Casey Schaufler   Smack: Simplified...
4038

69f287ae6   Casey Schaufler   Smack: secmark su...
4039
4040
  	switch (family) {
  	case PF_UNIX:
272cd7a8c   Casey Schaufler   Smack: Rule list ...
4041
  		ssp = sock->sk->sk_security;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4042
  		s = ssp->smk_out->smk_secid;
69f287ae6   Casey Schaufler   Smack: secmark su...
4043
4044
4045
4046
4047
4048
4049
  		break;
  	case PF_INET:
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  		s = skb->secmark;
  		if (s != 0)
  			break;
  #endif
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4050
4051
4052
  		/*
  		 * Translate what netlabel gave us.
  		 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
4053
4054
  		if (sock != NULL && sock->sk != NULL)
  			ssp = sock->sk->sk_security;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4055
4056
4057
  		netlbl_secattr_init(&secattr);
  		rc = netlbl_skbuff_getattr(skb, family, &secattr);
  		if (rc == 0) {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4058
4059
  			skp = smack_from_secattr(&secattr, ssp);
  			s = skp->smk_secid;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4060
4061
  		}
  		netlbl_secattr_destroy(&secattr);
69f287ae6   Casey Schaufler   Smack: secmark su...
4062
  		break;
69f287ae6   Casey Schaufler   Smack: secmark su...
4063
  	case PF_INET6:
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4064
  #ifdef SMACK_IPV6_SECMARK_LABELING
69f287ae6   Casey Schaufler   Smack: secmark su...
4065
  		s = skb->secmark;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4066
  #endif
69f287ae6   Casey Schaufler   Smack: secmark su...
4067
  		break;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
4068
4069
  	}
  	*secid = s;
e114e4737   Casey Schaufler   Smack: Simplified...
4070
4071
  	if (s == 0)
  		return -EINVAL;
e114e4737   Casey Schaufler   Smack: Simplified...
4072
4073
4074
4075
  	return 0;
  }
  
  /**
07feee8f8   Paul Moore   netlabel: Cleanup...
4076
4077
4078
   * smack_sock_graft - Initialize a newly created socket with an existing sock
   * @sk: child sock
   * @parent: parent socket
e114e4737   Casey Schaufler   Smack: Simplified...
4079
   *
07feee8f8   Paul Moore   netlabel: Cleanup...
4080
4081
   * Set the smk_{in,out} state of an existing sock based on the process that
   * is creating the new socket.
e114e4737   Casey Schaufler   Smack: Simplified...
4082
4083
4084
4085
   */
  static void smack_sock_graft(struct sock *sk, struct socket *parent)
  {
  	struct socket_smack *ssp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4086
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
4087

07feee8f8   Paul Moore   netlabel: Cleanup...
4088
4089
  	if (sk == NULL ||
  	    (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
e114e4737   Casey Schaufler   Smack: Simplified...
4090
4091
4092
  		return;
  
  	ssp = sk->sk_security;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
4093
  	ssp->smk_in = skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4094
  	ssp->smk_out = skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
4095
  	/* cssp->smk_packet is already set in smack_inet_csk_clone() */
e114e4737   Casey Schaufler   Smack: Simplified...
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
  }
  
  /**
   * smack_inet_conn_request - Smack access check on connect
   * @sk: socket involved
   * @skb: packet
   * @req: unused
   *
   * Returns 0 if a task with the packet label could write to
   * the socket, otherwise an error code
   */
  static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
  				   struct request_sock *req)
  {
07feee8f8   Paul Moore   netlabel: Cleanup...
4110
  	u16 family = sk->sk_family;
f7112e6c9   Casey Schaufler   Smack: allow for ...
4111
  	struct smack_known *skp;
e114e4737   Casey Schaufler   Smack: Simplified...
4112
  	struct socket_smack *ssp = sk->sk_security;
07feee8f8   Paul Moore   netlabel: Cleanup...
4113
4114
4115
  	struct netlbl_lsm_secattr secattr;
  	struct sockaddr_in addr;
  	struct iphdr *hdr;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4116
  	struct smack_known *hskp;
e114e4737   Casey Schaufler   Smack: Simplified...
4117
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
4118
  	struct smk_audit_info ad;
923e9a139   Kees Cook   Smack: build when...
4119
  #ifdef CONFIG_AUDIT
48c62af68   Eric Paris   LSM: shrink the c...
4120
  	struct lsm_network_audit net;
923e9a139   Kees Cook   Smack: build when...
4121
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
4122

69f287ae6   Casey Schaufler   Smack: secmark su...
4123
  #if IS_ENABLED(CONFIG_IPV6)
c67394434   Casey Schaufler   Smack: Local IPv6...
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
  	if (family == PF_INET6) {
  		/*
  		 * Handle mapped IPv4 packets arriving
  		 * via IPv6 sockets. Don't set up netlabel
  		 * processing on IPv6.
  		 */
  		if (skb->protocol == htons(ETH_P_IP))
  			family = PF_INET;
  		else
  			return 0;
  	}
69f287ae6   Casey Schaufler   Smack: secmark su...
4135
  #endif /* CONFIG_IPV6 */
e114e4737   Casey Schaufler   Smack: Simplified...
4136

7f368ad34   Casey Schaufler   Smack: secmark co...
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  	/*
  	 * If there is a secmark use it rather than the CIPSO label.
  	 * If there is no secmark fall back to CIPSO.
  	 * The secmark is assumed to reflect policy better.
  	 */
  	if (skb && skb->secmark != 0) {
  		skp = smack_from_secid(skb->secmark);
  		goto access_check;
  	}
  #endif /* CONFIG_SECURITY_SMACK_NETFILTER */
07feee8f8   Paul Moore   netlabel: Cleanup...
4148
4149
  	netlbl_secattr_init(&secattr);
  	rc = netlbl_skbuff_getattr(skb, family, &secattr);
e114e4737   Casey Schaufler   Smack: Simplified...
4150
  	if (rc == 0)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4151
  		skp = smack_from_secattr(&secattr, ssp);
e114e4737   Casey Schaufler   Smack: Simplified...
4152
  	else
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4153
  		skp = &smack_known_huh;
07feee8f8   Paul Moore   netlabel: Cleanup...
4154
  	netlbl_secattr_destroy(&secattr);
7f368ad34   Casey Schaufler   Smack: secmark co...
4155
4156
4157
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  access_check:
  #endif
ecfcc53fe   Etienne Basset   smack: implement ...
4158
  #ifdef CONFIG_AUDIT
48c62af68   Eric Paris   LSM: shrink the c...
4159
4160
4161
  	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
  	ad.a.u.net->family = family;
  	ad.a.u.net->netif = skb->skb_iif;
ecfcc53fe   Etienne Basset   smack: implement ...
4162
4163
  	ipv4_skb_to_auditdata(skb, &ad.a, NULL);
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
4164
  	/*
07feee8f8   Paul Moore   netlabel: Cleanup...
4165
4166
  	 * Receiving a packet requires that the other end be able to write
  	 * here. Read access is not required.
e114e4737   Casey Schaufler   Smack: Simplified...
4167
  	 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4168
4169
  	rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
  	rc = smk_bu_note("IPv4 connect", skp, ssp->smk_in, MAY_WRITE, rc);
07feee8f8   Paul Moore   netlabel: Cleanup...
4170
4171
4172
4173
4174
4175
4176
  	if (rc != 0)
  		return rc;
  
  	/*
  	 * Save the peer's label in the request_sock so we can later setup
  	 * smk_packet in the child socket so that SO_PEERCRED can report it.
  	 */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4177
  	req->peer_secid = skp->smk_secid;
07feee8f8   Paul Moore   netlabel: Cleanup...
4178
4179
4180
4181
  
  	/*
  	 * We need to decide if we want to label the incoming connection here
  	 * if we do we only need to label the request_sock and the stack will
25985edce   Lucas De Marchi   Fix common misspe...
4182
  	 * propagate the wire-label to the sock when it is created.
07feee8f8   Paul Moore   netlabel: Cleanup...
4183
4184
4185
4186
  	 */
  	hdr = ip_hdr(skb);
  	addr.sin_addr.s_addr = hdr->saddr;
  	rcu_read_lock();
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4187
  	hskp = smack_ipv4host_label(&addr);
f7112e6c9   Casey Schaufler   Smack: allow for ...
4188
  	rcu_read_unlock();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4189
  	if (hskp == NULL)
f7112e6c9   Casey Schaufler   Smack: allow for ...
4190
  		rc = netlbl_req_setattr(req, &skp->smk_netlabel);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4191
  	else
07feee8f8   Paul Moore   netlabel: Cleanup...
4192
  		netlbl_req_delattr(req);
e114e4737   Casey Schaufler   Smack: Simplified...
4193
4194
4195
  
  	return rc;
  }
07feee8f8   Paul Moore   netlabel: Cleanup...
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
  /**
   * smack_inet_csk_clone - Copy the connection information to the new socket
   * @sk: the new socket
   * @req: the connection's request_sock
   *
   * Transfer the connection's peer label to the newly created socket.
   */
  static void smack_inet_csk_clone(struct sock *sk,
  				 const struct request_sock *req)
  {
  	struct socket_smack *ssp = sk->sk_security;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4207
  	struct smack_known *skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
4208

2f823ff8b   Casey Schaufler   Smack: Improve ac...
4209
4210
  	if (req->peer_secid != 0) {
  		skp = smack_from_secid(req->peer_secid);
54e70ec5e   Casey Schaufler   Smack: bidirectio...
4211
  		ssp->smk_packet = skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4212
  	} else
272cd7a8c   Casey Schaufler   Smack: Rule list ...
4213
  		ssp->smk_packet = NULL;
07feee8f8   Paul Moore   netlabel: Cleanup...
4214
  }
e114e4737   Casey Schaufler   Smack: Simplified...
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
  /*
   * Key management security hooks
   *
   * Casey has not tested key support very heavily.
   * The permission check is most likely too restrictive.
   * If you care about keys please have a look.
   */
  #ifdef CONFIG_KEYS
  
  /**
   * smack_key_alloc - Set the key security blob
   * @key: object
d84f4f992   David Howells   CRED: Inaugurate ...
4227
   * @cred: the credentials to use
e114e4737   Casey Schaufler   Smack: Simplified...
4228
4229
4230
4231
4232
4233
   * @flags: unused
   *
   * No allocation required
   *
   * Returns 0
   */
d84f4f992   David Howells   CRED: Inaugurate ...
4234
  static int smack_key_alloc(struct key *key, const struct cred *cred,
e114e4737   Casey Schaufler   Smack: Simplified...
4235
4236
  			   unsigned long flags)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4237
  	struct smack_known *skp = smk_of_task(cred->security);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4238
  	key->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
  	return 0;
  }
  
  /**
   * smack_key_free - Clear the key security blob
   * @key: the object
   *
   * Clear the blob pointer
   */
  static void smack_key_free(struct key *key)
  {
  	key->security = NULL;
  }
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
4252
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
4253
4254
   * smack_key_permission - Smack access on a key
   * @key_ref: gets to the object
d84f4f992   David Howells   CRED: Inaugurate ...
4255
   * @cred: the credentials to use
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
4256
   * @perm: requested key permissions
e114e4737   Casey Schaufler   Smack: Simplified...
4257
4258
4259
4260
4261
   *
   * Return 0 if the task has read and write to the object,
   * an error code otherwise
   */
  static int smack_key_permission(key_ref_t key_ref,
f5895943d   David Howells   KEYS: Move the fl...
4262
  				const struct cred *cred, unsigned perm)
e114e4737   Casey Schaufler   Smack: Simplified...
4263
4264
  {
  	struct key *keyp;
ecfcc53fe   Etienne Basset   smack: implement ...
4265
  	struct smk_audit_info ad;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4266
  	struct smack_known *tkp = smk_of_task(cred->security);
fffea214a   Dmitry Kasatkin   smack: fix key pe...
4267
  	int request = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
4268
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
  
  	keyp = key_ref_to_ptr(key_ref);
  	if (keyp == NULL)
  		return -EINVAL;
  	/*
  	 * If the key hasn't been initialized give it access so that
  	 * it may do so.
  	 */
  	if (keyp->security == NULL)
  		return 0;
  	/*
  	 * This should not occur
  	 */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4282
  	if (tkp == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
4283
  		return -EACCES;
ecfcc53fe   Etienne Basset   smack: implement ...
4284
4285
4286
4287
4288
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
  	ad.a.u.key_struct.key = keyp->serial;
  	ad.a.u.key_struct.key_desc = keyp->description;
  #endif
fffea214a   Dmitry Kasatkin   smack: fix key pe...
4289
4290
4291
4292
  	if (perm & KEY_NEED_READ)
  		request = MAY_READ;
  	if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR))
  		request = MAY_WRITE;
d166c8024   Casey Schaufler   Smack: Bring-up a...
4293
4294
4295
  	rc = smk_access(tkp, keyp->security, request, &ad);
  	rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
4296
  }
7fc5f36e9   José Bollo   Smack: getting th...
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
  
  /*
   * smack_key_getsecurity - Smack label tagging the key
   * @key points to the key to be queried
   * @_buffer points to a pointer that should be set to point to the
   * resulting string (if no label or an error occurs).
   * Return the length of the string (including terminating NUL) or -ve if
   * an error.
   * May also return 0 (and a NULL buffer pointer) if there is no label.
   */
  static int smack_key_getsecurity(struct key *key, char **_buffer)
  {
  	struct smack_known *skp = key->security;
  	size_t length;
  	char *copy;
  
  	if (key->security == NULL) {
  		*_buffer = NULL;
  		return 0;
  	}
  
  	copy = kstrdup(skp->smk_known, GFP_KERNEL);
  	if (copy == NULL)
  		return -ENOMEM;
  	length = strlen(copy) + 1;
  
  	*_buffer = copy;
  	return length;
  }
e114e4737   Casey Schaufler   Smack: Simplified...
4326
4327
4328
  #endif /* CONFIG_KEYS */
  
  /*
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
   * Smack Audit hooks
   *
   * Audit requires a unique representation of each Smack specific
   * rule. This unique representation is used to distinguish the
   * object to be audited from remaining kernel objects and also
   * works as a glue between the audit hooks.
   *
   * Since repository entries are added but never deleted, we'll use
   * the smack_known label address related to the given audit rule as
   * the needed unique representation. This also better fits the smack
   * model where nearly everything is a label.
   */
  #ifdef CONFIG_AUDIT
  
  /**
   * smack_audit_rule_init - Initialize a smack audit rule
   * @field: audit rule fields given from user-space (audit.h)
   * @op: required testing operator (=, !=, >, <, ...)
   * @rulestr: smack label to be audited
   * @vrule: pointer to save our own audit rule representation
   *
   * Prepare to audit cases where (@field @op @rulestr) is true.
   * The label to be audited is created if necessay.
   */
  static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4355
  	struct smack_known *skp;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4356
4357
4358
4359
4360
  	char **rule = (char **)vrule;
  	*rule = NULL;
  
  	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
  		return -EINVAL;
5af75d8d5   Al Viro   audit: validate c...
4361
  	if (op != Audit_equal && op != Audit_not_equal)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4362
  		return -EINVAL;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4363
  	skp = smk_import_entry(rulestr, 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
4364
4365
4366
4367
  	if (IS_ERR(skp))
  		return PTR_ERR(skp);
  
  	*rule = skp->smk_known;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
  
  	return 0;
  }
  
  /**
   * smack_audit_rule_known - Distinguish Smack audit rules
   * @krule: rule of interest, in Audit kernel representation format
   *
   * This is used to filter Smack rules from remaining Audit ones.
   * If it's proved that this rule belongs to us, the
   * audit_rule_match hook will be called to do the final judgement.
   */
  static int smack_audit_rule_known(struct audit_krule *krule)
  {
  	struct audit_field *f;
  	int i;
  
  	for (i = 0; i < krule->field_count; i++) {
  		f = &krule->fields[i];
  
  		if (f->type == AUDIT_SUBJ_USER || f->type == AUDIT_OBJ_USER)
  			return 1;
  	}
  
  	return 0;
  }
  
  /**
   * smack_audit_rule_match - Audit given object ?
   * @secid: security id for identifying the object to test
   * @field: audit rule flags given from user-space
   * @op: required testing operator
   * @vrule: smack internal rule presentation
   * @actx: audit context associated with the check
   *
   * The core Audit hook. It's used to take the decision of
   * whether to audit or not to audit a given object.
   */
  static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
  				  struct audit_context *actx)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4409
  	struct smack_known *skp;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4410
  	char *rule = vrule;
4eb0f4abf   Richard Guy Briggs   smack: call WARN_...
4411
4412
4413
  	if (unlikely(!rule)) {
  		WARN_ONCE(1, "Smack: missing rule
  ");
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4414
4415
4416
4417
4418
  		return -ENOENT;
  	}
  
  	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
  		return 0;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4419
  	skp = smack_from_secid(secid);
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4420
4421
4422
4423
4424
4425
  
  	/*
  	 * No need to do string comparisons. If a match occurs,
  	 * both pointers will point to the same smack_known
  	 * label.
  	 */
5af75d8d5   Al Viro   audit: validate c...
4426
  	if (op == Audit_equal)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4427
  		return (rule == skp->smk_known);
5af75d8d5   Al Viro   audit: validate c...
4428
  	if (op == Audit_not_equal)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4429
  		return (rule != skp->smk_known);
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4430
4431
4432
  
  	return 0;
  }
491a0b08d   Casey Schaufler   Smack: Remove poi...
4433
4434
  /*
   * There is no need for a smack_audit_rule_free hook.
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4435
4436
   * No memory was allocated.
   */
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4437
4438
  
  #endif /* CONFIG_AUDIT */
251a2a958   Randy Dunlap   smack: fix lots o...
4439
  /**
746df9b59   David Quigley   Security: Add Hoo...
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
   * smack_ismaclabel - check if xattr @name references a smack MAC label
   * @name: Full xattr name to check.
   */
  static int smack_ismaclabel(const char *name)
  {
  	return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
  }
  
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
4450
4451
4452
4453
4454
4455
4456
4457
4458
   * smack_secid_to_secctx - return the smack label for a secid
   * @secid: incoming integer
   * @secdata: destination
   * @seclen: how long it is
   *
   * Exists for networking code.
   */
  static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4459
  	struct smack_known *skp = smack_from_secid(secid);
e114e4737   Casey Schaufler   Smack: Simplified...
4460

d5630b9d2   Eric Paris   security: secid_t...
4461
  	if (secdata)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4462
4463
  		*secdata = skp->smk_known;
  	*seclen = strlen(skp->smk_known);
e114e4737   Casey Schaufler   Smack: Simplified...
4464
4465
  	return 0;
  }
251a2a958   Randy Dunlap   smack: fix lots o...
4466
  /**
4bc87e627   Casey Schaufler   Smack: unlabeled ...
4467
4468
4469
4470
4471
4472
4473
   * smack_secctx_to_secid - return the secid for a smack label
   * @secdata: smack label
   * @seclen: how long result is
   * @secid: outgoing integer
   *
   * Exists for audit and networking code.
   */
e52c1764f   David Howells   Security: Make se...
4474
  static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
4bc87e627   Casey Schaufler   Smack: unlabeled ...
4475
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4476
4477
4478
4479
4480
4481
  	struct smack_known *skp = smk_find_entry(secdata);
  
  	if (skp)
  		*secid = skp->smk_secid;
  	else
  		*secid = 0;
4bc87e627   Casey Schaufler   Smack: unlabeled ...
4482
4483
  	return 0;
  }
491a0b08d   Casey Schaufler   Smack: Remove poi...
4484
4485
4486
4487
  /*
   * There used to be a smack_release_secctx hook
   * that did nothing back when hooks were in a vector.
   * Now that there's a list such a hook adds cost.
e114e4737   Casey Schaufler   Smack: Simplified...
4488
   */
e114e4737   Casey Schaufler   Smack: Simplified...
4489

1ee65e37e   David P. Quigley   LSM/SELinux: inod...
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
  static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
  {
  	return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, ctxlen, 0);
  }
  
  static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
  {
  	return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx, ctxlen, 0);
  }
  
  static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
  {
  	int len = 0;
  	len = smack_inode_getsecurity(inode, XATTR_SMACK_SUFFIX, ctx, true);
  
  	if (len < 0)
  		return len;
  	*ctxlen = len;
  	return 0;
  }
1eddfe8ed   Casey Schaufler   Smack: Three symb...
4510
  static struct security_hook_list smack_hooks[] = {
e20b043a6   Casey Schaufler   LSM: Add security...
4511
4512
4513
4514
4515
4516
4517
4518
4519
  	LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
  	LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
  	LSM_HOOK_INIT(syslog, smack_syslog),
  
  	LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security),
  	LSM_HOOK_INIT(sb_free_security, smack_sb_free_security),
  	LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data),
  	LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount),
  	LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
3bf2789ca   Vivek Trivedi   smack: allow moun...
4520
4521
  	LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts),
  	LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str),
e20b043a6   Casey Schaufler   LSM: Add security...
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
  
  	LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds),
  	LSM_HOOK_INIT(bprm_committing_creds, smack_bprm_committing_creds),
  	LSM_HOOK_INIT(bprm_secureexec, smack_bprm_secureexec),
  
  	LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security),
  	LSM_HOOK_INIT(inode_free_security, smack_inode_free_security),
  	LSM_HOOK_INIT(inode_init_security, smack_inode_init_security),
  	LSM_HOOK_INIT(inode_link, smack_inode_link),
  	LSM_HOOK_INIT(inode_unlink, smack_inode_unlink),
  	LSM_HOOK_INIT(inode_rmdir, smack_inode_rmdir),
  	LSM_HOOK_INIT(inode_rename, smack_inode_rename),
  	LSM_HOOK_INIT(inode_permission, smack_inode_permission),
  	LSM_HOOK_INIT(inode_setattr, smack_inode_setattr),
  	LSM_HOOK_INIT(inode_getattr, smack_inode_getattr),
  	LSM_HOOK_INIT(inode_setxattr, smack_inode_setxattr),
  	LSM_HOOK_INIT(inode_post_setxattr, smack_inode_post_setxattr),
  	LSM_HOOK_INIT(inode_getxattr, smack_inode_getxattr),
  	LSM_HOOK_INIT(inode_removexattr, smack_inode_removexattr),
  	LSM_HOOK_INIT(inode_getsecurity, smack_inode_getsecurity),
  	LSM_HOOK_INIT(inode_setsecurity, smack_inode_setsecurity),
  	LSM_HOOK_INIT(inode_listsecurity, smack_inode_listsecurity),
  	LSM_HOOK_INIT(inode_getsecid, smack_inode_getsecid),
e20b043a6   Casey Schaufler   LSM: Add security...
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
  	LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security),
  	LSM_HOOK_INIT(file_free_security, smack_file_free_security),
  	LSM_HOOK_INIT(file_ioctl, smack_file_ioctl),
  	LSM_HOOK_INIT(file_lock, smack_file_lock),
  	LSM_HOOK_INIT(file_fcntl, smack_file_fcntl),
  	LSM_HOOK_INIT(mmap_file, smack_mmap_file),
  	LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
  	LSM_HOOK_INIT(file_set_fowner, smack_file_set_fowner),
  	LSM_HOOK_INIT(file_send_sigiotask, smack_file_send_sigiotask),
  	LSM_HOOK_INIT(file_receive, smack_file_receive),
  
  	LSM_HOOK_INIT(file_open, smack_file_open),
  
  	LSM_HOOK_INIT(cred_alloc_blank, smack_cred_alloc_blank),
  	LSM_HOOK_INIT(cred_free, smack_cred_free),
  	LSM_HOOK_INIT(cred_prepare, smack_cred_prepare),
  	LSM_HOOK_INIT(cred_transfer, smack_cred_transfer),
  	LSM_HOOK_INIT(kernel_act_as, smack_kernel_act_as),
  	LSM_HOOK_INIT(kernel_create_files_as, smack_kernel_create_files_as),
  	LSM_HOOK_INIT(task_setpgid, smack_task_setpgid),
  	LSM_HOOK_INIT(task_getpgid, smack_task_getpgid),
  	LSM_HOOK_INIT(task_getsid, smack_task_getsid),
  	LSM_HOOK_INIT(task_getsecid, smack_task_getsecid),
  	LSM_HOOK_INIT(task_setnice, smack_task_setnice),
  	LSM_HOOK_INIT(task_setioprio, smack_task_setioprio),
  	LSM_HOOK_INIT(task_getioprio, smack_task_getioprio),
  	LSM_HOOK_INIT(task_setscheduler, smack_task_setscheduler),
  	LSM_HOOK_INIT(task_getscheduler, smack_task_getscheduler),
  	LSM_HOOK_INIT(task_movememory, smack_task_movememory),
  	LSM_HOOK_INIT(task_kill, smack_task_kill),
  	LSM_HOOK_INIT(task_wait, smack_task_wait),
  	LSM_HOOK_INIT(task_to_inode, smack_task_to_inode),
  
  	LSM_HOOK_INIT(ipc_permission, smack_ipc_permission),
  	LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid),
  
  	LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security),
  	LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security),
  
  	LSM_HOOK_INIT(msg_queue_alloc_security, smack_msg_queue_alloc_security),
  	LSM_HOOK_INIT(msg_queue_free_security, smack_msg_queue_free_security),
  	LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate),
  	LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl),
  	LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd),
  	LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv),
  
  	LSM_HOOK_INIT(shm_alloc_security, smack_shm_alloc_security),
  	LSM_HOOK_INIT(shm_free_security, smack_shm_free_security),
  	LSM_HOOK_INIT(shm_associate, smack_shm_associate),
  	LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl),
  	LSM_HOOK_INIT(shm_shmat, smack_shm_shmat),
  
  	LSM_HOOK_INIT(sem_alloc_security, smack_sem_alloc_security),
  	LSM_HOOK_INIT(sem_free_security, smack_sem_free_security),
  	LSM_HOOK_INIT(sem_associate, smack_sem_associate),
  	LSM_HOOK_INIT(sem_semctl, smack_sem_semctl),
  	LSM_HOOK_INIT(sem_semop, smack_sem_semop),
  
  	LSM_HOOK_INIT(d_instantiate, smack_d_instantiate),
  
  	LSM_HOOK_INIT(getprocattr, smack_getprocattr),
  	LSM_HOOK_INIT(setprocattr, smack_setprocattr),
  
  	LSM_HOOK_INIT(unix_stream_connect, smack_unix_stream_connect),
  	LSM_HOOK_INIT(unix_may_send, smack_unix_may_send),
  
  	LSM_HOOK_INIT(socket_post_create, smack_socket_post_create),
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4612
  #ifdef SMACK_IPV6_PORT_LABELING
e20b043a6   Casey Schaufler   LSM: Add security...
4613
  	LSM_HOOK_INIT(socket_bind, smack_socket_bind),
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4614
  #endif
e20b043a6   Casey Schaufler   LSM: Add security...
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
  	LSM_HOOK_INIT(socket_connect, smack_socket_connect),
  	LSM_HOOK_INIT(socket_sendmsg, smack_socket_sendmsg),
  	LSM_HOOK_INIT(socket_sock_rcv_skb, smack_socket_sock_rcv_skb),
  	LSM_HOOK_INIT(socket_getpeersec_stream, smack_socket_getpeersec_stream),
  	LSM_HOOK_INIT(socket_getpeersec_dgram, smack_socket_getpeersec_dgram),
  	LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security),
  	LSM_HOOK_INIT(sk_free_security, smack_sk_free_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),
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4625

e114e4737   Casey Schaufler   Smack: Simplified...
4626
4627
   /* key management security hooks */
  #ifdef CONFIG_KEYS
e20b043a6   Casey Schaufler   LSM: Add security...
4628
4629
4630
4631
  	LSM_HOOK_INIT(key_alloc, smack_key_alloc),
  	LSM_HOOK_INIT(key_free, smack_key_free),
  	LSM_HOOK_INIT(key_permission, smack_key_permission),
  	LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
e114e4737   Casey Schaufler   Smack: Simplified...
4632
  #endif /* CONFIG_KEYS */
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4633
4634
4635
  
   /* Audit hooks */
  #ifdef CONFIG_AUDIT
e20b043a6   Casey Schaufler   LSM: Add security...
4636
4637
4638
  	LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init),
  	LSM_HOOK_INIT(audit_rule_known, smack_audit_rule_known),
  	LSM_HOOK_INIT(audit_rule_match, smack_audit_rule_match),
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4639
  #endif /* CONFIG_AUDIT */
e20b043a6   Casey Schaufler   LSM: Add security...
4640
4641
4642
  	LSM_HOOK_INIT(ismaclabel, smack_ismaclabel),
  	LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx),
  	LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid),
e20b043a6   Casey Schaufler   LSM: Add security...
4643
4644
4645
  	LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
  	LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
  	LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
e114e4737   Casey Schaufler   Smack: Simplified...
4646
  };
7198e2eeb   Etienne Basset   smack: convert sm...
4647

86812bb0d   Casey Schaufler   Smack: move label...
4648
  static __init void init_smack_known_list(void)
7198e2eeb   Etienne Basset   smack: convert sm...
4649
  {
86812bb0d   Casey Schaufler   Smack: move label...
4650
  	/*
86812bb0d   Casey Schaufler   Smack: move label...
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
  	 * Initialize rule list locks
  	 */
  	mutex_init(&smack_known_huh.smk_rules_lock);
  	mutex_init(&smack_known_hat.smk_rules_lock);
  	mutex_init(&smack_known_floor.smk_rules_lock);
  	mutex_init(&smack_known_star.smk_rules_lock);
  	mutex_init(&smack_known_invalid.smk_rules_lock);
  	mutex_init(&smack_known_web.smk_rules_lock);
  	/*
  	 * Initialize rule lists
  	 */
  	INIT_LIST_HEAD(&smack_known_huh.smk_rules);
  	INIT_LIST_HEAD(&smack_known_hat.smk_rules);
  	INIT_LIST_HEAD(&smack_known_star.smk_rules);
  	INIT_LIST_HEAD(&smack_known_floor.smk_rules);
  	INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
  	INIT_LIST_HEAD(&smack_known_web.smk_rules);
  	/*
  	 * Create the known labels list
  	 */
4d7cf4a1f   Tomasz Stanislawski   security: smack: ...
4671
4672
4673
4674
4675
4676
  	smk_insert_entry(&smack_known_huh);
  	smk_insert_entry(&smack_known_hat);
  	smk_insert_entry(&smack_known_star);
  	smk_insert_entry(&smack_known_floor);
  	smk_insert_entry(&smack_known_invalid);
  	smk_insert_entry(&smack_known_web);
7198e2eeb   Etienne Basset   smack: convert sm...
4677
  }
e114e4737   Casey Schaufler   Smack: Simplified...
4678
4679
4680
4681
4682
4683
4684
  /**
   * smack_init - initialize the smack system
   *
   * Returns 0
   */
  static __init int smack_init(void)
  {
d84f4f992   David Howells   CRED: Inaugurate ...
4685
  	struct cred *cred;
676dac4b1   Casey Schaufler   This patch adds a...
4686
  	struct task_smack *tsp;
d84f4f992   David Howells   CRED: Inaugurate ...
4687

b1d9e6b06   Casey Schaufler   LSM: Switch to li...
4688
  	if (!security_module_enable("smack"))
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
4689
  		return 0;
1a5b472bd   Rohit   Security: smack: ...
4690
4691
4692
  	smack_inode_cache = KMEM_CACHE(inode_smack, 0);
  	if (!smack_inode_cache)
  		return -ENOMEM;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4693
4694
  	tsp = new_task_smack(&smack_known_floor, &smack_known_floor,
  				GFP_KERNEL);
1a5b472bd   Rohit   Security: smack: ...
4695
4696
  	if (tsp == NULL) {
  		kmem_cache_destroy(smack_inode_cache);
676dac4b1   Casey Schaufler   This patch adds a...
4697
  		return -ENOMEM;
1a5b472bd   Rohit   Security: smack: ...
4698
  	}
676dac4b1   Casey Schaufler   This patch adds a...
4699

d21b7b049   José Bollo   Smack: Minor init...
4700
  	smack_enabled = 1;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
  	pr_info("Smack:  Initializing.
  ");
  #ifdef CONFIG_SECURITY_SMACK_NETFILTER
  	pr_info("Smack:  Netfilter enabled.
  ");
  #endif
  #ifdef SMACK_IPV6_PORT_LABELING
  	pr_info("Smack:  IPv6 port labeling enabled.
  ");
  #endif
  #ifdef SMACK_IPV6_SECMARK_LABELING
  	pr_info("Smack:  IPv6 Netfilter enabled.
  ");
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
4715
4716
4717
4718
  
  	/*
  	 * Set the security state for the initial task.
  	 */
d84f4f992   David Howells   CRED: Inaugurate ...
4719
  	cred = (struct cred *) current->cred;
676dac4b1   Casey Schaufler   This patch adds a...
4720
  	cred->security = tsp;
e114e4737   Casey Schaufler   Smack: Simplified...
4721

86812bb0d   Casey Schaufler   Smack: move label...
4722
4723
  	/* initialize the smack_known_list */
  	init_smack_known_list();
e114e4737   Casey Schaufler   Smack: Simplified...
4724
4725
4726
4727
  
  	/*
  	 * Register with LSM
  	 */
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
4728
  	security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks));
e114e4737   Casey Schaufler   Smack: Simplified...
4729
4730
4731
4732
4733
4734
4735
4736
4737
  
  	return 0;
  }
  
  /*
   * Smack requires early initialization in order to label
   * all processes and objects when they are created.
   */
  security_initcall(smack_init);