Blame view

security/smack/smack_lsm.c 119 KB
d2912cb15   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
e114e4737   Casey Schaufler   Smack: Simplified...
2
3
4
5
6
  /*
   *  Simplified MAC Kernel (smack) security module
   *
   *  This file contains the smack hook function implementations.
   *
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
7
   *  Authors:
e114e4737   Casey Schaufler   Smack: Simplified...
8
   *	Casey Schaufler <casey@schaufler-ca.com>
84088ba23   Jarkko Sakkinen   Smack: domain tra...
9
   *	Jarkko Sakkinen <jarkko.sakkinen@intel.com>
e114e4737   Casey Schaufler   Smack: Simplified...
10
11
   *
   *  Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
07feee8f8   Paul Moore   netlabel: Cleanup...
12
   *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
82c21bfab   Paul Moore   doc: Update the e...
13
   *                Paul Moore <paul@paul-moore.com>
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
14
   *  Copyright (C) 2010 Nokia Corporation
84088ba23   Jarkko Sakkinen   Smack: domain tra...
15
   *  Copyright (C) 2011 Intel Corporation.
e114e4737   Casey Schaufler   Smack: Simplified...
16
17
18
19
20
21
   */
  
  #include <linux/xattr.h>
  #include <linux/pagemap.h>
  #include <linux/mount.h>
  #include <linux/stat.h>
e114e4737   Casey Schaufler   Smack: Simplified...
22
23
  #include <linux/kd.h>
  #include <asm/ioctls.h>
07feee8f8   Paul Moore   netlabel: Cleanup...
24
  #include <linux/ip.h>
e114e4737   Casey Schaufler   Smack: Simplified...
25
26
  #include <linux/tcp.h>
  #include <linux/udp.h>
c67394434   Casey Schaufler   Smack: Local IPv6...
27
  #include <linux/dccp.h>
d66a8acbd   Piotr Sawicki   Smack: Inform pee...
28
  #include <linux/icmpv6.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
29
  #include <linux/slab.h>
e114e4737   Casey Schaufler   Smack: Simplified...
30
  #include <linux/mutex.h>
e114e4737   Casey Schaufler   Smack: Simplified...
31
  #include <net/cipso_ipv4.h>
c67394434   Casey Schaufler   Smack: Local IPv6...
32
33
  #include <net/ip.h>
  #include <net/ipv6.h>
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
34
  #include <linux/audit.h>
1fd7317d0   Nick Black   Move magic number...
35
  #include <linux/magic.h>
2a7dba391   Eric Paris   fs/vfs/security: ...
36
  #include <linux/dcache.h>
16014d875   Jarkko Sakkinen   Smack: compilatio...
37
  #include <linux/personality.h>
404015308   Al Viro   security: trim se...
38
39
40
  #include <linux/msg.h>
  #include <linux/shm.h>
  #include <linux/binfmts.h>
3bf2789ca   Vivek Trivedi   smack: allow moun...
41
  #include <linux/parser.h>
2febd254a   David Howells   smack: Implement ...
42
43
  #include <linux/fs_context.h>
  #include <linux/fs_parser.h>
a8478a602   David Howells   smack: Implement ...
44
  #include <linux/watch_queue.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
00720f0e7   Arnd Bergmann   smack: avoid unus...
51
  static DEFINE_MUTEX(smack_ipv6_lock);
8b549ef42   Geliang Tang   smack: smk_ipv6_p...
52
  static LIST_HEAD(smk_ipv6_port_list);
4e328b088   Casey Schaufler   Smack: Create sma...
53
  struct kmem_cache *smack_rule_cache;
69f287ae6   Casey Schaufler   Smack: secmark su...
54
  int smack_enabled;
c67394434   Casey Schaufler   Smack: Local IPv6...
55

c3300aaf9   Al Viro   smack: get rid of...
56
57
58
59
60
61
  #define A(s) {"smack"#s, sizeof("smack"#s) - 1, Opt_##s}
  static struct {
  	const char *name;
  	int len;
  	int opt;
  } smk_mount_opts[] = {
6e7739fc9   Casey Schaufler   Smack: Restore th...
62
  	{"smackfsdef", sizeof("smackfsdef") - 1, Opt_fsdefault},
c3300aaf9   Al Viro   smack: get rid of...
63
  	A(fsdefault), A(fsfloor), A(fshat), A(fsroot), A(fstransmute)
3bf2789ca   Vivek Trivedi   smack: allow moun...
64
  };
c3300aaf9   Al Viro   smack: get rid of...
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  #undef A
  
  static int match_opt_prefix(char *s, int l, char **arg)
  {
  	int i;
  
  	for (i = 0; i < ARRAY_SIZE(smk_mount_opts); i++) {
  		size_t len = smk_mount_opts[i].len;
  		if (len > l || memcmp(s, smk_mount_opts[i].name, len))
  			continue;
  		if (len == l || s[len] != '=')
  			continue;
  		*arg = s + len + 1;
  		return smk_mount_opts[i].opt;
  	}
  	return Opt_error;
  }
3bf2789ca   Vivek Trivedi   smack: allow moun...
82

3d04c9240   Casey Schaufler   Smack - Fix build...
83
84
85
86
87
88
89
  #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...
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  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...
113
114
  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...
115
116
117
118
119
  {
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
  
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
120
121
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
122
123
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
124
125
  	pr_info("Smack %s: (%s %s %s) %s
  ", smk_bu_mess[rc],
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
126
  		sskp->smk_known, oskp->smk_known, acc, note);
d166c8024   Casey Schaufler   Smack: Bring-up a...
127
128
129
  	return 0;
  }
  #else
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
130
  #define smk_bu_note(note, sskp, oskp, mode, RC) (RC)
d166c8024   Casey Schaufler   Smack: Bring-up a...
131
132
133
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
134
135
  static int smk_bu_current(char *note, struct smack_known *oskp,
  			  int mode, int rc)
d166c8024   Casey Schaufler   Smack: Bring-up a...
136
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
137
  	struct task_smack *tsp = smack_cred(current_cred());
d166c8024   Casey Schaufler   Smack: Bring-up a...
138
139
140
141
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
  
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
142
143
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
144
145
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
146
147
  	pr_info("Smack %s: (%s %s %s) %s %s
  ", smk_bu_mess[rc],
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
148
149
  		tsp->smk_task->smk_known, oskp->smk_known,
  		acc, current->comm, note);
d166c8024   Casey Schaufler   Smack: Bring-up a...
150
151
152
  	return 0;
  }
  #else
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
153
  #define smk_bu_current(note, oskp, mode, RC) (RC)
d166c8024   Casey Schaufler   Smack: Bring-up a...
154
155
156
157
158
  #endif
  
  #ifdef CONFIG_SECURITY_SMACK_BRINGUP
  static int smk_bu_task(struct task_struct *otp, int mode, int rc)
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
159
  	struct task_smack *tsp = smack_cred(current_cred());
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
160
  	struct smack_known *smk_task = smk_of_task_struct(otp);
d166c8024   Casey Schaufler   Smack: Bring-up a...
161
162
163
164
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
  
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
165
166
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
167
168
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
169
170
  	pr_info("Smack %s: (%s %s %s) %s to %s
  ", smk_bu_mess[rc],
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
171
  		tsp->smk_task->smk_known, smk_task->smk_known, acc,
d166c8024   Casey Schaufler   Smack: Bring-up a...
172
173
174
175
176
177
178
179
180
181
  		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)
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
182
  	struct task_smack *tsp = smack_cred(current_cred());
fb4021b6f   Casey Schaufler   Smack: Abstract u...
183
  	struct inode_smack *isp = smack_inode(inode);
d166c8024   Casey Schaufler   Smack: Bring-up a...
184
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
185
186
187
188
  	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...
189
190
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
191
192
193
194
195
  	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...
196
197
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
198
199
200
201
  
  	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...
202
203
204
205
206
207
208
209
210
211
  		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)
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
212
  	struct task_smack *tsp = smack_cred(current_cred());
d166c8024   Casey Schaufler   Smack: Bring-up a...
213
  	struct smack_known *sskp = tsp->smk_task;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
214
  	struct inode *inode = file_inode(file);
fb4021b6f   Casey Schaufler   Smack: Abstract u...
215
  	struct inode_smack *isp = smack_inode(inode);
d166c8024   Casey Schaufler   Smack: Bring-up a...
216
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
217
218
219
220
  	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...
221
222
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
223
224
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
225
226
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
227
228
  	pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s
  ", smk_bu_mess[rc],
5e7270a6d   Casey Schaufler   Smack: Rework fil...
229
  		sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
a455589f1   Al Viro   assorted conversi...
230
  		inode->i_sb->s_id, inode->i_ino, file,
d166c8024   Casey Schaufler   Smack: Bring-up a...
231
232
233
234
235
236
237
238
239
240
241
  		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)
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
242
  	struct task_smack *tsp = smack_cred(cred);
d166c8024   Casey Schaufler   Smack: Bring-up a...
243
  	struct smack_known *sskp = tsp->smk_task;
450630975   Al Viro   don't open-code f...
244
  	struct inode *inode = file_inode(file);
fb4021b6f   Casey Schaufler   Smack: Abstract u...
245
  	struct inode_smack *isp = smack_inode(inode);
d166c8024   Casey Schaufler   Smack: Bring-up a...
246
  	char acc[SMK_NUM_ACCESS_TYPE + 1];
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
247
248
249
250
  	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...
251
252
  	if (rc <= 0)
  		return rc;
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
253
254
  	if (rc > SMACK_UNCONFINED_OBJECT)
  		rc = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
255
256
  
  	smk_bu_mode(mode, acc);
bf4b2fee9   Casey Schaufler   Smack: Allow an u...
257
258
  	pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s
  ", smk_bu_mess[rc],
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
259
  		sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
a455589f1   Al Viro   assorted conversi...
260
  		inode->i_sb->s_id, inode->i_ino, file,
d166c8024   Casey Schaufler   Smack: Bring-up a...
261
262
263
264
265
266
  		current->comm);
  	return 0;
  }
  #else
  #define smk_bu_credfile(cred, file, mode, RC) (RC)
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
267
268
  /**
   * smk_fetch - Fetch the smack label from a file.
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
269
   * @name: type of the label (attribute)
e114e4737   Casey Schaufler   Smack: Simplified...
270
271
272
   * @ip: a pointer to the inode
   * @dp: a pointer to the dentry
   *
e774ad683   Lukasz Pawelczyk   smack: pass error...
273
274
   * 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...
275
   */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
276
277
  static struct smack_known *smk_fetch(const char *name, struct inode *ip,
  					struct dentry *dp)
e114e4737   Casey Schaufler   Smack: Simplified...
278
279
  {
  	int rc;
f7112e6c9   Casey Schaufler   Smack: allow for ...
280
  	char *buffer;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
281
  	struct smack_known *skp = NULL;
e114e4737   Casey Schaufler   Smack: Simplified...
282

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

e5bfad3d7   Eric Biggers   smack: use GFP_NO...
286
  	buffer = kzalloc(SMK_LONGLABEL, GFP_NOFS);
f7112e6c9   Casey Schaufler   Smack: allow for ...
287
  	if (buffer == NULL)
e774ad683   Lukasz Pawelczyk   smack: pass error...
288
  		return ERR_PTR(-ENOMEM);
e114e4737   Casey Schaufler   Smack: Simplified...
289

3484eba91   Mark Salyzyn   FROMLIST: Add fla...
290
291
  	rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL,
  			    XATTR_NOSECURITY);
e774ad683   Lukasz Pawelczyk   smack: pass error...
292
293
294
295
296
  	if (rc < 0)
  		skp = ERR_PTR(rc);
  	else if (rc == 0)
  		skp = NULL;
  	else
2f823ff8b   Casey Schaufler   Smack: Improve ac...
297
  		skp = smk_import_entry(buffer, rc);
f7112e6c9   Casey Schaufler   Smack: allow for ...
298
299
  
  	kfree(buffer);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
300
  	return skp;
e114e4737   Casey Schaufler   Smack: Simplified...
301
302
303
  }
  
  /**
afb1cbe37   Casey Schaufler   LSM: Infrastructu...
304
   * init_inode_smack - initialize an inode security blob
a1a07f223   luanshi   smack: fix some k...
305
   * @inode: inode to extract the info from
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
306
   * @skp: a pointer to the Smack label entry to use in the blob
e114e4737   Casey Schaufler   Smack: Simplified...
307
   *
e114e4737   Casey Schaufler   Smack: Simplified...
308
   */
afb1cbe37   Casey Schaufler   LSM: Infrastructu...
309
  static void init_inode_smack(struct inode *inode, struct smack_known *skp)
e114e4737   Casey Schaufler   Smack: Simplified...
310
  {
afb1cbe37   Casey Schaufler   LSM: Infrastructu...
311
  	struct inode_smack *isp = smack_inode(inode);
e114e4737   Casey Schaufler   Smack: Simplified...
312

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
313
  	isp->smk_inode = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
314
  	isp->smk_flags = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
315
  }
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
316
  /**
bbd3662a8   Casey Schaufler   Infrastructure ma...
317
318
   * init_task_smack - initialize a task security blob
   * @tsp: blob to initialize
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
319
320
   * @task: a pointer to the Smack label for the running task
   * @forked: a pointer to the Smack label for the forked task
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
321
   *
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
322
   */
bbd3662a8   Casey Schaufler   Infrastructure ma...
323
324
  static void init_task_smack(struct task_smack *tsp, struct smack_known *task,
  					struct smack_known *forked)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
325
  {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
326
327
328
  	tsp->smk_task = task;
  	tsp->smk_forked = forked;
  	INIT_LIST_HEAD(&tsp->smk_rules);
38416e539   Zbigniew Jasinski   Smack: limited ca...
329
  	INIT_LIST_HEAD(&tsp->smk_relabel);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
330
  	mutex_init(&tsp->smk_rules_lock);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
331
332
333
334
  }
  
  /**
   * smk_copy_rules - copy a rule set
1a28979b3   Lukasz Pawelczyk   smack: miscellane...
335
336
337
   * @nhead: new rules header pointer
   * @ohead: old rules header pointer
   * @gfp: type of the memory for the allocation
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
338
339
340
341
342
343
344
345
346
   *
   * 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;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
347
  	list_for_each_entry_rcu(orp, ohead, list) {
4e328b088   Casey Schaufler   Smack: Create sma...
348
  		nrp = kmem_cache_zalloc(smack_rule_cache, gfp);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
349
350
351
352
353
354
355
356
357
  		if (nrp == NULL) {
  			rc = -ENOMEM;
  			break;
  		}
  		*nrp = *orp;
  		list_add_rcu(&nrp->list, nhead);
  	}
  	return rc;
  }
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
358
  /**
38416e539   Zbigniew Jasinski   Smack: limited ca...
359
360
361
362
363
364
365
366
367
368
369
370
   * 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;
38416e539   Zbigniew Jasinski   Smack: limited ca...
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  	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 ...
385
386
387
388
389
390
391
   * 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...
392
  	if (mode & PTRACE_MODE_ATTACH)
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
393
  		return MAY_READWRITE;
3dfb7d8cd   Jann Horn   security: let sec...
394
395
  	if (mode & PTRACE_MODE_READ)
  		return MAY_READ;
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
396
397
398
399
400
401
402
  
  	return 0;
  }
  
  /**
   * smk_ptrace_rule_check - helper for ptrace access
   * @tracer: tracer process
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
403
   * @tracee_known: label entry of the process that's about to be traced
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
404
405
406
407
408
   * @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...
409
410
  static int smk_ptrace_rule_check(struct task_struct *tracer,
  				 struct smack_known *tracee_known,
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
411
412
413
414
415
  				 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...
416
  	struct smack_known *tracer_known;
dcb569cf6   Casey Schaufler   Smack: ptrace cap...
417
  	const struct cred *tracercred;
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
  	rcu_read_lock();
dcb569cf6   Casey Schaufler   Smack: ptrace cap...
425
  	tracercred = __task_cred(tracer);
b17103a8b   Casey Schaufler   Smack: Abstract u...
426
  	tsp = smack_cred(tracercred);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
427
  	tracer_known = smk_of_task(tsp);
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
428

668678185   Lukasz Pawelczyk   Smack: adds smack...
429
430
431
  	if ((mode & PTRACE_MODE_ATTACH) &&
  	    (smack_ptrace_rule == SMACK_PTRACE_EXACT ||
  	     smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
432
  		if (tracer_known->smk_known == tracee_known->smk_known)
668678185   Lukasz Pawelczyk   Smack: adds smack...
433
434
435
  			rc = 0;
  		else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)
  			rc = -EACCES;
dcb569cf6   Casey Schaufler   Smack: ptrace cap...
436
  		else if (smack_privileged_cred(CAP_SYS_PTRACE, tracercred))
668678185   Lukasz Pawelczyk   Smack: adds smack...
437
438
439
440
441
  			rc = 0;
  		else
  			rc = -EACCES;
  
  		if (saip)
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
442
443
444
  			smack_log(tracer_known->smk_known,
  				  tracee_known->smk_known,
  				  0, rc, saip);
668678185   Lukasz Pawelczyk   Smack: adds smack...
445

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

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

b1d9e6b06   Casey Schaufler   LSM: Switch to li...
476
  	return smk_ptrace_rule_check(current, skp, mode, __func__);
5cd9c58fb   David Howells   security: Fix set...
477
478
479
480
481
482
483
484
  }
  
  /**
   * 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 ...
485
   * Do the capability checks, and require PTRACE_MODE_ATTACH.
5cd9c58fb   David Howells   security: Fix set...
486
487
488
489
   */
  static int smack_ptrace_traceme(struct task_struct *ptp)
  {
  	int rc;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
490
  	struct smack_known *skp;
5cd9c58fb   David Howells   security: Fix set...
491

b17103a8b   Casey Schaufler   Smack: Abstract u...
492
  	skp = smk_of_task(smack_cred(current_cred()));
ecfcc53fe   Etienne Basset   smack: implement ...
493

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

1880eff77   Casey Schaufler   Smack: onlycap li...
509
  	if (smack_privileged(CAP_MAC_OVERRIDE))
e114e4737   Casey Schaufler   Smack: Simplified...
510
  		return 0;
24ea1b6ef   Casey Schaufler   Smack: Rationaliz...
511
  	if (smack_syslog_label != NULL && smack_syslog_label != skp)
e114e4737   Casey Schaufler   Smack: Simplified...
512
513
514
515
  		rc = -EACCES;
  
  	return rc;
  }
e114e4737   Casey Schaufler   Smack: Simplified...
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  /*
   * 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...
534
535
536
537
  	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...
538
  	/*
9f50eda2a   Seth Forshee   Smack: Add suppor...
539
  	 * SMK_SB_INITIALIZED will be zero from kzalloc.
e830b3941   Casey Schaufler   Smack: Add smkfst...
540
  	 */
e114e4737   Casey Schaufler   Smack: Simplified...
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  	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;
  }
12085b14a   Al Viro   smack: switch to ...
556
557
558
  struct smack_mnt_opts {
  	const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute;
  };
e114e4737   Casey Schaufler   Smack: Simplified...
559

204cc0ccf   Al Viro   LSM: hide struct ...
560
561
  static void smack_free_mnt_opts(void *mnt_opts)
  {
12085b14a   Al Viro   smack: switch to ...
562
563
564
565
566
567
  	struct smack_mnt_opts *opts = mnt_opts;
  	kfree(opts->fsdefault);
  	kfree(opts->fsfloor);
  	kfree(opts->fshat);
  	kfree(opts->fsroot);
  	kfree(opts->fstransmute);
204cc0ccf   Al Viro   LSM: hide struct ...
568
569
  	kfree(opts);
  }
e114e4737   Casey Schaufler   Smack: Simplified...
570

55c0e5bd0   Al Viro   smack: take the g...
571
572
573
  static int smack_add_opt(int token, const char *s, void **mnt_opts)
  {
  	struct smack_mnt_opts *opts = *mnt_opts;
e114e4737   Casey Schaufler   Smack: Simplified...
574

55c0e5bd0   Al Viro   smack: take the g...
575
576
577
578
579
  	if (!opts) {
  		opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
  		if (!opts)
  			return -ENOMEM;
  		*mnt_opts = opts;
e114e4737   Casey Schaufler   Smack: Simplified...
580
  	}
55c0e5bd0   Al Viro   smack: take the g...
581
582
  	if (!s)
  		return -ENOMEM;
e114e4737   Casey Schaufler   Smack: Simplified...
583

55c0e5bd0   Al Viro   smack: take the g...
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
  	switch (token) {
  	case Opt_fsdefault:
  		if (opts->fsdefault)
  			goto out_opt_err;
  		opts->fsdefault = s;
  		break;
  	case Opt_fsfloor:
  		if (opts->fsfloor)
  			goto out_opt_err;
  		opts->fsfloor = s;
  		break;
  	case Opt_fshat:
  		if (opts->fshat)
  			goto out_opt_err;
  		opts->fshat = s;
  		break;
  	case Opt_fsroot:
  		if (opts->fsroot)
  			goto out_opt_err;
  		opts->fsroot = s;
  		break;
  	case Opt_fstransmute:
  		if (opts->fstransmute)
  			goto out_opt_err;
  		opts->fstransmute = s;
  		break;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
611
  	return 0;
55c0e5bd0   Al Viro   smack: take the g...
612
613
614
615
616
  
  out_opt_err:
  	pr_warn("Smack: duplicate mount options
  ");
  	return -EINVAL;
e114e4737   Casey Schaufler   Smack: Simplified...
617
  }
0b52075ee   Al Viro   introduce cloning...
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
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
  /**
   * smack_fs_context_dup - Duplicate the security data on fs_context duplication
   * @fc: The new filesystem context.
   * @src_fc: The source filesystem context being duplicated.
   *
   * Returns 0 on success or -ENOMEM on error.
   */
  static int smack_fs_context_dup(struct fs_context *fc,
  				struct fs_context *src_fc)
  {
  	struct smack_mnt_opts *dst, *src = src_fc->security;
  
  	if (!src)
  		return 0;
  
  	fc->security = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
  	if (!fc->security)
  		return -ENOMEM;
  	dst = fc->security;
  
  	if (src->fsdefault) {
  		dst->fsdefault = kstrdup(src->fsdefault, GFP_KERNEL);
  		if (!dst->fsdefault)
  			return -ENOMEM;
  	}
  	if (src->fsfloor) {
  		dst->fsfloor = kstrdup(src->fsfloor, GFP_KERNEL);
  		if (!dst->fsfloor)
  			return -ENOMEM;
  	}
  	if (src->fshat) {
  		dst->fshat = kstrdup(src->fshat, GFP_KERNEL);
  		if (!dst->fshat)
  			return -ENOMEM;
  	}
  	if (src->fsroot) {
  		dst->fsroot = kstrdup(src->fsroot, GFP_KERNEL);
  		if (!dst->fsroot)
  			return -ENOMEM;
  	}
  	if (src->fstransmute) {
  		dst->fstransmute = kstrdup(src->fstransmute, GFP_KERNEL);
  		if (!dst->fstransmute)
  			return -ENOMEM;
  	}
  	return 0;
  }
d7167b149   Al Viro   fs_parse: fold fs...
665
  static const struct fs_parameter_spec smack_fs_parameters[] = {
6e7739fc9   Casey Schaufler   Smack: Restore th...
666
667
668
669
670
671
  	fsparam_string("smackfsdef",		Opt_fsdefault),
  	fsparam_string("smackfsdefault",	Opt_fsdefault),
  	fsparam_string("smackfsfloor",		Opt_fsfloor),
  	fsparam_string("smackfshat",		Opt_fshat),
  	fsparam_string("smackfsroot",		Opt_fsroot),
  	fsparam_string("smackfstransmute",	Opt_fstransmute),
2febd254a   David Howells   smack: Implement ...
672
673
  	{}
  };
2febd254a   David Howells   smack: Implement ...
674
675
676
677
678
679
680
681
682
683
684
685
686
  /**
   * smack_fs_context_parse_param - Parse a single mount parameter
   * @fc: The new filesystem context being constructed.
   * @param: The parameter.
   *
   * Returns 0 on success, -ENOPARAM to pass the parameter on or anything else on
   * error.
   */
  static int smack_fs_context_parse_param(struct fs_context *fc,
  					struct fs_parameter *param)
  {
  	struct fs_parse_result result;
  	int opt, rc;
d7167b149   Al Viro   fs_parse: fold fs...
687
  	opt = fs_parse(fc, smack_fs_parameters, param, &result);
2febd254a   David Howells   smack: Implement ...
688
689
690
691
692
693
694
695
  	if (opt < 0)
  		return opt;
  
  	rc = smack_add_opt(opt, param->string, &fc->security);
  	if (!rc)
  		param->string = NULL;
  	return rc;
  }
d2497e12e   Al Viro   smack: rewrite sm...
696
  static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
3bf2789ca   Vivek Trivedi   smack: allow moun...
697
  {
d2497e12e   Al Viro   smack: rewrite sm...
698
699
  	char *from = options, *to = options;
  	bool first = true;
3bf2789ca   Vivek Trivedi   smack: allow moun...
700

c3300aaf9   Al Viro   smack: get rid of...
701
702
703
704
  	while (1) {
  		char *next = strchr(from, ',');
  		int token, len, rc;
  		char *arg = NULL;
3bf2789ca   Vivek Trivedi   smack: allow moun...
705

c3300aaf9   Al Viro   smack: get rid of...
706
707
708
709
  		if (next)
  			len = next - from;
  		else
  			len = strlen(from);
3bf2789ca   Vivek Trivedi   smack: allow moun...
710

c3300aaf9   Al Viro   smack: get rid of...
711
  		token = match_opt_prefix(from, len, &arg);
d2497e12e   Al Viro   smack: rewrite sm...
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
  		if (token != Opt_error) {
  			arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL);
  			rc = smack_add_opt(token, arg, mnt_opts);
  			if (unlikely(rc)) {
  				kfree(arg);
  				if (*mnt_opts)
  					smack_free_mnt_opts(*mnt_opts);
  				*mnt_opts = NULL;
  				return rc;
  			}
  		} else {
  			if (!first) {	// copy with preceding comma
  				from--;
  				len++;
  			}
  			if (to != from)
  				memmove(to, from, len);
  			to += len;
  			first = false;
3bf2789ca   Vivek Trivedi   smack: allow moun...
731
  		}
c3300aaf9   Al Viro   smack: get rid of...
732
733
734
  		if (!from[len])
  			break;
  		from += len + 1;
3bf2789ca   Vivek Trivedi   smack: allow moun...
735
  	}
d2497e12e   Al Viro   smack: rewrite sm...
736
  	*to = '\0';
3bf2789ca   Vivek Trivedi   smack: allow moun...
737
  	return 0;
3bf2789ca   Vivek Trivedi   smack: allow moun...
738
739
740
741
  }
  
  /**
   * smack_set_mnt_opts - set Smack specific mount options
e114e4737   Casey Schaufler   Smack: Simplified...
742
   * @sb: the file system superblock
a1a07f223   luanshi   smack: fix some k...
743
   * @mnt_opts: Smack mount options
3bf2789ca   Vivek Trivedi   smack: allow moun...
744
745
   * @kern_flags: mount option from kernel space or user space
   * @set_kern_flags: where to store converted mount opts
e114e4737   Casey Schaufler   Smack: Simplified...
746
747
   *
   * Returns 0 on success, an error code on failure
3bf2789ca   Vivek Trivedi   smack: allow moun...
748
749
750
   *
   * Allow filesystems with binary mount data to explicitly set Smack mount
   * labels.
e114e4737   Casey Schaufler   Smack: Simplified...
751
   */
3bf2789ca   Vivek Trivedi   smack: allow moun...
752
  static int smack_set_mnt_opts(struct super_block *sb,
204cc0ccf   Al Viro   LSM: hide struct ...
753
  		void *mnt_opts,
3bf2789ca   Vivek Trivedi   smack: allow moun...
754
755
  		unsigned long kern_flags,
  		unsigned long *set_kern_flags)
e114e4737   Casey Schaufler   Smack: Simplified...
756
757
  {
  	struct dentry *root = sb->s_root;
c6f493d63   David Howells   VFS: security/: d...
758
  	struct inode *inode = d_backing_inode(root);
e114e4737   Casey Schaufler   Smack: Simplified...
759
760
  	struct superblock_smack *sp = sb->s_security;
  	struct inode_smack *isp;
24ea1b6ef   Casey Schaufler   Smack: Rationaliz...
761
  	struct smack_known *skp;
12085b14a   Al Viro   smack: switch to ...
762
763
  	struct smack_mnt_opts *opts = mnt_opts;
  	bool transmute = false;
e114e4737   Casey Schaufler   Smack: Simplified...
764

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

afb1cbe37   Casey Schaufler   LSM: Infrastructu...
768
769
770
771
772
773
  	if (inode->i_security == NULL) {
  		int rc = lsm_inode_alloc(inode);
  
  		if (rc)
  			return rc;
  	}
2097f5992   Himanshu Shukla   smack: parse mnt ...
774
775
776
777
  	if (!smack_privileged(CAP_MAC_ADMIN)) {
  		/*
  		 * Unprivileged mounts don't get to specify Smack values.
  		 */
12085b14a   Al Viro   smack: switch to ...
778
  		if (opts)
2097f5992   Himanshu Shukla   smack: parse mnt ...
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
  			return -EPERM;
  		/*
  		 * Unprivileged mounts get root and default from the caller.
  		 */
  		skp = smk_of_current();
  		sp->smk_root = skp;
  		sp->smk_default = skp;
  		/*
  		 * 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) {
12085b14a   Al Viro   smack: switch to ...
794
  			transmute = true;
2097f5992   Himanshu Shukla   smack: parse mnt ...
795
796
797
  			sp->smk_flags |= SMK_SB_UNTRUSTED;
  		}
  	}
9f50eda2a   Seth Forshee   Smack: Add suppor...
798
  	sp->smk_flags |= SMK_SB_INITIALIZED;
e114e4737   Casey Schaufler   Smack: Simplified...
799

12085b14a   Al Viro   smack: switch to ...
800
801
802
  	if (opts) {
  		if (opts->fsdefault) {
  			skp = smk_import_entry(opts->fsdefault, 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
803
804
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
3bf2789ca   Vivek Trivedi   smack: allow moun...
805
  			sp->smk_default = skp;
12085b14a   Al Viro   smack: switch to ...
806
807
808
  		}
  		if (opts->fsfloor) {
  			skp = smk_import_entry(opts->fsfloor, 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
809
810
811
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
  			sp->smk_floor = skp;
12085b14a   Al Viro   smack: switch to ...
812
813
814
  		}
  		if (opts->fshat) {
  			skp = smk_import_entry(opts->fshat, 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
815
816
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
3bf2789ca   Vivek Trivedi   smack: allow moun...
817
  			sp->smk_hat = skp;
12085b14a   Al Viro   smack: switch to ...
818
819
820
  		}
  		if (opts->fsroot) {
  			skp = smk_import_entry(opts->fsroot, 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
821
822
823
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
  			sp->smk_root = skp;
12085b14a   Al Viro   smack: switch to ...
824
825
826
  		}
  		if (opts->fstransmute) {
  			skp = smk_import_entry(opts->fstransmute, 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
827
828
829
  			if (IS_ERR(skp))
  				return PTR_ERR(skp);
  			sp->smk_root = skp;
12085b14a   Al Viro   smack: switch to ...
830
  			transmute = true;
e114e4737   Casey Schaufler   Smack: Simplified...
831
832
833
834
835
836
  		}
  	}
  
  	/*
  	 * Initialize the root inode.
  	 */
afb1cbe37   Casey Schaufler   LSM: Infrastructu...
837
  	init_inode_smack(inode, sp->smk_root);
e114e4737   Casey Schaufler   Smack: Simplified...
838

afb1cbe37   Casey Schaufler   LSM: Infrastructu...
839
840
  	if (transmute) {
  		isp = smack_inode(inode);
e830b3941   Casey Schaufler   Smack: Add smkfst...
841
  		isp->smk_flags |= SMK_INODE_TRANSMUTE;
afb1cbe37   Casey Schaufler   LSM: Infrastructu...
842
  	}
e830b3941   Casey Schaufler   Smack: Add smkfst...
843

e114e4737   Casey Schaufler   Smack: Simplified...
844
845
846
847
848
849
850
851
852
853
854
855
856
  	return 0;
  }
  
  /**
   * 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 ...
857
858
  	int rc;
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
859
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
860
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
861

ecfcc53fe   Etienne Basset   smack: implement ...
862
  	rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
863
  	rc = smk_bu_current("statfs", sbp->smk_floor, MAY_READ, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
864
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
865
  }
e114e4737   Casey Schaufler   Smack: Simplified...
866
  /*
676dac4b1   Casey Schaufler   This patch adds a...
867
868
   * BPRM hooks
   */
ce8a43219   Casey Schaufler   Smack: Clean up c...
869
  /**
b8bff5992   Eric W. Biederman   exec: Factor secu...
870
   * smack_bprm_creds_for_exec - Update bprm->cred if needed for exec
ce8a43219   Casey Schaufler   Smack: Clean up c...
871
872
   * @bprm: the exec information
   *
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
873
   * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise
ce8a43219   Casey Schaufler   Smack: Clean up c...
874
   */
b8bff5992   Eric W. Biederman   exec: Factor secu...
875
  static int smack_bprm_creds_for_exec(struct linux_binprm *bprm)
676dac4b1   Casey Schaufler   This patch adds a...
876
  {
496ad9aa8   Al Viro   new helper: file_...
877
  	struct inode *inode = file_inode(bprm->file);
b17103a8b   Casey Schaufler   Smack: Abstract u...
878
  	struct task_smack *bsp = smack_cred(bprm->cred);
676dac4b1   Casey Schaufler   This patch adds a...
879
  	struct inode_smack *isp;
809c02e09   Seth Forshee   Smack: Handle lab...
880
  	struct superblock_smack *sbsp;
676dac4b1   Casey Schaufler   This patch adds a...
881
  	int rc;
fb4021b6f   Casey Schaufler   Smack: Abstract u...
882
  	isp = smack_inode(inode);
84088ba23   Jarkko Sakkinen   Smack: domain tra...
883
  	if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
676dac4b1   Casey Schaufler   This patch adds a...
884
  		return 0;
809c02e09   Seth Forshee   Smack: Handle lab...
885
886
887
888
  	sbsp = inode->i_sb->s_security;
  	if ((sbsp->smk_flags & SMK_SB_UNTRUSTED) &&
  	    isp->smk_task != sbsp->smk_root)
  		return 0;
9227dd2a8   Eric W. Biederman   exec: Remove LSM_...
889
  	if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
890
891
892
893
894
895
896
  		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...
897
  						   isp->smk_task,
5663884ca   Lukasz Pawelczyk   Smack: unify all ...
898
899
900
901
902
903
  						   PTRACE_MODE_ATTACH,
  						   __func__);
  		rcu_read_unlock();
  
  		if (rc != 0)
  			return rc;
3675f052b   Jann Horn   Smack: Don't igno...
904
905
  	}
  	if (bprm->unsafe & ~LSM_UNSAFE_PTRACE)
84088ba23   Jarkko Sakkinen   Smack: domain tra...
906
  		return -EPERM;
676dac4b1   Casey Schaufler   This patch adds a...
907

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

ccbb6e106   Kees Cook   smack: Refactor t...
911
912
913
  	/* Decide if this is a secure exec. */
  	if (bsp->smk_task != bsp->smk_forked)
  		bprm->secureexec = 1;
84088ba23   Jarkko Sakkinen   Smack: domain tra...
914
915
  	return 0;
  }
676dac4b1   Casey Schaufler   This patch adds a...
916

676dac4b1   Casey Schaufler   This patch adds a...
917
  /*
e114e4737   Casey Schaufler   Smack: Simplified...
918
919
920
921
922
   * Inode hooks
   */
  
  /**
   * smack_inode_alloc_security - allocate an inode blob
251a2a958   Randy Dunlap   smack: fix lots o...
923
   * @inode: the inode in need of a blob
e114e4737   Casey Schaufler   Smack: Simplified...
924
   *
a1a07f223   luanshi   smack: fix some k...
925
   * Returns 0
e114e4737   Casey Schaufler   Smack: Simplified...
926
927
928
   */
  static int smack_inode_alloc_security(struct inode *inode)
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
929
  	struct smack_known *skp = smk_of_current();
afb1cbe37   Casey Schaufler   LSM: Infrastructu...
930
  	init_inode_smack(inode, skp);
e114e4737   Casey Schaufler   Smack: Simplified...
931
932
933
934
  	return 0;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
935
   * smack_inode_init_security - copy out the smack from an inode
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
936
937
   * @inode: the newly created inode
   * @dir: containing directory object
2a7dba391   Eric Paris   fs/vfs/security: ...
938
   * @qstr: unused
e114e4737   Casey Schaufler   Smack: Simplified...
939
940
941
942
943
944
945
   * @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 -...
946
  				     const struct qstr *qstr, const char **name,
2a7dba391   Eric Paris   fs/vfs/security: ...
947
  				     void **value, size_t *len)
e114e4737   Casey Schaufler   Smack: Simplified...
948
  {
fb4021b6f   Casey Schaufler   Smack: Abstract u...
949
  	struct inode_smack *issp = smack_inode(inode);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
950
  	struct smack_known *skp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
951
952
  	struct smack_known *isp = smk_of_inode(inode);
  	struct smack_known *dsp = smk_of_inode(dir);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
953
  	int may;
e114e4737   Casey Schaufler   Smack: Simplified...
954

9548906b2   Tetsuo Handa   xattr: Constify -...
955
956
  	if (name)
  		*name = XATTR_SMACK_SUFFIX;
e114e4737   Casey Schaufler   Smack: Simplified...
957

68390ccf8   Lukasz Pawelczyk   smack: fix logic ...
958
  	if (value && len) {
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
959
  		rcu_read_lock();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
960
961
  		may = smk_access_entry(skp->smk_known, dsp->smk_known,
  				       &skp->smk_rules);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
962
  		rcu_read_unlock();
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
963
964
965
966
967
  
  		/*
  		 * If the access rule allows transmutation and
  		 * the directory requests transmutation then
  		 * by all means transmute.
2267b13a7   Casey Schaufler   Smack: recursive ...
968
  		 * Mark the inode as changed.
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
969
  		 */
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
970
  		if (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
2267b13a7   Casey Schaufler   Smack: recursive ...
971
  		    smk_inode_transmutable(dir)) {
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
972
  			isp = dsp;
2267b13a7   Casey Schaufler   Smack: recursive ...
973
974
  			issp->smk_flags |= SMK_INODE_CHANGED;
  		}
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
975

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
976
  		*value = kstrdup(isp->smk_known, GFP_NOFS);
e114e4737   Casey Schaufler   Smack: Simplified...
977
978
  		if (*value == NULL)
  			return -ENOMEM;
e114e4737   Casey Schaufler   Smack: Simplified...
979

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
980
  		*len = strlen(isp->smk_known);
68390ccf8   Lukasz Pawelczyk   smack: fix logic ...
981
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
  
  	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...
997
  	struct smack_known *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
998
999
  	struct smk_audit_info ad;
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
1000
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1001
  	smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1002

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

8802565b6   David Howells   Smack: Use d_is_p...
1007
  	if (rc == 0 && d_is_positive(new_dentry)) {
c6f493d63   David Howells   VFS: security/: d...
1008
  		isp = smk_of_inode(d_backing_inode(new_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1009
1010
  		smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
  		rc = smk_curacc(isp, MAY_WRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1011
  		rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_WRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
  	}
  
  	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...
1027
  	struct inode *ip = d_backing_inode(dentry);
ecfcc53fe   Etienne Basset   smack: implement ...
1028
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1029
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
1030
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1031
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1032
1033
1034
  	/*
  	 * You need write access to the thing you're unlinking
  	 */
ecfcc53fe   Etienne Basset   smack: implement ...
1035
  	rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1036
  	rc = smk_bu_inode(ip, MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1037
  	if (rc == 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
1038
1039
1040
  		/*
  		 * You also need write access to the containing directory
  		 */
cdb56b608   Igor Zhbanov   Fix NULL pointer ...
1041
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
1042
1043
  		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...
1044
  		rc = smk_bu_inode(dir, MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1045
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
  	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 ...
1059
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1060
  	int rc;
a269434d2   Eric Paris   LSM: separate LSM...
1061
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1062
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1063
1064
1065
  	/*
  	 * You need write access to the thing you're removing
  	 */
c6f493d63   David Howells   VFS: security/: d...
1066
1067
  	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 ...
1068
  	if (rc == 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
1069
1070
1071
  		/*
  		 * You also need write access to the containing directory
  		 */
cdb56b608   Igor Zhbanov   Fix NULL pointer ...
1072
  		smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
1073
1074
  		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...
1075
  		rc = smk_bu_inode(dir, MAY_WRITE, rc);
ecfcc53fe   Etienne Basset   smack: implement ...
1076
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1077
1078
1079
1080
1081
1082
  
  	return rc;
  }
  
  /**
   * smack_inode_rename - Smack check on rename
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
1083
1084
1085
1086
   * @old_inode: unused
   * @old_dentry: the old object
   * @new_inode: unused
   * @new_dentry: the new object
e114e4737   Casey Schaufler   Smack: Simplified...
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
   *
   * 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...
1099
  	struct smack_known *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
1100
  	struct smk_audit_info ad;
a269434d2   Eric Paris   LSM: separate LSM...
1101
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1102
  	smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1103

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

8802565b6   David Howells   Smack: Use d_is_p...
1108
  	if (rc == 0 && d_is_positive(new_dentry)) {
c6f493d63   David Howells   VFS: security/: d...
1109
  		isp = smk_of_inode(d_backing_inode(new_dentry));
ecfcc53fe   Etienne Basset   smack: implement ...
1110
1111
  		smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry);
  		rc = smk_curacc(isp, MAY_READWRITE, &ad);
c6f493d63   David Howells   VFS: security/: d...
1112
  		rc = smk_bu_inode(d_backing_inode(new_dentry), MAY_READWRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1113
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1114
1115
1116
1117
1118
1119
1120
  	return rc;
  }
  
  /**
   * smack_inode_permission - Smack version of permission()
   * @inode: the inode in question
   * @mask: the access requested
e114e4737   Casey Schaufler   Smack: Simplified...
1121
1122
1123
   *
   * This is the important Smack hook.
   *
a1a07f223   luanshi   smack: fix some k...
1124
   * Returns 0 if access is permitted, an error code otherwise
e114e4737   Casey Schaufler   Smack: Simplified...
1125
   */
e74f71eb7   Al Viro   ->permission() sa...
1126
  static int smack_inode_permission(struct inode *inode, int mask)
e114e4737   Casey Schaufler   Smack: Simplified...
1127
  {
9f50eda2a   Seth Forshee   Smack: Add suppor...
1128
  	struct superblock_smack *sbsp = inode->i_sb->s_security;
ecfcc53fe   Etienne Basset   smack: implement ...
1129
  	struct smk_audit_info ad;
e74f71eb7   Al Viro   ->permission() sa...
1130
  	int no_block = mask & MAY_NOT_BLOCK;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1131
  	int rc;
d09ca7397   Eric Paris   security: make LS...
1132
1133
  
  	mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
e114e4737   Casey Schaufler   Smack: Simplified...
1134
1135
1136
1137
1138
  	/*
  	 * No permission to check. Existence test. Yup, it's there.
  	 */
  	if (mask == 0)
  		return 0;
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
1139

9f50eda2a   Seth Forshee   Smack: Add suppor...
1140
1141
1142
1143
  	if (sbsp->smk_flags & SMK_SB_UNTRUSTED) {
  		if (smk_of_inode(inode) != sbsp->smk_root)
  			return -EACCES;
  	}
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
1144
  	/* May be droppable after audit */
e74f71eb7   Al Viro   ->permission() sa...
1145
  	if (no_block)
8c9e80ed2   Andi Kleen   SECURITY: Move ex...
1146
  		return -ECHILD;
f48b73998   Eric Paris   LSM: split LSM_AU...
1147
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
ecfcc53fe   Etienne Basset   smack: implement ...
1148
  	smk_ad_setfield_u_fs_inode(&ad, inode);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1149
1150
1151
  	rc = smk_curacc(smk_of_inode(inode), mask, &ad);
  	rc = smk_bu_inode(inode, mask, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
  }
  
  /**
   * 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 ...
1163
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1164
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1165
1166
1167
1168
1169
  	/*
  	 * Need to allow for clearing the setuid bit.
  	 */
  	if (iattr->ia_valid & ATTR_FORCE)
  		return 0;
a269434d2   Eric Paris   LSM: separate LSM...
1170
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1171
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
e114e4737   Casey Schaufler   Smack: Simplified...
1172

c6f493d63   David Howells   VFS: security/: d...
1173
1174
  	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...
1175
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1176
1177
1178
1179
  }
  
  /**
   * smack_inode_getattr - Smack check for getting attributes
a1a07f223   luanshi   smack: fix some k...
1180
   * @path: path to extract the info from
e114e4737   Casey Schaufler   Smack: Simplified...
1181
1182
1183
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
3f7036a07   Al Viro   switch security_i...
1184
  static int smack_inode_getattr(const struct path *path)
e114e4737   Casey Schaufler   Smack: Simplified...
1185
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1186
  	struct smk_audit_info ad;
c6f493d63   David Howells   VFS: security/: d...
1187
  	struct inode *inode = d_backing_inode(path->dentry);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1188
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1189

f48b73998   Eric Paris   LSM: split LSM_AU...
1190
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
3f7036a07   Al Viro   switch security_i...
1191
1192
1193
  	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...
1194
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1195
1196
1197
1198
1199
1200
  }
  
  /**
   * smack_inode_setxattr - Smack check for setting xattrs
   * @dentry: the object
   * @name: name of the attribute
e95ef49b7   Lukasz Pawelczyk   Small fixes in co...
1201
1202
   * @value: value of the attribute
   * @size: size of the value
e114e4737   Casey Schaufler   Smack: Simplified...
1203
1204
1205
1206
1207
1208
   * @flags: unused
   *
   * This protects the Smack attribute explicitly.
   *
   * Returns 0 if access is permitted, an error code otherwise
   */
8f0cfa52a   David Howells   xattr: add missin...
1209
1210
  static int smack_inode_setxattr(struct dentry *dentry, const char *name,
  				const void *value, size_t size, int flags)
e114e4737   Casey Schaufler   Smack: Simplified...
1211
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1212
  	struct smk_audit_info ad;
19760ad03   Casey Schaufler   Smack: Prevent th...
1213
1214
1215
1216
  	struct smack_known *skp;
  	int check_priv = 0;
  	int check_import = 0;
  	int check_star = 0;
bcdca225b   Casey Schaufler   Smack: update for...
1217
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1218

19760ad03   Casey Schaufler   Smack: Prevent th...
1219
1220
1221
  	/*
  	 * Check label validity here so import won't fail in post_setxattr
  	 */
bcdca225b   Casey Schaufler   Smack: update for...
1222
1223
  	if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
19760ad03   Casey Schaufler   Smack: Prevent th...
1224
1225
1226
1227
1228
1229
1230
1231
  	    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 ...
1232
  	} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
19760ad03   Casey Schaufler   Smack: Prevent th...
1233
  		check_priv = 1;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1234
1235
1236
  		if (size != TRANS_TRUE_SIZE ||
  		    strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
  			rc = -EINVAL;
bcdca225b   Casey Schaufler   Smack: update for...
1237
1238
  	} else
  		rc = cap_inode_setxattr(dentry, name, value, size, flags);
19760ad03   Casey Schaufler   Smack: Prevent th...
1239
1240
1241
1242
  	if (check_priv && !smack_privileged(CAP_MAC_ADMIN))
  		rc = -EPERM;
  
  	if (rc == 0 && check_import) {
b862e561b   Konstantin Khlebnikov   Smack: handle zer...
1243
  		skp = size ? smk_import_entry(value, size) : NULL;
e774ad683   Lukasz Pawelczyk   smack: pass error...
1244
1245
1246
  		if (IS_ERR(skp))
  			rc = PTR_ERR(skp);
  		else if (skp == NULL || (check_star &&
19760ad03   Casey Schaufler   Smack: Prevent th...
1247
1248
1249
  		    (skp == &smack_known_star || skp == &smack_known_web)))
  			rc = -EINVAL;
  	}
a269434d2   Eric Paris   LSM: separate LSM...
1250
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1251
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1252
  	if (rc == 0) {
c6f493d63   David Howells   VFS: security/: d...
1253
1254
  		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...
1255
  	}
bcdca225b   Casey Schaufler   Smack: update for...
1256
1257
  
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
  }
  
  /**
   * 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...
1271
1272
  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...
1273
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1274
  	struct smack_known *skp;
fb4021b6f   Casey Schaufler   Smack: Abstract u...
1275
  	struct inode_smack *isp = smack_inode(d_backing_inode(dentry));
676dac4b1   Casey Schaufler   This patch adds a...
1276

2f823ff8b   Casey Schaufler   Smack: Improve ac...
1277
1278
1279
1280
  	if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
  		isp->smk_flags |= SMK_INODE_TRANSMUTE;
  		return;
  	}
676dac4b1   Casey Schaufler   This patch adds a...
1281
  	if (strcmp(name, XATTR_NAME_SMACK) == 0) {
9598f4c9e   José Bollo   SMACK: Fix handli...
1282
  		skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
1283
  		if (!IS_ERR(skp))
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1284
  			isp->smk_inode = skp;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1285
  	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
9598f4c9e   José Bollo   SMACK: Fix handli...
1286
  		skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
1287
  		if (!IS_ERR(skp))
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1288
  			isp->smk_task = skp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1289
  	} else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
9598f4c9e   José Bollo   SMACK: Fix handli...
1290
  		skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
1291
  		if (!IS_ERR(skp))
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1292
  			isp->smk_mmap = skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1293
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1294
1295
1296
  
  	return;
  }
ce8a43219   Casey Schaufler   Smack: Clean up c...
1297
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1298
1299
1300
1301
1302
1303
   * 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...
1304
  static int smack_inode_getxattr(struct dentry *dentry, const char *name)
e114e4737   Casey Schaufler   Smack: Simplified...
1305
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1306
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1307
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1308

a269434d2   Eric Paris   LSM: separate LSM...
1309
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1310
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
c6f493d63   David Howells   VFS: security/: d...
1311
1312
  	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...
1313
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1314
  }
ce8a43219   Casey Schaufler   Smack: Clean up c...
1315
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1316
1317
1318
1319
1320
1321
1322
1323
   * 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...
1324
  static int smack_inode_removexattr(struct dentry *dentry, const char *name)
e114e4737   Casey Schaufler   Smack: Simplified...
1325
  {
676dac4b1   Casey Schaufler   This patch adds a...
1326
  	struct inode_smack *isp;
ecfcc53fe   Etienne Basset   smack: implement ...
1327
  	struct smk_audit_info ad;
bcdca225b   Casey Schaufler   Smack: update for...
1328
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1329

bcdca225b   Casey Schaufler   Smack: update for...
1330
1331
  	if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
  	    strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
676dac4b1   Casey Schaufler   This patch adds a...
1332
  	    strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
1333
  	    strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1334
  	    strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
5e9ab593c   Pankaj Kumar   bugfix patch for ...
1335
  	    strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
1880eff77   Casey Schaufler   Smack: onlycap li...
1336
  		if (!smack_privileged(CAP_MAC_ADMIN))
bcdca225b   Casey Schaufler   Smack: update for...
1337
1338
1339
  			rc = -EPERM;
  	} else
  		rc = cap_inode_removexattr(dentry, name);
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1340
1341
  	if (rc != 0)
  		return rc;
a269434d2   Eric Paris   LSM: separate LSM...
1342
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
ecfcc53fe   Etienne Basset   smack: implement ...
1343
  	smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
bcdca225b   Casey Schaufler   Smack: update for...
1344

c6f493d63   David Howells   VFS: security/: d...
1345
1346
  	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 ...
1347
1348
  	if (rc != 0)
  		return rc;
fb4021b6f   Casey Schaufler   Smack: Abstract u...
1349
  	isp = smack_inode(d_backing_inode(dentry));
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1350
1351
1352
1353
  	/*
  	 * Don't do anything special for these.
  	 *	XATTR_NAME_SMACKIPIN
  	 *	XATTR_NAME_SMACKIPOUT
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1354
  	 */
8012495e1   José Bollo   smack: fix cache ...
1355
  	if (strcmp(name, XATTR_NAME_SMACK) == 0) {
fc64005c9   Al Viro   don't bother with...
1356
  		struct super_block *sbp = dentry->d_sb;
8012495e1   José Bollo   smack: fix cache ...
1357
1358
1359
1360
  		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...
1361
  		isp->smk_task = NULL;
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1362
  	else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1363
  		isp->smk_mmap = NULL;
f59bdfba3   Casey Schaufler   Smack: Correctly ...
1364
1365
  	else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
  		isp->smk_flags &= ~SMK_INODE_TRANSMUTE;
676dac4b1   Casey Schaufler   This patch adds a...
1366

f59bdfba3   Casey Schaufler   Smack: Correctly ...
1367
  	return 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1368
1369
1370
1371
1372
1373
1374
  }
  
  /**
   * smack_inode_getsecurity - get smack xattrs
   * @inode: the object
   * @name: attribute name
   * @buffer: where to put the result
57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1375
   * @alloc: duplicate memory
e114e4737   Casey Schaufler   Smack: Simplified...
1376
1377
1378
   *
   * Returns the size of the attribute or an error code
   */
ea861dfd9   Andreas Gruenbacher   security: Make in...
1379
  static int smack_inode_getsecurity(struct inode *inode,
e114e4737   Casey Schaufler   Smack: Simplified...
1380
1381
1382
1383
1384
1385
1386
  				   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...
1387
  	struct smack_known *isp;
e114e4737   Casey Schaufler   Smack: Simplified...
1388

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1389
  	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0)
e114e4737   Casey Schaufler   Smack: Simplified...
1390
  		isp = smk_of_inode(inode);
57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1391
1392
1393
1394
1395
1396
1397
  	else {
  		/*
  		 * The rest of the Smack xattrs are only on sockets.
  		 */
  		sbp = ip->i_sb;
  		if (sbp->s_magic != SOCKFS_MAGIC)
  			return -EOPNOTSUPP;
e114e4737   Casey Schaufler   Smack: Simplified...
1398

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1399
1400
1401
  		sock = SOCKET_I(ip);
  		if (sock == NULL || sock->sk == NULL)
  			return -EOPNOTSUPP;
e114e4737   Casey Schaufler   Smack: Simplified...
1402

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1403
  		ssp = sock->sk->sk_security;
e114e4737   Casey Schaufler   Smack: Simplified...
1404

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1405
1406
1407
1408
1409
1410
1411
  		if (strcmp(name, XATTR_SMACK_IPIN) == 0)
  			isp = ssp->smk_in;
  		else if (strcmp(name, XATTR_SMACK_IPOUT) == 0)
  			isp = ssp->smk_out;
  		else
  			return -EOPNOTSUPP;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1412

57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1413
1414
1415
1416
  	if (alloc) {
  		*buffer = kstrdup(isp->smk_known, GFP_KERNEL);
  		if (*buffer == NULL)
  			return -ENOMEM;
e114e4737   Casey Schaufler   Smack: Simplified...
1417
  	}
57e7ba04d   Casey Schaufler   lsm: fix smack_in...
1418
  	return strlen(isp->smk_known);
e114e4737   Casey Schaufler   Smack: Simplified...
1419
1420
1421
1422
1423
1424
1425
1426
  }
  
  
  /**
   * smack_inode_listsecurity - list the Smack attributes
   * @inode: the object
   * @buffer: where they go
   * @buffer_size: size of buffer
e114e4737   Casey Schaufler   Smack: Simplified...
1427
1428
1429
1430
   */
  static int smack_inode_listsecurity(struct inode *inode, char *buffer,
  				    size_t buffer_size)
  {
fd5c9d230   Konstantin Khlebnikov   Smack: fix behavi...
1431
  	int len = sizeof(XATTR_NAME_SMACK);
e114e4737   Casey Schaufler   Smack: Simplified...
1432

fd5c9d230   Konstantin Khlebnikov   Smack: fix behavi...
1433
  	if (buffer != NULL && len <= buffer_size)
e114e4737   Casey Schaufler   Smack: Simplified...
1434
  		memcpy(buffer, XATTR_NAME_SMACK, len);
fd5c9d230   Konstantin Khlebnikov   Smack: fix behavi...
1435
1436
  
  	return len;
e114e4737   Casey Schaufler   Smack: Simplified...
1437
  }
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1438
1439
1440
1441
1442
  /**
   * 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...
1443
  static void smack_inode_getsecid(struct inode *inode, u32 *secid)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1444
  {
0f8983cf9   Casey Schaufler   Smack: Fix memory...
1445
  	struct smack_known *skp = smk_of_inode(inode);
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1446

0f8983cf9   Casey Schaufler   Smack: Fix memory...
1447
  	*secid = skp->smk_secid;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
1448
  }
e114e4737   Casey Schaufler   Smack: Simplified...
1449
1450
1451
  /*
   * File Hooks
   */
491a0b08d   Casey Schaufler   Smack: Remove poi...
1452
1453
  /*
   * There is no smack_file_permission hook
e114e4737   Casey Schaufler   Smack: Simplified...
1454
1455
1456
1457
1458
1459
1460
1461
   *
   * 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...
1462
1463
1464
1465
1466
1467
1468
1469
  
  /**
   * 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...
1470
1471
1472
   * 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...
1473
1474
1475
1476
   * Returns 0
   */
  static int smack_file_alloc_security(struct file *file)
  {
f28952ac9   Casey Schaufler   Smack: Abstract u...
1477
  	struct smack_known **blob = smack_file(file);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1478

f28952ac9   Casey Schaufler   Smack: Abstract u...
1479
  	*blob = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
1480
1481
1482
1483
  	return 0;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
   * 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 ...
1497
  	struct smk_audit_info ad;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1498
  	struct inode *inode = file_inode(file);
ecfcc53fe   Etienne Basset   smack: implement ...
1499

83a1e53f3   Seung-Woo Kim   Smack: ignore pri...
1500
1501
  	if (unlikely(IS_PRIVATE(inode)))
  		return 0;
f48b73998   Eric Paris   LSM: split LSM_AU...
1502
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
ecfcc53fe   Etienne Basset   smack: implement ...
1503
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
e114e4737   Casey Schaufler   Smack: Simplified...
1504

d166c8024   Casey Schaufler   Smack: Bring-up a...
1505
  	if (_IOC_DIR(cmd) & _IOC_WRITE) {
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1506
  		rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1507
1508
  		rc = smk_bu_file(file, MAY_WRITE, rc);
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1509

d166c8024   Casey Schaufler   Smack: Bring-up a...
1510
  	if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) {
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1511
  		rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1512
1513
  		rc = smk_bu_file(file, MAY_READ, rc);
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1514
1515
1516
1517
1518
1519
1520
  
  	return rc;
  }
  
  /**
   * smack_file_lock - Smack check on file locking
   * @file: the object
251a2a958   Randy Dunlap   smack: fix lots o...
1521
   * @cmd: unused
e114e4737   Casey Schaufler   Smack: Simplified...
1522
   *
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1523
   * Returns 0 if current has lock access, error code otherwise
e114e4737   Casey Schaufler   Smack: Simplified...
1524
1525
1526
   */
  static int smack_file_lock(struct file *file, unsigned int cmd)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
1527
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
1528
  	int rc;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1529
  	struct inode *inode = file_inode(file);
ecfcc53fe   Etienne Basset   smack: implement ...
1530

83a1e53f3   Seung-Woo Kim   Smack: ignore pri...
1531
1532
  	if (unlikely(IS_PRIVATE(inode)))
  		return 0;
92f425090   Eric Paris   SMACK: smack_file...
1533
1534
  	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...
1535
  	rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1536
1537
  	rc = smk_bu_file(file, MAY_LOCK, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1538
1539
1540
1541
1542
1543
1544
1545
  }
  
  /**
   * smack_file_fcntl - Smack check on fcntl
   * @file: the object
   * @cmd: what action to check
   * @arg: unused
   *
531f1d453   Casey Schaufler   Smack: Repair pro...
1546
1547
1548
1549
   * 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...
1550
1551
1552
1553
1554
   * 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 ...
1555
  	struct smk_audit_info ad;
531f1d453   Casey Schaufler   Smack: Repair pro...
1556
  	int rc = 0;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1557
  	struct inode *inode = file_inode(file);
ecfcc53fe   Etienne Basset   smack: implement ...
1558

83a1e53f3   Seung-Woo Kim   Smack: ignore pri...
1559
1560
  	if (unlikely(IS_PRIVATE(inode)))
  		return 0;
e114e4737   Casey Schaufler   Smack: Simplified...
1561
  	switch (cmd) {
e114e4737   Casey Schaufler   Smack: Simplified...
1562
  	case F_GETLK:
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1563
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1564
1565
  	case F_SETLK:
  	case F_SETLKW:
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1566
1567
  		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...
1568
  		rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1569
  		rc = smk_bu_file(file, MAY_LOCK, rc);
c0ab6e56d   Casey Schaufler   Smack: Implement ...
1570
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1571
1572
  	case F_SETOWN:
  	case F_SETSIG:
531f1d453   Casey Schaufler   Smack: Repair pro...
1573
1574
  		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...
1575
  		rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1576
  		rc = smk_bu_file(file, MAY_WRITE, rc);
e114e4737   Casey Schaufler   Smack: Simplified...
1577
1578
  		break;
  	default:
531f1d453   Casey Schaufler   Smack: Repair pro...
1579
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
1580
1581
1582
1583
1584
1585
  	}
  
  	return rc;
  }
  
  /**
e5467859f   Al Viro   split ->file_mmap...
1586
   * smack_mmap_file :
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1587
1588
1589
1590
1591
1592
1593
1594
   * 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...
1595
  static int smack_mmap_file(struct file *file,
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1596
  			   unsigned long reqprot, unsigned long prot,
e5467859f   Al Viro   split ->file_mmap...
1597
  			   unsigned long flags)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1598
  {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1599
  	struct smack_known *skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1600
  	struct smack_known *mkp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1601
1602
  	struct smack_rule *srp;
  	struct task_smack *tsp;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1603
  	struct smack_known *okp;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1604
  	struct inode_smack *isp;
809c02e09   Seth Forshee   Smack: Handle lab...
1605
  	struct superblock_smack *sbsp;
0e0a070d3   Casey Schaufler   Smack: correct be...
1606
1607
1608
  	int may;
  	int mmay;
  	int tmay;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1609
  	int rc;
496ad9aa8   Al Viro   new helper: file_...
1610
  	if (file == NULL)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1611
  		return 0;
83a1e53f3   Seung-Woo Kim   Smack: ignore pri...
1612
1613
  	if (unlikely(IS_PRIVATE(file_inode(file))))
  		return 0;
fb4021b6f   Casey Schaufler   Smack: Abstract u...
1614
  	isp = smack_inode(file_inode(file));
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1615
1616
  	if (isp->smk_mmap == NULL)
  		return 0;
809c02e09   Seth Forshee   Smack: Handle lab...
1617
1618
1619
1620
  	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...
1621
  	mkp = isp->smk_mmap;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1622

b17103a8b   Casey Schaufler   Smack: Abstract u...
1623
  	tsp = smack_cred(current_cred());
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1624
  	skp = smk_of_current();
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1625
1626
1627
1628
1629
1630
1631
  	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] ...
1632
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
1633
  	list_for_each_entry_rcu(srp, &skp->smk_rules, list) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1634
  		okp = srp->smk_object;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1635
1636
1637
  		/*
  		 * Matching labels always allows access.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1638
  		if (mkp->smk_known == okp->smk_known)
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1639
  			continue;
0e0a070d3   Casey Schaufler   Smack: correct be...
1640
1641
1642
1643
  		/*
  		 * If there is a matching local rule take
  		 * that into account as well.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1644
1645
1646
  		may = smk_access_entry(srp->smk_subject->smk_known,
  				       okp->smk_known,
  				       &tsp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
  		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...
1663
1664
  		mmay = smk_access_entry(mkp->smk_known, okp->smk_known,
  					&mkp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1665
1666
1667
1668
1669
1670
1671
1672
  		if (mmay == -ENOENT) {
  			rc = -EACCES;
  			break;
  		}
  		/*
  		 * If there is a local entry it modifies the
  		 * potential access, too.
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1673
1674
  		tmay = smk_access_entry(mkp->smk_known, okp->smk_known,
  					&tsp->smk_rules);
0e0a070d3   Casey Schaufler   Smack: correct be...
1675
1676
  		if (tmay != -ENOENT)
  			mmay &= tmay;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1677

0e0a070d3   Casey Schaufler   Smack: correct be...
1678
1679
1680
1681
1682
  		/*
  		 * If there is any access available to current that is
  		 * not available to a SMACK64MMAP subject
  		 * deny access.
  		 */
75a25637b   Casey Schaufler   Smack: correct fi...
1683
  		if ((may | mmay) != mmay) {
0e0a070d3   Casey Schaufler   Smack: correct be...
1684
  			rc = -EACCES;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1685
  			break;
0e0a070d3   Casey Schaufler   Smack: correct be...
1686
  		}
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1687
1688
1689
1690
1691
1692
1693
1694
  	}
  
  	rcu_read_unlock();
  
  	return rc;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1695
1696
1697
   * smack_file_set_fowner - set the file security blob value
   * @file: object in question
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1698
   */
e0b93eddf   Jeff Layton   security: make se...
1699
  static void smack_file_set_fowner(struct file *file)
e114e4737   Casey Schaufler   Smack: Simplified...
1700
  {
f28952ac9   Casey Schaufler   Smack: Abstract u...
1701
1702
1703
  	struct smack_known **blob = smack_file(file);
  
  	*blob = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
  }
  
  /**
   * 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)
  {
f28952ac9   Casey Schaufler   Smack: Abstract u...
1720
  	struct smack_known **blob;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1721
  	struct smack_known *skp;
b17103a8b   Casey Schaufler   Smack: Abstract u...
1722
  	struct smack_known *tkp = smk_of_task(smack_cred(tsk->cred));
dcb569cf6   Casey Schaufler   Smack: ptrace cap...
1723
  	const struct cred *tcred;
e114e4737   Casey Schaufler   Smack: Simplified...
1724
1725
  	struct file *file;
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1726
  	struct smk_audit_info ad;
e114e4737   Casey Schaufler   Smack: Simplified...
1727
1728
1729
1730
1731
  
  	/*
  	 * 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] ...
1732

ecfcc53fe   Etienne Basset   smack: implement ...
1733
  	/* we don't log here as rc can be overriden */
f28952ac9   Casey Schaufler   Smack: Abstract u...
1734
1735
  	blob = smack_file(file);
  	skp = *blob;
c60b90667   Casey Schaufler   Smack: Signal del...
1736
1737
  	rc = smk_access(skp, tkp, MAY_DELIVER, NULL);
  	rc = smk_bu_note("sigiotask", skp, tkp, MAY_DELIVER, rc);
dcb569cf6   Casey Schaufler   Smack: ptrace cap...
1738
1739
1740
1741
  
  	rcu_read_lock();
  	tcred = __task_cred(tsk);
  	if (rc != 0 && smack_privileged_cred(CAP_MAC_OVERRIDE, tcred))
ecfcc53fe   Etienne Basset   smack: implement ...
1742
  		rc = 0;
dcb569cf6   Casey Schaufler   Smack: ptrace cap...
1743
  	rcu_read_unlock();
ecfcc53fe   Etienne Basset   smack: implement ...
1744
1745
1746
  
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, tsk);
c60b90667   Casey Schaufler   Smack: Signal del...
1747
  	smack_log(skp->smk_known, tkp->smk_known, MAY_DELIVER, rc, &ad);
e114e4737   Casey Schaufler   Smack: Simplified...
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
  	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...
1759
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1760
  	int may = 0;
ecfcc53fe   Etienne Basset   smack: implement ...
1761
  	struct smk_audit_info ad;
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1762
  	struct inode *inode = file_inode(file);
79be09350   Casey Schaufler   Smack: File recei...
1763
1764
1765
  	struct socket *sock;
  	struct task_smack *tsp;
  	struct socket_smack *ssp;
e114e4737   Casey Schaufler   Smack: Simplified...
1766

9777582e8   Seung-Woo Kim   Smack: ignore pri...
1767
1768
  	if (unlikely(IS_PRIVATE(inode)))
  		return 0;
4482a44f6   Casey Schaufler   Smack: File recei...
1769
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
ecfcc53fe   Etienne Basset   smack: implement ...
1770
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
79be09350   Casey Schaufler   Smack: File recei...
1771

51d59af26   Casey Schaufler   Smack: Safer chec...
1772
  	if (inode->i_sb->s_magic == SOCKFS_MAGIC) {
79be09350   Casey Schaufler   Smack: File recei...
1773
1774
  		sock = SOCKET_I(inode);
  		ssp = sock->sk->sk_security;
b17103a8b   Casey Schaufler   Smack: Abstract u...
1775
  		tsp = smack_cred(current_cred());
79be09350   Casey Schaufler   Smack: File recei...
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
  		/*
  		 * 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...
1790
1791
1792
1793
1794
1795
1796
  	/*
  	 * 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...
1797
  	rc = smk_curacc(smk_of_inode(inode), may, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1798
1799
  	rc = smk_bu_file(file, may, rc);
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
1800
  }
531f1d453   Casey Schaufler   Smack: Repair pro...
1801
  /**
83d498569   Eric Paris   SELinux: rename d...
1802
   * smack_file_open - Smack dentry open processing
531f1d453   Casey Schaufler   Smack: Repair pro...
1803
   * @file: the object
531f1d453   Casey Schaufler   Smack: Repair pro...
1804
1805
   *
   * Set the security blob in the file structure.
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1806
1807
1808
   * 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...
1809
   *
a1a07f223   luanshi   smack: fix some k...
1810
   * Returns 0 if current has access, error code otherwise
531f1d453   Casey Schaufler   Smack: Repair pro...
1811
   */
948176920   Al Viro   ->file_open(): lo...
1812
  static int smack_file_open(struct file *file)
531f1d453   Casey Schaufler   Smack: Repair pro...
1813
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
1814
  	struct task_smack *tsp = smack_cred(file->f_cred);
5e7270a6d   Casey Schaufler   Smack: Rework fil...
1815
  	struct inode *inode = file_inode(file);
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1816
1817
  	struct smk_audit_info ad;
  	int rc;
531f1d453   Casey Schaufler   Smack: Repair pro...
1818

a6834c0b9   Casey Schaufler   Smack: Verify rea...
1819
1820
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
  	smk_ad_setfield_u_fs_path(&ad, file->f_path);
c9d238a18   Himanshu Shukla   SMACK: Use smk_ts...
1821
  	rc = smk_tskacc(tsp, smk_of_inode(inode), MAY_READ, &ad);
948176920   Al Viro   ->file_open(): lo...
1822
  	rc = smk_bu_credfile(file->f_cred, file, MAY_READ, rc);
a6834c0b9   Casey Schaufler   Smack: Verify rea...
1823
1824
  
  	return rc;
531f1d453   Casey Schaufler   Smack: Repair pro...
1825
  }
e114e4737   Casey Schaufler   Smack: Simplified...
1826
1827
1828
1829
1830
  /*
   * Task hooks
   */
  
  /**
ee18d64c1   David Howells   KEYS: Add a keyct...
1831
   * smack_cred_alloc_blank - "allocate" blank task-level security credentials
a1a07f223   luanshi   smack: fix some k...
1832
   * @cred: the new credentials
ee18d64c1   David Howells   KEYS: Add a keyct...
1833
1834
1835
1836
1837
1838
1839
1840
   * @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)
  {
bbd3662a8   Casey Schaufler   Infrastructure ma...
1841
  	init_task_smack(smack_cred(cred), NULL, NULL);
ee18d64c1   David Howells   KEYS: Add a keyct...
1842
1843
1844
1845
1846
  	return 0;
  }
  
  
  /**
f1752eec6   David Howells   CRED: Detach the ...
1847
1848
   * smack_cred_free - "free" task-level security credentials
   * @cred: the credentials in question
e114e4737   Casey Schaufler   Smack: Simplified...
1849
   *
e114e4737   Casey Schaufler   Smack: Simplified...
1850
   */
f1752eec6   David Howells   CRED: Detach the ...
1851
  static void smack_cred_free(struct cred *cred)
e114e4737   Casey Schaufler   Smack: Simplified...
1852
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
1853
  	struct task_smack *tsp = smack_cred(cred);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1854
1855
1856
  	struct smack_rule *rp;
  	struct list_head *l;
  	struct list_head *n;
38416e539   Zbigniew Jasinski   Smack: limited ca...
1857
  	smk_destroy_label_list(&tsp->smk_relabel);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1858
1859
1860
  	list_for_each_safe(l, n, &tsp->smk_rules) {
  		rp = list_entry(l, struct smack_rule, list);
  		list_del(&rp->list);
4e328b088   Casey Schaufler   Smack: Create sma...
1861
  		kmem_cache_free(smack_rule_cache, rp);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1862
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
1863
1864
1865
  }
  
  /**
d84f4f992   David Howells   CRED: Inaugurate ...
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
   * 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)
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
1876
  	struct task_smack *old_tsp = smack_cred(old);
bbd3662a8   Casey Schaufler   Infrastructure ma...
1877
  	struct task_smack *new_tsp = smack_cred(new);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1878
  	int rc;
676dac4b1   Casey Schaufler   This patch adds a...
1879

bbd3662a8   Casey Schaufler   Infrastructure ma...
1880
  	init_task_smack(new_tsp, old_tsp->smk_task, old_tsp->smk_task);
b437aba85   Himanshu Shukla   SMACK: Fix the me...
1881

7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1882
1883
1884
  	rc = smk_copy_rules(&new_tsp->smk_rules, &old_tsp->smk_rules, gfp);
  	if (rc != 0)
  		return rc;
38416e539   Zbigniew Jasinski   Smack: limited ca...
1885
1886
  	rc = smk_copy_relabel(&new_tsp->smk_relabel, &old_tsp->smk_relabel,
  				gfp);
bbd3662a8   Casey Schaufler   Infrastructure ma...
1887
  	return rc;
d84f4f992   David Howells   CRED: Inaugurate ...
1888
  }
251a2a958   Randy Dunlap   smack: fix lots o...
1889
  /**
ee18d64c1   David Howells   KEYS: Add a keyct...
1890
1891
1892
1893
1894
1895
1896
1897
   * 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)
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
1898
1899
  	struct task_smack *old_tsp = smack_cred(old);
  	struct task_smack *new_tsp = smack_cred(new);
676dac4b1   Casey Schaufler   This patch adds a...
1900
1901
1902
  
  	new_tsp->smk_task = old_tsp->smk_task;
  	new_tsp->smk_forked = old_tsp->smk_task;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1903
1904
  	mutex_init(&new_tsp->smk_rules_lock);
  	INIT_LIST_HEAD(&new_tsp->smk_rules);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
1905
  	/* cbs copy rule list */
ee18d64c1   David Howells   KEYS: Add a keyct...
1906
1907
1908
  }
  
  /**
3ec301132   Matthew Garrett   security: Add a c...
1909
   * smack_cred_getsecid - get the secid corresponding to a creds structure
a1a07f223   luanshi   smack: fix some k...
1910
   * @cred: the object creds
3ec301132   Matthew Garrett   security: Add a c...
1911
1912
1913
1914
   * @secid: where to put the result
   *
   * Sets the secid to contain a u32 version of the smack label.
   */
b17103a8b   Casey Schaufler   Smack: Abstract u...
1915
  static void smack_cred_getsecid(const struct cred *cred, u32 *secid)
3ec301132   Matthew Garrett   security: Add a c...
1916
1917
1918
1919
  {
  	struct smack_known *skp;
  
  	rcu_read_lock();
b17103a8b   Casey Schaufler   Smack: Abstract u...
1920
  	skp = smk_of_task(smack_cred(cred));
3ec301132   Matthew Garrett   security: Add a c...
1921
1922
1923
1924
1925
  	*secid = skp->smk_secid;
  	rcu_read_unlock();
  }
  
  /**
3a3b7ce93   David Howells   CRED: Allow kerne...
1926
   * smack_kernel_act_as - Set the subjective context in a set of credentials
251a2a958   Randy Dunlap   smack: fix lots o...
1927
1928
   * @new: points to the set of credentials to be modified.
   * @secid: specifies the security ID to be set
3a3b7ce93   David Howells   CRED: Allow kerne...
1929
1930
1931
1932
1933
   *
   * Set the security data for a kernel service.
   */
  static int smack_kernel_act_as(struct cred *new, u32 secid)
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
1934
  	struct task_smack *new_tsp = smack_cred(new);
3a3b7ce93   David Howells   CRED: Allow kerne...
1935

152f91d4d   Casey Schaufler   Smack: Remove unn...
1936
  	new_tsp->smk_task = smack_from_secid(secid);
3a3b7ce93   David Howells   CRED: Allow kerne...
1937
1938
1939
1940
1941
  	return 0;
  }
  
  /**
   * smack_kernel_create_files_as - Set the file creation label in a set of creds
251a2a958   Randy Dunlap   smack: fix lots o...
1942
1943
   * @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...
1944
1945
1946
1947
1948
1949
1950
   *
   * 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)
  {
fb4021b6f   Casey Schaufler   Smack: Abstract u...
1951
  	struct inode_smack *isp = smack_inode(inode);
b17103a8b   Casey Schaufler   Smack: Abstract u...
1952
  	struct task_smack *tsp = smack_cred(new);
3a3b7ce93   David Howells   CRED: Allow kerne...
1953

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1954
  	tsp->smk_forked = isp->smk_inode;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
1955
  	tsp->smk_task = tsp->smk_forked;
3a3b7ce93   David Howells   CRED: Allow kerne...
1956
1957
1958
1959
  	return 0;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
1960
1961
   * smk_curacc_on_task - helper to log task related access
   * @p: the task object
531f1d453   Casey Schaufler   Smack: Repair pro...
1962
1963
   * @access: the access requested
   * @caller: name of the calling function for audit
ecfcc53fe   Etienne Basset   smack: implement ...
1964
1965
1966
   *
   * Return 0 if access is permitted
   */
531f1d453   Casey Schaufler   Smack: Repair pro...
1967
1968
  static int smk_curacc_on_task(struct task_struct *p, int access,
  				const char *caller)
ecfcc53fe   Etienne Basset   smack: implement ...
1969
1970
  {
  	struct smk_audit_info ad;
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
1971
  	struct smack_known *skp = smk_of_task_struct(p);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1972
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1973

531f1d453   Casey Schaufler   Smack: Repair pro...
1974
  	smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
ecfcc53fe   Etienne Basset   smack: implement ...
1975
  	smk_ad_setfield_u_tsk(&ad, p);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
1976
  	rc = smk_curacc(skp, access, &ad);
d166c8024   Casey Schaufler   Smack: Bring-up a...
1977
1978
  	rc = smk_bu_task(p, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
1979
1980
1981
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
1982
1983
1984
1985
1986
1987
1988
1989
   * 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...
1990
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
  }
  
  /**
   * 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...
2001
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
  }
  
  /**
   * 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...
2012
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
  }
  
  /**
   * 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...
2024
  	struct smack_known *skp = smk_of_task_struct(p);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2025
2026
  
  	*secid = skp->smk_secid;
e114e4737   Casey Schaufler   Smack: Simplified...
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
  }
  
  /**
   * 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...
2038
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
  }
  
  /**
   * 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...
2050
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
  }
  
  /**
   * 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...
2061
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2062
2063
2064
2065
2066
  }
  
  /**
   * smack_task_setscheduler - Smack check on setting scheduler
   * @p: the task object
e114e4737   Casey Schaufler   Smack: Simplified...
2067
2068
2069
   *
   * Return 0 if read access is permitted
   */
b0ae19811   KOSAKI Motohiro   security: remove ...
2070
  static int smack_task_setscheduler(struct task_struct *p)
e114e4737   Casey Schaufler   Smack: Simplified...
2071
  {
b1d9e6b06   Casey Schaufler   LSM: Switch to li...
2072
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
  }
  
  /**
   * 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...
2083
  	return smk_curacc_on_task(p, MAY_READ, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
  }
  
  /**
   * 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...
2094
  	return smk_curacc_on_task(p, MAY_WRITE, __func__);
e114e4737   Casey Schaufler   Smack: Simplified...
2095
2096
2097
2098
2099
2100
2101
  }
  
  /**
   * smack_task_kill - Smack check on signal delivery
   * @p: the task object
   * @info: unused
   * @sig: unused
6b4f3d010   Stephen Smalley   usb, signal, secu...
2102
   * @cred: identifies the cred to use in lieu of current's
e114e4737   Casey Schaufler   Smack: Simplified...
2103
2104
2105
   *
   * Return 0 if write access is permitted
   *
e114e4737   Casey Schaufler   Smack: Simplified...
2106
   */
ae7795bc6   Eric W. Biederman   signal: Distingui...
2107
  static int smack_task_kill(struct task_struct *p, struct kernel_siginfo *info,
6b4f3d010   Stephen Smalley   usb, signal, secu...
2108
  			   int sig, const struct cred *cred)
e114e4737   Casey Schaufler   Smack: Simplified...
2109
  {
ecfcc53fe   Etienne Basset   smack: implement ...
2110
  	struct smk_audit_info ad;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2111
  	struct smack_known *skp;
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2112
  	struct smack_known *tkp = smk_of_task_struct(p);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2113
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2114

18d872f77   Rafal Krypa   Smack: ignore nul...
2115
2116
  	if (!sig)
  		return 0; /* null signal; existence test */
ecfcc53fe   Etienne Basset   smack: implement ...
2117
2118
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
  	smk_ad_setfield_u_tsk(&ad, p);
e114e4737   Casey Schaufler   Smack: Simplified...
2119
  	/*
e114e4737   Casey Schaufler   Smack: Simplified...
2120
2121
2122
  	 * Sending a signal requires that the sender
  	 * can write the receiver.
  	 */
6b4f3d010   Stephen Smalley   usb, signal, secu...
2123
  	if (cred == NULL) {
c60b90667   Casey Schaufler   Smack: Signal del...
2124
2125
  		rc = smk_curacc(tkp, MAY_DELIVER, &ad);
  		rc = smk_bu_task(p, MAY_DELIVER, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
2126
2127
  		return rc;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
2128
  	/*
6b4f3d010   Stephen Smalley   usb, signal, secu...
2129
  	 * If the cred isn't NULL we're dealing with some USB IO
e114e4737   Casey Schaufler   Smack: Simplified...
2130
2131
2132
  	 * specific behavior. This is not clean. For one thing
  	 * we can't take privilege into account.
  	 */
b17103a8b   Casey Schaufler   Smack: Abstract u...
2133
  	skp = smk_of_task(smack_cred(cred));
c60b90667   Casey Schaufler   Smack: Signal del...
2134
2135
  	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...
2136
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2137
2138
2139
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2140
2141
   * smack_task_to_inode - copy task smack into the inode blob
   * @p: task to copy from
251a2a958   Randy Dunlap   smack: fix lots o...
2142
   * @inode: inode to copy to
e114e4737   Casey Schaufler   Smack: Simplified...
2143
2144
2145
2146
2147
   *
   * Sets the smack pointer in the inode security blob
   */
  static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
  {
fb4021b6f   Casey Schaufler   Smack: Abstract u...
2148
  	struct inode_smack *isp = smack_inode(inode);
6d1cff2a8   Andrey Ryabinin   smack: fix possib...
2149
  	struct smack_known *skp = smk_of_task_struct(p);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2150

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2151
  	isp->smk_inode = skp;
7b4e88434   Casey Schaufler   Smack: Mark inode...
2152
  	isp->smk_flags |= SMK_INODE_INSTANT;
e114e4737   Casey Schaufler   Smack: Simplified...
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
  }
  
  /*
   * Socket hooks.
   */
  
  /**
   * smack_sk_alloc_security - Allocate a socket blob
   * @sk: the socket
   * @family: unused
251a2a958   Randy Dunlap   smack: fix lots o...
2163
   * @gfp_flags: memory allocation flags
e114e4737   Casey Schaufler   Smack: Simplified...
2164
2165
2166
2167
2168
2169
2170
   *
   * 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...
2171
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2172
2173
2174
2175
2176
  	struct socket_smack *ssp;
  
  	ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
  	if (ssp == NULL)
  		return -ENOMEM;
08382c9f6   jooseong lee   Smack: Assign sma...
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
  	/*
  	 * Sockets created by kernel threads receive web label.
  	 */
  	if (unlikely(current->flags & PF_KTHREAD)) {
  		ssp->smk_in = &smack_known_web;
  		ssp->smk_out = &smack_known_web;
  	} else {
  		ssp->smk_in = skp;
  		ssp->smk_out = skp;
  	}
272cd7a8c   Casey Schaufler   Smack: Rule list ...
2187
  	ssp->smk_packet = NULL;
e114e4737   Casey Schaufler   Smack: Simplified...
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
  
  	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)
  {
0c96d1f53   Vishal Goel   Smack: Fix the is...
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
  #ifdef SMACK_IPV6_PORT_LABELING
  	struct smk_port_label *spp;
  
  	if (sk->sk_family == PF_INET6) {
  		rcu_read_lock();
  		list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
  			if (spp->smk_sock != sk)
  				continue;
  			spp->smk_can_reuse = 1;
  			break;
  		}
  		rcu_read_unlock();
  	}
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
2216
2217
2218
2219
  	kfree(sk->sk_security);
  }
  
  /**
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2220
  * smack_ipv4host_label - check host based restrictions
07feee8f8   Paul Moore   netlabel: Cleanup...
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
  * @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 ...
2231
  static struct smack_known *smack_ipv4host_label(struct sockaddr_in *sip)
07feee8f8   Paul Moore   netlabel: Cleanup...
2232
  {
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2233
  	struct smk_net4addr *snp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2234
2235
2236
2237
  	struct in_addr *siap = &sip->sin_addr;
  
  	if (siap->s_addr == 0)
  		return NULL;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
  	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;
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
  /*
   * 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...
2293
  		/*
2e4939f70   Casey Schaufler   Smack: ipv6 label...
2294
2295
2296
2297
2298
2299
  		 * If the label is NULL the entry has
  		 * been renounced. Ignore it.
  		 */
  		if (snp->smk_label == NULL)
  			continue;
  		/*
07feee8f8   Paul Moore   netlabel: Cleanup...
2300
2301
2302
2303
  		* 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 ...
2304
  		for (found = 1, i = 0; i < 8; i++) {
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2305
2306
2307
2308
2309
  			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 ...
2310
  		}
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2311
2312
2313
  		if (found)
  			return snp->smk_label;
  	}
07feee8f8   Paul Moore   netlabel: Cleanup...
2314
2315
2316
2317
2318
  
  	return NULL;
  }
  
  /**
a2af03188   Casey Schaufler   Smack: Set socket...
2319
   * smack_netlbl_add - Set the secattr on a socket
e114e4737   Casey Schaufler   Smack: Simplified...
2320
2321
   * @sk: the socket
   *
a2af03188   Casey Schaufler   Smack: Set socket...
2322
   * Attach the outbound smack value (smk_out) to the socket.
e114e4737   Casey Schaufler   Smack: Simplified...
2323
2324
2325
   *
   * Returns 0 on success or an error code
   */
a2af03188   Casey Schaufler   Smack: Set socket...
2326
  static int smack_netlbl_add(struct sock *sk)
e114e4737   Casey Schaufler   Smack: Simplified...
2327
  {
07feee8f8   Paul Moore   netlabel: Cleanup...
2328
  	struct socket_smack *ssp = sk->sk_security;
a2af03188   Casey Schaufler   Smack: Set socket...
2329
2330
  	struct smack_known *skp = ssp->smk_out;
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2331

6d3dc07cb   Casey Schaufler   smack: Add suppor...
2332
2333
  	local_bh_disable();
  	bh_lock_sock_nested(sk);
a2af03188   Casey Schaufler   Smack: Set socket...
2334
2335
2336
2337
2338
2339
2340
2341
2342
  	rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel);
  	switch (rc) {
  	case 0:
  		ssp->smk_state = SMK_NETLBL_LABELED;
  		break;
  	case -EDESTADDRREQ:
  		ssp->smk_state = SMK_NETLBL_REQSKB;
  		rc = 0;
  		break;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2343
2344
2345
2346
  	}
  
  	bh_unlock_sock(sk);
  	local_bh_enable();
4bc87e627   Casey Schaufler   Smack: unlabeled ...
2347

e114e4737   Casey Schaufler   Smack: Simplified...
2348
2349
2350
2351
  	return rc;
  }
  
  /**
a2af03188   Casey Schaufler   Smack: Set socket...
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
   * smack_netlbl_delete - Remove the secattr from a socket
   * @sk: the socket
   *
   * Remove the outbound smack value from a socket
   */
  static void smack_netlbl_delete(struct sock *sk)
  {
  	struct socket_smack *ssp = sk->sk_security;
  
  	/*
  	 * Take the label off the socket if one is set.
  	 */
  	if (ssp->smk_state != SMK_NETLBL_LABELED)
  		return;
  
  	local_bh_disable();
  	bh_lock_sock_nested(sk);
  	netlbl_sock_delattr(sk);
  	bh_unlock_sock(sk);
  	local_bh_enable();
  	ssp->smk_state = SMK_NETLBL_UNLABELED;
  }
  
  /**
   * smk_ipv4_check - Perform IPv4 host access checks
07feee8f8   Paul Moore   netlabel: Cleanup...
2377
2378
2379
2380
2381
2382
2383
2384
2385
   * @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.
   *
   */
a2af03188   Casey Schaufler   Smack: Set socket...
2386
  static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap)
07feee8f8   Paul Moore   netlabel: Cleanup...
2387
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2388
  	struct smack_known *skp;
a2af03188   Casey Schaufler   Smack: Set socket...
2389
  	int rc = 0;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2390
  	struct smack_known *hkp;
07feee8f8   Paul Moore   netlabel: Cleanup...
2391
  	struct socket_smack *ssp = sk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
2392
  	struct smk_audit_info ad;
07feee8f8   Paul Moore   netlabel: Cleanup...
2393
2394
  
  	rcu_read_lock();
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2395
  	hkp = smack_ipv4host_label(sap);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2396
  	if (hkp != NULL) {
ecfcc53fe   Etienne Basset   smack: implement ...
2397
  #ifdef CONFIG_AUDIT
923e9a139   Kees Cook   Smack: build when...
2398
  		struct lsm_network_audit net;
48c62af68   Eric Paris   LSM: shrink the c...
2399
2400
2401
2402
  		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 ...
2403
  #endif
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2404
  		skp = ssp->smk_out;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2405
2406
  		rc = smk_access(skp, hkp, MAY_WRITE, &ad);
  		rc = smk_bu_note("IPv4 host check", skp, hkp, MAY_WRITE, rc);
a2af03188   Casey Schaufler   Smack: Set socket...
2407
2408
2409
2410
2411
  		/*
  		 * Clear the socket netlabel if it's set.
  		 */
  		if (!rc)
  			smack_netlbl_delete(sk);
07feee8f8   Paul Moore   netlabel: Cleanup...
2412
2413
  	}
  	rcu_read_unlock();
07feee8f8   Paul Moore   netlabel: Cleanup...
2414

a2af03188   Casey Schaufler   Smack: Set socket...
2415
  	return rc;
07feee8f8   Paul Moore   netlabel: Cleanup...
2416
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
  /**
   * 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;
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2449
2450
  
  #ifdef SMACK_IPV6_PORT_LABELING
07feee8f8   Paul Moore   netlabel: Cleanup...
2451
  /**
c67394434   Casey Schaufler   Smack: Local IPv6...
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
   * 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.
  		 */
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2472
2473
  		rcu_read_lock();
  		list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
c67394434   Casey Schaufler   Smack: Local IPv6...
2474
2475
2476
2477
  			if (sk != spp->smk_sock)
  				continue;
  			spp->smk_in = ssp->smk_in;
  			spp->smk_out = ssp->smk_out;
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2478
  			rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2479
2480
2481
2482
2483
2484
  			return;
  		}
  		/*
  		 * A NULL address is only used for updating existing
  		 * bound entries. If there isn't one, it's OK.
  		 */
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2485
  		rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
  		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.
  	 */
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2501
2502
  	rcu_read_lock();
  	list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
9d44c9738   Vishal Goel   Smack: Fix the is...
2503
  		if (spp->smk_port != port || spp->smk_sock_type != sock->type)
c67394434   Casey Schaufler   Smack: Local IPv6...
2504
  			continue;
0c96d1f53   Vishal Goel   Smack: Fix the is...
2505
2506
2507
2508
  		if (spp->smk_can_reuse != 1) {
  			rcu_read_unlock();
  			return;
  		}
c67394434   Casey Schaufler   Smack: Local IPv6...
2509
2510
2511
2512
  		spp->smk_port = port;
  		spp->smk_sock = sk;
  		spp->smk_in = ssp->smk_in;
  		spp->smk_out = ssp->smk_out;
0c96d1f53   Vishal Goel   Smack: Fix the is...
2513
  		spp->smk_can_reuse = 0;
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2514
  		rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2515
2516
  		return;
  	}
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2517
  	rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
  	/*
  	 * 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;
9d44c9738   Vishal Goel   Smack: Fix the is...
2529
  	spp->smk_sock_type = sock->type;
0c96d1f53   Vishal Goel   Smack: Fix the is...
2530
  	spp->smk_can_reuse = 0;
c67394434   Casey Schaufler   Smack: Local IPv6...
2531

3c7ce3427   Vishal Goel   SMACK: Add the rc...
2532
2533
2534
  	mutex_lock(&smack_ipv6_lock);
  	list_add_rcu(&spp->list, &smk_ipv6_port_list);
  	mutex_unlock(&smack_ipv6_lock);
c67394434   Casey Schaufler   Smack: Local IPv6...
2535
2536
  	return;
  }
00720f0e7   Arnd Bergmann   smack: avoid unus...
2537
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
2538
2539
2540
  
  /**
   * smk_ipv6_port_check - check Smack port access
a1a07f223   luanshi   smack: fix some k...
2541
   * @sk: socket
c67394434   Casey Schaufler   Smack: Local IPv6...
2542
   * @address: address
a1a07f223   luanshi   smack: fix some k...
2543
   * @act: the action being taken
c67394434   Casey Schaufler   Smack: Local IPv6...
2544
2545
2546
   *
   * Create or update the port list entry
   */
6ea062475   Casey Schaufler   Smack: IPv6 casti...
2547
  static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
c67394434   Casey Schaufler   Smack: Local IPv6...
2548
2549
  				int act)
  {
c67394434   Casey Schaufler   Smack: Local IPv6...
2550
2551
  	struct smk_port_label *spp;
  	struct socket_smack *ssp = sk->sk_security;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2552
2553
  	struct smack_known *skp = NULL;
  	unsigned short port;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2554
  	struct smack_known *object;
c67394434   Casey Schaufler   Smack: Local IPv6...
2555
2556
  
  	if (act == SMK_RECEIVING) {
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2557
  		skp = smack_ipv6host_label(address);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2558
  		object = ssp->smk_in;
c67394434   Casey Schaufler   Smack: Local IPv6...
2559
  	} else {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2560
  		skp = ssp->smk_out;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2561
  		object = smack_ipv6host_label(address);
c67394434   Casey Schaufler   Smack: Local IPv6...
2562
2563
2564
  	}
  
  	/*
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2565
  	 * The other end is a single label host.
c67394434   Casey Schaufler   Smack: Local IPv6...
2566
  	 */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2567
2568
2569
2570
2571
2572
  	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...
2573
2574
2575
2576
  
  	/*
  	 * It's remote, so port lookup does no good.
  	 */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2577
2578
  	if (!smk_ipv6_localhost(address))
  		return smk_ipv6_check(skp, object, address, act);
c67394434   Casey Schaufler   Smack: Local IPv6...
2579
2580
2581
2582
  
  	/*
  	 * It's local so the send check has to have passed.
  	 */
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2583
2584
  	if (act == SMK_RECEIVING)
  		return 0;
c67394434   Casey Schaufler   Smack: Local IPv6...
2585

21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2586
  	port = ntohs(address->sin6_port);
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2587
2588
  	rcu_read_lock();
  	list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
9d44c9738   Vishal Goel   Smack: Fix the is...
2589
  		if (spp->smk_port != port || spp->smk_sock_type != sk->sk_type)
c67394434   Casey Schaufler   Smack: Local IPv6...
2590
  			continue;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2591
  		object = spp->smk_in;
c67394434   Casey Schaufler   Smack: Local IPv6...
2592
  		if (act == SMK_CONNECTING)
54e70ec5e   Casey Schaufler   Smack: bidirectio...
2593
  			ssp->smk_packet = spp->smk_out;
c67394434   Casey Schaufler   Smack: Local IPv6...
2594
2595
  		break;
  	}
3c7ce3427   Vishal Goel   SMACK: Add the rc...
2596
  	rcu_read_unlock();
c67394434   Casey Schaufler   Smack: Local IPv6...
2597

21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2598
  	return smk_ipv6_check(skp, object, address, act);
c67394434   Casey Schaufler   Smack: Local IPv6...
2599
2600
2601
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
   * 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...
2616
  	struct smack_known *skp;
fb4021b6f   Casey Schaufler   Smack: Abstract u...
2617
  	struct inode_smack *nsp = smack_inode(inode);
e114e4737   Casey Schaufler   Smack: Simplified...
2618
2619
  	struct socket_smack *ssp;
  	struct socket *sock;
4bc87e627   Casey Schaufler   Smack: unlabeled ...
2620
  	int rc = 0;
e114e4737   Casey Schaufler   Smack: Simplified...
2621

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

2f823ff8b   Casey Schaufler   Smack: Improve ac...
2625
  	skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
2626
2627
  	if (IS_ERR(skp))
  		return PTR_ERR(skp);
e114e4737   Casey Schaufler   Smack: Simplified...
2628
2629
  
  	if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
2630
  		nsp->smk_inode = skp;
ddd29ec65   David P. Quigley   sysfs: Add labeli...
2631
  		nsp->smk_flags |= SMK_INODE_INSTANT;
e114e4737   Casey Schaufler   Smack: Simplified...
2632
2633
2634
2635
2636
2637
2638
2639
2640
  		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 ...
2641
  	if (sock == NULL || sock->sk == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
2642
2643
2644
2645
2646
  		return -EOPNOTSUPP;
  
  	ssp = sock->sk->sk_security;
  
  	if (strcmp(name, XATTR_SMACK_IPIN) == 0)
54e70ec5e   Casey Schaufler   Smack: bidirectio...
2647
  		ssp->smk_in = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
2648
  	else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2649
  		ssp->smk_out = skp;
c67394434   Casey Schaufler   Smack: Local IPv6...
2650
  		if (sock->sk->sk_family == PF_INET) {
a2af03188   Casey Schaufler   Smack: Set socket...
2651
  			rc = smack_netlbl_add(sock->sk);
b4e0d5f07   Casey Schaufler   Smack: UDS revision
2652
2653
2654
2655
2656
2657
  			if (rc != 0)
  				printk(KERN_WARNING
  					"Smack: \"%s\" netlbl error %d.
  ",
  					__func__, -rc);
  		}
e114e4737   Casey Schaufler   Smack: Simplified...
2658
2659
  	} else
  		return -EOPNOTSUPP;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2660
  #ifdef SMACK_IPV6_PORT_LABELING
c67394434   Casey Schaufler   Smack: Local IPv6...
2661
2662
  	if (sock->sk->sk_family == PF_INET6)
  		smk_ipv6_port_label(sock, NULL);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2663
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
2664

e114e4737   Casey Schaufler   Smack: Simplified...
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
  	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...
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
  	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...
2698
2699
2700
2701
  		return 0;
  	/*
  	 * Set the outbound netlbl.
  	 */
a2af03188   Casey Schaufler   Smack: Set socket...
2702
  	return smack_netlbl_add(sock->sk);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2703
  }
5859cdf55   Tom Gundersen   smack: provide so...
2704
2705
2706
2707
2708
2709
2710
  /**
   * smack_socket_socketpair - create socket pair
   * @socka: one socket
   * @sockb: another socket
   *
   * Cross reference the peer labels for SO_PEERSEC
   *
a1a07f223   luanshi   smack: fix some k...
2711
   * Returns 0
5859cdf55   Tom Gundersen   smack: provide so...
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
   */
  static int smack_socket_socketpair(struct socket *socka,
  		                   struct socket *sockb)
  {
  	struct socket_smack *asp = socka->sk->sk_security;
  	struct socket_smack *bsp = sockb->sk->sk_security;
  
  	asp->smk_packet = bsp->smk_out;
  	bsp->smk_packet = asp->smk_out;
  
  	return 0;
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2724
  #ifdef SMACK_IPV6_PORT_LABELING
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2725
  /**
c67394434   Casey Schaufler   Smack: Local IPv6...
2726
2727
2728
2729
2730
2731
2732
   * 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.
   *
b9ef5513c   Tetsuo Handa   smack: Check addr...
2733
   * Returns 0 on success, and error code otherwise
c67394434   Casey Schaufler   Smack: Local IPv6...
2734
2735
2736
2737
   */
  static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
  				int addrlen)
  {
b9ef5513c   Tetsuo Handa   smack: Check addr...
2738
2739
2740
2741
  	if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) {
  		if (addrlen < SIN6_LEN_RFC2133 ||
  		    address->sa_family != AF_INET6)
  			return -EINVAL;
c67394434   Casey Schaufler   Smack: Local IPv6...
2742
  		smk_ipv6_port_label(sock, address);
b9ef5513c   Tetsuo Handa   smack: Check addr...
2743
  	}
c67394434   Casey Schaufler   Smack: Local IPv6...
2744
2745
  	return 0;
  }
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2746
  #endif /* SMACK_IPV6_PORT_LABELING */
c67394434   Casey Schaufler   Smack: Local IPv6...
2747
2748
  
  /**
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
   * 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...
2761
2762
2763
  	int rc = 0;
  
  	if (sock->sk == NULL)
6d3dc07cb   Casey Schaufler   smack: Add suppor...
2764
  		return 0;
87fbfffcc   Casey Schaufler   broken ping to ip...
2765
2766
2767
2768
2769
2770
2771
  	if (sock->sk->sk_family != PF_INET &&
  	    (!IS_ENABLED(CONFIG_IPV6) || sock->sk->sk_family != PF_INET6))
  		return 0;
  	if (addrlen < offsetofend(struct sockaddr, sa_family))
  		return 0;
  	if (IS_ENABLED(CONFIG_IPV6) && sap->sa_family == AF_INET6) {
  		struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
00720f0e7   Arnd Bergmann   smack: avoid unus...
2772
  		struct smack_known *rsp = NULL;
da49b5dad   Vasyl Gomonovych   Smack: fix derefe...
2773

87fbfffcc   Casey Schaufler   broken ping to ip...
2774
2775
  		if (addrlen < SIN6_LEN_RFC2133)
  			return 0;
00720f0e7   Arnd Bergmann   smack: avoid unus...
2776
2777
  		if (__is_defined(SMACK_IPV6_SECMARK_LABELING))
  			rsp = smack_ipv6host_label(sip);
87fbfffcc   Casey Schaufler   broken ping to ip...
2778
2779
  		if (rsp != NULL) {
  			struct socket_smack *ssp = sock->sk->sk_security;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
2780
  			rc = smk_ipv6_check(ssp->smk_out, rsp, sip,
87fbfffcc   Casey Schaufler   broken ping to ip...
2781
2782
  					    SMK_CONNECTING);
  		}
00720f0e7   Arnd Bergmann   smack: avoid unus...
2783
2784
  		if (__is_defined(SMACK_IPV6_PORT_LABELING))
  			rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
87fbfffcc   Casey Schaufler   broken ping to ip...
2785
  		return rc;
c67394434   Casey Schaufler   Smack: Local IPv6...
2786
  	}
87fbfffcc   Casey Schaufler   broken ping to ip...
2787
2788
  	if (sap->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
  		return 0;
a2af03188   Casey Schaufler   Smack: Set socket...
2789
  	rc = smk_ipv4_check(sock->sk, (struct sockaddr_in *)sap);
c67394434   Casey Schaufler   Smack: Local IPv6...
2790
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
  }
  
  /**
   * 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)
  {
ecd5f82e0   Casey Schaufler   LSM: Infrastructu...
2821
  	struct smack_known **blob = smack_msg_msg(msg);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
2822

ecd5f82e0   Casey Schaufler   LSM: Infrastructu...
2823
  	*blob = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2824
2825
2826
2827
  	return 0;
  }
  
  /**
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2828
2829
   * smack_of_ipc - the smack pointer for the ipc
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
2830
2831
2832
   *
   * Returns a pointer to the smack value
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2833
  static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp)
e114e4737   Casey Schaufler   Smack: Simplified...
2834
  {
019bcca46   Casey Schaufler   Smack: Abstract u...
2835
2836
2837
  	struct smack_known **blob = smack_ipc(isp);
  
  	return *blob;
e114e4737   Casey Schaufler   Smack: Simplified...
2838
2839
2840
  }
  
  /**
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2841
2842
   * smack_ipc_alloc_security - Set the security blob for ipc
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
2843
2844
2845
   *
   * Returns 0
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2846
  static int smack_ipc_alloc_security(struct kern_ipc_perm *isp)
e114e4737   Casey Schaufler   Smack: Simplified...
2847
  {
019bcca46   Casey Schaufler   Smack: Abstract u...
2848
  	struct smack_known **blob = smack_ipc(isp);
e114e4737   Casey Schaufler   Smack: Simplified...
2849

019bcca46   Casey Schaufler   Smack: Abstract u...
2850
  	*blob = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
2851
2852
2853
2854
  	return 0;
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
2855
   * smk_curacc_shm : check if current has access on shm
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2856
   * @isp : the object
ecfcc53fe   Etienne Basset   smack: implement ...
2857
2858
2859
2860
   * @access : access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2861
  static int smk_curacc_shm(struct kern_ipc_perm *isp, int access)
ecfcc53fe   Etienne Basset   smack: implement ...
2862
  {
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2863
  	struct smack_known *ssp = smack_of_ipc(isp);
ecfcc53fe   Etienne Basset   smack: implement ...
2864
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
2865
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2866
2867
2868
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2869
  	ad.a.u.ipc_id = isp->id;
ecfcc53fe   Etienne Basset   smack: implement ...
2870
  #endif
d166c8024   Casey Schaufler   Smack: Bring-up a...
2871
2872
2873
  	rc = smk_curacc(ssp, access, &ad);
  	rc = smk_bu_current("shm", ssp, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2874
2875
2876
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2877
   * smack_shm_associate - Smack access check for shm
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2878
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
2879
2880
2881
2882
   * @shmflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2883
  static int smack_shm_associate(struct kern_ipc_perm *isp, int shmflg)
e114e4737   Casey Schaufler   Smack: Simplified...
2884
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2885
2886
2887
  	int may;
  
  	may = smack_flags_to_may(shmflg);
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2888
  	return smk_curacc_shm(isp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2889
2890
2891
2892
  }
  
  /**
   * smack_shm_shmctl - Smack access check for shm
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2893
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
2894
2895
2896
2897
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2898
  static int smack_shm_shmctl(struct kern_ipc_perm *isp, int cmd)
e114e4737   Casey Schaufler   Smack: Simplified...
2899
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2900
2901
2902
2903
2904
  	int may;
  
  	switch (cmd) {
  	case IPC_STAT:
  	case SHM_STAT:
c21a6970a   Davidlohr Bueso   ipc/shm: introduc...
2905
  	case SHM_STAT_ANY:
e114e4737   Casey Schaufler   Smack: Simplified...
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
  		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;
  	}
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2923
  	return smk_curacc_shm(isp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2924
2925
2926
2927
  }
  
  /**
   * smack_shm_shmat - Smack access for shmat
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2928
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
2929
2930
2931
2932
2933
   * @shmaddr: unused
   * @shmflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
a1a07f223   luanshi   smack: fix some k...
2934
  static int smack_shm_shmat(struct kern_ipc_perm *isp, char __user *shmaddr,
e114e4737   Casey Schaufler   Smack: Simplified...
2935
2936
  			   int shmflg)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2937
2938
2939
  	int may;
  
  	may = smack_flags_to_may(shmflg);
a1a07f223   luanshi   smack: fix some k...
2940
  	return smk_curacc_shm(isp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2941
2942
2943
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
2944
   * smk_curacc_sem : check if current has access on sem
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2945
   * @isp : the object
ecfcc53fe   Etienne Basset   smack: implement ...
2946
2947
2948
2949
   * @access : access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2950
  static int smk_curacc_sem(struct kern_ipc_perm *isp, int access)
ecfcc53fe   Etienne Basset   smack: implement ...
2951
  {
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2952
  	struct smack_known *ssp = smack_of_ipc(isp);
ecfcc53fe   Etienne Basset   smack: implement ...
2953
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
2954
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2955
2956
2957
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2958
  	ad.a.u.ipc_id = isp->id;
ecfcc53fe   Etienne Basset   smack: implement ...
2959
  #endif
d166c8024   Casey Schaufler   Smack: Bring-up a...
2960
2961
2962
  	rc = smk_curacc(ssp, access, &ad);
  	rc = smk_bu_current("sem", ssp, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
2963
2964
2965
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
2966
   * smack_sem_associate - Smack access check for sem
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2967
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
2968
2969
2970
2971
   * @semflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2972
  static int smack_sem_associate(struct kern_ipc_perm *isp, int semflg)
e114e4737   Casey Schaufler   Smack: Simplified...
2973
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2974
2975
2976
  	int may;
  
  	may = smack_flags_to_may(semflg);
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2977
  	return smk_curacc_sem(isp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
2978
2979
2980
2981
  }
  
  /**
   * smack_sem_shmctl - Smack access check for sem
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2982
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
2983
2984
2985
2986
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
2987
  static int smack_sem_semctl(struct kern_ipc_perm *isp, int cmd)
e114e4737   Casey Schaufler   Smack: Simplified...
2988
  {
e114e4737   Casey Schaufler   Smack: Simplified...
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
  	int may;
  
  	switch (cmd) {
  	case GETPID:
  	case GETNCNT:
  	case GETZCNT:
  	case GETVAL:
  	case GETALL:
  	case IPC_STAT:
  	case SEM_STAT:
a280d6dc7   Davidlohr Bueso   ipc/sem: introduc...
2999
  	case SEM_STAT_ANY:
e114e4737   Casey Schaufler   Smack: Simplified...
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
  		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;
  	}
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3017
  	return smk_curacc_sem(isp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3018
3019
3020
3021
  }
  
  /**
   * smack_sem_semop - Smack checks of semaphore operations
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3022
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
3023
3024
3025
3026
3027
3028
3029
3030
   * @sops: unused
   * @nsops: unused
   * @alter: unused
   *
   * Treated as read and write in all cases.
   *
   * Returns 0 if access is allowed, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3031
  static int smack_sem_semop(struct kern_ipc_perm *isp, struct sembuf *sops,
e114e4737   Casey Schaufler   Smack: Simplified...
3032
3033
  			   unsigned nsops, int alter)
  {
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3034
  	return smk_curacc_sem(isp, MAY_READWRITE);
e114e4737   Casey Schaufler   Smack: Simplified...
3035
3036
3037
  }
  
  /**
ecfcc53fe   Etienne Basset   smack: implement ...
3038
   * smk_curacc_msq : helper to check if current has access on msq
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3039
   * @isp : the msq
ecfcc53fe   Etienne Basset   smack: implement ...
3040
3041
3042
3043
   * @access : access requested
   *
   * return 0 if current has access, error otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3044
  static int smk_curacc_msq(struct kern_ipc_perm *isp, int access)
ecfcc53fe   Etienne Basset   smack: implement ...
3045
  {
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3046
  	struct smack_known *msp = smack_of_ipc(isp);
ecfcc53fe   Etienne Basset   smack: implement ...
3047
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3048
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3049
3050
3051
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC);
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3052
  	ad.a.u.ipc_id = isp->id;
ecfcc53fe   Etienne Basset   smack: implement ...
3053
  #endif
d166c8024   Casey Schaufler   Smack: Bring-up a...
3054
3055
3056
  	rc = smk_curacc(msp, access, &ad);
  	rc = smk_bu_current("msq", msp, access, rc);
  	return rc;
ecfcc53fe   Etienne Basset   smack: implement ...
3057
3058
3059
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
3060
   * smack_msg_queue_associate - Smack access check for msg_queue
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3061
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
3062
3063
3064
3065
   * @msqflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3066
  static int smack_msg_queue_associate(struct kern_ipc_perm *isp, int msqflg)
e114e4737   Casey Schaufler   Smack: Simplified...
3067
  {
e114e4737   Casey Schaufler   Smack: Simplified...
3068
3069
3070
  	int may;
  
  	may = smack_flags_to_may(msqflg);
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3071
  	return smk_curacc_msq(isp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3072
3073
3074
3075
  }
  
  /**
   * smack_msg_queue_msgctl - Smack access check for msg_queue
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3076
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
3077
3078
3079
3080
   * @cmd: what it wants to do
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3081
  static int smack_msg_queue_msgctl(struct kern_ipc_perm *isp, int cmd)
e114e4737   Casey Schaufler   Smack: Simplified...
3082
  {
e114e4737   Casey Schaufler   Smack: Simplified...
3083
3084
3085
3086
3087
  	int may;
  
  	switch (cmd) {
  	case IPC_STAT:
  	case MSG_STAT:
23c8cec8c   Davidlohr Bueso   ipc/msg: introduc...
3088
  	case MSG_STAT_ANY:
e114e4737   Casey Schaufler   Smack: Simplified...
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
  		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;
  	}
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3104
  	return smk_curacc_msq(isp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3105
3106
3107
3108
  }
  
  /**
   * smack_msg_queue_msgsnd - Smack access check for msg_queue
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3109
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
3110
3111
3112
3113
3114
   * @msg: unused
   * @msqflg: access requested
   *
   * Returns 0 if current has the requested access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3115
  static int smack_msg_queue_msgsnd(struct kern_ipc_perm *isp, struct msg_msg *msg,
e114e4737   Casey Schaufler   Smack: Simplified...
3116
3117
  				  int msqflg)
  {
ecfcc53fe   Etienne Basset   smack: implement ...
3118
  	int may;
e114e4737   Casey Schaufler   Smack: Simplified...
3119

ecfcc53fe   Etienne Basset   smack: implement ...
3120
  	may = smack_flags_to_may(msqflg);
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3121
  	return smk_curacc_msq(isp, may);
e114e4737   Casey Schaufler   Smack: Simplified...
3122
3123
3124
3125
  }
  
  /**
   * smack_msg_queue_msgsnd - Smack access check for msg_queue
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3126
   * @isp: the object
e114e4737   Casey Schaufler   Smack: Simplified...
3127
3128
3129
3130
3131
3132
3133
   * @msg: unused
   * @target: unused
   * @type: unused
   * @mode: unused
   *
   * Returns 0 if current has read and write access, error code otherwise
   */
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3134
  static int smack_msg_queue_msgrcv(struct kern_ipc_perm *isp, struct msg_msg *msg,
e114e4737   Casey Schaufler   Smack: Simplified...
3135
3136
  			struct task_struct *target, long type, int mode)
  {
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
3137
  	return smk_curacc_msq(isp, MAY_READWRITE);
e114e4737   Casey Schaufler   Smack: Simplified...
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
  }
  
  /**
   * 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)
  {
019bcca46   Casey Schaufler   Smack: Abstract u...
3149
3150
  	struct smack_known **blob = smack_ipc(ipp);
  	struct smack_known *iskp = *blob;
ecfcc53fe   Etienne Basset   smack: implement ...
3151
3152
  	int may = smack_flags_to_may(flag);
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3153
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3154

ecfcc53fe   Etienne Basset   smack: implement ...
3155
3156
3157
3158
  #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...
3159
3160
  	rc = smk_curacc(iskp, may, &ad);
  	rc = smk_bu_current("svipc", iskp, may, rc);
d166c8024   Casey Schaufler   Smack: Bring-up a...
3161
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3162
  }
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3163
3164
  /**
   * smack_ipc_getsecid - Extract smack security id
251a2a958   Randy Dunlap   smack: fix lots o...
3165
   * @ipp: the object permissions
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3166
3167
3168
3169
   * @secid: where result will be saved
   */
  static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
  {
019bcca46   Casey Schaufler   Smack: Abstract u...
3170
3171
  	struct smack_known **blob = smack_ipc(ipp);
  	struct smack_known *iskp = *blob;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3172

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3173
  	*secid = iskp->smk_secid;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
3174
  }
e114e4737   Casey Schaufler   Smack: Simplified...
3175
3176
  /**
   * smack_d_instantiate - Make sure the blob is correct on an inode
3e62cbb84   Dan Carpenter   smack: opt_dentry...
3177
   * @opt_dentry: dentry where inode will be attached
e114e4737   Casey Schaufler   Smack: Simplified...
3178
3179
3180
3181
3182
3183
3184
3185
3186
   * @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...
3187
3188
  	struct smack_known *skp;
  	struct smack_known *ckp = smk_of_current();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3189
  	struct smack_known *final;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3190
3191
  	char trattr[TRANS_TRUE_SIZE];
  	int transflag = 0;
2267b13a7   Casey Schaufler   Smack: recursive ...
3192
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3193
3194
3195
3196
  	struct dentry *dp;
  
  	if (inode == NULL)
  		return;
fb4021b6f   Casey Schaufler   Smack: Abstract u...
3197
  	isp = smack_inode(inode);
e114e4737   Casey Schaufler   Smack: Simplified...
3198

e114e4737   Casey Schaufler   Smack: Simplified...
3199
3200
3201
3202
3203
  	/*
  	 * If the inode is already instantiated
  	 * take the quick way out
  	 */
  	if (isp->smk_flags & SMK_INODE_INSTANT)
921bb1cbb   Casey Schaufler   Smack:- Remove mu...
3204
  		return;
e114e4737   Casey Schaufler   Smack: Simplified...
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
  
  	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...
3215
3216
3217
3218
3219
3220
  	 * 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 ...
3221
3222
  		switch (sbp->s_magic) {
  		case CGROUP_SUPER_MAGIC:
58c442f34   José Bollo   Smack: Handle CGR...
3223
  		case CGROUP2_SUPER_MAGIC:
36ea735b5   Casey Schaufler   Smack: Label cgro...
3224
3225
3226
3227
3228
  			/*
  			 * The cgroup filesystem is never mounted,
  			 * so there's no opportunity to set the mount
  			 * options.
  			 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3229
3230
  			sbsp->smk_root = &smack_known_star;
  			sbsp->smk_default = &smack_known_star;
1d8c2326a   Łukasz Stelmach   smack: introduce ...
3231
3232
3233
3234
3235
3236
3237
3238
3239
  			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...
3240
3241
3242
  		case PIPEFS_MAGIC:
  			isp->smk_inode = smk_of_current();
  			break;
805b65a80   Rafal Krypa   Smack: fix d_inst...
3243
3244
3245
3246
3247
3248
3249
  		case SOCKFS_MAGIC:
  			/*
  			 * Socket access is controlled by the socket
  			 * structures associated with the task involved.
  			 */
  			isp->smk_inode = &smack_known_star;
  			break;
1d8c2326a   Łukasz Stelmach   smack: introduce ...
3250
3251
3252
  		default:
  			isp->smk_inode = sbsp->smk_root;
  			break;
36ea735b5   Casey Schaufler   Smack: Label cgro...
3253
  		}
e97dcb0ea   Casey Schaufler   Smack: fuse mount...
3254
  		isp->smk_flags |= SMK_INODE_INSTANT;
921bb1cbb   Casey Schaufler   Smack:- Remove mu...
3255
  		return;
e97dcb0ea   Casey Schaufler   Smack: fuse mount...
3256
3257
3258
  	}
  
  	/*
e114e4737   Casey Schaufler   Smack: Simplified...
3259
3260
3261
3262
3263
3264
3265
  	 * 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...
3266
  	case CGROUP_SUPER_MAGIC:
58c442f34   José Bollo   Smack: Handle CGR...
3267
  	case CGROUP2_SUPER_MAGIC:
e114e4737   Casey Schaufler   Smack: Simplified...
3268
  		/*
25985edce   Lucas De Marchi   Fix common misspe...
3269
  		 * Casey says that it's a little embarrassing
e114e4737   Casey Schaufler   Smack: Simplified...
3270
3271
  		 * that the smack file system doesn't do
  		 * extended attributes.
36ea735b5   Casey Schaufler   Smack: Label cgro...
3272
  		 *
36ea735b5   Casey Schaufler   Smack: Label cgro...
3273
  		 * Cgroupfs is special
e114e4737   Casey Schaufler   Smack: Simplified...
3274
  		 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3275
  		final = &smack_known_star;
e114e4737   Casey Schaufler   Smack: Simplified...
3276
3277
3278
3279
3280
3281
3282
  		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...
3283
  		final = ckp;
e114e4737   Casey Schaufler   Smack: Simplified...
3284
  		break;
e114e4737   Casey Schaufler   Smack: Simplified...
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
  	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...
3297
  		final = &smack_known_star;
e114e4737   Casey Schaufler   Smack: Simplified...
3298
  		/*
e114e4737   Casey Schaufler   Smack: Simplified...
3299
3300
3301
3302
3303
  		 * 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.
  		 */
df561f668   Gustavo A. R. Silva   treewide: Use fal...
3304
  		fallthrough;
e114e4737   Casey Schaufler   Smack: Simplified...
3305
3306
3307
3308
  	default:
  		/*
  		 * This isn't an understood special case.
  		 * Get the value from the xattr.
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3309
3310
3311
3312
3313
3314
  		 */
  
  		/*
  		 * UNIX domain sockets use lower level socket data.
  		 */
  		if (S_ISSOCK(inode->i_mode)) {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3315
  			final = &smack_known_star;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3316
3317
3318
  			break;
  		}
  		/*
e114e4737   Casey Schaufler   Smack: Simplified...
3319
3320
3321
3322
3323
  		 * 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_...
3324
3325
  		if (!(inode->i_opflags & IOP_XATTR))
  		        break;
e114e4737   Casey Schaufler   Smack: Simplified...
3326
3327
3328
  		/*
  		 * Get the dentry for xattr.
  		 */
3e62cbb84   Dan Carpenter   smack: opt_dentry...
3329
  		dp = dget(opt_dentry);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3330
  		skp = smk_fetch(XATTR_NAME_SMACK, inode, dp);
e774ad683   Lukasz Pawelczyk   smack: pass error...
3331
  		if (!IS_ERR_OR_NULL(skp))
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3332
  			final = skp;
2267b13a7   Casey Schaufler   Smack: recursive ...
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
  
  		/*
  		 * 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_...
3349
  				rc = __vfs_setxattr(dp, inode,
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3350
  					XATTR_NAME_SMACKTRANSMUTE,
2267b13a7   Casey Schaufler   Smack: recursive ...
3351
3352
3353
  					TRANS_TRUE, TRANS_TRUE_SIZE,
  					0);
  			} else {
5d6c31910   Andreas Gruenbacher   xattr: Add __vfs_...
3354
  				rc = __vfs_getxattr(dp, inode,
2267b13a7   Casey Schaufler   Smack: recursive ...
3355
  					XATTR_NAME_SMACKTRANSMUTE, trattr,
3484eba91   Mark Salyzyn   FROMLIST: Add fla...
3356
  					TRANS_TRUE_SIZE, XATTR_NOSECURITY);
2267b13a7   Casey Schaufler   Smack: recursive ...
3357
3358
3359
  				if (rc >= 0 && strncmp(trattr, TRANS_TRUE,
  						       TRANS_TRUE_SIZE) != 0)
  					rc = -EINVAL;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3360
  			}
2267b13a7   Casey Schaufler   Smack: recursive ...
3361
3362
  			if (rc >= 0)
  				transflag = SMK_INODE_TRANSMUTE;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3363
  		}
809c02e09   Seth Forshee   Smack: Handle lab...
3364
3365
3366
3367
3368
3369
3370
3371
  		/*
  		 * 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...
3372

19760ad03   Casey Schaufler   Smack: Prevent th...
3373
  		skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
e774ad683   Lukasz Pawelczyk   smack: pass error...
3374
3375
  		if (IS_ERR(skp) || skp == &smack_known_star ||
  		    skp == &smack_known_web)
19760ad03   Casey Schaufler   Smack: Prevent th...
3376
3377
  			skp = NULL;
  		isp->smk_mmap = skp;
676dac4b1   Casey Schaufler   This patch adds a...
3378

e114e4737   Casey Schaufler   Smack: Simplified...
3379
3380
3381
3382
3383
  		dput(dp);
  		break;
  	}
  
  	if (final == NULL)
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3384
  		isp->smk_inode = ckp;
e114e4737   Casey Schaufler   Smack: Simplified...
3385
3386
  	else
  		isp->smk_inode = final;
5c6d1125f   Jarkko Sakkinen   Smack: Transmute ...
3387
  	isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
e114e4737   Casey Schaufler   Smack: Simplified...
3388

e114e4737   Casey Schaufler   Smack: Simplified...
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
  	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...
3404
  	struct smack_known *skp = smk_of_task_struct(p);
e114e4737   Casey Schaufler   Smack: Simplified...
3405
3406
3407
3408
3409
  	char *cp;
  	int slen;
  
  	if (strcmp(name, "current") != 0)
  		return -EINVAL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3410
  	cp = kstrdup(skp->smk_known, GFP_KERNEL);
e114e4737   Casey Schaufler   Smack: Simplified...
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
  	if (cp == NULL)
  		return -ENOMEM;
  
  	slen = strlen(cp);
  	*value = cp;
  	return slen;
  }
  
  /**
   * smack_setprocattr - Smack process attribute setting
e114e4737   Casey Schaufler   Smack: Simplified...
3421
3422
3423
3424
3425
3426
3427
3428
3429
   * @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
   */
b21507e27   Stephen Smalley   proc,security: mo...
3430
  static int smack_setprocattr(const char *name, void *value, size_t size)
e114e4737   Casey Schaufler   Smack: Simplified...
3431
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
3432
  	struct task_smack *tsp = smack_cred(current_cred());
d84f4f992   David Howells   CRED: Inaugurate ...
3433
  	struct cred *new;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3434
  	struct smack_known *skp;
38416e539   Zbigniew Jasinski   Smack: limited ca...
3435
3436
  	struct smack_known_list_elem *sklep;
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3437

38416e539   Zbigniew Jasinski   Smack: limited ca...
3438
  	if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel))
5cd9c58fb   David Howells   security: Fix set...
3439
  		return -EPERM;
f7112e6c9   Casey Schaufler   Smack: allow for ...
3440
  	if (value == NULL || size == 0 || size >= SMK_LONGLABEL)
e114e4737   Casey Schaufler   Smack: Simplified...
3441
3442
3443
3444
  		return -EINVAL;
  
  	if (strcmp(name, "current") != 0)
  		return -EINVAL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3445
  	skp = smk_import_entry(value, size);
e774ad683   Lukasz Pawelczyk   smack: pass error...
3446
3447
  	if (IS_ERR(skp))
  		return PTR_ERR(skp);
e114e4737   Casey Schaufler   Smack: Simplified...
3448

6d3dc07cb   Casey Schaufler   smack: Add suppor...
3449
  	/*
7128ea159   Himanshu Shukla   SMACK: Do not app...
3450
3451
  	 * No process is ever allowed the web ("@") label
  	 * and the star ("*") label.
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3452
  	 */
7128ea159   Himanshu Shukla   SMACK: Do not app...
3453
3454
  	if (skp == &smack_known_web || skp == &smack_known_star)
  		return -EINVAL;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3455

38416e539   Zbigniew Jasinski   Smack: limited ca...
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
  	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 ...
3466
  	new = prepare_creds();
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3467
  	if (new == NULL)
d84f4f992   David Howells   CRED: Inaugurate ...
3468
  		return -ENOMEM;
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
3469

b17103a8b   Casey Schaufler   Smack: Abstract u...
3470
  	tsp = smack_cred(new);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3471
  	tsp->smk_task = skp;
38416e539   Zbigniew Jasinski   Smack: limited ca...
3472
3473
3474
3475
  	/*
  	 * process can change its label only once
  	 */
  	smk_destroy_label_list(&tsp->smk_relabel);
7898e1f8e   Casey Schaufler   Subject: [PATCH] ...
3476

d84f4f992   David Howells   CRED: Inaugurate ...
3477
  	commit_creds(new);
e114e4737   Casey Schaufler   Smack: Simplified...
3478
3479
3480
3481
3482
  	return size;
  }
  
  /**
   * smack_unix_stream_connect - Smack access on UDS
3610cda53   David S. Miller   af_unix: Avoid so...
3483
3484
   * @sock: one sock
   * @other: the other sock
e114e4737   Casey Schaufler   Smack: Simplified...
3485
3486
3487
3488
3489
   * @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...
3490
3491
  static int smack_unix_stream_connect(struct sock *sock,
  				     struct sock *other, struct sock *newsk)
e114e4737   Casey Schaufler   Smack: Simplified...
3492
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3493
  	struct smack_known *skp;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3494
  	struct smack_known *okp;
d2e7ad192   James Morris   Merge branch 'mas...
3495
3496
  	struct socket_smack *ssp = sock->sk_security;
  	struct socket_smack *osp = other->sk_security;
975d5e55c   Casey Schaufler   Smack: Provide in...
3497
  	struct socket_smack *nsp = newsk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
3498
  	struct smk_audit_info ad;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3499
  	int rc = 0;
923e9a139   Kees Cook   Smack: build when...
3500
3501
  #ifdef CONFIG_AUDIT
  	struct lsm_network_audit net;
923e9a139   Kees Cook   Smack: build when...
3502
  #endif
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3503

2f823ff8b   Casey Schaufler   Smack: Improve ac...
3504
3505
  	if (!smack_privileged(CAP_MAC_OVERRIDE)) {
  		skp = ssp->smk_out;
96be7b542   Zbigniew Jasinski   smack: Fix a bidi...
3506
  		okp = osp->smk_in;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3507
3508
3509
3510
  #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...
3511
3512
  		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...
3513
  		if (rc == 0) {
96be7b542   Zbigniew Jasinski   smack: Fix a bidi...
3514
3515
  			okp = osp->smk_out;
  			skp = ssp->smk_in;
138a868f0   Rafal Krypa   smack: Add missin...
3516
  			rc = smk_access(okp, skp, MAY_WRITE, &ad);
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3517
  			rc = smk_bu_note("UDS connect", okp, skp,
d166c8024   Casey Schaufler   Smack: Bring-up a...
3518
3519
  						MAY_WRITE, rc);
  		}
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3520
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3521

975d5e55c   Casey Schaufler   Smack: Provide in...
3522
3523
3524
3525
  	/*
  	 * Cross reference the peer labels for SO_PEERSEC.
  	 */
  	if (rc == 0) {
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3526
3527
  		nsp->smk_packet = ssp->smk_out;
  		ssp->smk_packet = osp->smk_out;
975d5e55c   Casey Schaufler   Smack: Provide in...
3528
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3529
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
  }
  
  /**
   * 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
3542
3543
  	struct socket_smack *ssp = sock->sk->sk_security;
  	struct socket_smack *osp = other->sk->sk_security;
ecfcc53fe   Etienne Basset   smack: implement ...
3544
  	struct smk_audit_info ad;
d166c8024   Casey Schaufler   Smack: Bring-up a...
3545
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3546

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

2f823ff8b   Casey Schaufler   Smack: Improve ac...
3553
3554
  	if (smack_privileged(CAP_MAC_OVERRIDE))
  		return 0;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3555

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
3556
3557
  	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...
3558
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3559
3560
3561
  }
  
  /**
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3562
3563
   * smack_socket_sendmsg - Smack check based on destination host
   * @sock: the socket
251a2a958   Randy Dunlap   smack: fix lots o...
3564
   * @msg: the message
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3565
3566
   * @size: the size of the message
   *
c67394434   Casey Schaufler   Smack: Local IPv6...
3567
3568
3569
   * 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...
3570
3571
3572
3573
3574
   */
  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 ...
3575
  #if IS_ENABLED(CONFIG_IPV6)
6ea062475   Casey Schaufler   Smack: IPv6 casti...
3576
  	struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3577
3578
3579
3580
3581
  #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...
3582
  	int rc = 0;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3583
3584
3585
3586
  
  	/*
  	 * Perfectly reasonable for this to be NULL
  	 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3587
  	if (sip == NULL)
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3588
  		return 0;
81bd0d562   Roman Kubiak   Smack: type confu...
3589
  	switch (sock->sk->sk_family) {
c67394434   Casey Schaufler   Smack: Local IPv6...
3590
  	case AF_INET:
b9ef5513c   Tetsuo Handa   smack: Check addr...
3591
3592
3593
  		if (msg->msg_namelen < sizeof(struct sockaddr_in) ||
  		    sip->sin_family != AF_INET)
  			return -EINVAL;
a2af03188   Casey Schaufler   Smack: Set socket...
3594
  		rc = smk_ipv4_check(sock->sk, sip);
c67394434   Casey Schaufler   Smack: Local IPv6...
3595
  		break;
619ae03e9   Casey Schaufler   Smack: Fix kbuild...
3596
  #if IS_ENABLED(CONFIG_IPV6)
c67394434   Casey Schaufler   Smack: Local IPv6...
3597
  	case AF_INET6:
b9ef5513c   Tetsuo Handa   smack: Check addr...
3598
3599
3600
  		if (msg->msg_namelen < SIN6_LEN_RFC2133 ||
  		    sap->sin6_family != AF_INET6)
  			return -EINVAL;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3601
3602
3603
3604
3605
3606
3607
  #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...
3608
  		rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3609
  #endif
619ae03e9   Casey Schaufler   Smack: Fix kbuild...
3610
  #endif /* IS_ENABLED(CONFIG_IPV6) */
c67394434   Casey Schaufler   Smack: Local IPv6...
3611
3612
3613
  		break;
  	}
  	return rc;
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3614
  }
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3615
  /**
251a2a958   Randy Dunlap   smack: fix lots o...
3616
   * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
e114e4737   Casey Schaufler   Smack: Simplified...
3617
   * @sap: netlabel secattr
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3618
   * @ssp: socket security information
e114e4737   Casey Schaufler   Smack: Simplified...
3619
   *
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3620
   * Returns a pointer to a Smack label entry found on the label list.
e114e4737   Casey Schaufler   Smack: Simplified...
3621
   */
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3622
3623
  static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
  						struct socket_smack *ssp)
e114e4737   Casey Schaufler   Smack: Simplified...
3624
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3625
  	struct smack_known *skp;
f7112e6c9   Casey Schaufler   Smack: allow for ...
3626
  	int found = 0;
677264e8f   Casey Schaufler   Smack: network la...
3627
3628
  	int acat;
  	int kcat;
e114e4737   Casey Schaufler   Smack: Simplified...
3629

322dd63c7   Casey Schaufler   Smack: Use the ne...
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
  	/*
  	 * Netlabel found it in the cache.
  	 */
  	if ((sap->flags & NETLBL_SECATTR_CACHE) != 0)
  		return (struct smack_known *)sap->cache->data;
  
  	if ((sap->flags & NETLBL_SECATTR_SECID) != 0)
  		/*
  		 * Looks like a fallback, which gives us a secid.
  		 */
  		return smack_from_secid(sap->attr.secid);
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3641
  	if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) {
e114e4737   Casey Schaufler   Smack: Simplified...
3642
  		/*
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3643
  		 * Looks like a CIPSO packet.
e114e4737   Casey Schaufler   Smack: Simplified...
3644
3645
3646
  		 * If there are flags but no level netlabel isn't
  		 * behaving the way we expect it to.
  		 *
f7112e6c9   Casey Schaufler   Smack: allow for ...
3647
  		 * Look it up in the label table
e114e4737   Casey Schaufler   Smack: Simplified...
3648
3649
3650
3651
  		 * Without guidance regarding the smack value
  		 * for the packet fall back on the network
  		 * ambient value.
  		 */
f7112e6c9   Casey Schaufler   Smack: allow for ...
3652
  		rcu_read_lock();
348dc288d   Vishal Goel   Smack: Traverse t...
3653
  		list_for_each_entry_rcu(skp, &smack_known_list, list) {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3654
  			if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl)
f7112e6c9   Casey Schaufler   Smack: allow for ...
3655
  				continue;
677264e8f   Casey Schaufler   Smack: network la...
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
  			/*
  			 * 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...
3666
3667
3668
  				acat = netlbl_catmap_walk(sap->attr.mls.cat,
  							  acat + 1);
  				kcat = netlbl_catmap_walk(
677264e8f   Casey Schaufler   Smack: network la...
3669
3670
3671
3672
3673
3674
3675
3676
3677
  					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...
3678
  		}
f7112e6c9   Casey Schaufler   Smack: allow for ...
3679
3680
3681
  		rcu_read_unlock();
  
  		if (found)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3682
  			return skp;
f7112e6c9   Casey Schaufler   Smack: allow for ...
3683

54e70ec5e   Casey Schaufler   Smack: bidirectio...
3684
  		if (ssp != NULL && ssp->smk_in == &smack_known_star)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3685
3686
  			return &smack_known_web;
  		return &smack_known_star;
e114e4737   Casey Schaufler   Smack: Simplified...
3687
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
3688
  	/*
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3689
3690
3691
  	 * Without guidance regarding the smack value
  	 * for the packet fall back on the network
  	 * ambient value.
e114e4737   Casey Schaufler   Smack: Simplified...
3692
  	 */
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3693
  	return smack_net_ambient;
e114e4737   Casey Schaufler   Smack: Simplified...
3694
  }
69f287ae6   Casey Schaufler   Smack: secmark su...
3695
  #if IS_ENABLED(CONFIG_IPV6)
6ea062475   Casey Schaufler   Smack: IPv6 casti...
3696
  static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip)
c67394434   Casey Schaufler   Smack: Local IPv6...
3697
  {
c67394434   Casey Schaufler   Smack: Local IPv6...
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
  	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:
a07ef9516   Piotr Sawicki   Smack: Check UDP-...
3730
  	case IPPROTO_UDPLITE:
c67394434   Casey Schaufler   Smack: Local IPv6...
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
  		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...
3743
  #endif /* CONFIG_IPV6 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3744

e114e4737   Casey Schaufler   Smack: Simplified...
3745
  /**
36be81293   Casey Schaufler   Smack: Consolidat...
3746
3747
3748
3749
3750
   * smack_from_skb - Smack data from the secmark in an skb
   * @skb: packet
   *
   * Returns smack_known of the secmark or NULL if that won't work.
   */
bf0afe673   Casey Schaufler   Smack: Fix build ...
3751
  #ifdef CONFIG_NETWORK_SECMARK
36be81293   Casey Schaufler   Smack: Consolidat...
3752
3753
3754
3755
3756
3757
3758
  static struct smack_known *smack_from_skb(struct sk_buff *skb)
  {
  	if (skb == NULL || skb->secmark == 0)
  		return NULL;
  
  	return smack_from_secid(skb->secmark);
  }
bf0afe673   Casey Schaufler   Smack: Fix build ...
3759
3760
3761
3762
3763
3764
  #else
  static inline struct smack_known *smack_from_skb(struct sk_buff *skb)
  {
  	return NULL;
  }
  #endif
36be81293   Casey Schaufler   Smack: Consolidat...
3765
3766
  
  /**
a2af03188   Casey Schaufler   Smack: Set socket...
3767
3768
3769
3770
3771
   * smack_from_netlbl - Smack data from the IP options in an skb
   * @sk: socket data came in on
   * @family: address family
   * @skb: packet
   *
322dd63c7   Casey Schaufler   Smack: Use the ne...
3772
3773
3774
   * Find the Smack label in the IP options. If it hasn't been
   * added to the netlabel cache, add it here.
   *
a2af03188   Casey Schaufler   Smack: Set socket...
3775
3776
3777
3778
3779
3780
3781
3782
   * Returns smack_known of the IP options or NULL if that won't work.
   */
  static struct smack_known *smack_from_netlbl(struct sock *sk, u16 family,
  					     struct sk_buff *skb)
  {
  	struct netlbl_lsm_secattr secattr;
  	struct socket_smack *ssp = NULL;
  	struct smack_known *skp = NULL;
edd615371   Casey Schaufler   Smack: Remove unn...
3783
  	int rc;
a2af03188   Casey Schaufler   Smack: Set socket...
3784
3785
3786
3787
3788
  
  	netlbl_secattr_init(&secattr);
  
  	if (sk)
  		ssp = sk->sk_security;
322dd63c7   Casey Schaufler   Smack: Use the ne...
3789
3790
  
  	if (netlbl_skbuff_getattr(skb, family, &secattr) == 0) {
a2af03188   Casey Schaufler   Smack: Set socket...
3791
  		skp = smack_from_secattr(&secattr, ssp);
322dd63c7   Casey Schaufler   Smack: Use the ne...
3792
3793
3794
  		if (secattr.flags & NETLBL_SECATTR_CACHEABLE)
  			rc = netlbl_cache_add(skb, family, &skp->smk_netlabel);
  	}
a2af03188   Casey Schaufler   Smack: Set socket...
3795
3796
3797
3798
3799
3800
3801
  
  	netlbl_secattr_destroy(&secattr);
  
  	return skp;
  }
  
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
3802
3803
3804
3805
3806
3807
3808
3809
   * 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)
  {
e114e4737   Casey Schaufler   Smack: Simplified...
3810
  	struct socket_smack *ssp = sk->sk_security;
69f287ae6   Casey Schaufler   Smack: secmark su...
3811
  	struct smack_known *skp = NULL;
c67394434   Casey Schaufler   Smack: Local IPv6...
3812
  	int rc = 0;
ecfcc53fe   Etienne Basset   smack: implement ...
3813
  	struct smk_audit_info ad;
129a99890   Piotr Sawicki   Smack: Fix handli...
3814
  	u16 family = sk->sk_family;
923e9a139   Kees Cook   Smack: build when...
3815
  #ifdef CONFIG_AUDIT
48c62af68   Eric Paris   LSM: shrink the c...
3816
  	struct lsm_network_audit net;
923e9a139   Kees Cook   Smack: build when...
3817
  #endif
69f287ae6   Casey Schaufler   Smack: secmark su...
3818
3819
3820
  #if IS_ENABLED(CONFIG_IPV6)
  	struct sockaddr_in6 sadd;
  	int proto;
129a99890   Piotr Sawicki   Smack: Fix handli...
3821
3822
3823
  
  	if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
  		family = PF_INET;
69f287ae6   Casey Schaufler   Smack: secmark su...
3824
  #endif /* CONFIG_IPV6 */
129a99890   Piotr Sawicki   Smack: Fix handli...
3825
  	switch (family) {
c67394434   Casey Schaufler   Smack: Local IPv6...
3826
  	case PF_INET:
69f287ae6   Casey Schaufler   Smack: secmark su...
3827
3828
3829
3830
3831
  		/*
  		 * 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.
  		 */
36be81293   Casey Schaufler   Smack: Consolidat...
3832
  		skp = smack_from_skb(skb);
a2af03188   Casey Schaufler   Smack: Set socket...
3833
3834
3835
3836
  		if (skp == NULL) {
  			skp = smack_from_netlbl(sk, family, skb);
  			if (skp == NULL)
  				skp = smack_net_ambient;
69f287ae6   Casey Schaufler   Smack: secmark su...
3837
  		}
6d3dc07cb   Casey Schaufler   smack: Add suppor...
3838

ecfcc53fe   Etienne Basset   smack: implement ...
3839
  #ifdef CONFIG_AUDIT
c67394434   Casey Schaufler   Smack: Local IPv6...
3840
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
129a99890   Piotr Sawicki   Smack: Fix handli...
3841
  		ad.a.u.net->family = family;
c67394434   Casey Schaufler   Smack: Local IPv6...
3842
3843
  		ad.a.u.net->netif = skb->skb_iif;
  		ipv4_skb_to_auditdata(skb, &ad.a, NULL);
ecfcc53fe   Etienne Basset   smack: implement ...
3844
  #endif
c67394434   Casey Schaufler   Smack: Local IPv6...
3845
3846
3847
3848
3849
3850
  		/*
  		 * 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...
3851
3852
  		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...
3853
  					MAY_WRITE, rc);
c67394434   Casey Schaufler   Smack: Local IPv6...
3854
  		if (rc != 0)
129a99890   Piotr Sawicki   Smack: Fix handli...
3855
  			netlbl_skbuff_err(skb, family, rc, 0);
c67394434   Casey Schaufler   Smack: Local IPv6...
3856
  		break;
69f287ae6   Casey Schaufler   Smack: secmark su...
3857
  #if IS_ENABLED(CONFIG_IPV6)
c67394434   Casey Schaufler   Smack: Local IPv6...
3858
  	case PF_INET6:
69f287ae6   Casey Schaufler   Smack: secmark su...
3859
  		proto = smk_skb_to_addr_ipv6(skb, &sadd);
a07ef9516   Piotr Sawicki   Smack: Check UDP-...
3860
3861
  		if (proto != IPPROTO_UDP && proto != IPPROTO_UDPLITE &&
  		    proto != IPPROTO_TCP && proto != IPPROTO_DCCP)
69f287ae6   Casey Schaufler   Smack: secmark su...
3862
  			break;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3863
  #ifdef SMACK_IPV6_SECMARK_LABELING
36be81293   Casey Schaufler   Smack: Consolidat...
3864
3865
3866
3867
  		skp = smack_from_skb(skb);
  		if (skp == NULL) {
  			if (smk_ipv6_localhost(&sadd))
  				break;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3868
  			skp = smack_ipv6host_label(&sadd);
36be81293   Casey Schaufler   Smack: Consolidat...
3869
3870
3871
  			if (skp == NULL)
  				skp = smack_net_ambient;
  		}
69f287ae6   Casey Schaufler   Smack: secmark su...
3872
3873
  #ifdef CONFIG_AUDIT
  		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
129a99890   Piotr Sawicki   Smack: Fix handli...
3874
  		ad.a.u.net->family = family;
69f287ae6   Casey Schaufler   Smack: secmark su...
3875
3876
3877
3878
3879
3880
  		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 ...
3881
3882
  #endif /* SMACK_IPV6_SECMARK_LABELING */
  #ifdef SMACK_IPV6_PORT_LABELING
69f287ae6   Casey Schaufler   Smack: secmark su...
3883
  		rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3884
  #endif /* SMACK_IPV6_PORT_LABELING */
d66a8acbd   Piotr Sawicki   Smack: Inform pee...
3885
3886
3887
  		if (rc != 0)
  			icmpv6_send(skb, ICMPV6_DEST_UNREACH,
  					ICMPV6_ADM_PROHIBITED, 0);
c67394434   Casey Schaufler   Smack: Local IPv6...
3888
  		break;
69f287ae6   Casey Schaufler   Smack: secmark su...
3889
  #endif /* CONFIG_IPV6 */
c67394434   Casey Schaufler   Smack: Local IPv6...
3890
  	}
69f287ae6   Casey Schaufler   Smack: secmark su...
3891

a8134296b   Paul Moore   smack: Fix missin...
3892
  	return rc;
e114e4737   Casey Schaufler   Smack: Simplified...
3893
3894
3895
3896
3897
3898
3899
  }
  
  /**
   * 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...
3900
   * @len: max thereof
e114e4737   Casey Schaufler   Smack: Simplified...
3901
3902
3903
3904
3905
3906
3907
3908
   *
   * 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 ...
3909
3910
  	char *rcp = "";
  	int slen = 1;
e114e4737   Casey Schaufler   Smack: Simplified...
3911
3912
3913
  	int rc = 0;
  
  	ssp = sock->sk->sk_security;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3914
  	if (ssp->smk_packet != NULL) {
54e70ec5e   Casey Schaufler   Smack: bidirectio...
3915
  		rcp = ssp->smk_packet->smk_known;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3916
3917
  		slen = strlen(rcp) + 1;
  	}
e114e4737   Casey Schaufler   Smack: Simplified...
3918
3919
3920
  
  	if (slen > len)
  		rc = -ERANGE;
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3921
  	else if (copy_to_user(optval, rcp, slen) != 0)
e114e4737   Casey Schaufler   Smack: Simplified...
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
  		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
3933
   * @sock: the peer socket
e114e4737   Casey Schaufler   Smack: Simplified...
3934
3935
3936
3937
3938
3939
3940
3941
3942
   * @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)
  
  {
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3943
  	struct socket_smack *ssp = NULL;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3944
  	struct smack_known *skp;
a2af03188   Casey Schaufler   Smack: Set socket...
3945
  	struct sock *sk = NULL;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3946
3947
  	int family = PF_UNSPEC;
  	u32 s = 0;	/* 0 is the invalid secid */
e114e4737   Casey Schaufler   Smack: Simplified...
3948

b4e0d5f07   Casey Schaufler   Smack: UDS revision
3949
3950
3951
  	if (skb != NULL) {
  		if (skb->protocol == htons(ETH_P_IP))
  			family = PF_INET;
69f287ae6   Casey Schaufler   Smack: secmark su...
3952
  #if IS_ENABLED(CONFIG_IPV6)
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3953
3954
  		else if (skb->protocol == htons(ETH_P_IPV6))
  			family = PF_INET6;
69f287ae6   Casey Schaufler   Smack: secmark su...
3955
  #endif /* CONFIG_IPV6 */
e114e4737   Casey Schaufler   Smack: Simplified...
3956
  	}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3957
3958
  	if (family == PF_UNSPEC && sock != NULL)
  		family = sock->sk->sk_family;
e114e4737   Casey Schaufler   Smack: Simplified...
3959

69f287ae6   Casey Schaufler   Smack: secmark su...
3960
3961
  	switch (family) {
  	case PF_UNIX:
272cd7a8c   Casey Schaufler   Smack: Rule list ...
3962
  		ssp = sock->sk->sk_security;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3963
  		s = ssp->smk_out->smk_secid;
69f287ae6   Casey Schaufler   Smack: secmark su...
3964
3965
  		break;
  	case PF_INET:
36be81293   Casey Schaufler   Smack: Consolidat...
3966
3967
3968
  		skp = smack_from_skb(skb);
  		if (skp) {
  			s = skp->smk_secid;
69f287ae6   Casey Schaufler   Smack: secmark su...
3969
  			break;
36be81293   Casey Schaufler   Smack: Consolidat...
3970
  		}
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3971
3972
3973
  		/*
  		 * Translate what netlabel gave us.
  		 */
a2af03188   Casey Schaufler   Smack: Set socket...
3974
3975
3976
3977
  		if (sock != NULL)
  			sk = sock->sk;
  		skp = smack_from_netlbl(sk, family, skb);
  		if (skp != NULL)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
3978
  			s = skp->smk_secid;
69f287ae6   Casey Schaufler   Smack: secmark su...
3979
  		break;
69f287ae6   Casey Schaufler   Smack: secmark su...
3980
  	case PF_INET6:
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3981
  #ifdef SMACK_IPV6_SECMARK_LABELING
36be81293   Casey Schaufler   Smack: Consolidat...
3982
3983
3984
  		skp = smack_from_skb(skb);
  		if (skp)
  			s = skp->smk_secid;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
3985
  #endif
69f287ae6   Casey Schaufler   Smack: secmark su...
3986
  		break;
b4e0d5f07   Casey Schaufler   Smack: UDS revision
3987
3988
  	}
  	*secid = s;
e114e4737   Casey Schaufler   Smack: Simplified...
3989
3990
  	if (s == 0)
  		return -EINVAL;
e114e4737   Casey Schaufler   Smack: Simplified...
3991
3992
3993
3994
  	return 0;
  }
  
  /**
07feee8f8   Paul Moore   netlabel: Cleanup...
3995
3996
3997
   * smack_sock_graft - Initialize a newly created socket with an existing sock
   * @sk: child sock
   * @parent: parent socket
e114e4737   Casey Schaufler   Smack: Simplified...
3998
   *
07feee8f8   Paul Moore   netlabel: Cleanup...
3999
4000
   * 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...
4001
4002
4003
4004
   */
  static void smack_sock_graft(struct sock *sk, struct socket *parent)
  {
  	struct socket_smack *ssp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4005
  	struct smack_known *skp = smk_of_current();
e114e4737   Casey Schaufler   Smack: Simplified...
4006

07feee8f8   Paul Moore   netlabel: Cleanup...
4007
4008
  	if (sk == NULL ||
  	    (sk->sk_family != PF_INET && sk->sk_family != PF_INET6))
e114e4737   Casey Schaufler   Smack: Simplified...
4009
4010
4011
  		return;
  
  	ssp = sk->sk_security;
54e70ec5e   Casey Schaufler   Smack: bidirectio...
4012
  	ssp->smk_in = skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4013
  	ssp->smk_out = skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
4014
  	/* cssp->smk_packet is already set in smack_inet_csk_clone() */
e114e4737   Casey Schaufler   Smack: Simplified...
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
  }
  
  /**
   * 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...
4029
  	u16 family = sk->sk_family;
f7112e6c9   Casey Schaufler   Smack: allow for ...
4030
  	struct smack_known *skp;
e114e4737   Casey Schaufler   Smack: Simplified...
4031
  	struct socket_smack *ssp = sk->sk_security;
07feee8f8   Paul Moore   netlabel: Cleanup...
4032
4033
  	struct sockaddr_in addr;
  	struct iphdr *hdr;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4034
  	struct smack_known *hskp;
e114e4737   Casey Schaufler   Smack: Simplified...
4035
  	int rc;
ecfcc53fe   Etienne Basset   smack: implement ...
4036
  	struct smk_audit_info ad;
923e9a139   Kees Cook   Smack: build when...
4037
  #ifdef CONFIG_AUDIT
48c62af68   Eric Paris   LSM: shrink the c...
4038
  	struct lsm_network_audit net;
923e9a139   Kees Cook   Smack: build when...
4039
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
4040

69f287ae6   Casey Schaufler   Smack: secmark su...
4041
  #if IS_ENABLED(CONFIG_IPV6)
c67394434   Casey Schaufler   Smack: Local IPv6...
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
  	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...
4053
  #endif /* CONFIG_IPV6 */
e114e4737   Casey Schaufler   Smack: Simplified...
4054

7f368ad34   Casey Schaufler   Smack: secmark co...
4055
4056
4057
4058
4059
  	/*
  	 * 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.
  	 */
36be81293   Casey Schaufler   Smack: Consolidat...
4060
  	skp = smack_from_skb(skb);
a2af03188   Casey Schaufler   Smack: Set socket...
4061
4062
4063
4064
  	if (skp == NULL) {
  		skp = smack_from_netlbl(sk, family, skb);
  		if (skp == NULL)
  			skp = &smack_known_huh;
7f368ad34   Casey Schaufler   Smack: secmark co...
4065
  	}
7f368ad34   Casey Schaufler   Smack: secmark co...
4066

ecfcc53fe   Etienne Basset   smack: implement ...
4067
  #ifdef CONFIG_AUDIT
48c62af68   Eric Paris   LSM: shrink the c...
4068
4069
4070
  	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 ...
4071
4072
  	ipv4_skb_to_auditdata(skb, &ad.a, NULL);
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
4073
  	/*
07feee8f8   Paul Moore   netlabel: Cleanup...
4074
4075
  	 * Receiving a packet requires that the other end be able to write
  	 * here. Read access is not required.
e114e4737   Casey Schaufler   Smack: Simplified...
4076
  	 */
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4077
4078
  	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...
4079
4080
4081
4082
4083
4084
4085
  	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...
4086
  	req->peer_secid = skp->smk_secid;
07feee8f8   Paul Moore   netlabel: Cleanup...
4087
4088
4089
4090
  
  	/*
  	 * 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...
4091
  	 * propagate the wire-label to the sock when it is created.
07feee8f8   Paul Moore   netlabel: Cleanup...
4092
4093
4094
4095
  	 */
  	hdr = ip_hdr(skb);
  	addr.sin_addr.s_addr = hdr->saddr;
  	rcu_read_lock();
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4096
  	hskp = smack_ipv4host_label(&addr);
f7112e6c9   Casey Schaufler   Smack: allow for ...
4097
  	rcu_read_unlock();
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4098
  	if (hskp == NULL)
f7112e6c9   Casey Schaufler   Smack: allow for ...
4099
  		rc = netlbl_req_setattr(req, &skp->smk_netlabel);
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4100
  	else
07feee8f8   Paul Moore   netlabel: Cleanup...
4101
  		netlbl_req_delattr(req);
e114e4737   Casey Schaufler   Smack: Simplified...
4102
4103
4104
  
  	return rc;
  }
07feee8f8   Paul Moore   netlabel: Cleanup...
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
  /**
   * 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...
4116
  	struct smack_known *skp;
07feee8f8   Paul Moore   netlabel: Cleanup...
4117

2f823ff8b   Casey Schaufler   Smack: Improve ac...
4118
4119
  	if (req->peer_secid != 0) {
  		skp = smack_from_secid(req->peer_secid);
54e70ec5e   Casey Schaufler   Smack: bidirectio...
4120
  		ssp->smk_packet = skp;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4121
  	} else
272cd7a8c   Casey Schaufler   Smack: Rule list ...
4122
  		ssp->smk_packet = NULL;
07feee8f8   Paul Moore   netlabel: Cleanup...
4123
  }
e114e4737   Casey Schaufler   Smack: Simplified...
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
  /*
   * 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 ...
4136
   * @cred: the credentials to use
e114e4737   Casey Schaufler   Smack: Simplified...
4137
4138
4139
4140
4141
4142
   * @flags: unused
   *
   * No allocation required
   *
   * Returns 0
   */
d84f4f992   David Howells   CRED: Inaugurate ...
4143
  static int smack_key_alloc(struct key *key, const struct cred *cred,
e114e4737   Casey Schaufler   Smack: Simplified...
4144
4145
  			   unsigned long flags)
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
4146
  	struct smack_known *skp = smk_of_task(smack_cred(cred));
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4147

21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4148
  	key->security = skp;
e114e4737   Casey Schaufler   Smack: Simplified...
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
  	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...
4162
  /**
e114e4737   Casey Schaufler   Smack: Simplified...
4163
4164
   * smack_key_permission - Smack access on a key
   * @key_ref: gets to the object
d84f4f992   David Howells   CRED: Inaugurate ...
4165
   * @cred: the credentials to use
8c0637e95   David Howells   keys: Make the KE...
4166
   * @need_perm: requested key permission
e114e4737   Casey Schaufler   Smack: Simplified...
4167
4168
4169
4170
4171
   *
   * 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,
8c0637e95   David Howells   keys: Make the KE...
4172
4173
  				const struct cred *cred,
  				enum key_need_perm need_perm)
e114e4737   Casey Schaufler   Smack: Simplified...
4174
4175
  {
  	struct key *keyp;
ecfcc53fe   Etienne Basset   smack: implement ...
4176
  	struct smk_audit_info ad;
b17103a8b   Casey Schaufler   Smack: Abstract u...
4177
  	struct smack_known *tkp = smk_of_task(smack_cred(cred));
fffea214a   Dmitry Kasatkin   smack: fix key pe...
4178
  	int request = 0;
d166c8024   Casey Schaufler   Smack: Bring-up a...
4179
  	int rc;
e114e4737   Casey Schaufler   Smack: Simplified...
4180

5b841bfab   Zoran Markovic   smack: fix access...
4181
4182
4183
  	/*
  	 * Validate requested permissions
  	 */
8c0637e95   David Howells   keys: Make the KE...
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
  	switch (need_perm) {
  	case KEY_NEED_READ:
  	case KEY_NEED_SEARCH:
  	case KEY_NEED_VIEW:
  		request |= MAY_READ;
  		break;
  	case KEY_NEED_WRITE:
  	case KEY_NEED_LINK:
  	case KEY_NEED_SETATTR:
  		request |= MAY_WRITE;
  		break;
  	case KEY_NEED_UNSPECIFIED:
  	case KEY_NEED_UNLINK:
  	case KEY_SYSADMIN_OVERRIDE:
  	case KEY_AUTHTOKEN_OVERRIDE:
  	case KEY_DEFER_PERM_CHECK:
  		return 0;
  	default:
5b841bfab   Zoran Markovic   smack: fix access...
4202
  		return -EINVAL;
8c0637e95   David Howells   keys: Make the KE...
4203
  	}
5b841bfab   Zoran Markovic   smack: fix access...
4204

e114e4737   Casey Schaufler   Smack: Simplified...
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
  	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...
4217
  	if (tkp == NULL)
e114e4737   Casey Schaufler   Smack: Simplified...
4218
  		return -EACCES;
d19dfe58b   Casey Schaufler   Smack: Privilege ...
4219

a8478a602   David Howells   smack: Implement ...
4220
  	if (smack_privileged(CAP_MAC_OVERRIDE))
d19dfe58b   Casey Schaufler   Smack: Privilege ...
4221
  		return 0;
ecfcc53fe   Etienne Basset   smack: implement ...
4222
4223
4224
4225
4226
  #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
d166c8024   Casey Schaufler   Smack: Bring-up a...
4227
4228
4229
  	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...
4230
  }
7fc5f36e9   José Bollo   Smack: getting th...
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
  
  /*
   * 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;
  }
a8478a602   David Howells   smack: Implement ...
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
  
  #ifdef CONFIG_KEY_NOTIFICATIONS
  /**
   * smack_watch_key - Smack access to watch a key for notifications.
   * @key: The key to be watched
   *
   * Return 0 if the @watch->cred has permission to read from the key object and
   * an error otherwise.
   */
  static int smack_watch_key(struct key *key)
  {
  	struct smk_audit_info ad;
  	struct smack_known *tkp = smk_of_current();
  	int rc;
  
  	if (key == NULL)
  		return -EINVAL;
  	/*
  	 * If the key hasn't been initialized give it access so that
  	 * it may do so.
  	 */
  	if (key->security == NULL)
  		return 0;
  	/*
  	 * This should not occur
  	 */
  	if (tkp == NULL)
  		return -EACCES;
  
  	if (smack_privileged_cred(CAP_MAC_OVERRIDE, current_cred()))
  		return 0;
  
  #ifdef CONFIG_AUDIT
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
  	ad.a.u.key_struct.key = key->serial;
  	ad.a.u.key_struct.key_desc = key->description;
  #endif
  	rc = smk_access(tkp, key->security, MAY_READ, &ad);
  	rc = smk_bu_note("key watch", tkp, key->security, MAY_READ, rc);
  	return rc;
  }
  #endif /* CONFIG_KEY_NOTIFICATIONS */
e114e4737   Casey Schaufler   Smack: Simplified...
4302
  #endif /* CONFIG_KEYS */
a8478a602   David Howells   smack: Implement ...
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
  #ifdef CONFIG_WATCH_QUEUE
  /**
   * smack_post_notification - Smack access to post a notification to a queue
   * @w_cred: The credentials of the watcher.
   * @cred: The credentials of the event source (may be NULL).
   * @n: The notification message to be posted.
   */
  static int smack_post_notification(const struct cred *w_cred,
  				   const struct cred *cred,
  				   struct watch_notification *n)
  {
  	struct smk_audit_info ad;
  	struct smack_known *subj, *obj;
  	int rc;
  
  	/* Always let maintenance notifications through. */
  	if (n->type == WATCH_TYPE_META)
  		return 0;
  
  	if (!cred)
  		return 0;
  	subj = smk_of_task(smack_cred(cred));
  	obj = smk_of_task(smack_cred(w_cred));
  
  	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NOTIFICATION);
  	rc = smk_access(subj, obj, MAY_WRITE, &ad);
  	rc = smk_bu_note("notification", subj, obj, MAY_WRITE, rc);
  	return rc;
  }
  #endif /* CONFIG_WATCH_QUEUE */
e114e4737   Casey Schaufler   Smack: Simplified...
4333
  /*
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
   * 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...
4360
  	struct smack_known *skp;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4361
4362
4363
4364
4365
  	char **rule = (char **)vrule;
  	*rule = NULL;
  
  	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
  		return -EINVAL;
5af75d8d5   Al Viro   audit: validate c...
4366
  	if (op != Audit_equal && op != Audit_not_equal)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4367
  		return -EINVAL;
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4368
  	skp = smk_import_entry(rulestr, 0);
e774ad683   Lukasz Pawelczyk   smack: pass error...
4369
4370
4371
4372
  	if (IS_ERR(skp))
  		return PTR_ERR(skp);
  
  	*rule = skp->smk_known;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
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
  
  	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
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4406
4407
4408
4409
   *
   * The core Audit hook. It's used to take the decision of
   * whether to audit or not to audit a given object.
   */
90462a5bd   Richard Guy Briggs   audit: remove unu...
4410
  static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule)
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4411
  {
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4412
  	struct smack_known *skp;
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4413
  	char *rule = vrule;
4eb0f4abf   Richard Guy Briggs   smack: call WARN_...
4414
4415
4416
  	if (unlikely(!rule)) {
  		WARN_ONCE(1, "Smack: missing rule
  ");
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4417
4418
4419
4420
4421
  		return -ENOENT;
  	}
  
  	if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
  		return 0;
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4422
  	skp = smack_from_secid(secid);
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4423
4424
4425
4426
4427
4428
  
  	/*
  	 * 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...
4429
  	if (op == Audit_equal)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4430
  		return (rule == skp->smk_known);
5af75d8d5   Al Viro   audit: validate c...
4431
  	if (op == Audit_not_equal)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4432
  		return (rule != skp->smk_known);
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4433
4434
4435
  
  	return 0;
  }
491a0b08d   Casey Schaufler   Smack: Remove poi...
4436
4437
  /*
   * There is no need for a smack_audit_rule_free hook.
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4438
4439
   * No memory was allocated.
   */
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4440
4441
  
  #endif /* CONFIG_AUDIT */
251a2a958   Randy Dunlap   smack: fix lots o...
4442
  /**
746df9b59   David Quigley   Security: Add Hoo...
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
   * 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...
4453
4454
4455
4456
4457
4458
4459
4460
4461
   * 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...
4462
  	struct smack_known *skp = smack_from_secid(secid);
e114e4737   Casey Schaufler   Smack: Simplified...
4463

d5630b9d2   Eric Paris   security: secid_t...
4464
  	if (secdata)
2f823ff8b   Casey Schaufler   Smack: Improve ac...
4465
4466
  		*secdata = skp->smk_known;
  	*seclen = strlen(skp->smk_known);
e114e4737   Casey Schaufler   Smack: Simplified...
4467
4468
  	return 0;
  }
251a2a958   Randy Dunlap   smack: fix lots o...
4469
  /**
4bc87e627   Casey Schaufler   Smack: unlabeled ...
4470
4471
4472
4473
4474
4475
4476
   * 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...
4477
  static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
4bc87e627   Casey Schaufler   Smack: unlabeled ...
4478
  {
21c7eae21   Lukasz Pawelczyk   Make Smack operat...
4479
4480
4481
4482
4483
4484
  	struct smack_known *skp = smk_find_entry(secdata);
  
  	if (skp)
  		*secid = skp->smk_secid;
  	else
  		*secid = 0;
4bc87e627   Casey Schaufler   Smack: unlabeled ...
4485
4486
  	return 0;
  }
491a0b08d   Casey Schaufler   Smack: Remove poi...
4487
4488
4489
4490
  /*
   * 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...
4491
   */
e114e4737   Casey Schaufler   Smack: Simplified...
4492

1ee65e37e   David P. Quigley   LSM/SELinux: inod...
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
  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)
  {
0f8983cf9   Casey Schaufler   Smack: Fix memory...
4505
  	struct smack_known *skp = smk_of_inode(inode);
1ee65e37e   David P. Quigley   LSM/SELinux: inod...
4506

0f8983cf9   Casey Schaufler   Smack: Fix memory...
4507
4508
  	*ctx = skp->smk_known;
  	*ctxlen = strlen(skp->smk_known);
1ee65e37e   David P. Quigley   LSM/SELinux: inod...
4509
4510
  	return 0;
  }
d6d80cb57   Casey Schaufler   Smack: Base suppo...
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
  static int smack_inode_copy_up(struct dentry *dentry, struct cred **new)
  {
  
  	struct task_smack *tsp;
  	struct smack_known *skp;
  	struct inode_smack *isp;
  	struct cred *new_creds = *new;
  
  	if (new_creds == NULL) {
  		new_creds = prepare_creds();
  		if (new_creds == NULL)
  			return -ENOMEM;
  	}
b17103a8b   Casey Schaufler   Smack: Abstract u...
4524
  	tsp = smack_cred(new_creds);
d6d80cb57   Casey Schaufler   Smack: Base suppo...
4525
4526
4527
4528
  
  	/*
  	 * Get label from overlay inode and set it in create_sid
  	 */
fb4021b6f   Casey Schaufler   Smack: Abstract u...
4529
  	isp = smack_inode(d_inode(dentry->d_parent));
d6d80cb57   Casey Schaufler   Smack: Base suppo...
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
  	skp = isp->smk_inode;
  	tsp->smk_task = skp;
  	*new = new_creds;
  	return 0;
  }
  
  static int smack_inode_copy_up_xattr(const char *name)
  {
  	/*
  	 * Return 1 if this is the smack access Smack attribute.
  	 */
  	if (strcmp(name, XATTR_NAME_SMACK) == 0)
  		return 1;
  
  	return -EOPNOTSUPP;
  }
  
  static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
  					struct qstr *name,
  					const struct cred *old,
  					struct cred *new)
  {
b17103a8b   Casey Schaufler   Smack: Abstract u...
4552
4553
  	struct task_smack *otsp = smack_cred(old);
  	struct task_smack *ntsp = smack_cred(new);
d6d80cb57   Casey Schaufler   Smack: Base suppo...
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
  	struct inode_smack *isp;
  	int may;
  
  	/*
  	 * Use the process credential unless all of
  	 * the transmuting criteria are met
  	 */
  	ntsp->smk_task = otsp->smk_task;
  
  	/*
  	 * the attribute of the containing directory
  	 */
fb4021b6f   Casey Schaufler   Smack: Abstract u...
4566
  	isp = smack_inode(d_inode(dentry->d_parent));
d6d80cb57   Casey Schaufler   Smack: Base suppo...
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
  
  	if (isp->smk_flags & SMK_INODE_TRANSMUTE) {
  		rcu_read_lock();
  		may = smk_access_entry(otsp->smk_task->smk_known,
  				       isp->smk_inode->smk_known,
  				       &otsp->smk_task->smk_rules);
  		rcu_read_unlock();
  
  		/*
  		 * If the directory is transmuting and the rule
  		 * providing access is transmuting use the containing
  		 * directory label instead of the process label.
  		 */
  		if (may > 0 && (may & MAY_TRANSMUTE))
  			ntsp->smk_task = isp->smk_inode;
  	}
  	return 0;
  }
bbd3662a8   Casey Schaufler   Infrastructure ma...
4585
4586
  struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = {
  	.lbs_cred = sizeof(struct task_smack),
33bf60cab   Casey Schaufler   LSM: Infrastructu...
4587
  	.lbs_file = sizeof(struct smack_known *),
afb1cbe37   Casey Schaufler   LSM: Infrastructu...
4588
  	.lbs_inode = sizeof(struct inode_smack),
ecd5f82e0   Casey Schaufler   LSM: Infrastructu...
4589
4590
  	.lbs_ipc = sizeof(struct smack_known *),
  	.lbs_msg_msg = sizeof(struct smack_known *),
bbd3662a8   Casey Schaufler   Infrastructure ma...
4591
  };
ca97d939d   James Morris   security: mark LS...
4592
  static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
e20b043a6   Casey Schaufler   LSM: Add security...
4593
4594
4595
  	LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check),
  	LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme),
  	LSM_HOOK_INIT(syslog, smack_syslog),
0b52075ee   Al Viro   introduce cloning...
4596
  	LSM_HOOK_INIT(fs_context_dup, smack_fs_context_dup),
2febd254a   David Howells   smack: Implement ...
4597
  	LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param),
e20b043a6   Casey Schaufler   LSM: Add security...
4598
4599
  	LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security),
  	LSM_HOOK_INIT(sb_free_security, smack_sb_free_security),
204cc0ccf   Al Viro   LSM: hide struct ...
4600
  	LSM_HOOK_INIT(sb_free_mnt_opts, smack_free_mnt_opts),
5b4002391   Al Viro   LSM: turn sb_eat_...
4601
  	LSM_HOOK_INIT(sb_eat_lsm_opts, smack_sb_eat_lsm_opts),
e20b043a6   Casey Schaufler   LSM: Add security...
4602
  	LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
3bf2789ca   Vivek Trivedi   smack: allow moun...
4603
  	LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts),
e20b043a6   Casey Schaufler   LSM: Add security...
4604

b8bff5992   Eric W. Biederman   exec: Factor secu...
4605
  	LSM_HOOK_INIT(bprm_creds_for_exec, smack_bprm_creds_for_exec),
e20b043a6   Casey Schaufler   LSM: Add security...
4606
4607
  
  	LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security),
e20b043a6   Casey Schaufler   LSM: Add security...
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
  	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...
4624
  	LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security),
e20b043a6   Casey Schaufler   LSM: Add security...
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
  	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),
3ec301132   Matthew Garrett   security: Add a c...
4640
  	LSM_HOOK_INIT(cred_getsecid, smack_cred_getsecid),
e20b043a6   Casey Schaufler   LSM: Add security...
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
  	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),
e20b043a6   Casey Schaufler   LSM: Add security...
4654
4655
4656
4657
4658
4659
  	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),
e20b043a6   Casey Schaufler   LSM: Add security...
4660

0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
4661
  	LSM_HOOK_INIT(msg_queue_alloc_security, smack_ipc_alloc_security),
e20b043a6   Casey Schaufler   LSM: Add security...
4662
4663
4664
4665
  	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),
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
4666
  	LSM_HOOK_INIT(shm_alloc_security, smack_ipc_alloc_security),
e20b043a6   Casey Schaufler   LSM: Add security...
4667
4668
4669
  	LSM_HOOK_INIT(shm_associate, smack_shm_associate),
  	LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl),
  	LSM_HOOK_INIT(shm_shmat, smack_shm_shmat),
0d79cbf83   Eric W. Biederman   ipc/smack: Tidy u...
4670
  	LSM_HOOK_INIT(sem_alloc_security, smack_ipc_alloc_security),
e20b043a6   Casey Schaufler   LSM: Add security...
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
  	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),
5859cdf55   Tom Gundersen   smack: provide so...
4684
  	LSM_HOOK_INIT(socket_socketpair, smack_socket_socketpair),
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4685
  #ifdef SMACK_IPV6_PORT_LABELING
e20b043a6   Casey Schaufler   LSM: Add security...
4686
  	LSM_HOOK_INIT(socket_bind, smack_socket_bind),
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4687
  #endif
e20b043a6   Casey Schaufler   LSM: Add security...
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
  	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 ...
4698

e114e4737   Casey Schaufler   Smack: Simplified...
4699
4700
   /* key management security hooks */
  #ifdef CONFIG_KEYS
e20b043a6   Casey Schaufler   LSM: Add security...
4701
4702
4703
4704
  	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),
a8478a602   David Howells   smack: Implement ...
4705
4706
4707
  #ifdef CONFIG_KEY_NOTIFICATIONS
  	LSM_HOOK_INIT(watch_key, smack_watch_key),
  #endif
e114e4737   Casey Schaufler   Smack: Simplified...
4708
  #endif /* CONFIG_KEYS */
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4709

a8478a602   David Howells   smack: Implement ...
4710
4711
4712
  #ifdef CONFIG_WATCH_QUEUE
  	LSM_HOOK_INIT(post_notification, smack_post_notification),
  #endif
d20bdda6d   Ahmed S. Darwish   Smack: Integrate ...
4713
4714
   /* Audit hooks */
  #ifdef CONFIG_AUDIT
e20b043a6   Casey Schaufler   LSM: Add security...
4715
4716
4717
  	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 ...
4718
  #endif /* CONFIG_AUDIT */
e20b043a6   Casey Schaufler   LSM: Add security...
4719
4720
4721
  	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...
4722
4723
4724
  	LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx),
  	LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx),
  	LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx),
d6d80cb57   Casey Schaufler   Smack: Base suppo...
4725
4726
4727
  	LSM_HOOK_INIT(inode_copy_up, smack_inode_copy_up),
  	LSM_HOOK_INIT(inode_copy_up_xattr, smack_inode_copy_up_xattr),
  	LSM_HOOK_INIT(dentry_create_files_as, smack_dentry_create_files_as),
e114e4737   Casey Schaufler   Smack: Simplified...
4728
  };
7198e2eeb   Etienne Basset   smack: convert sm...
4729

86812bb0d   Casey Schaufler   Smack: move label...
4730
  static __init void init_smack_known_list(void)
7198e2eeb   Etienne Basset   smack: convert sm...
4731
  {
86812bb0d   Casey Schaufler   Smack: move label...
4732
  	/*
86812bb0d   Casey Schaufler   Smack: move label...
4733
4734
4735
4736
4737
4738
  	 * 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);
86812bb0d   Casey Schaufler   Smack: move label...
4739
4740
4741
4742
4743
4744
4745
4746
  	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);
86812bb0d   Casey Schaufler   Smack: move label...
4747
4748
4749
4750
  	INIT_LIST_HEAD(&smack_known_web.smk_rules);
  	/*
  	 * Create the known labels list
  	 */
4d7cf4a1f   Tomasz Stanislawski   security: smack: ...
4751
4752
4753
4754
  	smk_insert_entry(&smack_known_huh);
  	smk_insert_entry(&smack_known_hat);
  	smk_insert_entry(&smack_known_star);
  	smk_insert_entry(&smack_known_floor);
4d7cf4a1f   Tomasz Stanislawski   security: smack: ...
4755
  	smk_insert_entry(&smack_known_web);
7198e2eeb   Etienne Basset   smack: convert sm...
4756
  }
e114e4737   Casey Schaufler   Smack: Simplified...
4757
4758
4759
  /**
   * smack_init - initialize the smack system
   *
a1a07f223   luanshi   smack: fix some k...
4760
   * Returns 0 on success, -ENOMEM is there's no memory
e114e4737   Casey Schaufler   Smack: Simplified...
4761
4762
4763
   */
  static __init int smack_init(void)
  {
bbd3662a8   Casey Schaufler   Infrastructure ma...
4764
  	struct cred *cred = (struct cred *) current->cred;
676dac4b1   Casey Schaufler   This patch adds a...
4765
  	struct task_smack *tsp;
d84f4f992   David Howells   CRED: Inaugurate ...
4766

4e328b088   Casey Schaufler   Smack: Create sma...
4767
  	smack_rule_cache = KMEM_CACHE(smack_rule, 0);
4ca752870   Casey Schaufler   Smack:- Remove re...
4768
  	if (!smack_rule_cache)
4e328b088   Casey Schaufler   Smack: Create sma...
4769
  		return -ENOMEM;
4e328b088   Casey Schaufler   Smack: Create sma...
4770

bbd3662a8   Casey Schaufler   Infrastructure ma...
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
  	/*
  	 * Set the security state for the initial task.
  	 */
  	tsp = smack_cred(cred);
  	init_task_smack(tsp, &smack_known_floor, &smack_known_floor);
  
  	/*
  	 * Register with LSM
  	 */
  	security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
d21b7b049   José Bollo   Smack: Minor init...
4781
  	smack_enabled = 1;
21abb1ec4   Casey Schaufler   Smack: IPv6 host ...
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
  	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...
4796

86812bb0d   Casey Schaufler   Smack: move label...
4797
4798
  	/* initialize the smack_known_list */
  	init_smack_known_list();
e114e4737   Casey Schaufler   Smack: Simplified...
4799

e114e4737   Casey Schaufler   Smack: Simplified...
4800
4801
4802
4803
4804
4805
4806
  	return 0;
  }
  
  /*
   * Smack requires early initialization in order to label
   * all processes and objects when they are created.
   */
3d6e5f6dc   Kees Cook   LSM: Convert secu...
4807
  DEFINE_LSM(smack) = {
07aed2f2a   Kees Cook   LSM: Record LSM n...
4808
  	.name = "smack",
14bd99c82   Kees Cook   LSM: Separate ide...
4809
  	.flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
bbd3662a8   Casey Schaufler   Infrastructure ma...
4810
  	.blobs = &smack_blob_sizes,
3d6e5f6dc   Kees Cook   LSM: Convert secu...
4811
4812
  	.init = smack_init,
  };