blob: 5ce633aabce6e7f2d1d984b7b9ef398ed1c713b7 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * NSA Security-Enhanced Linux (SELinux) security module
3 *
4 * This file contains the SELinux hook function implementations.
5 *
6 * Authors: Stephen Smalley, <sds@epoch.ncsc.mil>
Eric Paris828dfe12008-04-17 13:17:49 -04007 * Chris Vance, <cvance@nai.com>
8 * Wayne Salamon, <wsalamon@nai.com>
9 * James Morris <jmorris@redhat.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 *
11 * Copyright (C) 2001,2002 Networks Associates Technology, Inc.
Eric Paris2069f452008-07-04 09:47:13 +100012 * Copyright (C) 2003-2008 Red Hat, Inc., James Morris <jmorris@redhat.com>
13 * Eric Paris <eparis@redhat.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -070014 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
Eric Paris828dfe12008-04-17 13:17:49 -040015 * <dgoeddel@trustedcs.com>
Paul Mooreed6d76e2009-08-28 18:12:49 -040016 * Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P.
Paul Moore82c21bf2011-08-01 11:10:33 +000017 * Paul Moore <paul@paul-moore.com>
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +090018 * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
Eric Paris828dfe12008-04-17 13:17:49 -040019 * Yuichi Nakamura <ynakam@hitachisoft.jp>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License version 2,
Eric Paris828dfe12008-04-17 13:17:49 -040023 * as published by the Free Software Foundation.
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 */
25
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <linux/init.h>
Eric Paris0b24dcb2011-02-25 15:39:20 -050027#include <linux/kd.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/kernel.h>
Roland McGrath0d094ef2008-07-25 19:45:49 -070029#include <linux/tracehook.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include <linux/errno.h>
31#include <linux/sched.h>
Casey Schaufler3c4ed7b2015-05-02 15:10:46 -070032#include <linux/lsm_hooks.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/xattr.h>
34#include <linux/capability.h>
35#include <linux/unistd.h>
36#include <linux/mm.h>
37#include <linux/mman.h>
38#include <linux/slab.h>
39#include <linux/pagemap.h>
Eric Paris0b24dcb2011-02-25 15:39:20 -050040#include <linux/proc_fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/swap.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <linux/spinlock.h>
43#include <linux/syscalls.h>
Eric Paris2a7dba32011-02-01 11:05:39 -050044#include <linux/dcache.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <linux/file.h>
Al Viro9f3acc32008-04-24 07:44:08 -040046#include <linux/fdtable.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <linux/namei.h>
48#include <linux/mount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <linux/netfilter_ipv4.h>
50#include <linux/netfilter_ipv6.h>
51#include <linux/tty.h>
52#include <net/icmp.h>
Stephen Hemminger227b60f2007-10-10 17:30:46 -070053#include <net/ip.h> /* for local_port_range[] */
Linus Torvalds1da177e2005-04-16 15:20:36 -070054#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
Paul Moore47180062013-12-04 16:10:45 -050055#include <net/inet_connection_sock.h>
Paul Moore220deb92008-01-29 08:38:23 -050056#include <net/net_namespace.h>
Paul Moored621d352008-01-29 08:43:36 -050057#include <net/netlabel.h>
Eric Parisf5269712008-05-14 11:27:45 -040058#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070059#include <asm/ioctls.h>
Arun Sharma600634972011-07-26 16:09:06 -070060#include <linux/atomic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070061#include <linux/bitops.h>
62#include <linux/interrupt.h>
63#include <linux/netdevice.h> /* for network interface checks */
Hong zhi guo77954982013-03-27 06:49:35 +000064#include <net/netlink.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070065#include <linux/tcp.h>
66#include <linux/udp.h>
James Morris2ee92d42006-11-13 16:09:01 -080067#include <linux/dccp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070068#include <linux/quota.h>
69#include <linux/un.h> /* for Unix socket types */
70#include <net/af_unix.h> /* for Unix socket types */
71#include <linux/parser.h>
72#include <linux/nfs_mount.h>
73#include <net/ipv6.h>
74#include <linux/hugetlb.h>
75#include <linux/personality.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070076#include <linux/audit.h>
Eric Paris6931dfc2005-06-30 02:58:51 -070077#include <linux/string.h>
Catherine Zhang877ce7c2006-06-29 12:27:47 -070078#include <linux/selinux.h>
Eric Paris23970742006-09-25 23:32:01 -070079#include <linux/mutex.h>
Frank Mayharf06febc2008-09-12 09:54:39 -070080#include <linux/posix-timers.h>
Kees Cook00234592010-02-03 15:36:43 -080081#include <linux/syslog.h>
Serge E. Hallyn34867402011-03-23 16:43:17 -070082#include <linux/user_namespace.h>
Paul Gortmaker44fc7ea2011-05-26 20:52:10 -040083#include <linux/export.h>
Al Viro40401532012-02-13 03:58:52 +000084#include <linux/msg.h>
85#include <linux/shm.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
87#include "avc.h"
88#include "objsec.h"
89#include "netif.h"
Paul Moore224dfbd2008-01-29 08:38:13 -050090#include "netnode.h"
Paul Moore3e1121722008-04-10 10:48:14 -040091#include "netport.h"
Trent Jaegerd28d1e02005-12-13 23:12:40 -080092#include "xfrm.h"
Paul Moorec60475b2007-02-28 15:14:23 -050093#include "netlabel.h"
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +020094#include "audit.h"
James Morris7b98a582011-08-30 12:52:32 +100095#include "avc_ss.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Paul Moored621d352008-01-29 08:43:36 -050097/* SECMARK reference count */
James Morris56a4ca92011-08-17 11:08:43 +100098static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
Paul Moored621d352008-01-29 08:43:36 -050099
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
Eric Paris828dfe12008-04-17 13:17:49 -0400101int selinux_enforcing;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
103static int __init enforcing_setup(char *str)
104{
Eric Parisf5269712008-05-14 11:27:45 -0400105 unsigned long enforcing;
Jingoo Han29707b22014-02-05 15:13:14 +0900106 if (!kstrtoul(str, 0, &enforcing))
Eric Parisf5269712008-05-14 11:27:45 -0400107 selinux_enforcing = enforcing ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 return 1;
109}
110__setup("enforcing=", enforcing_setup);
111#endif
112
113#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
114int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE;
115
116static int __init selinux_enabled_setup(char *str)
117{
Eric Parisf5269712008-05-14 11:27:45 -0400118 unsigned long enabled;
Jingoo Han29707b22014-02-05 15:13:14 +0900119 if (!kstrtoul(str, 0, &enabled))
Eric Parisf5269712008-05-14 11:27:45 -0400120 selinux_enabled = enabled ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 return 1;
122}
123__setup("selinux=", selinux_enabled_setup);
Stephen Smalley30d55282006-05-03 10:52:36 -0400124#else
125int selinux_enabled = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126#endif
127
Christoph Lametere18b8902006-12-06 20:33:20 -0800128static struct kmem_cache *sel_inode_cache;
Sangwoo63205652015-10-21 17:44:30 -0400129static struct kmem_cache *file_security_cache;
James Morris7cae7e22006-03-22 00:09:22 -0800130
Paul Moored621d352008-01-29 08:43:36 -0500131/**
132 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
133 *
134 * Description:
135 * This function checks the SECMARK reference counter to see if any SECMARK
136 * targets are currently configured, if the reference counter is greater than
137 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
Chris PeBenito2be4d742013-05-03 09:05:39 -0400138 * enabled, false (0) if SECMARK is disabled. If the always_check_network
139 * policy capability is enabled, SECMARK is always considered enabled.
Paul Moored621d352008-01-29 08:43:36 -0500140 *
141 */
142static int selinux_secmark_enabled(void)
143{
Chris PeBenito2be4d742013-05-03 09:05:39 -0400144 return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount));
145}
146
147/**
148 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
149 *
150 * Description:
151 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
152 * (1) if any are enabled or false (0) if neither are enabled. If the
153 * always_check_network policy capability is enabled, peer labeling
154 * is always considered enabled.
155 *
156 */
157static int selinux_peerlbl_enabled(void)
158{
159 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
Paul Moored621d352008-01-29 08:43:36 -0500160}
161
Paul Moore615e51f2014-06-26 14:33:56 -0400162static int selinux_netcache_avc_callback(u32 event)
163{
164 if (event == AVC_CALLBACK_RESET) {
165 sel_netif_flush();
166 sel_netnode_flush();
167 sel_netport_flush();
168 synchronize_net();
169 }
170 return 0;
171}
172
David Howellsd84f4f92008-11-14 10:39:23 +1100173/*
174 * initialise the security for the init task
175 */
176static void cred_init_security(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177{
David Howells3b11a1d2008-11-14 10:39:26 +1100178 struct cred *cred = (struct cred *) current->real_cred;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 struct task_security_struct *tsec;
180
James Morris89d155e2005-10-30 14:59:21 -0800181 tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 if (!tsec)
David Howellsd84f4f92008-11-14 10:39:23 +1100183 panic("SELinux: Failed to initialize initial task.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184
David Howellsd84f4f92008-11-14 10:39:23 +1100185 tsec->osid = tsec->sid = SECINITSID_KERNEL;
David Howellsf1752ee2008-11-14 10:39:17 +1100186 cred->security = tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187}
188
David Howells275bb412008-11-14 10:39:19 +1100189/*
David Howells88e67f32008-11-14 10:39:21 +1100190 * get the security ID of a set of credentials
191 */
192static inline u32 cred_sid(const struct cred *cred)
193{
194 const struct task_security_struct *tsec;
195
196 tsec = cred->security;
197 return tsec->sid;
198}
199
200/*
David Howells3b11a1d2008-11-14 10:39:26 +1100201 * get the objective security ID of a task
David Howells275bb412008-11-14 10:39:19 +1100202 */
203static inline u32 task_sid(const struct task_struct *task)
204{
David Howells275bb412008-11-14 10:39:19 +1100205 u32 sid;
206
207 rcu_read_lock();
David Howells88e67f32008-11-14 10:39:21 +1100208 sid = cred_sid(__task_cred(task));
David Howells275bb412008-11-14 10:39:19 +1100209 rcu_read_unlock();
210 return sid;
211}
212
213/*
David Howells3b11a1d2008-11-14 10:39:26 +1100214 * get the subjective security ID of the current task
David Howells275bb412008-11-14 10:39:19 +1100215 */
216static inline u32 current_sid(void)
217{
Paul Moore5fb49872010-04-22 14:46:19 -0400218 const struct task_security_struct *tsec = current_security();
David Howells275bb412008-11-14 10:39:19 +1100219
220 return tsec->sid;
221}
222
David Howells88e67f32008-11-14 10:39:21 +1100223/* Allocate and free functions for each kind of security blob. */
224
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225static int inode_alloc_security(struct inode *inode)
226{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 struct inode_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +1100228 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
Josef Bacika02fe132008-04-04 09:35:05 +1100230 isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 if (!isec)
232 return -ENOMEM;
233
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +0100234 spin_lock_init(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 INIT_LIST_HEAD(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 isec->inode = inode;
237 isec->sid = SECINITSID_UNLABELED;
238 isec->sclass = SECCLASS_FILE;
David Howells275bb412008-11-14 10:39:19 +1100239 isec->task_sid = sid;
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100240 isec->initialized = LABEL_INVALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 inode->i_security = isec;
242
243 return 0;
244}
245
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500246static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
247
248/*
249 * Try reloading inode security labels that have been marked as invalid. The
250 * @may_sleep parameter indicates when sleeping and thus reloading labels is
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100251 * allowed; when set to false, returns -ECHILD when the label is
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500252 * invalid. The @opt_dentry parameter should be set to a dentry of the inode;
253 * when no dentry is available, set it to NULL instead.
254 */
255static int __inode_security_revalidate(struct inode *inode,
256 struct dentry *opt_dentry,
257 bool may_sleep)
258{
259 struct inode_security_struct *isec = inode->i_security;
260
261 might_sleep_if(may_sleep);
262
Paul Moore1ac424762016-04-18 16:41:38 -0400263 if (ss_initialized && isec->initialized != LABEL_INITIALIZED) {
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500264 if (!may_sleep)
265 return -ECHILD;
266
267 /*
268 * Try reloading the inode security label. This will fail if
269 * @opt_dentry is NULL and no dentry for this inode can be
270 * found; in that case, continue using the old label.
271 */
272 inode_doinit_with_dentry(inode, opt_dentry);
273 }
274 return 0;
275}
276
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500277static struct inode_security_struct *inode_security_novalidate(struct inode *inode)
278{
279 return inode->i_security;
280}
281
282static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu)
283{
284 int error;
285
286 error = __inode_security_revalidate(inode, NULL, !rcu);
287 if (error)
288 return ERR_PTR(error);
289 return inode->i_security;
290}
291
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500292/*
293 * Get the security label of an inode.
294 */
295static struct inode_security_struct *inode_security(struct inode *inode)
296{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500297 __inode_security_revalidate(inode, NULL, true);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500298 return inode->i_security;
299}
300
Paul Moore2c971652016-04-19 16:36:28 -0400301static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry)
302{
303 struct inode *inode = d_backing_inode(dentry);
304
305 return inode->i_security;
306}
307
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500308/*
309 * Get the security label of a dentry's backing inode.
310 */
311static struct inode_security_struct *backing_inode_security(struct dentry *dentry)
312{
313 struct inode *inode = d_backing_inode(dentry);
314
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500315 __inode_security_revalidate(inode, dentry, true);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500316 return inode->i_security;
317}
318
Steven Rostedt3dc91d42014-01-09 21:46:34 -0500319static void inode_free_rcu(struct rcu_head *head)
320{
321 struct inode_security_struct *isec;
322
323 isec = container_of(head, struct inode_security_struct, rcu);
324 kmem_cache_free(sel_inode_cache, isec);
325}
326
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327static void inode_free_security(struct inode *inode)
328{
329 struct inode_security_struct *isec = inode->i_security;
330 struct superblock_security_struct *sbsec = inode->i_sb->s_security;
331
Waiman Long9629d042015-07-10 17:19:56 -0400332 /*
333 * As not all inode security structures are in a list, we check for
334 * empty list outside of the lock to make sure that we won't waste
335 * time taking a lock doing nothing.
336 *
337 * The list_del_init() function can be safely called more than once.
338 * It should not be possible for this function to be called with
339 * concurrent list_add(), but for better safety against future changes
340 * in the code, we use list_empty_careful() here.
341 */
342 if (!list_empty_careful(&isec->list)) {
343 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 list_del_init(&isec->list);
Waiman Long9629d042015-07-10 17:19:56 -0400345 spin_unlock(&sbsec->isec_lock);
346 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347
Steven Rostedt3dc91d42014-01-09 21:46:34 -0500348 /*
349 * The inode may still be referenced in a path walk and
350 * a call to selinux_inode_permission() can be made
351 * after inode_free_security() is called. Ideally, the VFS
352 * wouldn't do this, but fixing that is a much harder
353 * job. For now, simply free the i_security via RCU, and
354 * leave the current inode->i_security pointer intact.
355 * The inode will be freed after the RCU grace period too.
356 */
357 call_rcu(&isec->rcu, inode_free_rcu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358}
359
360static int file_alloc_security(struct file *file)
361{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 struct file_security_struct *fsec;
David Howells275bb412008-11-14 10:39:19 +1100363 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364
Sangwoo63205652015-10-21 17:44:30 -0400365 fsec = kmem_cache_zalloc(file_security_cache, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 if (!fsec)
367 return -ENOMEM;
368
David Howells275bb412008-11-14 10:39:19 +1100369 fsec->sid = sid;
370 fsec->fown_sid = sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 file->f_security = fsec;
372
373 return 0;
374}
375
376static void file_free_security(struct file *file)
377{
378 struct file_security_struct *fsec = file->f_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 file->f_security = NULL;
Sangwoo63205652015-10-21 17:44:30 -0400380 kmem_cache_free(file_security_cache, fsec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381}
382
383static int superblock_alloc_security(struct super_block *sb)
384{
385 struct superblock_security_struct *sbsec;
386
James Morris89d155e2005-10-30 14:59:21 -0800387 sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 if (!sbsec)
389 return -ENOMEM;
390
Eric Parisbc7e9822006-09-25 23:32:02 -0700391 mutex_init(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 INIT_LIST_HEAD(&sbsec->isec_head);
393 spin_lock_init(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 sbsec->sb = sb;
395 sbsec->sid = SECINITSID_UNLABELED;
396 sbsec->def_sid = SECINITSID_FILE;
Eric Parisc312feb2006-07-10 04:43:53 -0700397 sbsec->mntpoint_sid = SECINITSID_UNLABELED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 sb->s_security = sbsec;
399
400 return 0;
401}
402
403static void superblock_free_security(struct super_block *sb)
404{
405 struct superblock_security_struct *sbsec = sb->s_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 sb->s_security = NULL;
407 kfree(sbsec);
408}
409
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410/* The file system's label must be initialized prior to use. */
411
David Quigleyeb9ae682013-05-22 12:50:37 -0400412static const char *labeling_behaviors[7] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 "uses xattr",
414 "uses transition SIDs",
415 "uses task SIDs",
416 "uses genfs_contexts",
417 "not configured for labeling",
418 "uses mountpoint labeling",
David Quigleyeb9ae682013-05-22 12:50:37 -0400419 "uses native labeling",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420};
421
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422static inline int inode_doinit(struct inode *inode)
423{
424 return inode_doinit_with_dentry(inode, NULL);
425}
426
427enum {
Eric Paris31e87932007-09-19 17:19:12 -0400428 Opt_error = -1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 Opt_context = 1,
430 Opt_fscontext = 2,
Eric Parisc9180a52007-11-30 13:00:35 -0500431 Opt_defcontext = 3,
432 Opt_rootcontext = 4,
David P. Quigley11689d42009-01-16 09:22:03 -0500433 Opt_labelsupport = 5,
Eric Parisd355987f2012-08-24 15:58:53 -0400434 Opt_nextmntopt = 6,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435};
436
Eric Parisd355987f2012-08-24 15:58:53 -0400437#define NUM_SEL_MNT_OPTS (Opt_nextmntopt - 1)
438
Steven Whitehousea447c092008-10-13 10:46:57 +0100439static const match_table_t tokens = {
Eric Paris832cbd92008-04-01 13:24:09 -0400440 {Opt_context, CONTEXT_STR "%s"},
441 {Opt_fscontext, FSCONTEXT_STR "%s"},
442 {Opt_defcontext, DEFCONTEXT_STR "%s"},
443 {Opt_rootcontext, ROOTCONTEXT_STR "%s"},
David P. Quigley11689d42009-01-16 09:22:03 -0500444 {Opt_labelsupport, LABELSUPP_STR},
Eric Paris31e87932007-09-19 17:19:12 -0400445 {Opt_error, NULL},
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446};
447
448#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
449
Eric Parisc312feb2006-07-10 04:43:53 -0700450static int may_context_mount_sb_relabel(u32 sid,
451 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100452 const struct cred *cred)
Eric Parisc312feb2006-07-10 04:43:53 -0700453{
David Howells275bb412008-11-14 10:39:19 +1100454 const struct task_security_struct *tsec = cred->security;
Eric Parisc312feb2006-07-10 04:43:53 -0700455 int rc;
456
457 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
458 FILESYSTEM__RELABELFROM, NULL);
459 if (rc)
460 return rc;
461
462 rc = avc_has_perm(tsec->sid, sid, SECCLASS_FILESYSTEM,
463 FILESYSTEM__RELABELTO, NULL);
464 return rc;
465}
466
Eric Paris08089252006-07-10 04:43:55 -0700467static int may_context_mount_inode_relabel(u32 sid,
468 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100469 const struct cred *cred)
Eric Paris08089252006-07-10 04:43:55 -0700470{
David Howells275bb412008-11-14 10:39:19 +1100471 const struct task_security_struct *tsec = cred->security;
Eric Paris08089252006-07-10 04:43:55 -0700472 int rc;
473 rc = avc_has_perm(tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
474 FILESYSTEM__RELABELFROM, NULL);
475 if (rc)
476 return rc;
477
478 rc = avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM,
479 FILESYSTEM__ASSOCIATE, NULL);
480 return rc;
481}
482
Eric Parisb43e7252012-10-10 14:27:35 -0400483static int selinux_is_sblabel_mnt(struct super_block *sb)
484{
485 struct superblock_security_struct *sbsec = sb->s_security;
486
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500487 return sbsec->behavior == SECURITY_FS_USE_XATTR ||
488 sbsec->behavior == SECURITY_FS_USE_TRANS ||
489 sbsec->behavior == SECURITY_FS_USE_TASK ||
J. Bruce Fields9fc2b4b2015-06-04 15:57:25 -0400490 sbsec->behavior == SECURITY_FS_USE_NATIVE ||
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500491 /* Special handling. Genfs but also in-core setxattr handler */
492 !strcmp(sb->s_type->name, "sysfs") ||
493 !strcmp(sb->s_type->name, "pstore") ||
494 !strcmp(sb->s_type->name, "debugfs") ||
Yongqin Liua2c7c6f2017-01-09 10:07:30 -0500495 !strcmp(sb->s_type->name, "tracefs") ||
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500496 !strcmp(sb->s_type->name, "rootfs");
Eric Parisb43e7252012-10-10 14:27:35 -0400497}
498
Eric Parisc9180a52007-11-30 13:00:35 -0500499static int sb_finish_set_opts(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500{
501 struct superblock_security_struct *sbsec = sb->s_security;
502 struct dentry *root = sb->s_root;
David Howellsc6f493d2015-03-17 22:26:22 +0000503 struct inode *root_inode = d_backing_inode(root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 int rc = 0;
505
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
507 /* Make sure that the xattr handler exists and that no
508 error other than -ENODATA is returned by getxattr on
509 the root directory. -ENODATA is ok, as this may be
510 the first boot of the SELinux kernel before we have
511 assigned xattr values to the filesystem. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200512 if (!(root_inode->i_opflags & IOP_XATTR)) {
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800513 printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
514 "xattr support\n", sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 rc = -EOPNOTSUPP;
516 goto out;
517 }
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200518
519 rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 if (rc < 0 && rc != -ENODATA) {
521 if (rc == -EOPNOTSUPP)
522 printk(KERN_WARNING "SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800523 "%s) has no security xattr handler\n",
524 sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 else
526 printk(KERN_WARNING "SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800527 "%s) getxattr errno %d\n", sb->s_id,
528 sb->s_type->name, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 goto out;
530 }
531 }
532
Eric Parisc9180a52007-11-30 13:00:35 -0500533 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800534 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
535 sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536
Eric Pariseadcabc2012-08-24 15:59:14 -0400537 sbsec->flags |= SE_SBINITIALIZED;
Eric Parisb43e7252012-10-10 14:27:35 -0400538 if (selinux_is_sblabel_mnt(sb))
Eric Paris12f348b2012-10-09 10:56:25 -0400539 sbsec->flags |= SBLABEL_MNT;
David P. Quigleyddd29ec2009-09-09 14:25:37 -0400540
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 /* Initialize the root inode. */
Eric Parisc9180a52007-11-30 13:00:35 -0500542 rc = inode_doinit_with_dentry(root_inode, root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543
544 /* Initialize any other inodes associated with the superblock, e.g.
545 inodes created prior to initial policy load or inodes created
546 during get_sb by a pseudo filesystem that directly
547 populates itself. */
548 spin_lock(&sbsec->isec_lock);
549next_inode:
550 if (!list_empty(&sbsec->isec_head)) {
551 struct inode_security_struct *isec =
552 list_entry(sbsec->isec_head.next,
Eric Parisc9180a52007-11-30 13:00:35 -0500553 struct inode_security_struct, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 struct inode *inode = isec->inode;
Stephen Smalley923190d2014-10-06 16:32:52 -0400555 list_del_init(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 spin_unlock(&sbsec->isec_lock);
557 inode = igrab(inode);
558 if (inode) {
Eric Parisc9180a52007-11-30 13:00:35 -0500559 if (!IS_PRIVATE(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 inode_doinit(inode);
561 iput(inode);
562 }
563 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 goto next_inode;
565 }
566 spin_unlock(&sbsec->isec_lock);
567out:
Eric Parisc9180a52007-11-30 13:00:35 -0500568 return rc;
569}
570
571/*
572 * This function should allow an FS to ask what it's mount security
573 * options were so it can use those later for submounts, displaying
574 * mount options, or whatever.
575 */
576static int selinux_get_mnt_opts(const struct super_block *sb,
Eric Parise0007522008-03-05 10:31:54 -0500577 struct security_mnt_opts *opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500578{
579 int rc = 0, i;
580 struct superblock_security_struct *sbsec = sb->s_security;
581 char *context = NULL;
582 u32 len;
583 char tmp;
584
Eric Parise0007522008-03-05 10:31:54 -0500585 security_init_mnt_opts(opts);
Eric Parisc9180a52007-11-30 13:00:35 -0500586
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500587 if (!(sbsec->flags & SE_SBINITIALIZED))
Eric Parisc9180a52007-11-30 13:00:35 -0500588 return -EINVAL;
589
590 if (!ss_initialized)
591 return -EINVAL;
592
Eric Parisaf8e50c2012-08-24 15:59:00 -0400593 /* make sure we always check enough bits to cover the mask */
594 BUILD_BUG_ON(SE_MNTMASK >= (1 << NUM_SEL_MNT_OPTS));
595
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500596 tmp = sbsec->flags & SE_MNTMASK;
Eric Parisc9180a52007-11-30 13:00:35 -0500597 /* count the number of mount options for this sb */
Eric Parisaf8e50c2012-08-24 15:59:00 -0400598 for (i = 0; i < NUM_SEL_MNT_OPTS; i++) {
Eric Parisc9180a52007-11-30 13:00:35 -0500599 if (tmp & 0x01)
Eric Parise0007522008-03-05 10:31:54 -0500600 opts->num_mnt_opts++;
Eric Parisc9180a52007-11-30 13:00:35 -0500601 tmp >>= 1;
602 }
David P. Quigley11689d42009-01-16 09:22:03 -0500603 /* Check if the Label support flag is set */
Eric Paris0b4bdb32013-08-28 13:32:42 -0400604 if (sbsec->flags & SBLABEL_MNT)
David P. Quigley11689d42009-01-16 09:22:03 -0500605 opts->num_mnt_opts++;
Eric Parisc9180a52007-11-30 13:00:35 -0500606
Eric Parise0007522008-03-05 10:31:54 -0500607 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
608 if (!opts->mnt_opts) {
Eric Parisc9180a52007-11-30 13:00:35 -0500609 rc = -ENOMEM;
610 goto out_free;
611 }
612
Eric Parise0007522008-03-05 10:31:54 -0500613 opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC);
614 if (!opts->mnt_opts_flags) {
Eric Parisc9180a52007-11-30 13:00:35 -0500615 rc = -ENOMEM;
616 goto out_free;
617 }
618
619 i = 0;
620 if (sbsec->flags & FSCONTEXT_MNT) {
621 rc = security_sid_to_context(sbsec->sid, &context, &len);
622 if (rc)
623 goto out_free;
Eric Parise0007522008-03-05 10:31:54 -0500624 opts->mnt_opts[i] = context;
625 opts->mnt_opts_flags[i++] = FSCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500626 }
627 if (sbsec->flags & CONTEXT_MNT) {
628 rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len);
629 if (rc)
630 goto out_free;
Eric Parise0007522008-03-05 10:31:54 -0500631 opts->mnt_opts[i] = context;
632 opts->mnt_opts_flags[i++] = CONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500633 }
634 if (sbsec->flags & DEFCONTEXT_MNT) {
635 rc = security_sid_to_context(sbsec->def_sid, &context, &len);
636 if (rc)
637 goto out_free;
Eric Parise0007522008-03-05 10:31:54 -0500638 opts->mnt_opts[i] = context;
639 opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500640 }
641 if (sbsec->flags & ROOTCONTEXT_MNT) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500642 struct dentry *root = sbsec->sb->s_root;
643 struct inode_security_struct *isec = backing_inode_security(root);
Eric Parisc9180a52007-11-30 13:00:35 -0500644
645 rc = security_sid_to_context(isec->sid, &context, &len);
646 if (rc)
647 goto out_free;
Eric Parise0007522008-03-05 10:31:54 -0500648 opts->mnt_opts[i] = context;
649 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500650 }
Eric Paris12f348b2012-10-09 10:56:25 -0400651 if (sbsec->flags & SBLABEL_MNT) {
David P. Quigley11689d42009-01-16 09:22:03 -0500652 opts->mnt_opts[i] = NULL;
Eric Paris12f348b2012-10-09 10:56:25 -0400653 opts->mnt_opts_flags[i++] = SBLABEL_MNT;
David P. Quigley11689d42009-01-16 09:22:03 -0500654 }
Eric Parisc9180a52007-11-30 13:00:35 -0500655
Eric Parise0007522008-03-05 10:31:54 -0500656 BUG_ON(i != opts->num_mnt_opts);
Eric Parisc9180a52007-11-30 13:00:35 -0500657
658 return 0;
659
660out_free:
Eric Parise0007522008-03-05 10:31:54 -0500661 security_free_mnt_opts(opts);
Eric Parisc9180a52007-11-30 13:00:35 -0500662 return rc;
663}
664
665static int bad_option(struct superblock_security_struct *sbsec, char flag,
666 u32 old_sid, u32 new_sid)
667{
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500668 char mnt_flags = sbsec->flags & SE_MNTMASK;
669
Eric Parisc9180a52007-11-30 13:00:35 -0500670 /* check if the old mount command had the same options */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500671 if (sbsec->flags & SE_SBINITIALIZED)
Eric Parisc9180a52007-11-30 13:00:35 -0500672 if (!(sbsec->flags & flag) ||
673 (old_sid != new_sid))
674 return 1;
675
676 /* check if we were passed the same options twice,
677 * aka someone passed context=a,context=b
678 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500679 if (!(sbsec->flags & SE_SBINITIALIZED))
680 if (mnt_flags & flag)
Eric Parisc9180a52007-11-30 13:00:35 -0500681 return 1;
682 return 0;
683}
Eric Parise0007522008-03-05 10:31:54 -0500684
Eric Parisc9180a52007-11-30 13:00:35 -0500685/*
686 * Allow filesystems with binary mount data to explicitly set mount point
687 * labeling information.
688 */
Eric Parise0007522008-03-05 10:31:54 -0500689static int selinux_set_mnt_opts(struct super_block *sb,
David Quigley649f6e72013-05-22 12:50:36 -0400690 struct security_mnt_opts *opts,
691 unsigned long kern_flags,
692 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500693{
David Howells275bb412008-11-14 10:39:19 +1100694 const struct cred *cred = current_cred();
Eric Parisc9180a52007-11-30 13:00:35 -0500695 int rc = 0, i;
Eric Parisc9180a52007-11-30 13:00:35 -0500696 struct superblock_security_struct *sbsec = sb->s_security;
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800697 const char *name = sb->s_type->name;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500698 struct dentry *root = sbsec->sb->s_root;
Paul Moore2c971652016-04-19 16:36:28 -0400699 struct inode_security_struct *root_isec;
Eric Parisc9180a52007-11-30 13:00:35 -0500700 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
701 u32 defcontext_sid = 0;
Eric Parise0007522008-03-05 10:31:54 -0500702 char **mount_options = opts->mnt_opts;
703 int *flags = opts->mnt_opts_flags;
704 int num_opts = opts->num_mnt_opts;
Eric Parisc9180a52007-11-30 13:00:35 -0500705
706 mutex_lock(&sbsec->lock);
707
708 if (!ss_initialized) {
709 if (!num_opts) {
710 /* Defer initialization until selinux_complete_init,
711 after the initial policy is loaded and the security
712 server is ready to handle calls. */
Eric Parisc9180a52007-11-30 13:00:35 -0500713 goto out;
714 }
715 rc = -EINVAL;
Eric Paris744ba352008-04-17 11:52:44 -0400716 printk(KERN_WARNING "SELinux: Unable to set superblock options "
717 "before the security server is initialized\n");
Eric Parisc9180a52007-11-30 13:00:35 -0500718 goto out;
719 }
David Quigley649f6e72013-05-22 12:50:36 -0400720 if (kern_flags && !set_kern_flags) {
721 /* Specifying internal flags without providing a place to
722 * place the results is not allowed */
723 rc = -EINVAL;
724 goto out;
725 }
Eric Parisc9180a52007-11-30 13:00:35 -0500726
727 /*
Eric Parise0007522008-03-05 10:31:54 -0500728 * Binary mount data FS will come through this function twice. Once
729 * from an explicit call and once from the generic calls from the vfs.
730 * Since the generic VFS calls will not contain any security mount data
731 * we need to skip the double mount verification.
732 *
733 * This does open a hole in which we will not notice if the first
734 * mount using this sb set explict options and a second mount using
735 * this sb does not set any security options. (The first options
736 * will be used for both mounts)
737 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500738 if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
Eric Parise0007522008-03-05 10:31:54 -0500739 && (num_opts == 0))
Eric Parisf5269712008-05-14 11:27:45 -0400740 goto out;
Eric Parise0007522008-03-05 10:31:54 -0500741
Paul Moore2c971652016-04-19 16:36:28 -0400742 root_isec = backing_inode_security_novalidate(root);
743
Eric Parise0007522008-03-05 10:31:54 -0500744 /*
Eric Parisc9180a52007-11-30 13:00:35 -0500745 * parse the mount options, check if they are valid sids.
746 * also check if someone is trying to mount the same sb more
747 * than once with different security options.
748 */
749 for (i = 0; i < num_opts; i++) {
750 u32 sid;
David P. Quigley11689d42009-01-16 09:22:03 -0500751
Eric Paris12f348b2012-10-09 10:56:25 -0400752 if (flags[i] == SBLABEL_MNT)
David P. Quigley11689d42009-01-16 09:22:03 -0500753 continue;
Rasmus Villemoes44be2f62015-10-21 17:44:25 -0400754 rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL);
Eric Parisc9180a52007-11-30 13:00:35 -0500755 if (rc) {
Rasmus Villemoes44be2f62015-10-21 17:44:25 -0400756 printk(KERN_WARNING "SELinux: security_context_str_to_sid"
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800757 "(%s) failed for (dev %s, type %s) errno=%d\n",
758 mount_options[i], sb->s_id, name, rc);
Eric Parisc9180a52007-11-30 13:00:35 -0500759 goto out;
760 }
761 switch (flags[i]) {
762 case FSCONTEXT_MNT:
763 fscontext_sid = sid;
764
765 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
766 fscontext_sid))
767 goto out_double_mount;
768
769 sbsec->flags |= FSCONTEXT_MNT;
770 break;
771 case CONTEXT_MNT:
772 context_sid = sid;
773
774 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
775 context_sid))
776 goto out_double_mount;
777
778 sbsec->flags |= CONTEXT_MNT;
779 break;
780 case ROOTCONTEXT_MNT:
781 rootcontext_sid = sid;
782
783 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
784 rootcontext_sid))
785 goto out_double_mount;
786
787 sbsec->flags |= ROOTCONTEXT_MNT;
788
789 break;
790 case DEFCONTEXT_MNT:
791 defcontext_sid = sid;
792
793 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
794 defcontext_sid))
795 goto out_double_mount;
796
797 sbsec->flags |= DEFCONTEXT_MNT;
798
799 break;
800 default:
801 rc = -EINVAL;
802 goto out;
803 }
804 }
805
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500806 if (sbsec->flags & SE_SBINITIALIZED) {
Eric Parisc9180a52007-11-30 13:00:35 -0500807 /* previously mounted with options, but not on this attempt? */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500808 if ((sbsec->flags & SE_MNTMASK) && !num_opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500809 goto out_double_mount;
810 rc = 0;
811 goto out;
812 }
813
James Morris089be432008-07-15 18:32:49 +1000814 if (strcmp(sb->s_type->name, "proc") == 0)
Stephen Smalley134509d2015-06-04 16:22:17 -0400815 sbsec->flags |= SE_SBPROC | SE_SBGENFS;
816
Stephen Smalley8e014722015-06-04 16:22:17 -0400817 if (!strcmp(sb->s_type->name, "debugfs") ||
818 !strcmp(sb->s_type->name, "sysfs") ||
819 !strcmp(sb->s_type->name, "pstore"))
Stephen Smalley134509d2015-06-04 16:22:17 -0400820 sbsec->flags |= SE_SBGENFS;
Eric Parisc9180a52007-11-30 13:00:35 -0500821
David Quigleyeb9ae682013-05-22 12:50:37 -0400822 if (!sbsec->behavior) {
823 /*
824 * Determine the labeling behavior to use for this
825 * filesystem type.
826 */
Paul Moore98f700f2013-09-18 13:52:20 -0400827 rc = security_fs_use(sb);
David Quigleyeb9ae682013-05-22 12:50:37 -0400828 if (rc) {
829 printk(KERN_WARNING
830 "%s: security_fs_use(%s) returned %d\n",
831 __func__, sb->s_type->name, rc);
832 goto out;
833 }
Eric Parisc9180a52007-11-30 13:00:35 -0500834 }
Seth Forsheeaad82892016-04-26 14:36:20 -0500835
836 /*
837 * If this is a user namespace mount, no contexts are allowed
838 * on the command line and security labels must be ignored.
839 */
840 if (sb->s_user_ns != &init_user_ns) {
841 if (context_sid || fscontext_sid || rootcontext_sid ||
842 defcontext_sid) {
843 rc = -EACCES;
844 goto out;
845 }
846 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
847 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
848 rc = security_transition_sid(current_sid(), current_sid(),
849 SECCLASS_FILE, NULL,
850 &sbsec->mntpoint_sid);
851 if (rc)
852 goto out;
853 }
854 goto out_set_opts;
855 }
856
Eric Parisc9180a52007-11-30 13:00:35 -0500857 /* sets the context of the superblock for the fs being mounted. */
858 if (fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100859 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500860 if (rc)
861 goto out;
862
863 sbsec->sid = fscontext_sid;
864 }
865
866 /*
867 * Switch to using mount point labeling behavior.
868 * sets the label used on all file below the mountpoint, and will set
869 * the superblock context if not already set.
870 */
David Quigleyeb9ae682013-05-22 12:50:37 -0400871 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
872 sbsec->behavior = SECURITY_FS_USE_NATIVE;
873 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
874 }
875
Eric Parisc9180a52007-11-30 13:00:35 -0500876 if (context_sid) {
877 if (!fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100878 rc = may_context_mount_sb_relabel(context_sid, sbsec,
879 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500880 if (rc)
881 goto out;
882 sbsec->sid = context_sid;
883 } else {
David Howells275bb412008-11-14 10:39:19 +1100884 rc = may_context_mount_inode_relabel(context_sid, sbsec,
885 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500886 if (rc)
887 goto out;
888 }
889 if (!rootcontext_sid)
890 rootcontext_sid = context_sid;
891
892 sbsec->mntpoint_sid = context_sid;
893 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
894 }
895
896 if (rootcontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100897 rc = may_context_mount_inode_relabel(rootcontext_sid, sbsec,
898 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500899 if (rc)
900 goto out;
901
902 root_isec->sid = rootcontext_sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -0500903 root_isec->initialized = LABEL_INITIALIZED;
Eric Parisc9180a52007-11-30 13:00:35 -0500904 }
905
906 if (defcontext_sid) {
David Quigleyeb9ae682013-05-22 12:50:37 -0400907 if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
908 sbsec->behavior != SECURITY_FS_USE_NATIVE) {
Eric Parisc9180a52007-11-30 13:00:35 -0500909 rc = -EINVAL;
910 printk(KERN_WARNING "SELinux: defcontext option is "
911 "invalid for this filesystem type\n");
912 goto out;
913 }
914
915 if (defcontext_sid != sbsec->def_sid) {
916 rc = may_context_mount_inode_relabel(defcontext_sid,
David Howells275bb412008-11-14 10:39:19 +1100917 sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500918 if (rc)
919 goto out;
920 }
921
922 sbsec->def_sid = defcontext_sid;
923 }
924
Seth Forsheeaad82892016-04-26 14:36:20 -0500925out_set_opts:
Eric Parisc9180a52007-11-30 13:00:35 -0500926 rc = sb_finish_set_opts(sb);
927out:
Eric Parisbc7e9822006-09-25 23:32:02 -0700928 mutex_unlock(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -0500930out_double_mount:
931 rc = -EINVAL;
932 printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800933 "security settings for (dev %s, type %s)\n", sb->s_id, name);
Eric Parisc9180a52007-11-30 13:00:35 -0500934 goto out;
935}
936
Jeff Layton094f7b62013-04-01 08:14:24 -0400937static int selinux_cmp_sb_context(const struct super_block *oldsb,
938 const struct super_block *newsb)
939{
940 struct superblock_security_struct *old = oldsb->s_security;
941 struct superblock_security_struct *new = newsb->s_security;
942 char oldflags = old->flags & SE_MNTMASK;
943 char newflags = new->flags & SE_MNTMASK;
944
945 if (oldflags != newflags)
946 goto mismatch;
947 if ((oldflags & FSCONTEXT_MNT) && old->sid != new->sid)
948 goto mismatch;
949 if ((oldflags & CONTEXT_MNT) && old->mntpoint_sid != new->mntpoint_sid)
950 goto mismatch;
951 if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid)
952 goto mismatch;
953 if (oldflags & ROOTCONTEXT_MNT) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500954 struct inode_security_struct *oldroot = backing_inode_security(oldsb->s_root);
955 struct inode_security_struct *newroot = backing_inode_security(newsb->s_root);
Jeff Layton094f7b62013-04-01 08:14:24 -0400956 if (oldroot->sid != newroot->sid)
957 goto mismatch;
958 }
959 return 0;
960mismatch:
961 printk(KERN_WARNING "SELinux: mount invalid. Same superblock, "
962 "different security settings for (dev %s, "
963 "type %s)\n", newsb->s_id, newsb->s_type->name);
964 return -EBUSY;
965}
966
967static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
Eric Parisc9180a52007-11-30 13:00:35 -0500968 struct super_block *newsb)
969{
970 const struct superblock_security_struct *oldsbsec = oldsb->s_security;
971 struct superblock_security_struct *newsbsec = newsb->s_security;
972
973 int set_fscontext = (oldsbsec->flags & FSCONTEXT_MNT);
974 int set_context = (oldsbsec->flags & CONTEXT_MNT);
975 int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT);
976
Eric Paris0f5e6422008-04-21 16:24:11 -0400977 /*
978 * if the parent was able to be mounted it clearly had no special lsm
Al Viroe8c26252010-03-23 06:36:54 -0400979 * mount options. thus we can safely deal with this superblock later
Eric Paris0f5e6422008-04-21 16:24:11 -0400980 */
Al Viroe8c26252010-03-23 06:36:54 -0400981 if (!ss_initialized)
Jeff Layton094f7b62013-04-01 08:14:24 -0400982 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500983
Eric Parisc9180a52007-11-30 13:00:35 -0500984 /* how can we clone if the old one wasn't set up?? */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500985 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
Eric Parisc9180a52007-11-30 13:00:35 -0500986
Jeff Layton094f7b62013-04-01 08:14:24 -0400987 /* if fs is reusing a sb, make sure that the contexts match */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500988 if (newsbsec->flags & SE_SBINITIALIZED)
Jeff Layton094f7b62013-04-01 08:14:24 -0400989 return selinux_cmp_sb_context(oldsb, newsb);
Eric Paris5a552612008-04-09 14:08:35 -0400990
Eric Parisc9180a52007-11-30 13:00:35 -0500991 mutex_lock(&newsbsec->lock);
992
993 newsbsec->flags = oldsbsec->flags;
994
995 newsbsec->sid = oldsbsec->sid;
996 newsbsec->def_sid = oldsbsec->def_sid;
997 newsbsec->behavior = oldsbsec->behavior;
998
999 if (set_context) {
1000 u32 sid = oldsbsec->mntpoint_sid;
1001
1002 if (!set_fscontext)
1003 newsbsec->sid = sid;
1004 if (!set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001005 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -05001006 newisec->sid = sid;
1007 }
1008 newsbsec->mntpoint_sid = sid;
1009 }
1010 if (set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001011 const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root);
1012 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -05001013
1014 newisec->sid = oldisec->sid;
1015 }
1016
1017 sb_finish_set_opts(newsb);
1018 mutex_unlock(&newsbsec->lock);
Jeff Layton094f7b62013-04-01 08:14:24 -04001019 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -05001020}
1021
Adrian Bunk2e1479d2008-03-17 22:29:23 +02001022static int selinux_parse_opts_str(char *options,
1023 struct security_mnt_opts *opts)
Eric Parisc9180a52007-11-30 13:00:35 -05001024{
Eric Parise0007522008-03-05 10:31:54 -05001025 char *p;
Eric Parisc9180a52007-11-30 13:00:35 -05001026 char *context = NULL, *defcontext = NULL;
1027 char *fscontext = NULL, *rootcontext = NULL;
Eric Parise0007522008-03-05 10:31:54 -05001028 int rc, num_mnt_opts = 0;
Eric Parisc9180a52007-11-30 13:00:35 -05001029
Eric Parise0007522008-03-05 10:31:54 -05001030 opts->num_mnt_opts = 0;
Eric Parisc9180a52007-11-30 13:00:35 -05001031
1032 /* Standard string-based options. */
1033 while ((p = strsep(&options, "|")) != NULL) {
1034 int token;
1035 substring_t args[MAX_OPT_ARGS];
1036
1037 if (!*p)
1038 continue;
1039
1040 token = match_token(p, tokens, args);
1041
1042 switch (token) {
1043 case Opt_context:
1044 if (context || defcontext) {
1045 rc = -EINVAL;
1046 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
1047 goto out_err;
1048 }
1049 context = match_strdup(&args[0]);
1050 if (!context) {
1051 rc = -ENOMEM;
1052 goto out_err;
1053 }
1054 break;
1055
1056 case Opt_fscontext:
1057 if (fscontext) {
1058 rc = -EINVAL;
1059 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
1060 goto out_err;
1061 }
1062 fscontext = match_strdup(&args[0]);
1063 if (!fscontext) {
1064 rc = -ENOMEM;
1065 goto out_err;
1066 }
1067 break;
1068
1069 case Opt_rootcontext:
1070 if (rootcontext) {
1071 rc = -EINVAL;
1072 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
1073 goto out_err;
1074 }
1075 rootcontext = match_strdup(&args[0]);
1076 if (!rootcontext) {
1077 rc = -ENOMEM;
1078 goto out_err;
1079 }
1080 break;
1081
1082 case Opt_defcontext:
1083 if (context || defcontext) {
1084 rc = -EINVAL;
1085 printk(KERN_WARNING SEL_MOUNT_FAIL_MSG);
1086 goto out_err;
1087 }
1088 defcontext = match_strdup(&args[0]);
1089 if (!defcontext) {
1090 rc = -ENOMEM;
1091 goto out_err;
1092 }
1093 break;
David P. Quigley11689d42009-01-16 09:22:03 -05001094 case Opt_labelsupport:
1095 break;
Eric Parisc9180a52007-11-30 13:00:35 -05001096 default:
1097 rc = -EINVAL;
1098 printk(KERN_WARNING "SELinux: unknown mount option\n");
1099 goto out_err;
1100
1101 }
1102 }
1103
Eric Parise0007522008-03-05 10:31:54 -05001104 rc = -ENOMEM;
Tetsuo Handa8931c3b2016-11-14 20:16:12 +09001105 opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_KERNEL);
Eric Parise0007522008-03-05 10:31:54 -05001106 if (!opts->mnt_opts)
1107 goto out_err;
1108
Tetsuo Handa8931c3b2016-11-14 20:16:12 +09001109 opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int),
1110 GFP_KERNEL);
Eric Parise0007522008-03-05 10:31:54 -05001111 if (!opts->mnt_opts_flags) {
1112 kfree(opts->mnt_opts);
1113 goto out_err;
Eric Parisc9180a52007-11-30 13:00:35 -05001114 }
1115
Eric Parise0007522008-03-05 10:31:54 -05001116 if (fscontext) {
1117 opts->mnt_opts[num_mnt_opts] = fscontext;
1118 opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT;
1119 }
1120 if (context) {
1121 opts->mnt_opts[num_mnt_opts] = context;
1122 opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT;
1123 }
1124 if (rootcontext) {
1125 opts->mnt_opts[num_mnt_opts] = rootcontext;
1126 opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT;
1127 }
1128 if (defcontext) {
1129 opts->mnt_opts[num_mnt_opts] = defcontext;
1130 opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT;
1131 }
1132
1133 opts->num_mnt_opts = num_mnt_opts;
1134 return 0;
1135
Eric Parisc9180a52007-11-30 13:00:35 -05001136out_err:
1137 kfree(context);
1138 kfree(defcontext);
1139 kfree(fscontext);
1140 kfree(rootcontext);
1141 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142}
Eric Parise0007522008-03-05 10:31:54 -05001143/*
1144 * string mount options parsing and call set the sbsec
1145 */
1146static int superblock_doinit(struct super_block *sb, void *data)
1147{
1148 int rc = 0;
1149 char *options = data;
1150 struct security_mnt_opts opts;
1151
1152 security_init_mnt_opts(&opts);
1153
1154 if (!data)
1155 goto out;
1156
1157 BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA);
1158
1159 rc = selinux_parse_opts_str(options, &opts);
1160 if (rc)
1161 goto out_err;
1162
1163out:
David Quigley649f6e72013-05-22 12:50:36 -04001164 rc = selinux_set_mnt_opts(sb, &opts, 0, NULL);
Eric Parise0007522008-03-05 10:31:54 -05001165
1166out_err:
1167 security_free_mnt_opts(&opts);
1168 return rc;
1169}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170
Adrian Bunk3583a712008-07-22 20:21:23 +03001171static void selinux_write_opts(struct seq_file *m,
1172 struct security_mnt_opts *opts)
Eric Paris2069f452008-07-04 09:47:13 +10001173{
1174 int i;
1175 char *prefix;
1176
1177 for (i = 0; i < opts->num_mnt_opts; i++) {
David P. Quigley11689d42009-01-16 09:22:03 -05001178 char *has_comma;
1179
1180 if (opts->mnt_opts[i])
1181 has_comma = strchr(opts->mnt_opts[i], ',');
1182 else
1183 has_comma = NULL;
Eric Paris2069f452008-07-04 09:47:13 +10001184
1185 switch (opts->mnt_opts_flags[i]) {
1186 case CONTEXT_MNT:
1187 prefix = CONTEXT_STR;
1188 break;
1189 case FSCONTEXT_MNT:
1190 prefix = FSCONTEXT_STR;
1191 break;
1192 case ROOTCONTEXT_MNT:
1193 prefix = ROOTCONTEXT_STR;
1194 break;
1195 case DEFCONTEXT_MNT:
1196 prefix = DEFCONTEXT_STR;
1197 break;
Eric Paris12f348b2012-10-09 10:56:25 -04001198 case SBLABEL_MNT:
David P. Quigley11689d42009-01-16 09:22:03 -05001199 seq_putc(m, ',');
1200 seq_puts(m, LABELSUPP_STR);
1201 continue;
Eric Paris2069f452008-07-04 09:47:13 +10001202 default:
1203 BUG();
Eric Parisa35c6c832011-04-20 10:21:28 -04001204 return;
Eric Paris2069f452008-07-04 09:47:13 +10001205 };
1206 /* we need a comma before each option */
1207 seq_putc(m, ',');
1208 seq_puts(m, prefix);
1209 if (has_comma)
1210 seq_putc(m, '\"');
Kees Cooka068acf2015-09-04 15:44:57 -07001211 seq_escape(m, opts->mnt_opts[i], "\"\n\\");
Eric Paris2069f452008-07-04 09:47:13 +10001212 if (has_comma)
1213 seq_putc(m, '\"');
1214 }
1215}
1216
1217static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
1218{
1219 struct security_mnt_opts opts;
1220 int rc;
1221
1222 rc = selinux_get_mnt_opts(sb, &opts);
Eric Paris383795c2008-07-29 17:07:26 -04001223 if (rc) {
1224 /* before policy load we may get EINVAL, don't show anything */
1225 if (rc == -EINVAL)
1226 rc = 0;
Eric Paris2069f452008-07-04 09:47:13 +10001227 return rc;
Eric Paris383795c2008-07-29 17:07:26 -04001228 }
Eric Paris2069f452008-07-04 09:47:13 +10001229
1230 selinux_write_opts(m, &opts);
1231
1232 security_free_mnt_opts(&opts);
1233
1234 return rc;
1235}
1236
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237static inline u16 inode_mode_to_security_class(umode_t mode)
1238{
1239 switch (mode & S_IFMT) {
1240 case S_IFSOCK:
1241 return SECCLASS_SOCK_FILE;
1242 case S_IFLNK:
1243 return SECCLASS_LNK_FILE;
1244 case S_IFREG:
1245 return SECCLASS_FILE;
1246 case S_IFBLK:
1247 return SECCLASS_BLK_FILE;
1248 case S_IFDIR:
1249 return SECCLASS_DIR;
1250 case S_IFCHR:
1251 return SECCLASS_CHR_FILE;
1252 case S_IFIFO:
1253 return SECCLASS_FIFO_FILE;
1254
1255 }
1256
1257 return SECCLASS_FILE;
1258}
1259
James Morris13402582005-09-30 14:24:34 -04001260static inline int default_protocol_stream(int protocol)
1261{
1262 return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP);
1263}
1264
1265static inline int default_protocol_dgram(int protocol)
1266{
1267 return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP);
1268}
1269
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270static inline u16 socket_type_to_security_class(int family, int type, int protocol)
1271{
Stephen Smalleyda69a532017-01-09 10:07:30 -05001272 int extsockclass = selinux_policycap_extsockclass;
1273
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 switch (family) {
1275 case PF_UNIX:
1276 switch (type) {
1277 case SOCK_STREAM:
1278 case SOCK_SEQPACKET:
1279 return SECCLASS_UNIX_STREAM_SOCKET;
1280 case SOCK_DGRAM:
1281 return SECCLASS_UNIX_DGRAM_SOCKET;
1282 }
1283 break;
1284 case PF_INET:
1285 case PF_INET6:
1286 switch (type) {
1287 case SOCK_STREAM:
Stephen Smalleyda69a532017-01-09 10:07:30 -05001288 case SOCK_SEQPACKET:
James Morris13402582005-09-30 14:24:34 -04001289 if (default_protocol_stream(protocol))
1290 return SECCLASS_TCP_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001291 else if (extsockclass && protocol == IPPROTO_SCTP)
1292 return SECCLASS_SCTP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001293 else
1294 return SECCLASS_RAWIP_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 case SOCK_DGRAM:
James Morris13402582005-09-30 14:24:34 -04001296 if (default_protocol_dgram(protocol))
1297 return SECCLASS_UDP_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001298 else if (extsockclass && protocol == IPPROTO_ICMP)
1299 return SECCLASS_ICMP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001300 else
1301 return SECCLASS_RAWIP_SOCKET;
James Morris2ee92d42006-11-13 16:09:01 -08001302 case SOCK_DCCP:
1303 return SECCLASS_DCCP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001304 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 return SECCLASS_RAWIP_SOCKET;
1306 }
1307 break;
1308 case PF_NETLINK:
1309 switch (protocol) {
1310 case NETLINK_ROUTE:
1311 return SECCLASS_NETLINK_ROUTE_SOCKET;
Pavel Emelyanov7f1fb602011-12-06 07:56:43 +00001312 case NETLINK_SOCK_DIAG:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 return SECCLASS_NETLINK_TCPDIAG_SOCKET;
1314 case NETLINK_NFLOG:
1315 return SECCLASS_NETLINK_NFLOG_SOCKET;
1316 case NETLINK_XFRM:
1317 return SECCLASS_NETLINK_XFRM_SOCKET;
1318 case NETLINK_SELINUX:
1319 return SECCLASS_NETLINK_SELINUX_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001320 case NETLINK_ISCSI:
1321 return SECCLASS_NETLINK_ISCSI_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 case NETLINK_AUDIT:
1323 return SECCLASS_NETLINK_AUDIT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001324 case NETLINK_FIB_LOOKUP:
1325 return SECCLASS_NETLINK_FIB_LOOKUP_SOCKET;
1326 case NETLINK_CONNECTOR:
1327 return SECCLASS_NETLINK_CONNECTOR_SOCKET;
1328 case NETLINK_NETFILTER:
1329 return SECCLASS_NETLINK_NETFILTER_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 case NETLINK_DNRTMSG:
1331 return SECCLASS_NETLINK_DNRT_SOCKET;
James Morris0c9b7942005-04-16 15:24:13 -07001332 case NETLINK_KOBJECT_UEVENT:
1333 return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001334 case NETLINK_GENERIC:
1335 return SECCLASS_NETLINK_GENERIC_SOCKET;
1336 case NETLINK_SCSITRANSPORT:
1337 return SECCLASS_NETLINK_SCSITRANSPORT_SOCKET;
1338 case NETLINK_RDMA:
1339 return SECCLASS_NETLINK_RDMA_SOCKET;
1340 case NETLINK_CRYPTO:
1341 return SECCLASS_NETLINK_CRYPTO_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 default:
1343 return SECCLASS_NETLINK_SOCKET;
1344 }
1345 case PF_PACKET:
1346 return SECCLASS_PACKET_SOCKET;
1347 case PF_KEY:
1348 return SECCLASS_KEY_SOCKET;
Christopher J. PeBenito3e3ff152006-06-09 00:25:03 -07001349 case PF_APPLETALK:
1350 return SECCLASS_APPLETALK_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 }
1352
Stephen Smalleyda69a532017-01-09 10:07:30 -05001353 if (extsockclass) {
1354 switch (family) {
1355 case PF_AX25:
1356 return SECCLASS_AX25_SOCKET;
1357 case PF_IPX:
1358 return SECCLASS_IPX_SOCKET;
1359 case PF_NETROM:
1360 return SECCLASS_NETROM_SOCKET;
1361 case PF_BRIDGE:
1362 return SECCLASS_BRIDGE_SOCKET;
1363 case PF_ATMPVC:
1364 return SECCLASS_ATMPVC_SOCKET;
1365 case PF_X25:
1366 return SECCLASS_X25_SOCKET;
1367 case PF_ROSE:
1368 return SECCLASS_ROSE_SOCKET;
1369 case PF_DECnet:
1370 return SECCLASS_DECNET_SOCKET;
1371 case PF_ATMSVC:
1372 return SECCLASS_ATMSVC_SOCKET;
1373 case PF_RDS:
1374 return SECCLASS_RDS_SOCKET;
1375 case PF_IRDA:
1376 return SECCLASS_IRDA_SOCKET;
1377 case PF_PPPOX:
1378 return SECCLASS_PPPOX_SOCKET;
1379 case PF_LLC:
1380 return SECCLASS_LLC_SOCKET;
1381 case PF_IB:
1382 return SECCLASS_IB_SOCKET;
1383 case PF_MPLS:
1384 return SECCLASS_MPLS_SOCKET;
1385 case PF_CAN:
1386 return SECCLASS_CAN_SOCKET;
1387 case PF_TIPC:
1388 return SECCLASS_TIPC_SOCKET;
1389 case PF_BLUETOOTH:
1390 return SECCLASS_BLUETOOTH_SOCKET;
1391 case PF_IUCV:
1392 return SECCLASS_IUCV_SOCKET;
1393 case PF_RXRPC:
1394 return SECCLASS_RXRPC_SOCKET;
1395 case PF_ISDN:
1396 return SECCLASS_ISDN_SOCKET;
1397 case PF_PHONET:
1398 return SECCLASS_PHONET_SOCKET;
1399 case PF_IEEE802154:
1400 return SECCLASS_IEEE802154_SOCKET;
1401 case PF_CAIF:
1402 return SECCLASS_CAIF_SOCKET;
1403 case PF_ALG:
1404 return SECCLASS_ALG_SOCKET;
1405 case PF_NFC:
1406 return SECCLASS_NFC_SOCKET;
1407 case PF_VSOCK:
1408 return SECCLASS_VSOCK_SOCKET;
1409 case PF_KCM:
1410 return SECCLASS_KCM_SOCKET;
1411 case PF_QIPCRTR:
1412 return SECCLASS_QIPCRTR_SOCKET;
1413#if PF_MAX > 43
1414#error New address family defined, please update this function.
1415#endif
1416 }
1417 }
1418
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 return SECCLASS_SOCKET;
1420}
1421
Stephen Smalley134509d2015-06-04 16:22:17 -04001422static int selinux_genfs_get_sid(struct dentry *dentry,
1423 u16 tclass,
1424 u16 flags,
1425 u32 *sid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426{
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001427 int rc;
Al Virofc640052016-04-10 01:33:30 -04001428 struct super_block *sb = dentry->d_sb;
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001429 char *buffer, *path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430
Eric Paris828dfe12008-04-17 13:17:49 -04001431 buffer = (char *)__get_free_page(GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 if (!buffer)
1433 return -ENOMEM;
1434
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001435 path = dentry_path_raw(dentry, buffer, PAGE_SIZE);
1436 if (IS_ERR(path))
1437 rc = PTR_ERR(path);
1438 else {
Stephen Smalley134509d2015-06-04 16:22:17 -04001439 if (flags & SE_SBPROC) {
1440 /* each process gets a /proc/PID/ entry. Strip off the
1441 * PID part to get a valid selinux labeling.
1442 * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
1443 while (path[1] >= '0' && path[1] <= '9') {
1444 path[1] = '/';
1445 path++;
1446 }
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001447 }
Stephen Smalley134509d2015-06-04 16:22:17 -04001448 rc = security_genfs_sid(sb->s_type->name, path, tclass, sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 free_page((unsigned long)buffer);
1451 return rc;
1452}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453
1454/* The inode's security attributes must be initialized before first use. */
1455static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
1456{
1457 struct superblock_security_struct *sbsec = NULL;
1458 struct inode_security_struct *isec = inode->i_security;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001459 u32 task_sid, sid = 0;
1460 u16 sclass;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461 struct dentry *dentry;
1462#define INITCONTEXTLEN 255
1463 char *context = NULL;
1464 unsigned len = 0;
1465 int rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001467 if (isec->initialized == LABEL_INITIALIZED)
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001468 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001470 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001471 if (isec->initialized == LABEL_INITIALIZED)
Eric Paris23970742006-09-25 23:32:01 -07001472 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001474 if (isec->sclass == SECCLASS_FILE)
1475 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1476
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 sbsec = inode->i_sb->s_security;
David P. Quigley0d90a7e2009-01-16 09:22:02 -05001478 if (!(sbsec->flags & SE_SBINITIALIZED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 /* Defer initialization until selinux_complete_init,
1480 after the initial policy is loaded and the security
1481 server is ready to handle calls. */
1482 spin_lock(&sbsec->isec_lock);
1483 if (list_empty(&isec->list))
1484 list_add(&isec->list, &sbsec->isec_head);
1485 spin_unlock(&sbsec->isec_lock);
Eric Paris23970742006-09-25 23:32:01 -07001486 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 }
1488
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001489 sclass = isec->sclass;
1490 task_sid = isec->task_sid;
1491 sid = isec->sid;
1492 isec->initialized = LABEL_PENDING;
1493 spin_unlock(&isec->lock);
1494
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 switch (sbsec->behavior) {
David Quigleyeb9ae682013-05-22 12:50:37 -04001496 case SECURITY_FS_USE_NATIVE:
1497 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 case SECURITY_FS_USE_XATTR:
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001499 if (!(inode->i_opflags & IOP_XATTR)) {
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001500 sid = sbsec->def_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 break;
1502 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 /* Need a dentry, since the xattr API requires one.
1504 Life would be simpler if we could just pass the inode. */
1505 if (opt_dentry) {
1506 /* Called from d_instantiate or d_splice_alias. */
1507 dentry = dget(opt_dentry);
1508 } else {
1509 /* Called from selinux_complete_init, try to find a dentry. */
1510 dentry = d_find_alias(inode);
1511 }
1512 if (!dentry) {
Eric Parisdf7f54c2009-03-09 14:35:58 -04001513 /*
1514 * this is can be hit on boot when a file is accessed
1515 * before the policy is loaded. When we load policy we
1516 * may find inodes that have no dentry on the
1517 * sbsec->isec_head list. No reason to complain as these
1518 * will get fixed up the next time we go through
1519 * inode_doinit with a dentry, before these inodes could
1520 * be used again by userspace.
1521 */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001522 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 }
1524
1525 len = INITCONTEXTLEN;
Eric Paris4cb912f2009-02-12 14:50:05 -05001526 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 if (!context) {
1528 rc = -ENOMEM;
1529 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001530 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001532 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001533 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 if (rc == -ERANGE) {
James Morris314dabb2009-08-10 22:00:13 +10001535 kfree(context);
1536
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 /* Need a larger buffer. Query for the right size. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001538 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 if (rc < 0) {
1540 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001541 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 len = rc;
Eric Paris4cb912f2009-02-12 14:50:05 -05001544 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 if (!context) {
1546 rc = -ENOMEM;
1547 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001548 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001550 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001551 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 }
1553 dput(dentry);
1554 if (rc < 0) {
1555 if (rc != -ENODATA) {
Eric Paris744ba352008-04-17 11:52:44 -04001556 printk(KERN_WARNING "SELinux: %s: getxattr returned "
Harvey Harrisondd6f9532008-03-06 10:03:59 +11001557 "%d for dev=%s ino=%ld\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558 -rc, inode->i_sb->s_id, inode->i_ino);
1559 kfree(context);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001560 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 }
1562 /* Map ENODATA to the default file SID */
1563 sid = sbsec->def_sid;
1564 rc = 0;
1565 } else {
James Morrisf5c1d5b2005-07-28 01:07:37 -07001566 rc = security_context_to_sid_default(context, rc, &sid,
Stephen Smalley869ab512008-04-04 08:46:05 -04001567 sbsec->def_sid,
1568 GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 if (rc) {
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001570 char *dev = inode->i_sb->s_id;
1571 unsigned long ino = inode->i_ino;
1572
1573 if (rc == -EINVAL) {
1574 if (printk_ratelimit())
1575 printk(KERN_NOTICE "SELinux: inode=%lu on dev=%s was found to have an invalid "
1576 "context=%s. This indicates you may need to relabel the inode or the "
1577 "filesystem in question.\n", ino, dev, context);
1578 } else {
1579 printk(KERN_WARNING "SELinux: %s: context_to_sid(%s) "
1580 "returned %d for dev=%s ino=%ld\n",
1581 __func__, context, -rc, dev, ino);
1582 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 kfree(context);
1584 /* Leave with the unlabeled SID */
1585 rc = 0;
1586 break;
1587 }
1588 }
1589 kfree(context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 break;
1591 case SECURITY_FS_USE_TASK:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001592 sid = task_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 break;
1594 case SECURITY_FS_USE_TRANS:
1595 /* Default to the fs SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001596 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597
1598 /* Try to obtain a transition SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001599 rc = security_transition_sid(task_sid, sid, sclass, NULL, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001601 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 break;
Eric Parisc312feb2006-07-10 04:43:53 -07001603 case SECURITY_FS_USE_MNTPOINT:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001604 sid = sbsec->mntpoint_sid;
Eric Parisc312feb2006-07-10 04:43:53 -07001605 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 default:
Eric Parisc312feb2006-07-10 04:43:53 -07001607 /* Default to the fs superblock SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001608 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609
Stephen Smalley134509d2015-06-04 16:22:17 -04001610 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
Paul Mooref64410e2014-03-19 16:46:18 -04001611 /* We must have a dentry to determine the label on
1612 * procfs inodes */
1613 if (opt_dentry)
1614 /* Called from d_instantiate or
1615 * d_splice_alias. */
1616 dentry = dget(opt_dentry);
1617 else
1618 /* Called from selinux_complete_init, try to
1619 * find a dentry. */
1620 dentry = d_find_alias(inode);
1621 /*
1622 * This can be hit on boot when a file is accessed
1623 * before the policy is loaded. When we load policy we
1624 * may find inodes that have no dentry on the
1625 * sbsec->isec_head list. No reason to complain as
1626 * these will get fixed up the next time we go through
1627 * inode_doinit() with a dentry, before these inodes
1628 * could be used again by userspace.
1629 */
1630 if (!dentry)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001631 goto out;
1632 rc = selinux_genfs_get_sid(dentry, sclass,
Stephen Smalley134509d2015-06-04 16:22:17 -04001633 sbsec->flags, &sid);
Paul Mooref64410e2014-03-19 16:46:18 -04001634 dput(dentry);
1635 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001636 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 }
1638 break;
1639 }
1640
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001641out:
1642 spin_lock(&isec->lock);
1643 if (isec->initialized == LABEL_PENDING) {
1644 if (!sid || rc) {
1645 isec->initialized = LABEL_INVALID;
1646 goto out_unlock;
1647 }
1648
1649 isec->initialized = LABEL_INITIALIZED;
1650 isec->sid = sid;
1651 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652
Eric Paris23970742006-09-25 23:32:01 -07001653out_unlock:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001654 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 return rc;
1656}
1657
1658/* Convert a Linux signal to an access vector. */
1659static inline u32 signal_to_av(int sig)
1660{
1661 u32 perm = 0;
1662
1663 switch (sig) {
1664 case SIGCHLD:
1665 /* Commonly granted from child to parent. */
1666 perm = PROCESS__SIGCHLD;
1667 break;
1668 case SIGKILL:
1669 /* Cannot be caught or ignored */
1670 perm = PROCESS__SIGKILL;
1671 break;
1672 case SIGSTOP:
1673 /* Cannot be caught or ignored */
1674 perm = PROCESS__SIGSTOP;
1675 break;
1676 default:
1677 /* All other signals. */
1678 perm = PROCESS__SIGNAL;
1679 break;
1680 }
1681
1682 return perm;
1683}
1684
David Howells275bb412008-11-14 10:39:19 +11001685/*
David Howellsd84f4f92008-11-14 10:39:23 +11001686 * Check permission between a pair of credentials
1687 * fork check, ptrace check, etc.
1688 */
1689static int cred_has_perm(const struct cred *actor,
1690 const struct cred *target,
1691 u32 perms)
1692{
1693 u32 asid = cred_sid(actor), tsid = cred_sid(target);
1694
1695 return avc_has_perm(asid, tsid, SECCLASS_PROCESS, perms, NULL);
1696}
1697
1698/*
David Howells88e67f32008-11-14 10:39:21 +11001699 * Check permission between a pair of tasks, e.g. signal checks,
David Howells275bb412008-11-14 10:39:19 +11001700 * fork check, ptrace check, etc.
1701 * tsk1 is the actor and tsk2 is the target
David Howells3b11a1d2008-11-14 10:39:26 +11001702 * - this uses the default subjective creds of tsk1
David Howells275bb412008-11-14 10:39:19 +11001703 */
1704static int task_has_perm(const struct task_struct *tsk1,
1705 const struct task_struct *tsk2,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 u32 perms)
1707{
David Howells275bb412008-11-14 10:39:19 +11001708 const struct task_security_struct *__tsec1, *__tsec2;
1709 u32 sid1, sid2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710
David Howells275bb412008-11-14 10:39:19 +11001711 rcu_read_lock();
1712 __tsec1 = __task_cred(tsk1)->security; sid1 = __tsec1->sid;
1713 __tsec2 = __task_cred(tsk2)->security; sid2 = __tsec2->sid;
1714 rcu_read_unlock();
1715 return avc_has_perm(sid1, sid2, SECCLASS_PROCESS, perms, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716}
1717
David Howells3b11a1d2008-11-14 10:39:26 +11001718/*
1719 * Check permission between current and another task, e.g. signal checks,
1720 * fork check, ptrace check, etc.
1721 * current is the actor and tsk2 is the target
1722 * - this uses current's subjective creds
1723 */
1724static int current_has_perm(const struct task_struct *tsk,
1725 u32 perms)
1726{
1727 u32 sid, tsid;
1728
1729 sid = current_sid();
1730 tsid = task_sid(tsk);
1731 return avc_has_perm(sid, tsid, SECCLASS_PROCESS, perms, NULL);
1732}
1733
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001734#if CAP_LAST_CAP > 63
1735#error Fix SELinux to handle capabilities > 63.
1736#endif
1737
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738/* Check whether a task is allowed to use a capability. */
Eric Paris6a9de492012-01-03 12:25:14 -05001739static int cred_has_capability(const struct cred *cred,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001740 int cap, int audit, bool initns)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741{
Thomas Liu2bf49692009-07-14 12:14:09 -04001742 struct common_audit_data ad;
Eric Paris06112162008-11-11 22:02:50 +11001743 struct av_decision avd;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001744 u16 sclass;
David Howells3699c532009-01-06 22:27:01 +00001745 u32 sid = cred_sid(cred);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001746 u32 av = CAP_TO_MASK(cap);
Eric Paris06112162008-11-11 22:02:50 +11001747 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748
Eric Paris50c205f2012-04-04 15:01:43 -04001749 ad.type = LSM_AUDIT_DATA_CAP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 ad.u.cap = cap;
1751
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001752 switch (CAP_TO_INDEX(cap)) {
1753 case 0:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001754 sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001755 break;
1756 case 1:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001757 sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001758 break;
1759 default:
1760 printk(KERN_ERR
1761 "SELinux: out of range capability %d\n", cap);
1762 BUG();
Eric Parisa35c6c832011-04-20 10:21:28 -04001763 return -EINVAL;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001764 }
Eric Paris06112162008-11-11 22:02:50 +11001765
David Howells275bb412008-11-14 10:39:19 +11001766 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001767 if (audit == SECURITY_CAP_AUDIT) {
NeilBrown7b20ea22015-03-23 13:37:39 +11001768 int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001769 if (rc2)
1770 return rc2;
1771 }
Eric Paris06112162008-11-11 22:02:50 +11001772 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773}
1774
1775/* Check whether a task is allowed to use a system operation. */
1776static int task_has_system(struct task_struct *tsk,
1777 u32 perms)
1778{
David Howells275bb412008-11-14 10:39:19 +11001779 u32 sid = task_sid(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780
David Howells275bb412008-11-14 10:39:19 +11001781 return avc_has_perm(sid, SECINITSID_KERNEL,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 SECCLASS_SYSTEM, perms, NULL);
1783}
1784
1785/* Check whether a task has a particular permission to an inode.
1786 The 'adp' parameter is optional and allows other audit
1787 data to be passed (e.g. the dentry). */
David Howells88e67f32008-11-14 10:39:21 +11001788static int inode_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 struct inode *inode,
1790 u32 perms,
Linus Torvalds19e49832013-10-04 12:54:11 -07001791 struct common_audit_data *adp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 struct inode_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +11001794 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
David Howellse0e81732009-09-02 09:13:40 +01001796 validate_creds(cred);
1797
Eric Paris828dfe12008-04-17 13:17:49 -04001798 if (unlikely(IS_PRIVATE(inode)))
Stephen Smalleybbaca6c2007-02-14 00:34:16 -08001799 return 0;
1800
David Howells88e67f32008-11-14 10:39:21 +11001801 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 isec = inode->i_security;
1803
Linus Torvalds19e49832013-10-04 12:54:11 -07001804 return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805}
1806
1807/* Same as inode_has_perm, but pass explicit audit data containing
1808 the dentry to help the auditing code to more easily generate the
1809 pathname if needed. */
David Howells88e67f32008-11-14 10:39:21 +11001810static inline int dentry_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 struct dentry *dentry,
1812 u32 av)
1813{
David Howellsc6f493d2015-03-17 22:26:22 +00001814 struct inode *inode = d_backing_inode(dentry);
Thomas Liu2bf49692009-07-14 12:14:09 -04001815 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001816
Eric Paris50c205f2012-04-04 15:01:43 -04001817 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Paris2875fa02011-04-28 16:04:24 -04001818 ad.u.dentry = dentry;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001819 __inode_security_revalidate(inode, dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001820 return inode_has_perm(cred, inode, av, &ad);
Eric Paris2875fa02011-04-28 16:04:24 -04001821}
1822
1823/* Same as inode_has_perm, but pass explicit audit data containing
1824 the path to help the auditing code to more easily generate the
1825 pathname if needed. */
1826static inline int path_has_perm(const struct cred *cred,
Al Viro3f7036a2015-03-08 19:28:30 -04001827 const struct path *path,
Eric Paris2875fa02011-04-28 16:04:24 -04001828 u32 av)
1829{
David Howellsc6f493d2015-03-17 22:26:22 +00001830 struct inode *inode = d_backing_inode(path->dentry);
Eric Paris2875fa02011-04-28 16:04:24 -04001831 struct common_audit_data ad;
1832
Eric Paris50c205f2012-04-04 15:01:43 -04001833 ad.type = LSM_AUDIT_DATA_PATH;
Eric Paris2875fa02011-04-28 16:04:24 -04001834 ad.u.path = *path;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001835 __inode_security_revalidate(inode, path->dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001836 return inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837}
1838
David Howells13f8e982013-06-13 23:37:55 +01001839/* Same as path_has_perm, but uses the inode from the file struct. */
1840static inline int file_path_has_perm(const struct cred *cred,
1841 struct file *file,
1842 u32 av)
1843{
1844 struct common_audit_data ad;
1845
Vivek Goyal43af5de2016-09-09 11:37:49 -04001846 ad.type = LSM_AUDIT_DATA_FILE;
1847 ad.u.file = file;
Linus Torvalds19e49832013-10-04 12:54:11 -07001848 return inode_has_perm(cred, file_inode(file), av, &ad);
David Howells13f8e982013-06-13 23:37:55 +01001849}
1850
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851/* Check whether a task can use an open file descriptor to
1852 access an inode in a given way. Check access to the
1853 descriptor itself, and then use dentry_has_perm to
1854 check a particular permission to the file.
1855 Access to the descriptor is implicitly granted if it
1856 has the same SID as the process. If av is zero, then
1857 access to the file is not checked, e.g. for cases
1858 where only the descriptor is affected like seek. */
David Howells88e67f32008-11-14 10:39:21 +11001859static int file_has_perm(const struct cred *cred,
1860 struct file *file,
1861 u32 av)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 struct file_security_struct *fsec = file->f_security;
Al Viro496ad9a2013-01-23 17:07:38 -05001864 struct inode *inode = file_inode(file);
Thomas Liu2bf49692009-07-14 12:14:09 -04001865 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001866 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 int rc;
1868
Vivek Goyal43af5de2016-09-09 11:37:49 -04001869 ad.type = LSM_AUDIT_DATA_FILE;
1870 ad.u.file = file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
David Howells275bb412008-11-14 10:39:19 +11001872 if (sid != fsec->sid) {
1873 rc = avc_has_perm(sid, fsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 SECCLASS_FD,
1875 FD__USE,
1876 &ad);
1877 if (rc)
David Howells88e67f32008-11-14 10:39:21 +11001878 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 }
1880
1881 /* av is zero if only checking access to the descriptor. */
David Howells88e67f32008-11-14 10:39:21 +11001882 rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 if (av)
Linus Torvalds19e49832013-10-04 12:54:11 -07001884 rc = inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885
David Howells88e67f32008-11-14 10:39:21 +11001886out:
1887 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888}
1889
David Howellsc3c188b2015-07-10 17:19:58 -04001890/*
1891 * Determine the label for an inode that might be unioned.
1892 */
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001893static int
1894selinux_determine_inode_label(const struct task_security_struct *tsec,
1895 struct inode *dir,
1896 const struct qstr *name, u16 tclass,
1897 u32 *_new_isid)
David Howellsc3c188b2015-07-10 17:19:58 -04001898{
1899 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
David Howellsc3c188b2015-07-10 17:19:58 -04001900
1901 if ((sbsec->flags & SE_SBINITIALIZED) &&
1902 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
1903 *_new_isid = sbsec->mntpoint_sid;
1904 } else if ((sbsec->flags & SBLABEL_MNT) &&
1905 tsec->create_sid) {
1906 *_new_isid = tsec->create_sid;
1907 } else {
Paul Moore20cdef82016-04-04 14:14:42 -04001908 const struct inode_security_struct *dsec = inode_security(dir);
David Howellsc3c188b2015-07-10 17:19:58 -04001909 return security_transition_sid(tsec->sid, dsec->sid, tclass,
1910 name, _new_isid);
1911 }
1912
1913 return 0;
1914}
1915
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916/* Check whether a task can create a file. */
1917static int may_create(struct inode *dir,
1918 struct dentry *dentry,
1919 u16 tclass)
1920{
Paul Moore5fb49872010-04-22 14:46:19 -04001921 const struct task_security_struct *tsec = current_security();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 struct inode_security_struct *dsec;
1923 struct superblock_security_struct *sbsec;
David Howells275bb412008-11-14 10:39:19 +11001924 u32 sid, newsid;
Thomas Liu2bf49692009-07-14 12:14:09 -04001925 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 int rc;
1927
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001928 dsec = inode_security(dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 sbsec = dir->i_sb->s_security;
1930
David Howells275bb412008-11-14 10:39:19 +11001931 sid = tsec->sid;
David Howells275bb412008-11-14 10:39:19 +11001932
Eric Paris50c205f2012-04-04 15:01:43 -04001933 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001934 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
David Howells275bb412008-11-14 10:39:19 +11001936 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 DIR__ADD_NAME | DIR__SEARCH,
1938 &ad);
1939 if (rc)
1940 return rc;
1941
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001942 rc = selinux_determine_inode_label(current_security(), dir,
1943 &dentry->d_name, tclass, &newsid);
David Howellsc3c188b2015-07-10 17:19:58 -04001944 if (rc)
1945 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946
David Howells275bb412008-11-14 10:39:19 +11001947 rc = avc_has_perm(sid, newsid, tclass, FILE__CREATE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 if (rc)
1949 return rc;
1950
1951 return avc_has_perm(newsid, sbsec->sid,
1952 SECCLASS_FILESYSTEM,
1953 FILESYSTEM__ASSOCIATE, &ad);
1954}
1955
Michael LeMay4eb582c2006-06-26 00:24:57 -07001956/* Check whether a task can create a key. */
1957static int may_create_key(u32 ksid,
1958 struct task_struct *ctx)
1959{
David Howells275bb412008-11-14 10:39:19 +11001960 u32 sid = task_sid(ctx);
Michael LeMay4eb582c2006-06-26 00:24:57 -07001961
David Howells275bb412008-11-14 10:39:19 +11001962 return avc_has_perm(sid, ksid, SECCLASS_KEY, KEY__CREATE, NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07001963}
1964
Eric Paris828dfe12008-04-17 13:17:49 -04001965#define MAY_LINK 0
1966#define MAY_UNLINK 1
1967#define MAY_RMDIR 2
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968
1969/* Check whether a task can link, unlink, or rmdir a file/directory. */
1970static int may_link(struct inode *dir,
1971 struct dentry *dentry,
1972 int kind)
1973
1974{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975 struct inode_security_struct *dsec, *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04001976 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11001977 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978 u32 av;
1979 int rc;
1980
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001981 dsec = inode_security(dir);
1982 isec = backing_inode_security(dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983
Eric Paris50c205f2012-04-04 15:01:43 -04001984 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001985 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986
1987 av = DIR__SEARCH;
1988 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
David Howells275bb412008-11-14 10:39:19 +11001989 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990 if (rc)
1991 return rc;
1992
1993 switch (kind) {
1994 case MAY_LINK:
1995 av = FILE__LINK;
1996 break;
1997 case MAY_UNLINK:
1998 av = FILE__UNLINK;
1999 break;
2000 case MAY_RMDIR:
2001 av = DIR__RMDIR;
2002 break;
2003 default:
Eric Paris744ba352008-04-17 11:52:44 -04002004 printk(KERN_WARNING "SELinux: %s: unrecognized kind %d\n",
2005 __func__, kind);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006 return 0;
2007 }
2008
David Howells275bb412008-11-14 10:39:19 +11002009 rc = avc_has_perm(sid, isec->sid, isec->sclass, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010 return rc;
2011}
2012
2013static inline int may_rename(struct inode *old_dir,
2014 struct dentry *old_dentry,
2015 struct inode *new_dir,
2016 struct dentry *new_dentry)
2017{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018 struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04002019 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11002020 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021 u32 av;
2022 int old_is_dir, new_is_dir;
2023 int rc;
2024
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002025 old_dsec = inode_security(old_dir);
2026 old_isec = backing_inode_security(old_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00002027 old_is_dir = d_is_dir(old_dentry);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002028 new_dsec = inode_security(new_dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029
Eric Paris50c205f2012-04-04 15:01:43 -04002030 ad.type = LSM_AUDIT_DATA_DENTRY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031
Eric Parisa2694342011-04-25 13:10:27 -04002032 ad.u.dentry = old_dentry;
David Howells275bb412008-11-14 10:39:19 +11002033 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
2035 if (rc)
2036 return rc;
David Howells275bb412008-11-14 10:39:19 +11002037 rc = avc_has_perm(sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 old_isec->sclass, FILE__RENAME, &ad);
2039 if (rc)
2040 return rc;
2041 if (old_is_dir && new_dir != old_dir) {
David Howells275bb412008-11-14 10:39:19 +11002042 rc = avc_has_perm(sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 old_isec->sclass, DIR__REPARENT, &ad);
2044 if (rc)
2045 return rc;
2046 }
2047
Eric Parisa2694342011-04-25 13:10:27 -04002048 ad.u.dentry = new_dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 av = DIR__ADD_NAME | DIR__SEARCH;
David Howells2c616d42015-01-29 12:02:33 +00002050 if (d_is_positive(new_dentry))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 av |= DIR__REMOVE_NAME;
David Howells275bb412008-11-14 10:39:19 +11002052 rc = avc_has_perm(sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053 if (rc)
2054 return rc;
David Howells2c616d42015-01-29 12:02:33 +00002055 if (d_is_positive(new_dentry)) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002056 new_isec = backing_inode_security(new_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00002057 new_is_dir = d_is_dir(new_dentry);
David Howells275bb412008-11-14 10:39:19 +11002058 rc = avc_has_perm(sid, new_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002059 new_isec->sclass,
2060 (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
2061 if (rc)
2062 return rc;
2063 }
2064
2065 return 0;
2066}
2067
2068/* Check whether a task can perform a filesystem operation. */
David Howells88e67f32008-11-14 10:39:21 +11002069static int superblock_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070 struct super_block *sb,
2071 u32 perms,
Thomas Liu2bf49692009-07-14 12:14:09 -04002072 struct common_audit_data *ad)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074 struct superblock_security_struct *sbsec;
David Howells88e67f32008-11-14 10:39:21 +11002075 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077 sbsec = sb->s_security;
David Howells275bb412008-11-14 10:39:19 +11002078 return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079}
2080
2081/* Convert a Linux mode and permission mask to an access vector. */
2082static inline u32 file_mask_to_av(int mode, int mask)
2083{
2084 u32 av = 0;
2085
Al Virodba19c62011-07-25 20:49:29 -04002086 if (!S_ISDIR(mode)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087 if (mask & MAY_EXEC)
2088 av |= FILE__EXECUTE;
2089 if (mask & MAY_READ)
2090 av |= FILE__READ;
2091
2092 if (mask & MAY_APPEND)
2093 av |= FILE__APPEND;
2094 else if (mask & MAY_WRITE)
2095 av |= FILE__WRITE;
2096
2097 } else {
2098 if (mask & MAY_EXEC)
2099 av |= DIR__SEARCH;
2100 if (mask & MAY_WRITE)
2101 av |= DIR__WRITE;
2102 if (mask & MAY_READ)
2103 av |= DIR__READ;
2104 }
2105
2106 return av;
2107}
2108
2109/* Convert a Linux file to an access vector. */
2110static inline u32 file_to_av(struct file *file)
2111{
2112 u32 av = 0;
2113
2114 if (file->f_mode & FMODE_READ)
2115 av |= FILE__READ;
2116 if (file->f_mode & FMODE_WRITE) {
2117 if (file->f_flags & O_APPEND)
2118 av |= FILE__APPEND;
2119 else
2120 av |= FILE__WRITE;
2121 }
Stephen Smalley0794c662008-03-17 08:55:18 -04002122 if (!av) {
2123 /*
2124 * Special file opened with flags 3 for ioctl-only use.
2125 */
2126 av = FILE__IOCTL;
2127 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128
2129 return av;
2130}
2131
Eric Paris8b6a5a32008-10-29 17:06:46 -04002132/*
2133 * Convert a file to an access vector and include the correct open
2134 * open permission.
2135 */
2136static inline u32 open_file_to_av(struct file *file)
2137{
2138 u32 av = file_to_av(file);
2139
Eric Paris49b7b8d2010-07-23 11:44:09 -04002140 if (selinux_policycap_openperm)
2141 av |= FILE__OPEN;
2142
Eric Paris8b6a5a32008-10-29 17:06:46 -04002143 return av;
2144}
2145
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146/* Hook functions begin here. */
2147
Stephen Smalley79af7302015-01-21 10:54:10 -05002148static int selinux_binder_set_context_mgr(struct task_struct *mgr)
2149{
2150 u32 mysid = current_sid();
2151 u32 mgrsid = task_sid(mgr);
2152
2153 return avc_has_perm(mysid, mgrsid, SECCLASS_BINDER,
2154 BINDER__SET_CONTEXT_MGR, NULL);
2155}
2156
2157static int selinux_binder_transaction(struct task_struct *from,
2158 struct task_struct *to)
2159{
2160 u32 mysid = current_sid();
2161 u32 fromsid = task_sid(from);
2162 u32 tosid = task_sid(to);
2163 int rc;
2164
2165 if (mysid != fromsid) {
2166 rc = avc_has_perm(mysid, fromsid, SECCLASS_BINDER,
2167 BINDER__IMPERSONATE, NULL);
2168 if (rc)
2169 return rc;
2170 }
2171
2172 return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
2173 NULL);
2174}
2175
2176static int selinux_binder_transfer_binder(struct task_struct *from,
2177 struct task_struct *to)
2178{
2179 u32 fromsid = task_sid(from);
2180 u32 tosid = task_sid(to);
2181
2182 return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
2183 NULL);
2184}
2185
2186static int selinux_binder_transfer_file(struct task_struct *from,
2187 struct task_struct *to,
2188 struct file *file)
2189{
2190 u32 sid = task_sid(to);
2191 struct file_security_struct *fsec = file->f_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002192 struct dentry *dentry = file->f_path.dentry;
Paul Moore20cdef82016-04-04 14:14:42 -04002193 struct inode_security_struct *isec;
Stephen Smalley79af7302015-01-21 10:54:10 -05002194 struct common_audit_data ad;
2195 int rc;
2196
2197 ad.type = LSM_AUDIT_DATA_PATH;
2198 ad.u.path = file->f_path;
2199
2200 if (sid != fsec->sid) {
2201 rc = avc_has_perm(sid, fsec->sid,
2202 SECCLASS_FD,
2203 FD__USE,
2204 &ad);
2205 if (rc)
2206 return rc;
2207 }
2208
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002209 if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
Stephen Smalley79af7302015-01-21 10:54:10 -05002210 return 0;
2211
Paul Moore20cdef82016-04-04 14:14:42 -04002212 isec = backing_inode_security(dentry);
Stephen Smalley79af7302015-01-21 10:54:10 -05002213 return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file),
2214 &ad);
2215}
2216
Ingo Molnar9e488582009-05-07 19:26:19 +10002217static int selinux_ptrace_access_check(struct task_struct *child,
David Howells5cd9c582008-08-14 11:37:28 +01002218 unsigned int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219{
Eric Paris69f594a2012-01-03 12:25:15 -05002220 if (mode & PTRACE_MODE_READ) {
David Howells275bb412008-11-14 10:39:19 +11002221 u32 sid = current_sid();
2222 u32 csid = task_sid(child);
2223 return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL);
Stephen Smalley006ebb42008-05-19 08:32:49 -04002224 }
2225
David Howells3b11a1d2008-11-14 10:39:26 +11002226 return current_has_perm(child, PROCESS__PTRACE);
David Howells5cd9c582008-08-14 11:37:28 +01002227}
2228
2229static int selinux_ptrace_traceme(struct task_struct *parent)
2230{
David Howells5cd9c582008-08-14 11:37:28 +01002231 return task_has_perm(parent, current, PROCESS__PTRACE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232}
2233
2234static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
Eric Paris828dfe12008-04-17 13:17:49 -04002235 kernel_cap_t *inheritable, kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002237 return current_has_perm(target, PROCESS__GETCAP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238}
2239
David Howellsd84f4f92008-11-14 10:39:23 +11002240static int selinux_capset(struct cred *new, const struct cred *old,
2241 const kernel_cap_t *effective,
2242 const kernel_cap_t *inheritable,
2243 const kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244{
David Howellsd84f4f92008-11-14 10:39:23 +11002245 return cred_has_perm(old, new, PROCESS__SETCAP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246}
2247
James Morris5626d3e2009-01-30 10:05:06 +11002248/*
2249 * (This comment used to live with the selinux_task_setuid hook,
2250 * which was removed).
2251 *
2252 * Since setuid only affects the current process, and since the SELinux
2253 * controls are not based on the Linux identity attributes, SELinux does not
2254 * need to control this operation. However, SELinux does control the use of
2255 * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
2256 */
2257
Eric Paris6a9de492012-01-03 12:25:14 -05002258static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
2259 int cap, int audit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260{
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04002261 return cred_has_capability(cred, cap, audit, ns == &init_user_ns);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262}
2263
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
2265{
David Howells88e67f32008-11-14 10:39:21 +11002266 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267 int rc = 0;
2268
2269 if (!sb)
2270 return 0;
2271
2272 switch (cmds) {
Eric Paris828dfe12008-04-17 13:17:49 -04002273 case Q_SYNC:
2274 case Q_QUOTAON:
2275 case Q_QUOTAOFF:
2276 case Q_SETINFO:
2277 case Q_SETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002278 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAMOD, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002279 break;
2280 case Q_GETFMT:
2281 case Q_GETINFO:
2282 case Q_GETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002283 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAGET, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002284 break;
2285 default:
2286 rc = 0; /* let the kernel handle invalid cmds */
2287 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 }
2289 return rc;
2290}
2291
2292static int selinux_quota_on(struct dentry *dentry)
2293{
David Howells88e67f32008-11-14 10:39:21 +11002294 const struct cred *cred = current_cred();
2295
Eric Paris2875fa02011-04-28 16:04:24 -04002296 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297}
2298
Eric Paris12b30522010-11-15 18:36:29 -05002299static int selinux_syslog(int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002300{
2301 int rc;
2302
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303 switch (type) {
Kees Cookd78ca3c2010-02-03 15:37:13 -08002304 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
2305 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
Eric Paris828dfe12008-04-17 13:17:49 -04002306 rc = task_has_system(current, SYSTEM__SYSLOG_READ);
2307 break;
Kees Cookd78ca3c2010-02-03 15:37:13 -08002308 case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
2309 case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
2310 /* Set level of messages printed to console */
2311 case SYSLOG_ACTION_CONSOLE_LEVEL:
Eric Paris828dfe12008-04-17 13:17:49 -04002312 rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
2313 break;
Kees Cookd78ca3c2010-02-03 15:37:13 -08002314 case SYSLOG_ACTION_CLOSE: /* Close log */
2315 case SYSLOG_ACTION_OPEN: /* Open log */
2316 case SYSLOG_ACTION_READ: /* Read from log */
2317 case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */
2318 case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
Eric Paris828dfe12008-04-17 13:17:49 -04002319 default:
2320 rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
2321 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 }
2323 return rc;
2324}
2325
2326/*
2327 * Check that a process has enough memory to allocate a new virtual
2328 * mapping. 0 means there is enough memory for the allocation to
2329 * succeed and -ENOMEM implies there is not.
2330 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331 * Do not audit the selinux permission check, as this is applied to all
2332 * processes that allocate mappings.
2333 */
Alan Cox34b4e4a2007-08-22 14:01:28 -07002334static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335{
2336 int rc, cap_sys_admin = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002338 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04002339 SECURITY_CAP_NOAUDIT, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340 if (rc == 0)
2341 cap_sys_admin = 1;
2342
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002343 return cap_sys_admin;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344}
2345
2346/* binprm security operations */
2347
Paul Moore0c6181c2016-03-30 21:41:21 -04002348static u32 ptrace_parent_sid(struct task_struct *task)
2349{
2350 u32 sid = 0;
2351 struct task_struct *tracer;
2352
2353 rcu_read_lock();
2354 tracer = ptrace_parent(task);
2355 if (tracer)
2356 sid = task_sid(tracer);
2357 rcu_read_unlock();
2358
2359 return sid;
2360}
2361
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002362static int check_nnp_nosuid(const struct linux_binprm *bprm,
2363 const struct task_security_struct *old_tsec,
2364 const struct task_security_struct *new_tsec)
2365{
2366 int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
Andy Lutomirski380cf5b2016-06-23 16:41:05 -05002367 int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002368 int rc;
2369
2370 if (!nnp && !nosuid)
2371 return 0; /* neither NNP nor nosuid */
2372
2373 if (new_tsec->sid == old_tsec->sid)
2374 return 0; /* No change in credentials */
2375
2376 /*
2377 * The only transitions we permit under NNP or nosuid
2378 * are transitions to bounded SIDs, i.e. SIDs that are
2379 * guaranteed to only be allowed a subset of the permissions
2380 * of the current SID.
2381 */
2382 rc = security_bounded_transition(old_tsec->sid, new_tsec->sid);
2383 if (rc) {
2384 /*
2385 * On failure, preserve the errno values for NNP vs nosuid.
2386 * NNP: Operation not permitted for caller.
2387 * nosuid: Permission denied to file.
2388 */
2389 if (nnp)
2390 return -EPERM;
2391 else
2392 return -EACCES;
2393 }
2394 return 0;
2395}
2396
David Howellsa6f76f22008-11-14 10:39:24 +11002397static int selinux_bprm_set_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398{
David Howellsa6f76f22008-11-14 10:39:24 +11002399 const struct task_security_struct *old_tsec;
2400 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 struct inode_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04002402 struct common_audit_data ad;
Al Viro496ad9a2013-01-23 17:07:38 -05002403 struct inode *inode = file_inode(bprm->file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404 int rc;
2405
David Howellsa6f76f22008-11-14 10:39:24 +11002406 /* SELinux context only depends on initial program or script and not
2407 * the script interpreter */
2408 if (bprm->cred_prepared)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409 return 0;
2410
David Howellsa6f76f22008-11-14 10:39:24 +11002411 old_tsec = current_security();
2412 new_tsec = bprm->cred->security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002413 isec = inode_security(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414
2415 /* Default to the current task SID. */
David Howellsa6f76f22008-11-14 10:39:24 +11002416 new_tsec->sid = old_tsec->sid;
2417 new_tsec->osid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418
Michael LeMay28eba5b2006-06-27 02:53:42 -07002419 /* Reset fs, key, and sock SIDs on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002420 new_tsec->create_sid = 0;
2421 new_tsec->keycreate_sid = 0;
2422 new_tsec->sockcreate_sid = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423
David Howellsa6f76f22008-11-14 10:39:24 +11002424 if (old_tsec->exec_sid) {
2425 new_tsec->sid = old_tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426 /* Reset exec SID on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002427 new_tsec->exec_sid = 0;
Andy Lutomirski259e5e62012-04-12 16:47:50 -05002428
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002429 /* Fail on NNP or nosuid if not an allowed transition. */
2430 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2431 if (rc)
2432 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433 } else {
2434 /* Check for a default transition on this program. */
David Howellsa6f76f22008-11-14 10:39:24 +11002435 rc = security_transition_sid(old_tsec->sid, isec->sid,
Eric Paris652bb9b2011-02-01 11:05:40 -05002436 SECCLASS_PROCESS, NULL,
2437 &new_tsec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438 if (rc)
2439 return rc;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002440
2441 /*
2442 * Fallback to old SID on NNP or nosuid if not an allowed
2443 * transition.
2444 */
2445 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2446 if (rc)
2447 new_tsec->sid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448 }
2449
Vivek Goyal43af5de2016-09-09 11:37:49 -04002450 ad.type = LSM_AUDIT_DATA_FILE;
2451 ad.u.file = bprm->file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452
David Howellsa6f76f22008-11-14 10:39:24 +11002453 if (new_tsec->sid == old_tsec->sid) {
2454 rc = avc_has_perm(old_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
2456 if (rc)
2457 return rc;
2458 } else {
2459 /* Check permissions for the transition. */
David Howellsa6f76f22008-11-14 10:39:24 +11002460 rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461 SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
2462 if (rc)
2463 return rc;
2464
David Howellsa6f76f22008-11-14 10:39:24 +11002465 rc = avc_has_perm(new_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002466 SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
2467 if (rc)
2468 return rc;
2469
David Howellsa6f76f22008-11-14 10:39:24 +11002470 /* Check for shared state */
2471 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
2472 rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
2473 SECCLASS_PROCESS, PROCESS__SHARE,
2474 NULL);
2475 if (rc)
2476 return -EPERM;
2477 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478
David Howellsa6f76f22008-11-14 10:39:24 +11002479 /* Make sure that anyone attempting to ptrace over a task that
2480 * changes its SID has the appropriate permit */
2481 if (bprm->unsafe &
2482 (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
Paul Moore0c6181c2016-03-30 21:41:21 -04002483 u32 ptsid = ptrace_parent_sid(current);
David Howellsa6f76f22008-11-14 10:39:24 +11002484 if (ptsid != 0) {
2485 rc = avc_has_perm(ptsid, new_tsec->sid,
2486 SECCLASS_PROCESS,
2487 PROCESS__PTRACE, NULL);
2488 if (rc)
2489 return -EPERM;
2490 }
2491 }
2492
2493 /* Clear any possibly unsafe personality bits on exec: */
2494 bprm->per_clear |= PER_CLEAR_ON_SETID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495 }
2496
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497 return 0;
2498}
2499
Eric Paris828dfe12008-04-17 13:17:49 -04002500static int selinux_bprm_secureexec(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501{
Paul Moore5fb49872010-04-22 14:46:19 -04002502 const struct task_security_struct *tsec = current_security();
David Howells275bb412008-11-14 10:39:19 +11002503 u32 sid, osid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 int atsecure = 0;
2505
David Howells275bb412008-11-14 10:39:19 +11002506 sid = tsec->sid;
2507 osid = tsec->osid;
2508
2509 if (osid != sid) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002510 /* Enable secure mode for SIDs transitions unless
2511 the noatsecure permission is granted between
2512 the two SIDs, i.e. ahp returns 0. */
David Howells275bb412008-11-14 10:39:19 +11002513 atsecure = avc_has_perm(osid, sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002514 SECCLASS_PROCESS,
2515 PROCESS__NOATSECURE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 }
2517
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002518 return !!atsecure;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002519}
2520
Al Viroc3c073f2012-08-21 22:32:06 -04002521static int match_file(const void *p, struct file *file, unsigned fd)
2522{
2523 return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0;
2524}
2525
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526/* Derived from fs/exec.c:flush_old_files. */
David Howells745ca242008-11-14 10:39:22 +11002527static inline void flush_unauthorized_files(const struct cred *cred,
2528 struct files_struct *files)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 struct file *file, *devnull = NULL;
Stephen Smalleyb20c8122006-09-25 23:32:03 -07002531 struct tty_struct *tty;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002532 int drop_tty = 0;
Al Viroc3c073f2012-08-21 22:32:06 -04002533 unsigned n;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002535 tty = get_current_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 if (tty) {
Peter Hurley4a510962016-01-09 21:35:23 -08002537 spin_lock(&tty->files_lock);
Eric Paris37dd0bd2008-10-31 17:40:00 -04002538 if (!list_empty(&tty->tty_files)) {
Nick Piggind996b622010-08-18 04:37:36 +10002539 struct tty_file_private *file_priv;
Eric Paris37dd0bd2008-10-31 17:40:00 -04002540
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541 /* Revalidate access to controlling tty.
David Howells13f8e982013-06-13 23:37:55 +01002542 Use file_path_has_perm on the tty path directly
2543 rather than using file_has_perm, as this particular
2544 open file may belong to another process and we are
2545 only interested in the inode-based check here. */
Nick Piggind996b622010-08-18 04:37:36 +10002546 file_priv = list_first_entry(&tty->tty_files,
2547 struct tty_file_private, list);
2548 file = file_priv->file;
David Howells13f8e982013-06-13 23:37:55 +01002549 if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE))
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002550 drop_tty = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 }
Peter Hurley4a510962016-01-09 21:35:23 -08002552 spin_unlock(&tty->files_lock);
Alan Cox452a00d2008-10-13 10:39:13 +01002553 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 }
Eric W. Biederman98a27ba2007-05-08 00:26:56 -07002555 /* Reset controlling tty. */
2556 if (drop_tty)
2557 no_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558
2559 /* Revalidate access to inherited open files. */
Al Viroc3c073f2012-08-21 22:32:06 -04002560 n = iterate_fd(files, 0, match_file, cred);
2561 if (!n) /* none found? */
2562 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563
Al Viroc3c073f2012-08-21 22:32:06 -04002564 devnull = dentry_open(&selinux_null, O_RDWR, cred);
Al Viro45525b22012-10-16 13:30:07 -04002565 if (IS_ERR(devnull))
2566 devnull = NULL;
2567 /* replace all the matching ones with this */
2568 do {
2569 replace_fd(n - 1, devnull, 0);
2570 } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
2571 if (devnull)
Al Viroc3c073f2012-08-21 22:32:06 -04002572 fput(devnull);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573}
2574
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575/*
David Howellsa6f76f22008-11-14 10:39:24 +11002576 * Prepare a process for imminent new credential changes due to exec
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577 */
David Howellsa6f76f22008-11-14 10:39:24 +11002578static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579{
David Howellsa6f76f22008-11-14 10:39:24 +11002580 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581 struct rlimit *rlim, *initrlim;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582 int rc, i;
2583
David Howellsa6f76f22008-11-14 10:39:24 +11002584 new_tsec = bprm->cred->security;
2585 if (new_tsec->sid == new_tsec->osid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002586 return;
2587
2588 /* Close files for which the new task SID is not authorized. */
David Howellsa6f76f22008-11-14 10:39:24 +11002589 flush_unauthorized_files(bprm->cred, current->files);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590
David Howellsa6f76f22008-11-14 10:39:24 +11002591 /* Always clear parent death signal on SID transitions. */
2592 current->pdeath_signal = 0;
2593
2594 /* Check whether the new SID can inherit resource limits from the old
2595 * SID. If not, reset all soft limits to the lower of the current
2596 * task's hard limit and the init task's soft limit.
2597 *
2598 * Note that the setting of hard limits (even to lower them) can be
2599 * controlled by the setrlimit check. The inclusion of the init task's
2600 * soft limit into the computation is to avoid resetting soft limits
2601 * higher than the default soft limit for cases where the default is
2602 * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
2603 */
2604 rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
2605 PROCESS__RLIMITINH, NULL);
2606 if (rc) {
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002607 /* protect against do_prlimit() */
2608 task_lock(current);
David Howellsa6f76f22008-11-14 10:39:24 +11002609 for (i = 0; i < RLIM_NLIMITS; i++) {
2610 rlim = current->signal->rlim + i;
2611 initrlim = init_task.signal->rlim + i;
2612 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2613 }
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002614 task_unlock(current);
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002615 if (IS_ENABLED(CONFIG_POSIX_TIMERS))
2616 update_rlimit_cpu(current, rlimit(RLIMIT_CPU));
David Howellsa6f76f22008-11-14 10:39:24 +11002617 }
2618}
2619
2620/*
2621 * Clean up the process immediately after the installation of new credentials
2622 * due to exec
2623 */
2624static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2625{
2626 const struct task_security_struct *tsec = current_security();
2627 struct itimerval itimer;
David Howellsa6f76f22008-11-14 10:39:24 +11002628 u32 osid, sid;
2629 int rc, i;
David Howellsa6f76f22008-11-14 10:39:24 +11002630
David Howellsa6f76f22008-11-14 10:39:24 +11002631 osid = tsec->osid;
2632 sid = tsec->sid;
2633
2634 if (sid == osid)
2635 return;
2636
2637 /* Check whether the new SID can inherit signal state from the old SID.
2638 * If not, clear itimers to avoid subsequent signal generation and
2639 * flush and unblock signals.
2640 *
2641 * This must occur _after_ the task SID has been updated so that any
2642 * kill done after the flush will be checked against the new SID.
2643 */
2644 rc = avc_has_perm(osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645 if (rc) {
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002646 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
2647 memset(&itimer, 0, sizeof itimer);
2648 for (i = 0; i < 3; i++)
2649 do_setitimer(i, &itimer, NULL);
2650 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651 spin_lock_irq(&current->sighand->siglock);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002652 if (!fatal_signal_pending(current)) {
2653 flush_sigqueue(&current->pending);
2654 flush_sigqueue(&current->signal->shared_pending);
David Howells3bcac022009-04-29 13:45:05 +01002655 flush_signal_handlers(current, 1);
2656 sigemptyset(&current->blocked);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002657 recalc_sigpending();
David Howells3bcac022009-04-29 13:45:05 +01002658 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 spin_unlock_irq(&current->sighand->siglock);
2660 }
2661
David Howellsa6f76f22008-11-14 10:39:24 +11002662 /* Wake up the parent if it is waiting so that it can recheck
2663 * wait permission to the new task SID. */
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002664 read_lock(&tasklist_lock);
Oleg Nesterov0b7570e2009-09-23 15:56:46 -07002665 __wake_up_parent(current, current->real_parent);
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002666 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667}
2668
2669/* superblock security operations */
2670
2671static int selinux_sb_alloc_security(struct super_block *sb)
2672{
2673 return superblock_alloc_security(sb);
2674}
2675
2676static void selinux_sb_free_security(struct super_block *sb)
2677{
2678 superblock_free_security(sb);
2679}
2680
2681static inline int match_prefix(char *prefix, int plen, char *option, int olen)
2682{
2683 if (plen > olen)
2684 return 0;
2685
2686 return !memcmp(prefix, option, plen);
2687}
2688
2689static inline int selinux_option(char *option, int len)
2690{
Eric Paris832cbd92008-04-01 13:24:09 -04002691 return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) ||
2692 match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) ||
2693 match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) ||
David P. Quigley11689d42009-01-16 09:22:03 -05002694 match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len) ||
2695 match_prefix(LABELSUPP_STR, sizeof(LABELSUPP_STR)-1, option, len));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696}
2697
2698static inline void take_option(char **to, char *from, int *first, int len)
2699{
2700 if (!*first) {
2701 **to = ',';
2702 *to += 1;
Cory Olmo3528a952006-09-29 01:58:44 -07002703 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 *first = 0;
2705 memcpy(*to, from, len);
2706 *to += len;
2707}
2708
Eric Paris828dfe12008-04-17 13:17:49 -04002709static inline void take_selinux_option(char **to, char *from, int *first,
2710 int len)
Cory Olmo3528a952006-09-29 01:58:44 -07002711{
2712 int current_size = 0;
2713
2714 if (!*first) {
2715 **to = '|';
2716 *to += 1;
Eric Paris828dfe12008-04-17 13:17:49 -04002717 } else
Cory Olmo3528a952006-09-29 01:58:44 -07002718 *first = 0;
2719
2720 while (current_size < len) {
2721 if (*from != '"') {
2722 **to = *from;
2723 *to += 1;
2724 }
2725 from += 1;
2726 current_size += 1;
2727 }
2728}
2729
Eric Parise0007522008-03-05 10:31:54 -05002730static int selinux_sb_copy_data(char *orig, char *copy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731{
2732 int fnosec, fsec, rc = 0;
2733 char *in_save, *in_curr, *in_end;
2734 char *sec_curr, *nosec_save, *nosec;
Cory Olmo3528a952006-09-29 01:58:44 -07002735 int open_quote = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736
2737 in_curr = orig;
2738 sec_curr = copy;
2739
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740 nosec = (char *)get_zeroed_page(GFP_KERNEL);
2741 if (!nosec) {
2742 rc = -ENOMEM;
2743 goto out;
2744 }
2745
2746 nosec_save = nosec;
2747 fnosec = fsec = 1;
2748 in_save = in_end = orig;
2749
2750 do {
Cory Olmo3528a952006-09-29 01:58:44 -07002751 if (*in_end == '"')
2752 open_quote = !open_quote;
2753 if ((*in_end == ',' && open_quote == 0) ||
2754 *in_end == '\0') {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755 int len = in_end - in_curr;
2756
2757 if (selinux_option(in_curr, len))
Cory Olmo3528a952006-09-29 01:58:44 -07002758 take_selinux_option(&sec_curr, in_curr, &fsec, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759 else
2760 take_option(&nosec, in_curr, &fnosec, len);
2761
2762 in_curr = in_end + 1;
2763 }
2764 } while (*in_end++);
2765
Eric Paris6931dfc2005-06-30 02:58:51 -07002766 strcpy(in_save, nosec_save);
Gerald Schaeferda3caa22005-06-21 17:15:18 -07002767 free_page((unsigned long)nosec_save);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768out:
2769 return rc;
2770}
2771
Eric Paris026eb162011-03-03 16:09:14 -05002772static int selinux_sb_remount(struct super_block *sb, void *data)
2773{
2774 int rc, i, *flags;
2775 struct security_mnt_opts opts;
2776 char *secdata, **mount_options;
2777 struct superblock_security_struct *sbsec = sb->s_security;
2778
2779 if (!(sbsec->flags & SE_SBINITIALIZED))
2780 return 0;
2781
2782 if (!data)
2783 return 0;
2784
2785 if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
2786 return 0;
2787
2788 security_init_mnt_opts(&opts);
2789 secdata = alloc_secdata();
2790 if (!secdata)
2791 return -ENOMEM;
2792 rc = selinux_sb_copy_data(data, secdata);
2793 if (rc)
2794 goto out_free_secdata;
2795
2796 rc = selinux_parse_opts_str(secdata, &opts);
2797 if (rc)
2798 goto out_free_secdata;
2799
2800 mount_options = opts.mnt_opts;
2801 flags = opts.mnt_opts_flags;
2802
2803 for (i = 0; i < opts.num_mnt_opts; i++) {
2804 u32 sid;
Eric Paris026eb162011-03-03 16:09:14 -05002805
Eric Paris12f348b2012-10-09 10:56:25 -04002806 if (flags[i] == SBLABEL_MNT)
Eric Paris026eb162011-03-03 16:09:14 -05002807 continue;
Rasmus Villemoes44be2f62015-10-21 17:44:25 -04002808 rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL);
Eric Paris026eb162011-03-03 16:09:14 -05002809 if (rc) {
Rasmus Villemoes44be2f62015-10-21 17:44:25 -04002810 printk(KERN_WARNING "SELinux: security_context_str_to_sid"
Linus Torvalds29b1deb2013-12-15 11:17:45 -08002811 "(%s) failed for (dev %s, type %s) errno=%d\n",
2812 mount_options[i], sb->s_id, sb->s_type->name, rc);
Eric Paris026eb162011-03-03 16:09:14 -05002813 goto out_free_opts;
2814 }
2815 rc = -EINVAL;
2816 switch (flags[i]) {
2817 case FSCONTEXT_MNT:
2818 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
2819 goto out_bad_option;
2820 break;
2821 case CONTEXT_MNT:
2822 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
2823 goto out_bad_option;
2824 break;
2825 case ROOTCONTEXT_MNT: {
2826 struct inode_security_struct *root_isec;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002827 root_isec = backing_inode_security(sb->s_root);
Eric Paris026eb162011-03-03 16:09:14 -05002828
2829 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
2830 goto out_bad_option;
2831 break;
2832 }
2833 case DEFCONTEXT_MNT:
2834 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
2835 goto out_bad_option;
2836 break;
2837 default:
2838 goto out_free_opts;
2839 }
2840 }
2841
2842 rc = 0;
2843out_free_opts:
2844 security_free_mnt_opts(&opts);
2845out_free_secdata:
2846 free_secdata(secdata);
2847 return rc;
2848out_bad_option:
2849 printk(KERN_WARNING "SELinux: unable to change security options "
Linus Torvalds29b1deb2013-12-15 11:17:45 -08002850 "during remount (dev %s, type=%s)\n", sb->s_id,
2851 sb->s_type->name);
Eric Paris026eb162011-03-03 16:09:14 -05002852 goto out_free_opts;
2853}
2854
James Morris12204e22008-12-19 10:44:42 +11002855static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856{
David Howells88e67f32008-11-14 10:39:21 +11002857 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002858 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 int rc;
2860
2861 rc = superblock_doinit(sb, data);
2862 if (rc)
2863 return rc;
2864
James Morris74192242008-12-19 11:41:10 +11002865 /* Allow all mounts performed by the kernel */
2866 if (flags & MS_KERNMOUNT)
2867 return 0;
2868
Eric Paris50c205f2012-04-04 15:01:43 -04002869 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002870 ad.u.dentry = sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002871 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872}
2873
David Howells726c3342006-06-23 02:02:58 -07002874static int selinux_sb_statfs(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875{
David Howells88e67f32008-11-14 10:39:21 +11002876 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002877 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878
Eric Paris50c205f2012-04-04 15:01:43 -04002879 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002880 ad.u.dentry = dentry->d_sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002881 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882}
2883
Al Viro808d4e32012-10-11 11:42:01 -04002884static int selinux_mount(const char *dev_name,
Al Viro8a04c432016-03-25 14:52:53 -04002885 const struct path *path,
Al Viro808d4e32012-10-11 11:42:01 -04002886 const char *type,
Eric Paris828dfe12008-04-17 13:17:49 -04002887 unsigned long flags,
2888 void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889{
David Howells88e67f32008-11-14 10:39:21 +11002890 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891
2892 if (flags & MS_REMOUNT)
Al Virod8c95842011-12-07 18:16:57 -05002893 return superblock_has_perm(cred, path->dentry->d_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002894 FILESYSTEM__REMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895 else
Eric Paris2875fa02011-04-28 16:04:24 -04002896 return path_has_perm(cred, path, FILE__MOUNTON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897}
2898
2899static int selinux_umount(struct vfsmount *mnt, int flags)
2900{
David Howells88e67f32008-11-14 10:39:21 +11002901 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902
David Howells88e67f32008-11-14 10:39:21 +11002903 return superblock_has_perm(cred, mnt->mnt_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002904 FILESYSTEM__UNMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905}
2906
2907/* inode security operations */
2908
2909static int selinux_inode_alloc_security(struct inode *inode)
2910{
2911 return inode_alloc_security(inode);
2912}
2913
2914static void selinux_inode_free_security(struct inode *inode)
2915{
2916 inode_free_security(inode);
2917}
2918
David Quigleyd47be3d2013-05-22 12:50:34 -04002919static int selinux_dentry_init_security(struct dentry *dentry, int mode,
Al Viro4f3ccd72016-07-20 16:06:15 -04002920 const struct qstr *name, void **ctx,
David Quigleyd47be3d2013-05-22 12:50:34 -04002921 u32 *ctxlen)
2922{
David Quigleyd47be3d2013-05-22 12:50:34 -04002923 u32 newsid;
2924 int rc;
2925
Vivek Goyalc957f6d2016-07-13 10:44:51 -04002926 rc = selinux_determine_inode_label(current_security(),
2927 d_inode(dentry->d_parent), name,
David Howellsc3c188b2015-07-10 17:19:58 -04002928 inode_mode_to_security_class(mode),
2929 &newsid);
2930 if (rc)
2931 return rc;
David Quigleyd47be3d2013-05-22 12:50:34 -04002932
2933 return security_sid_to_context(newsid, (char **)ctx, ctxlen);
2934}
2935
Vivek Goyala518b0a2016-07-13 10:44:53 -04002936static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
2937 struct qstr *name,
2938 const struct cred *old,
2939 struct cred *new)
2940{
2941 u32 newsid;
2942 int rc;
2943 struct task_security_struct *tsec;
2944
2945 rc = selinux_determine_inode_label(old->security,
2946 d_inode(dentry->d_parent), name,
2947 inode_mode_to_security_class(mode),
2948 &newsid);
2949 if (rc)
2950 return rc;
2951
2952 tsec = new->security;
2953 tsec->create_sid = newsid;
2954 return 0;
2955}
2956
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002957static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
Tetsuo Handa95489062013-07-25 05:44:02 +09002958 const struct qstr *qstr,
2959 const char **name,
Eric Paris2a7dba32011-02-01 11:05:39 -05002960 void **value, size_t *len)
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002961{
Paul Moore5fb49872010-04-22 14:46:19 -04002962 const struct task_security_struct *tsec = current_security();
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002963 struct superblock_security_struct *sbsec;
David Howells275bb412008-11-14 10:39:19 +11002964 u32 sid, newsid, clen;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002965 int rc;
Tetsuo Handa95489062013-07-25 05:44:02 +09002966 char *context;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002967
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002968 sbsec = dir->i_sb->s_security;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002969
David Howells275bb412008-11-14 10:39:19 +11002970 sid = tsec->sid;
2971 newsid = tsec->create_sid;
2972
Vivek Goyalc957f6d2016-07-13 10:44:51 -04002973 rc = selinux_determine_inode_label(current_security(),
David Howellsc3c188b2015-07-10 17:19:58 -04002974 dir, qstr,
2975 inode_mode_to_security_class(inode->i_mode),
2976 &newsid);
2977 if (rc)
2978 return rc;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002979
Eric Paris296fddf2006-09-25 23:32:00 -07002980 /* Possibly defer initialization to selinux_complete_init. */
David P. Quigley0d90a7e2009-01-16 09:22:02 -05002981 if (sbsec->flags & SE_SBINITIALIZED) {
Eric Paris296fddf2006-09-25 23:32:00 -07002982 struct inode_security_struct *isec = inode->i_security;
2983 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2984 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05002985 isec->initialized = LABEL_INITIALIZED;
Eric Paris296fddf2006-09-25 23:32:00 -07002986 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002987
Eric Paris12f348b2012-10-09 10:56:25 -04002988 if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT))
Stephen Smalley25a74f32005-11-08 21:34:33 -08002989 return -EOPNOTSUPP;
2990
Tetsuo Handa95489062013-07-25 05:44:02 +09002991 if (name)
2992 *name = XATTR_SELINUX_SUFFIX;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002993
2994 if (value && len) {
Stephen Smalley12b29f32008-05-07 13:03:20 -04002995 rc = security_sid_to_context_force(newsid, &context, &clen);
Tetsuo Handa95489062013-07-25 05:44:02 +09002996 if (rc)
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002997 return rc;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002998 *value = context;
2999 *len = clen;
3000 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003001
Stephen Smalley5e41ff92005-09-09 13:01:35 -07003002 return 0;
3003}
3004
Al Viro4acdaf22011-07-26 01:42:34 -04003005static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006{
3007 return may_create(dir, dentry, SECCLASS_FILE);
3008}
3009
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
3011{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012 return may_link(dir, old_dentry, MAY_LINK);
3013}
3014
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
3016{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017 return may_link(dir, dentry, MAY_UNLINK);
3018}
3019
3020static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
3021{
3022 return may_create(dir, dentry, SECCLASS_LNK_FILE);
3023}
3024
Al Viro18bb1db2011-07-26 01:41:39 -04003025static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026{
3027 return may_create(dir, dentry, SECCLASS_DIR);
3028}
3029
Linus Torvalds1da177e2005-04-16 15:20:36 -07003030static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
3031{
3032 return may_link(dir, dentry, MAY_RMDIR);
3033}
3034
Al Viro1a67aaf2011-07-26 01:52:52 -04003035static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037 return may_create(dir, dentry, inode_mode_to_security_class(mode));
3038}
3039
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
Eric Paris828dfe12008-04-17 13:17:49 -04003041 struct inode *new_inode, struct dentry *new_dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042{
3043 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
3044}
3045
Linus Torvalds1da177e2005-04-16 15:20:36 -07003046static int selinux_inode_readlink(struct dentry *dentry)
3047{
David Howells88e67f32008-11-14 10:39:21 +11003048 const struct cred *cred = current_cred();
3049
Eric Paris2875fa02011-04-28 16:04:24 -04003050 return dentry_has_perm(cred, dentry, FILE__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051}
3052
NeilBrownbda0be72015-03-23 13:37:39 +11003053static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
3054 bool rcu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055{
David Howells88e67f32008-11-14 10:39:21 +11003056 const struct cred *cred = current_cred();
NeilBrownbda0be72015-03-23 13:37:39 +11003057 struct common_audit_data ad;
3058 struct inode_security_struct *isec;
3059 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003060
NeilBrownbda0be72015-03-23 13:37:39 +11003061 validate_creds(cred);
3062
3063 ad.type = LSM_AUDIT_DATA_DENTRY;
3064 ad.u.dentry = dentry;
3065 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05003066 isec = inode_security_rcu(inode, rcu);
3067 if (IS_ERR(isec))
3068 return PTR_ERR(isec);
NeilBrownbda0be72015-03-23 13:37:39 +11003069
3070 return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, &ad,
3071 rcu ? MAY_NOT_BLOCK : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072}
3073
Eric Parisd4cf970d2012-04-04 15:01:42 -04003074static noinline int audit_inode_permission(struct inode *inode,
3075 u32 perms, u32 audited, u32 denied,
Stephen Smalley626b9742014-04-29 11:29:04 -07003076 int result,
Eric Parisd4cf970d2012-04-04 15:01:42 -04003077 unsigned flags)
3078{
3079 struct common_audit_data ad;
Eric Parisd4cf970d2012-04-04 15:01:42 -04003080 struct inode_security_struct *isec = inode->i_security;
3081 int rc;
3082
Eric Paris50c205f2012-04-04 15:01:43 -04003083 ad.type = LSM_AUDIT_DATA_INODE;
Eric Parisd4cf970d2012-04-04 15:01:42 -04003084 ad.u.inode = inode;
3085
3086 rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
Stephen Smalley626b9742014-04-29 11:29:04 -07003087 audited, denied, result, &ad, flags);
Eric Parisd4cf970d2012-04-04 15:01:42 -04003088 if (rc)
3089 return rc;
3090 return 0;
3091}
3092
Al Viroe74f71e2011-06-20 19:38:15 -04003093static int selinux_inode_permission(struct inode *inode, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003094{
David Howells88e67f32008-11-14 10:39:21 +11003095 const struct cred *cred = current_cred();
Eric Parisb782e0a2010-07-23 11:44:03 -04003096 u32 perms;
3097 bool from_access;
Al Virocf1dd1d2011-06-20 19:44:08 -04003098 unsigned flags = mask & MAY_NOT_BLOCK;
Eric Paris2e334052012-04-04 15:01:42 -04003099 struct inode_security_struct *isec;
3100 u32 sid;
3101 struct av_decision avd;
3102 int rc, rc2;
3103 u32 audited, denied;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104
Eric Parisb782e0a2010-07-23 11:44:03 -04003105 from_access = mask & MAY_ACCESS;
Eric Parisd09ca732010-07-23 11:43:57 -04003106 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
3107
Eric Parisb782e0a2010-07-23 11:44:03 -04003108 /* No permission to check. Existence test. */
3109 if (!mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111
Eric Paris2e334052012-04-04 15:01:42 -04003112 validate_creds(cred);
Eric Parisb782e0a2010-07-23 11:44:03 -04003113
Eric Paris2e334052012-04-04 15:01:42 -04003114 if (unlikely(IS_PRIVATE(inode)))
3115 return 0;
Eric Parisb782e0a2010-07-23 11:44:03 -04003116
3117 perms = file_mask_to_av(inode->i_mode, mask);
3118
Eric Paris2e334052012-04-04 15:01:42 -04003119 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05003120 isec = inode_security_rcu(inode, flags & MAY_NOT_BLOCK);
3121 if (IS_ERR(isec))
3122 return PTR_ERR(isec);
Eric Paris2e334052012-04-04 15:01:42 -04003123
3124 rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd);
3125 audited = avc_audit_required(perms, &avd, rc,
3126 from_access ? FILE__AUDIT_ACCESS : 0,
3127 &denied);
3128 if (likely(!audited))
3129 return rc;
3130
Stephen Smalley626b9742014-04-29 11:29:04 -07003131 rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
Eric Paris2e334052012-04-04 15:01:42 -04003132 if (rc2)
3133 return rc2;
3134 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135}
3136
3137static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
3138{
David Howells88e67f32008-11-14 10:39:21 +11003139 const struct cred *cred = current_cred();
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003140 unsigned int ia_valid = iattr->ia_valid;
Eric Paris95dbf732012-04-04 13:45:34 -04003141 __u32 av = FILE__WRITE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003143 /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
3144 if (ia_valid & ATTR_FORCE) {
3145 ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE |
3146 ATTR_FORCE);
3147 if (!ia_valid)
3148 return 0;
3149 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003151 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
3152 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
Eric Paris2875fa02011-04-28 16:04:24 -04003153 return dentry_has_perm(cred, dentry, FILE__SETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154
Jeff Vander Stoep44d37ad2015-10-21 17:44:25 -04003155 if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)
3156 && !(ia_valid & ATTR_FILE))
Eric Paris95dbf732012-04-04 13:45:34 -04003157 av |= FILE__OPEN;
3158
3159 return dentry_has_perm(cred, dentry, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160}
3161
Al Viro3f7036a2015-03-08 19:28:30 -04003162static int selinux_inode_getattr(const struct path *path)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163{
Al Viro3f7036a2015-03-08 19:28:30 -04003164 return path_has_perm(current_cred(), path, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165}
3166
David Howells8f0cfa52008-04-29 00:59:41 -07003167static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
Serge E. Hallynb5376772007-10-16 23:31:36 -07003168{
David Howells88e67f32008-11-14 10:39:21 +11003169 const struct cred *cred = current_cred();
3170
Serge E. Hallynb5376772007-10-16 23:31:36 -07003171 if (!strncmp(name, XATTR_SECURITY_PREFIX,
3172 sizeof XATTR_SECURITY_PREFIX - 1)) {
3173 if (!strcmp(name, XATTR_NAME_CAPS)) {
3174 if (!capable(CAP_SETFCAP))
3175 return -EPERM;
3176 } else if (!capable(CAP_SYS_ADMIN)) {
3177 /* A different attribute in the security namespace.
3178 Restrict to administrator. */
3179 return -EPERM;
3180 }
3181 }
3182
3183 /* Not an attribute we recognize, so just check the
3184 ordinary setattr permission. */
Eric Paris2875fa02011-04-28 16:04:24 -04003185 return dentry_has_perm(cred, dentry, FILE__SETATTR);
Serge E. Hallynb5376772007-10-16 23:31:36 -07003186}
3187
David Howells8f0cfa52008-04-29 00:59:41 -07003188static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3189 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190{
David Howellsc6f493d2015-03-17 22:26:22 +00003191 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003192 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193 struct superblock_security_struct *sbsec;
Thomas Liu2bf49692009-07-14 12:14:09 -04003194 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11003195 u32 newsid, sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196 int rc = 0;
3197
Serge E. Hallynb5376772007-10-16 23:31:36 -07003198 if (strcmp(name, XATTR_NAME_SELINUX))
3199 return selinux_inode_setotherxattr(dentry, name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200
3201 sbsec = inode->i_sb->s_security;
Eric Paris12f348b2012-10-09 10:56:25 -04003202 if (!(sbsec->flags & SBLABEL_MNT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203 return -EOPNOTSUPP;
3204
Serge E. Hallyn2e149672011-03-23 16:43:26 -07003205 if (!inode_owner_or_capable(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003206 return -EPERM;
3207
Eric Paris50c205f2012-04-04 15:01:43 -04003208 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04003209 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210
Paul Moore20cdef82016-04-04 14:14:42 -04003211 isec = backing_inode_security(dentry);
David Howells275bb412008-11-14 10:39:19 +11003212 rc = avc_has_perm(sid, isec->sid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003213 FILE__RELABELFROM, &ad);
3214 if (rc)
3215 return rc;
3216
Nikolay Aleksandrov52a4c642014-03-07 12:44:19 +01003217 rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003218 if (rc == -EINVAL) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04003219 if (!capable(CAP_MAC_ADMIN)) {
3220 struct audit_buffer *ab;
3221 size_t audit_size;
3222 const char *str;
3223
3224 /* We strip a nul only if it is at the end, otherwise the
3225 * context contains a nul and we should audit that */
Al Viroe3fea3f2012-06-09 08:15:16 +01003226 if (value) {
3227 str = value;
3228 if (str[size - 1] == '\0')
3229 audit_size = size - 1;
3230 else
3231 audit_size = size;
3232 } else {
3233 str = "";
3234 audit_size = 0;
3235 }
Eric Parisd6ea83e2012-04-04 13:45:49 -04003236 ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR);
3237 audit_log_format(ab, "op=setxattr invalid_context=");
3238 audit_log_n_untrustedstring(ab, value, audit_size);
3239 audit_log_end(ab);
3240
Stephen Smalley12b29f32008-05-07 13:03:20 -04003241 return rc;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003242 }
Stephen Smalley12b29f32008-05-07 13:03:20 -04003243 rc = security_context_to_sid_force(value, size, &newsid);
3244 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003245 if (rc)
3246 return rc;
3247
David Howells275bb412008-11-14 10:39:19 +11003248 rc = avc_has_perm(sid, newsid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003249 FILE__RELABELTO, &ad);
3250 if (rc)
3251 return rc;
3252
David Howells275bb412008-11-14 10:39:19 +11003253 rc = security_validate_transition(isec->sid, newsid, sid,
Eric Paris828dfe12008-04-17 13:17:49 -04003254 isec->sclass);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255 if (rc)
3256 return rc;
3257
3258 return avc_has_perm(newsid,
3259 sbsec->sid,
3260 SECCLASS_FILESYSTEM,
3261 FILESYSTEM__ASSOCIATE,
3262 &ad);
3263}
3264
David Howells8f0cfa52008-04-29 00:59:41 -07003265static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
Eric Parisf5269712008-05-14 11:27:45 -04003266 const void *value, size_t size,
David Howells8f0cfa52008-04-29 00:59:41 -07003267 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268{
David Howellsc6f493d2015-03-17 22:26:22 +00003269 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003270 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003271 u32 newsid;
3272 int rc;
3273
3274 if (strcmp(name, XATTR_NAME_SELINUX)) {
3275 /* Not an attribute we recognize, so nothing to do. */
3276 return;
3277 }
3278
Stephen Smalley12b29f32008-05-07 13:03:20 -04003279 rc = security_context_to_sid_force(value, size, &newsid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280 if (rc) {
Stephen Smalley12b29f32008-05-07 13:03:20 -04003281 printk(KERN_ERR "SELinux: unable to map context to SID"
3282 "for (%s, %lu), rc=%d\n",
3283 inode->i_sb->s_id, inode->i_ino, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003284 return;
3285 }
3286
Paul Moore20cdef82016-04-04 14:14:42 -04003287 isec = backing_inode_security(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003288 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003289 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003290 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003291 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003292 spin_unlock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003293
Linus Torvalds1da177e2005-04-16 15:20:36 -07003294 return;
3295}
3296
David Howells8f0cfa52008-04-29 00:59:41 -07003297static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298{
David Howells88e67f32008-11-14 10:39:21 +11003299 const struct cred *cred = current_cred();
3300
Eric Paris2875fa02011-04-28 16:04:24 -04003301 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302}
3303
Eric Paris828dfe12008-04-17 13:17:49 -04003304static int selinux_inode_listxattr(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003305{
David Howells88e67f32008-11-14 10:39:21 +11003306 const struct cred *cred = current_cred();
3307
Eric Paris2875fa02011-04-28 16:04:24 -04003308 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309}
3310
David Howells8f0cfa52008-04-29 00:59:41 -07003311static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312{
Serge E. Hallynb5376772007-10-16 23:31:36 -07003313 if (strcmp(name, XATTR_NAME_SELINUX))
3314 return selinux_inode_setotherxattr(dentry, name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003315
3316 /* No one is allowed to remove a SELinux security label.
3317 You can change the label, but all data must be labeled. */
3318 return -EACCES;
3319}
3320
James Morrisd381d8a2005-10-30 14:59:22 -08003321/*
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003322 * Copy the inode security context value to the user.
James Morrisd381d8a2005-10-30 14:59:22 -08003323 *
3324 * Permission check is handled by selinux_inode_getxattr hook.
3325 */
Andreas Gruenbacherea861df2015-12-24 11:09:39 -05003326static int selinux_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003327{
David P. Quigley42492592008-02-04 22:29:39 -08003328 u32 size;
3329 int error;
3330 char *context = NULL;
Paul Moore20cdef82016-04-04 14:14:42 -04003331 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003332
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00003333 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3334 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003335
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003336 /*
3337 * If the caller has CAP_MAC_ADMIN, then get the raw context
3338 * value even if it is not defined by current policy; otherwise,
3339 * use the in-core value under current policy.
3340 * Use the non-auditing forms of the permission checks since
3341 * getxattr may be called by unprivileged processes commonly
3342 * and lack of permission just means that we fall back to the
3343 * in-core context value, not a denial.
3344 */
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07003345 error = cap_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN,
3346 SECURITY_CAP_NOAUDIT);
3347 if (!error)
3348 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04003349 SECURITY_CAP_NOAUDIT, true);
Paul Moore20cdef82016-04-04 14:14:42 -04003350 isec = inode_security(inode);
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003351 if (!error)
3352 error = security_sid_to_context_force(isec->sid, &context,
3353 &size);
3354 else
3355 error = security_sid_to_context(isec->sid, &context, &size);
David P. Quigley42492592008-02-04 22:29:39 -08003356 if (error)
3357 return error;
3358 error = size;
3359 if (alloc) {
3360 *buffer = context;
3361 goto out_nofree;
3362 }
3363 kfree(context);
3364out_nofree:
3365 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366}
3367
3368static int selinux_inode_setsecurity(struct inode *inode, const char *name,
Eric Paris828dfe12008-04-17 13:17:49 -04003369 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003370{
Paul Moore2c971652016-04-19 16:36:28 -04003371 struct inode_security_struct *isec = inode_security_novalidate(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372 u32 newsid;
3373 int rc;
3374
3375 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3376 return -EOPNOTSUPP;
3377
3378 if (!value || !size)
3379 return -EACCES;
3380
Rasmus Villemoes20ba96a2015-10-21 17:44:26 -04003381 rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382 if (rc)
3383 return rc;
3384
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003385 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003386 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003388 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003389 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390 return 0;
3391}
3392
3393static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
3394{
3395 const int len = sizeof(XATTR_NAME_SELINUX);
3396 if (buffer && len <= buffer_size)
3397 memcpy(buffer, XATTR_NAME_SELINUX, len);
3398 return len;
3399}
3400
Andreas Gruenbacherd6335d72015-12-24 11:09:39 -05003401static void selinux_inode_getsecid(struct inode *inode, u32 *secid)
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003402{
Andreas Gruenbachere817c2f2016-02-18 12:04:08 +01003403 struct inode_security_struct *isec = inode_security_novalidate(inode);
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003404 *secid = isec->sid;
3405}
3406
Vivek Goyal56909eb2016-07-13 10:44:48 -04003407static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
3408{
3409 u32 sid;
3410 struct task_security_struct *tsec;
3411 struct cred *new_creds = *new;
3412
3413 if (new_creds == NULL) {
3414 new_creds = prepare_creds();
3415 if (!new_creds)
3416 return -ENOMEM;
3417 }
3418
3419 tsec = new_creds->security;
3420 /* Get label from overlay inode and set it in create_sid */
3421 selinux_inode_getsecid(d_inode(src), &sid);
3422 tsec->create_sid = sid;
3423 *new = new_creds;
3424 return 0;
3425}
3426
Vivek Goyal19472b62016-07-13 10:44:50 -04003427static int selinux_inode_copy_up_xattr(const char *name)
3428{
3429 /* The copy_up hook above sets the initial context on an inode, but we
3430 * don't then want to overwrite it by blindly copying all the lower
3431 * xattrs up. Instead, we have to filter out SELinux-related xattrs.
3432 */
3433 if (strcmp(name, XATTR_NAME_SELINUX) == 0)
3434 return 1; /* Discard */
3435 /*
3436 * Any other attribute apart from SELINUX is not claimed, supported
3437 * by selinux.
3438 */
3439 return -EOPNOTSUPP;
3440}
3441
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442/* file security operations */
3443
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003444static int selinux_revalidate_file_permission(struct file *file, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445{
David Howells88e67f32008-11-14 10:39:21 +11003446 const struct cred *cred = current_cred();
Al Viro496ad9a2013-01-23 17:07:38 -05003447 struct inode *inode = file_inode(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449 /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */
3450 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
3451 mask |= MAY_APPEND;
3452
Paul Moore389fb8002009-03-27 17:10:34 -04003453 return file_has_perm(cred, file,
3454 file_mask_to_av(inode->i_mode, mask));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455}
3456
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003457static int selinux_file_permission(struct file *file, int mask)
3458{
Al Viro496ad9a2013-01-23 17:07:38 -05003459 struct inode *inode = file_inode(file);
Stephen Smalley20dda182009-06-22 14:54:53 -04003460 struct file_security_struct *fsec = file->f_security;
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003461 struct inode_security_struct *isec;
Stephen Smalley20dda182009-06-22 14:54:53 -04003462 u32 sid = current_sid();
3463
Paul Moore389fb8002009-03-27 17:10:34 -04003464 if (!mask)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003465 /* No permission to check. Existence test. */
3466 return 0;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003467
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003468 isec = inode_security(inode);
Stephen Smalley20dda182009-06-22 14:54:53 -04003469 if (sid == fsec->sid && fsec->isid == isec->sid &&
3470 fsec->pseqno == avc_policy_seqno())
Eric Paris83d49852012-04-04 13:45:40 -04003471 /* No change since file_open check. */
Stephen Smalley20dda182009-06-22 14:54:53 -04003472 return 0;
3473
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003474 return selinux_revalidate_file_permission(file, mask);
3475}
3476
Linus Torvalds1da177e2005-04-16 15:20:36 -07003477static int selinux_file_alloc_security(struct file *file)
3478{
3479 return file_alloc_security(file);
3480}
3481
3482static void selinux_file_free_security(struct file *file)
3483{
3484 file_free_security(file);
3485}
3486
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003487/*
3488 * Check whether a task has the ioctl permission and cmd
3489 * operation to an inode.
3490 */
Geliang Tang1d2a1682015-10-21 17:44:27 -04003491static int ioctl_has_perm(const struct cred *cred, struct file *file,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003492 u32 requested, u16 cmd)
3493{
3494 struct common_audit_data ad;
3495 struct file_security_struct *fsec = file->f_security;
3496 struct inode *inode = file_inode(file);
Paul Moore20cdef82016-04-04 14:14:42 -04003497 struct inode_security_struct *isec;
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003498 struct lsm_ioctlop_audit ioctl;
3499 u32 ssid = cred_sid(cred);
3500 int rc;
3501 u8 driver = cmd >> 8;
3502 u8 xperm = cmd & 0xff;
3503
3504 ad.type = LSM_AUDIT_DATA_IOCTL_OP;
3505 ad.u.op = &ioctl;
3506 ad.u.op->cmd = cmd;
3507 ad.u.op->path = file->f_path;
3508
3509 if (ssid != fsec->sid) {
3510 rc = avc_has_perm(ssid, fsec->sid,
3511 SECCLASS_FD,
3512 FD__USE,
3513 &ad);
3514 if (rc)
3515 goto out;
3516 }
3517
3518 if (unlikely(IS_PRIVATE(inode)))
3519 return 0;
3520
Paul Moore20cdef82016-04-04 14:14:42 -04003521 isec = inode_security(inode);
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003522 rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass,
3523 requested, driver, xperm, &ad);
3524out:
3525 return rc;
3526}
3527
Linus Torvalds1da177e2005-04-16 15:20:36 -07003528static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3529 unsigned long arg)
3530{
David Howells88e67f32008-11-14 10:39:21 +11003531 const struct cred *cred = current_cred();
Eric Paris0b24dcb2011-02-25 15:39:20 -05003532 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003533
Eric Paris0b24dcb2011-02-25 15:39:20 -05003534 switch (cmd) {
3535 case FIONREAD:
3536 /* fall through */
3537 case FIBMAP:
3538 /* fall through */
3539 case FIGETBSZ:
3540 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003541 case FS_IOC_GETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003542 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003543 case FS_IOC_GETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003544 error = file_has_perm(cred, file, FILE__GETATTR);
3545 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546
Al Viro2f99c362012-03-23 16:04:05 -04003547 case FS_IOC_SETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003548 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003549 case FS_IOC_SETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003550 error = file_has_perm(cred, file, FILE__SETATTR);
3551 break;
3552
3553 /* sys_ioctl() checks */
3554 case FIONBIO:
3555 /* fall through */
3556 case FIOASYNC:
3557 error = file_has_perm(cred, file, 0);
3558 break;
3559
3560 case KDSKBENT:
3561 case KDSKBSENT:
Eric Paris6a9de492012-01-03 12:25:14 -05003562 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04003563 SECURITY_CAP_AUDIT, true);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003564 break;
3565
3566 /* default case assumes that the command will go
3567 * to the file's ioctl() function.
3568 */
3569 default:
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003570 error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003571 }
3572 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003573}
3574
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003575static int default_noexec;
3576
Linus Torvalds1da177e2005-04-16 15:20:36 -07003577static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
3578{
David Howells88e67f32008-11-14 10:39:21 +11003579 const struct cred *cred = current_cred();
David Howellsd84f4f92008-11-14 10:39:23 +11003580 int rc = 0;
David Howells88e67f32008-11-14 10:39:21 +11003581
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003582 if (default_noexec &&
Stephen Smalley892e8ca2015-07-10 09:40:59 -04003583 (prot & PROT_EXEC) && (!file || IS_PRIVATE(file_inode(file)) ||
3584 (!shared && (prot & PROT_WRITE)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003585 /*
3586 * We are making executable an anonymous mapping or a
3587 * private file mapping that will also be writable.
3588 * This has an additional check.
3589 */
David Howellsd84f4f92008-11-14 10:39:23 +11003590 rc = cred_has_perm(cred, cred, PROCESS__EXECMEM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003591 if (rc)
David Howellsd84f4f92008-11-14 10:39:23 +11003592 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003593 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003594
3595 if (file) {
3596 /* read access is always possible with a mapping */
3597 u32 av = FILE__READ;
3598
3599 /* write access only matters if the mapping is shared */
3600 if (shared && (prot & PROT_WRITE))
3601 av |= FILE__WRITE;
3602
3603 if (prot & PROT_EXEC)
3604 av |= FILE__EXECUTE;
3605
David Howells88e67f32008-11-14 10:39:21 +11003606 return file_has_perm(cred, file, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003607 }
David Howellsd84f4f92008-11-14 10:39:23 +11003608
3609error:
3610 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003611}
3612
Al Viroe5467852012-05-30 13:30:51 -04003613static int selinux_mmap_addr(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003614{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07003615 int rc = 0;
Paul Moore98883bf2014-03-19 16:46:11 -04003616
3617 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
3618 u32 sid = current_sid();
3619 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
3620 MEMPROTECT__MMAP_ZERO, NULL);
3621 }
3622
3623 return rc;
Al Viroe5467852012-05-30 13:30:51 -04003624}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003625
Al Viroe5467852012-05-30 13:30:51 -04003626static int selinux_mmap_file(struct file *file, unsigned long reqprot,
3627 unsigned long prot, unsigned long flags)
3628{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003629 if (selinux_checkreqprot)
3630 prot = reqprot;
3631
3632 return file_map_prot_check(file, prot,
3633 (flags & MAP_TYPE) == MAP_SHARED);
3634}
3635
3636static int selinux_file_mprotect(struct vm_area_struct *vma,
3637 unsigned long reqprot,
3638 unsigned long prot)
3639{
David Howells88e67f32008-11-14 10:39:21 +11003640 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003641
3642 if (selinux_checkreqprot)
3643 prot = reqprot;
3644
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003645 if (default_noexec &&
3646 (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
James Morrisd541bbe2009-01-29 12:19:51 +11003647 int rc = 0;
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003648 if (vma->vm_start >= vma->vm_mm->start_brk &&
3649 vma->vm_end <= vma->vm_mm->brk) {
David Howellsd84f4f92008-11-14 10:39:23 +11003650 rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003651 } else if (!vma->vm_file &&
Stephen Smalleyc2316db2016-04-08 13:55:03 -04003652 ((vma->vm_start <= vma->vm_mm->start_stack &&
3653 vma->vm_end >= vma->vm_mm->start_stack) ||
Andy Lutomirskid17af502016-09-30 10:58:58 -07003654 vma_is_stack_for_current(vma))) {
David Howells3b11a1d2008-11-14 10:39:26 +11003655 rc = current_has_perm(current, PROCESS__EXECSTACK);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003656 } else if (vma->vm_file && vma->anon_vma) {
3657 /*
3658 * We are making executable a file mapping that has
3659 * had some COW done. Since pages might have been
3660 * written, check ability to execute the possibly
3661 * modified content. This typically should only
3662 * occur for text relocations.
3663 */
David Howellsd84f4f92008-11-14 10:39:23 +11003664 rc = file_has_perm(cred, vma->vm_file, FILE__EXECMOD);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003665 }
Lorenzo Hernandez García-Hierro6b992192005-06-25 14:54:34 -07003666 if (rc)
3667 return rc;
3668 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669
3670 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
3671}
3672
3673static int selinux_file_lock(struct file *file, unsigned int cmd)
3674{
David Howells88e67f32008-11-14 10:39:21 +11003675 const struct cred *cred = current_cred();
3676
3677 return file_has_perm(cred, file, FILE__LOCK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003678}
3679
3680static int selinux_file_fcntl(struct file *file, unsigned int cmd,
3681 unsigned long arg)
3682{
David Howells88e67f32008-11-14 10:39:21 +11003683 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 int err = 0;
3685
3686 switch (cmd) {
Eric Paris828dfe12008-04-17 13:17:49 -04003687 case F_SETFL:
Eric Paris828dfe12008-04-17 13:17:49 -04003688 if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
David Howells88e67f32008-11-14 10:39:21 +11003689 err = file_has_perm(cred, file, FILE__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003691 }
3692 /* fall through */
3693 case F_SETOWN:
3694 case F_SETSIG:
3695 case F_GETFL:
3696 case F_GETOWN:
3697 case F_GETSIG:
Cyrill Gorcunov1d151c32012-07-30 14:43:00 -07003698 case F_GETOWNER_UIDS:
Eric Paris828dfe12008-04-17 13:17:49 -04003699 /* Just check FD__USE permission */
David Howells88e67f32008-11-14 10:39:21 +11003700 err = file_has_perm(cred, file, 0);
Eric Paris828dfe12008-04-17 13:17:49 -04003701 break;
3702 case F_GETLK:
3703 case F_SETLK:
3704 case F_SETLKW:
Jeff Layton0d3f7a22014-04-22 08:23:58 -04003705 case F_OFD_GETLK:
3706 case F_OFD_SETLK:
3707 case F_OFD_SETLKW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708#if BITS_PER_LONG == 32
Eric Paris828dfe12008-04-17 13:17:49 -04003709 case F_GETLK64:
3710 case F_SETLK64:
3711 case F_SETLKW64:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003712#endif
David Howells88e67f32008-11-14 10:39:21 +11003713 err = file_has_perm(cred, file, FILE__LOCK);
Eric Paris828dfe12008-04-17 13:17:49 -04003714 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715 }
3716
3717 return err;
3718}
3719
Jeff Laytone0b93ed2014-08-22 11:27:32 -04003720static void selinux_file_set_fowner(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722 struct file_security_struct *fsec;
3723
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 fsec = file->f_security;
David Howells275bb412008-11-14 10:39:19 +11003725 fsec->fown_sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003726}
3727
3728static int selinux_file_send_sigiotask(struct task_struct *tsk,
3729 struct fown_struct *fown, int signum)
3730{
Eric Paris828dfe12008-04-17 13:17:49 -04003731 struct file *file;
Stephen Smalley65c90bc2009-05-04 15:43:18 -04003732 u32 sid = task_sid(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003733 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734 struct file_security_struct *fsec;
3735
3736 /* struct fown_struct is never outside the context of a struct file */
Eric Paris828dfe12008-04-17 13:17:49 -04003737 file = container_of(fown, struct file, f_owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003738
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739 fsec = file->f_security;
3740
3741 if (!signum)
3742 perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
3743 else
3744 perm = signal_to_av(signum);
3745
David Howells275bb412008-11-14 10:39:19 +11003746 return avc_has_perm(fsec->fown_sid, sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003747 SECCLASS_PROCESS, perm, NULL);
3748}
3749
3750static int selinux_file_receive(struct file *file)
3751{
David Howells88e67f32008-11-14 10:39:21 +11003752 const struct cred *cred = current_cred();
3753
3754 return file_has_perm(cred, file, file_to_av(file));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003755}
3756
Eric Paris83d49852012-04-04 13:45:40 -04003757static int selinux_file_open(struct file *file, const struct cred *cred)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003758{
3759 struct file_security_struct *fsec;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003760 struct inode_security_struct *isec;
David Howellsd84f4f92008-11-14 10:39:23 +11003761
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003762 fsec = file->f_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003763 isec = inode_security(file_inode(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003764 /*
3765 * Save inode label and policy sequence number
3766 * at open-time so that selinux_file_permission
3767 * can determine whether revalidation is necessary.
3768 * Task label is already saved in the file security
3769 * struct as its SID.
3770 */
3771 fsec->isid = isec->sid;
3772 fsec->pseqno = avc_policy_seqno();
3773 /*
3774 * Since the inode label or policy seqno may have changed
3775 * between the selinux_inode_permission check and the saving
3776 * of state above, recheck that access is still permitted.
3777 * Otherwise, access might never be revalidated against the
3778 * new inode label or new policy.
3779 * This check is not redundant - do not remove.
3780 */
David Howells13f8e982013-06-13 23:37:55 +01003781 return file_path_has_perm(cred, file, open_file_to_av(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003782}
3783
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784/* task security operations */
3785
3786static int selinux_task_create(unsigned long clone_flags)
3787{
David Howells3b11a1d2008-11-14 10:39:26 +11003788 return current_has_perm(current, PROCESS__FORK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789}
3790
David Howellsf1752ee2008-11-14 10:39:17 +11003791/*
David Howellsee18d642009-09-02 09:14:21 +01003792 * allocate the SELinux part of blank credentials
3793 */
3794static int selinux_cred_alloc_blank(struct cred *cred, gfp_t gfp)
3795{
3796 struct task_security_struct *tsec;
3797
3798 tsec = kzalloc(sizeof(struct task_security_struct), gfp);
3799 if (!tsec)
3800 return -ENOMEM;
3801
3802 cred->security = tsec;
3803 return 0;
3804}
3805
3806/*
David Howellsf1752ee2008-11-14 10:39:17 +11003807 * detach and free the LSM part of a set of credentials
3808 */
3809static void selinux_cred_free(struct cred *cred)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003810{
David Howellsf1752ee2008-11-14 10:39:17 +11003811 struct task_security_struct *tsec = cred->security;
David Howellse0e81732009-09-02 09:13:40 +01003812
Tetsuo Handa2edeaa32011-02-07 13:36:10 +00003813 /*
3814 * cred->security == NULL if security_cred_alloc_blank() or
3815 * security_prepare_creds() returned an error.
3816 */
3817 BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE);
David Howellse0e81732009-09-02 09:13:40 +01003818 cred->security = (void *) 0x7UL;
David Howellsf1752ee2008-11-14 10:39:17 +11003819 kfree(tsec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820}
3821
David Howellsd84f4f92008-11-14 10:39:23 +11003822/*
3823 * prepare a new set of credentials for modification
3824 */
3825static int selinux_cred_prepare(struct cred *new, const struct cred *old,
3826 gfp_t gfp)
3827{
3828 const struct task_security_struct *old_tsec;
3829 struct task_security_struct *tsec;
3830
3831 old_tsec = old->security;
3832
3833 tsec = kmemdup(old_tsec, sizeof(struct task_security_struct), gfp);
3834 if (!tsec)
3835 return -ENOMEM;
3836
3837 new->security = tsec;
3838 return 0;
3839}
3840
3841/*
David Howellsee18d642009-09-02 09:14:21 +01003842 * transfer the SELinux data to a blank set of creds
3843 */
3844static void selinux_cred_transfer(struct cred *new, const struct cred *old)
3845{
3846 const struct task_security_struct *old_tsec = old->security;
3847 struct task_security_struct *tsec = new->security;
3848
3849 *tsec = *old_tsec;
3850}
3851
3852/*
David Howells3a3b7ce2008-11-14 10:39:28 +11003853 * set the security data for a kernel service
3854 * - all the creation contexts are set to unlabelled
3855 */
3856static int selinux_kernel_act_as(struct cred *new, u32 secid)
3857{
3858 struct task_security_struct *tsec = new->security;
3859 u32 sid = current_sid();
3860 int ret;
3861
3862 ret = avc_has_perm(sid, secid,
3863 SECCLASS_KERNEL_SERVICE,
3864 KERNEL_SERVICE__USE_AS_OVERRIDE,
3865 NULL);
3866 if (ret == 0) {
3867 tsec->sid = secid;
3868 tsec->create_sid = 0;
3869 tsec->keycreate_sid = 0;
3870 tsec->sockcreate_sid = 0;
3871 }
3872 return ret;
3873}
3874
3875/*
3876 * set the file creation context in a security record to the same as the
3877 * objective context of the specified inode
3878 */
3879static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3880{
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003881 struct inode_security_struct *isec = inode_security(inode);
David Howells3a3b7ce2008-11-14 10:39:28 +11003882 struct task_security_struct *tsec = new->security;
3883 u32 sid = current_sid();
3884 int ret;
3885
3886 ret = avc_has_perm(sid, isec->sid,
3887 SECCLASS_KERNEL_SERVICE,
3888 KERNEL_SERVICE__CREATE_FILES_AS,
3889 NULL);
3890
3891 if (ret == 0)
3892 tsec->create_sid = isec->sid;
David Howellsef574712010-02-26 01:56:16 +00003893 return ret;
David Howells3a3b7ce2008-11-14 10:39:28 +11003894}
3895
Eric Parisdd8dbf22009-11-03 16:35:32 +11003896static int selinux_kernel_module_request(char *kmod_name)
Eric Paris25354c42009-08-13 09:45:03 -04003897{
Eric Parisdd8dbf22009-11-03 16:35:32 +11003898 u32 sid;
3899 struct common_audit_data ad;
3900
3901 sid = task_sid(current);
3902
Eric Paris50c205f2012-04-04 15:01:43 -04003903 ad.type = LSM_AUDIT_DATA_KMOD;
Eric Parisdd8dbf22009-11-03 16:35:32 +11003904 ad.u.kmod_name = kmod_name;
3905
3906 return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM,
3907 SYSTEM__MODULE_REQUEST, &ad);
Eric Paris25354c42009-08-13 09:45:03 -04003908}
3909
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003910static int selinux_kernel_module_from_file(struct file *file)
3911{
3912 struct common_audit_data ad;
3913 struct inode_security_struct *isec;
3914 struct file_security_struct *fsec;
3915 u32 sid = current_sid();
3916 int rc;
3917
3918 /* init_module */
3919 if (file == NULL)
3920 return avc_has_perm(sid, sid, SECCLASS_SYSTEM,
3921 SYSTEM__MODULE_LOAD, NULL);
3922
3923 /* finit_module */
Paul Moore20cdef82016-04-04 14:14:42 -04003924
Vivek Goyal43af5de2016-09-09 11:37:49 -04003925 ad.type = LSM_AUDIT_DATA_FILE;
3926 ad.u.file = file;
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003927
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003928 fsec = file->f_security;
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003929 if (sid != fsec->sid) {
3930 rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
3931 if (rc)
3932 return rc;
3933 }
3934
Paul Moore20cdef82016-04-04 14:14:42 -04003935 isec = inode_security(file_inode(file));
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003936 return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
3937 SYSTEM__MODULE_LOAD, &ad);
3938}
3939
3940static int selinux_kernel_read_file(struct file *file,
3941 enum kernel_read_file_id id)
3942{
3943 int rc = 0;
3944
3945 switch (id) {
3946 case READING_MODULE:
3947 rc = selinux_kernel_module_from_file(file);
3948 break;
3949 default:
3950 break;
3951 }
3952
3953 return rc;
3954}
3955
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3957{
David Howells3b11a1d2008-11-14 10:39:26 +11003958 return current_has_perm(p, PROCESS__SETPGID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959}
3960
3961static int selinux_task_getpgid(struct task_struct *p)
3962{
David Howells3b11a1d2008-11-14 10:39:26 +11003963 return current_has_perm(p, PROCESS__GETPGID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964}
3965
3966static int selinux_task_getsid(struct task_struct *p)
3967{
David Howells3b11a1d2008-11-14 10:39:26 +11003968 return current_has_perm(p, PROCESS__GETSESSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969}
3970
David Quigleyf9008e4c2006-06-30 01:55:46 -07003971static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
3972{
David Howells275bb412008-11-14 10:39:19 +11003973 *secid = task_sid(p);
David Quigleyf9008e4c2006-06-30 01:55:46 -07003974}
3975
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976static int selinux_task_setnice(struct task_struct *p, int nice)
3977{
David Howells3b11a1d2008-11-14 10:39:26 +11003978 return current_has_perm(p, PROCESS__SETSCHED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979}
3980
James Morris03e68062006-06-23 02:03:58 -07003981static int selinux_task_setioprio(struct task_struct *p, int ioprio)
3982{
David Howells3b11a1d2008-11-14 10:39:26 +11003983 return current_has_perm(p, PROCESS__SETSCHED);
James Morris03e68062006-06-23 02:03:58 -07003984}
3985
David Quigleya1836a42006-06-30 01:55:49 -07003986static int selinux_task_getioprio(struct task_struct *p)
3987{
David Howells3b11a1d2008-11-14 10:39:26 +11003988 return current_has_perm(p, PROCESS__GETSCHED);
David Quigleya1836a42006-06-30 01:55:49 -07003989}
3990
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003991static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
3992 struct rlimit *new_rlim)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993{
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003994 struct rlimit *old_rlim = p->signal->rlim + resource;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995
3996 /* Control the ability to change the hard limit (whether
3997 lowering or raising it), so that the hard limit can
3998 later be used as a safe reset point for the soft limit
David Howellsd84f4f92008-11-14 10:39:23 +11003999 upon context transitions. See selinux_bprm_committing_creds. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004000 if (old_rlim->rlim_max != new_rlim->rlim_max)
Jiri Slaby8fd00b42009-08-26 18:41:16 +02004001 return current_has_perm(p, PROCESS__SETRLIMIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002
4003 return 0;
4004}
4005
KOSAKI Motohirob0ae1982010-10-15 04:21:18 +09004006static int selinux_task_setscheduler(struct task_struct *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007{
David Howells3b11a1d2008-11-14 10:39:26 +11004008 return current_has_perm(p, PROCESS__SETSCHED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009}
4010
4011static int selinux_task_getscheduler(struct task_struct *p)
4012{
David Howells3b11a1d2008-11-14 10:39:26 +11004013 return current_has_perm(p, PROCESS__GETSCHED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004014}
4015
David Quigley35601542006-06-23 02:04:01 -07004016static int selinux_task_movememory(struct task_struct *p)
4017{
David Howells3b11a1d2008-11-14 10:39:26 +11004018 return current_has_perm(p, PROCESS__SETSCHED);
David Quigley35601542006-06-23 02:04:01 -07004019}
4020
David Quigleyf9008e4c2006-06-30 01:55:46 -07004021static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
4022 int sig, u32 secid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004023{
4024 u32 perm;
4025 int rc;
4026
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027 if (!sig)
4028 perm = PROCESS__SIGNULL; /* null signal; existence test */
4029 else
4030 perm = signal_to_av(sig);
David Quigleyf9008e4c2006-06-30 01:55:46 -07004031 if (secid)
David Howells275bb412008-11-14 10:39:19 +11004032 rc = avc_has_perm(secid, task_sid(p),
4033 SECCLASS_PROCESS, perm, NULL);
David Quigleyf9008e4c2006-06-30 01:55:46 -07004034 else
David Howells3b11a1d2008-11-14 10:39:26 +11004035 rc = current_has_perm(p, perm);
David Quigleyf9008e4c2006-06-30 01:55:46 -07004036 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004037}
4038
Linus Torvalds1da177e2005-04-16 15:20:36 -07004039static int selinux_task_wait(struct task_struct *p)
4040{
Eric Paris8a535142007-10-22 16:10:31 -04004041 return task_has_perm(p, current, PROCESS__SIGCHLD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004042}
4043
Linus Torvalds1da177e2005-04-16 15:20:36 -07004044static void selinux_task_to_inode(struct task_struct *p,
4045 struct inode *inode)
4046{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004047 struct inode_security_struct *isec = inode->i_security;
David Howells275bb412008-11-14 10:39:19 +11004048 u32 sid = task_sid(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004050 spin_lock(&isec->lock);
Andreas Gruenbacherdb978da2016-11-10 22:18:28 +01004051 isec->sclass = inode_mode_to_security_class(inode->i_mode);
David Howells275bb412008-11-14 10:39:19 +11004052 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004053 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004054 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055}
4056
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004058static int selinux_parse_skb_ipv4(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004059 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004060{
4061 int offset, ihlen, ret = -EINVAL;
4062 struct iphdr _iph, *ih;
4063
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004064 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
4066 if (ih == NULL)
4067 goto out;
4068
4069 ihlen = ih->ihl * 4;
4070 if (ihlen < sizeof(_iph))
4071 goto out;
4072
Eric Paris48c62af2012-04-02 13:15:44 -04004073 ad->u.net->v4info.saddr = ih->saddr;
4074 ad->u.net->v4info.daddr = ih->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075 ret = 0;
4076
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004077 if (proto)
4078 *proto = ih->protocol;
4079
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080 switch (ih->protocol) {
Eric Paris828dfe12008-04-17 13:17:49 -04004081 case IPPROTO_TCP: {
4082 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004083
Eric Paris828dfe12008-04-17 13:17:49 -04004084 if (ntohs(ih->frag_off) & IP_OFFSET)
4085 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004086
4087 offset += ihlen;
4088 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4089 if (th == NULL)
4090 break;
4091
Eric Paris48c62af2012-04-02 13:15:44 -04004092 ad->u.net->sport = th->source;
4093 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004094 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004095 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004096
Eric Paris828dfe12008-04-17 13:17:49 -04004097 case IPPROTO_UDP: {
4098 struct udphdr _udph, *uh;
4099
4100 if (ntohs(ih->frag_off) & IP_OFFSET)
4101 break;
4102
4103 offset += ihlen;
4104 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4105 if (uh == NULL)
4106 break;
4107
Eric Paris48c62af2012-04-02 13:15:44 -04004108 ad->u.net->sport = uh->source;
4109 ad->u.net->dport = uh->dest;
Eric Paris828dfe12008-04-17 13:17:49 -04004110 break;
4111 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112
James Morris2ee92d42006-11-13 16:09:01 -08004113 case IPPROTO_DCCP: {
4114 struct dccp_hdr _dccph, *dh;
4115
4116 if (ntohs(ih->frag_off) & IP_OFFSET)
4117 break;
4118
4119 offset += ihlen;
4120 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4121 if (dh == NULL)
4122 break;
4123
Eric Paris48c62af2012-04-02 13:15:44 -04004124 ad->u.net->sport = dh->dccph_sport;
4125 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004126 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004127 }
James Morris2ee92d42006-11-13 16:09:01 -08004128
Eric Paris828dfe12008-04-17 13:17:49 -04004129 default:
4130 break;
4131 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004132out:
4133 return ret;
4134}
4135
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004136#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137
4138/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004139static int selinux_parse_skb_ipv6(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004140 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004141{
4142 u8 nexthdr;
4143 int ret = -EINVAL, offset;
4144 struct ipv6hdr _ipv6h, *ip6;
Jesse Gross75f28112011-11-30 17:05:51 -08004145 __be16 frag_off;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004146
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004147 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
4149 if (ip6 == NULL)
4150 goto out;
4151
Eric Paris48c62af2012-04-02 13:15:44 -04004152 ad->u.net->v6info.saddr = ip6->saddr;
4153 ad->u.net->v6info.daddr = ip6->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004154 ret = 0;
4155
4156 nexthdr = ip6->nexthdr;
4157 offset += sizeof(_ipv6h);
Jesse Gross75f28112011-11-30 17:05:51 -08004158 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159 if (offset < 0)
4160 goto out;
4161
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004162 if (proto)
4163 *proto = nexthdr;
4164
Linus Torvalds1da177e2005-04-16 15:20:36 -07004165 switch (nexthdr) {
4166 case IPPROTO_TCP: {
Eric Paris828dfe12008-04-17 13:17:49 -04004167 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004168
4169 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4170 if (th == NULL)
4171 break;
4172
Eric Paris48c62af2012-04-02 13:15:44 -04004173 ad->u.net->sport = th->source;
4174 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175 break;
4176 }
4177
4178 case IPPROTO_UDP: {
4179 struct udphdr _udph, *uh;
4180
4181 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4182 if (uh == NULL)
4183 break;
4184
Eric Paris48c62af2012-04-02 13:15:44 -04004185 ad->u.net->sport = uh->source;
4186 ad->u.net->dport = uh->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004187 break;
4188 }
4189
James Morris2ee92d42006-11-13 16:09:01 -08004190 case IPPROTO_DCCP: {
4191 struct dccp_hdr _dccph, *dh;
4192
4193 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4194 if (dh == NULL)
4195 break;
4196
Eric Paris48c62af2012-04-02 13:15:44 -04004197 ad->u.net->sport = dh->dccph_sport;
4198 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004199 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004200 }
James Morris2ee92d42006-11-13 16:09:01 -08004201
Linus Torvalds1da177e2005-04-16 15:20:36 -07004202 /* includes fragments */
4203 default:
4204 break;
4205 }
4206out:
4207 return ret;
4208}
4209
4210#endif /* IPV6 */
4211
Thomas Liu2bf49692009-07-14 12:14:09 -04004212static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
David Howellscf9481e2008-07-27 21:31:07 +10004213 char **_addrp, int src, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214{
David Howellscf9481e2008-07-27 21:31:07 +10004215 char *addrp;
4216 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217
Eric Paris48c62af2012-04-02 13:15:44 -04004218 switch (ad->u.net->family) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219 case PF_INET:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004220 ret = selinux_parse_skb_ipv4(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004221 if (ret)
4222 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004223 addrp = (char *)(src ? &ad->u.net->v4info.saddr :
4224 &ad->u.net->v4info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004225 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004226
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004227#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228 case PF_INET6:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004229 ret = selinux_parse_skb_ipv6(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004230 if (ret)
4231 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004232 addrp = (char *)(src ? &ad->u.net->v6info.saddr :
4233 &ad->u.net->v6info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004234 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004235#endif /* IPV6 */
4236 default:
David Howellscf9481e2008-07-27 21:31:07 +10004237 addrp = NULL;
4238 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239 }
4240
David Howellscf9481e2008-07-27 21:31:07 +10004241parse_error:
4242 printk(KERN_WARNING
4243 "SELinux: failure in selinux_parse_skb(),"
4244 " unable to parse packet\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004245 return ret;
David Howellscf9481e2008-07-27 21:31:07 +10004246
4247okay:
4248 if (_addrp)
4249 *_addrp = addrp;
4250 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251}
4252
Paul Moore4f6a9932007-03-01 14:35:22 -05004253/**
Paul Moore220deb92008-01-29 08:38:23 -05004254 * selinux_skb_peerlbl_sid - Determine the peer label of a packet
Paul Moore4f6a9932007-03-01 14:35:22 -05004255 * @skb: the packet
Paul Moore75e22912008-01-29 08:38:04 -05004256 * @family: protocol family
Paul Moore220deb92008-01-29 08:38:23 -05004257 * @sid: the packet's peer label SID
Paul Moore4f6a9932007-03-01 14:35:22 -05004258 *
4259 * Description:
Paul Moore220deb92008-01-29 08:38:23 -05004260 * Check the various different forms of network peer labeling and determine
4261 * the peer label/SID for the packet; most of the magic actually occurs in
4262 * the security server function security_net_peersid_cmp(). The function
4263 * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
4264 * or -EACCES if @sid is invalid due to inconsistencies with the different
4265 * peer labels.
Paul Moore4f6a9932007-03-01 14:35:22 -05004266 *
4267 */
Paul Moore220deb92008-01-29 08:38:23 -05004268static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
Paul Moore4f6a9932007-03-01 14:35:22 -05004269{
Paul Moore71f1cb02008-01-29 08:51:16 -05004270 int err;
Paul Moore4f6a9932007-03-01 14:35:22 -05004271 u32 xfrm_sid;
4272 u32 nlbl_sid;
Paul Moore220deb92008-01-29 08:38:23 -05004273 u32 nlbl_type;
Paul Moore4f6a9932007-03-01 14:35:22 -05004274
Paul Moore817eff72013-12-10 14:57:54 -05004275 err = selinux_xfrm_skb_sid(skb, &xfrm_sid);
Paul Moorebed4d7e2013-07-23 17:38:40 -04004276 if (unlikely(err))
4277 return -EACCES;
4278 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
4279 if (unlikely(err))
4280 return -EACCES;
Paul Moore220deb92008-01-29 08:38:23 -05004281
Paul Moore71f1cb02008-01-29 08:51:16 -05004282 err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
4283 if (unlikely(err)) {
4284 printk(KERN_WARNING
4285 "SELinux: failure in selinux_skb_peerlbl_sid(),"
4286 " unable to determine packet's peer label\n");
Paul Moore220deb92008-01-29 08:38:23 -05004287 return -EACCES;
Paul Moore71f1cb02008-01-29 08:51:16 -05004288 }
Paul Moore220deb92008-01-29 08:38:23 -05004289
4290 return 0;
Paul Moore4f6a9932007-03-01 14:35:22 -05004291}
4292
Paul Moore446b8022013-12-04 16:10:51 -05004293/**
4294 * selinux_conn_sid - Determine the child socket label for a connection
4295 * @sk_sid: the parent socket's SID
4296 * @skb_sid: the packet's SID
4297 * @conn_sid: the resulting connection SID
4298 *
4299 * If @skb_sid is valid then the user:role:type information from @sk_sid is
4300 * combined with the MLS information from @skb_sid in order to create
4301 * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy
4302 * of @sk_sid. Returns zero on success, negative values on failure.
4303 *
4304 */
4305static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
4306{
4307 int err = 0;
4308
4309 if (skb_sid != SECSID_NULL)
4310 err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid);
4311 else
4312 *conn_sid = sk_sid;
4313
4314 return err;
4315}
4316
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317/* socket security operations */
Paul Moored4f2d972010-04-22 14:46:18 -04004318
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004319static int socket_sockcreate_sid(const struct task_security_struct *tsec,
4320 u16 secclass, u32 *socksid)
Paul Moored4f2d972010-04-22 14:46:18 -04004321{
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004322 if (tsec->sockcreate_sid > SECSID_NULL) {
4323 *socksid = tsec->sockcreate_sid;
4324 return 0;
4325 }
4326
4327 return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL,
4328 socksid);
Paul Moored4f2d972010-04-22 14:46:18 -04004329}
4330
Paul Moore253bfae2010-04-22 14:46:19 -04004331static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332{
Paul Moore253bfae2010-04-22 14:46:19 -04004333 struct sk_security_struct *sksec = sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004334 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004335 struct lsm_network_audit net = {0,};
Paul Moore253bfae2010-04-22 14:46:19 -04004336 u32 tsid = task_sid(task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337
Paul Moore253bfae2010-04-22 14:46:19 -04004338 if (sksec->sid == SECINITSID_KERNEL)
4339 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340
Eric Paris50c205f2012-04-04 15:01:43 -04004341 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004342 ad.u.net = &net;
4343 ad.u.net->sk = sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344
Paul Moore253bfae2010-04-22 14:46:19 -04004345 return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004346}
4347
4348static int selinux_socket_create(int family, int type,
4349 int protocol, int kern)
4350{
Paul Moore5fb49872010-04-22 14:46:19 -04004351 const struct task_security_struct *tsec = current_security();
Paul Moored4f2d972010-04-22 14:46:18 -04004352 u32 newsid;
David Howells275bb412008-11-14 10:39:19 +11004353 u16 secclass;
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004354 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004355
4356 if (kern)
Paul Moored4f2d972010-04-22 14:46:18 -04004357 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358
David Howells275bb412008-11-14 10:39:19 +11004359 secclass = socket_type_to_security_class(family, type, protocol);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004360 rc = socket_sockcreate_sid(tsec, secclass, &newsid);
4361 if (rc)
4362 return rc;
4363
Paul Moored4f2d972010-04-22 14:46:18 -04004364 return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004365}
4366
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004367static int selinux_socket_post_create(struct socket *sock, int family,
4368 int type, int protocol, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369{
Paul Moore5fb49872010-04-22 14:46:19 -04004370 const struct task_security_struct *tsec = current_security();
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004371 struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock));
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004372 struct sk_security_struct *sksec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004373 u16 sclass = socket_type_to_security_class(family, type, protocol);
4374 u32 sid = SECINITSID_KERNEL;
David Howells275bb412008-11-14 10:39:19 +11004375 int err = 0;
4376
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004377 if (!kern) {
4378 err = socket_sockcreate_sid(tsec, sclass, &sid);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004379 if (err)
4380 return err;
4381 }
David Howells275bb412008-11-14 10:39:19 +11004382
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004383 isec->sclass = sclass;
4384 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004385 isec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004386
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004387 if (sock->sk) {
4388 sksec = sock->sk->sk_security;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004389 sksec->sclass = sclass;
4390 sksec->sid = sid;
Paul Moore389fb8002009-03-27 17:10:34 -04004391 err = selinux_netlbl_socket_post_create(sock->sk, family);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004392 }
4393
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004394 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004395}
4396
4397/* Range of port numbers used to automatically bind.
4398 Need to determine whether we should perform a name_bind
4399 permission check between the socket and the port number. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004400
4401static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
4402{
Paul Moore253bfae2010-04-22 14:46:19 -04004403 struct sock *sk = sock->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004404 u16 family;
4405 int err;
4406
Paul Moore253bfae2010-04-22 14:46:19 -04004407 err = sock_has_perm(current, sk, SOCKET__BIND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408 if (err)
4409 goto out;
4410
4411 /*
4412 * If PF_INET or PF_INET6, check name_bind permission for the port.
James Morris13402582005-09-30 14:24:34 -04004413 * Multiple address binding for SCTP is not supported yet: we just
4414 * check the first address now.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004415 */
Paul Moore253bfae2010-04-22 14:46:19 -04004416 family = sk->sk_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004417 if (family == PF_INET || family == PF_INET6) {
4418 char *addrp;
Paul Moore253bfae2010-04-22 14:46:19 -04004419 struct sk_security_struct *sksec = sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004420 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004421 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004422 struct sockaddr_in *addr4 = NULL;
4423 struct sockaddr_in6 *addr6 = NULL;
4424 unsigned short snum;
James Morrise399f982008-06-12 01:39:58 +10004425 u32 sid, node_perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004426
Linus Torvalds1da177e2005-04-16 15:20:36 -07004427 if (family == PF_INET) {
4428 addr4 = (struct sockaddr_in *)address;
4429 snum = ntohs(addr4->sin_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004430 addrp = (char *)&addr4->sin_addr.s_addr;
4431 } else {
4432 addr6 = (struct sockaddr_in6 *)address;
4433 snum = ntohs(addr6->sin6_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004434 addrp = (char *)&addr6->sin6_addr.s6_addr;
4435 }
4436
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004437 if (snum) {
4438 int low, high;
4439
Eric W. Biederman0bbf87d2013-09-28 14:10:59 -07004440 inet_get_local_port_range(sock_net(sk), &low, &high);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004441
4442 if (snum < max(PROT_SOCK, low) || snum > high) {
Paul Moore3e1121722008-04-10 10:48:14 -04004443 err = sel_netport_sid(sk->sk_protocol,
4444 snum, &sid);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004445 if (err)
4446 goto out;
Eric Paris50c205f2012-04-04 15:01:43 -04004447 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004448 ad.u.net = &net;
4449 ad.u.net->sport = htons(snum);
4450 ad.u.net->family = family;
Paul Moore253bfae2010-04-22 14:46:19 -04004451 err = avc_has_perm(sksec->sid, sid,
4452 sksec->sclass,
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004453 SOCKET__NAME_BIND, &ad);
4454 if (err)
4455 goto out;
4456 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457 }
Eric Paris828dfe12008-04-17 13:17:49 -04004458
Paul Moore253bfae2010-04-22 14:46:19 -04004459 switch (sksec->sclass) {
James Morris13402582005-09-30 14:24:34 -04004460 case SECCLASS_TCP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004461 node_perm = TCP_SOCKET__NODE_BIND;
4462 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004463
James Morris13402582005-09-30 14:24:34 -04004464 case SECCLASS_UDP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465 node_perm = UDP_SOCKET__NODE_BIND;
4466 break;
James Morris2ee92d42006-11-13 16:09:01 -08004467
4468 case SECCLASS_DCCP_SOCKET:
4469 node_perm = DCCP_SOCKET__NODE_BIND;
4470 break;
4471
Linus Torvalds1da177e2005-04-16 15:20:36 -07004472 default:
4473 node_perm = RAWIP_SOCKET__NODE_BIND;
4474 break;
4475 }
Eric Paris828dfe12008-04-17 13:17:49 -04004476
Paul Moore224dfbd2008-01-29 08:38:13 -05004477 err = sel_netnode_sid(addrp, family, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004478 if (err)
4479 goto out;
Eric Paris828dfe12008-04-17 13:17:49 -04004480
Eric Paris50c205f2012-04-04 15:01:43 -04004481 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004482 ad.u.net = &net;
4483 ad.u.net->sport = htons(snum);
4484 ad.u.net->family = family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485
4486 if (family == PF_INET)
Eric Paris48c62af2012-04-02 13:15:44 -04004487 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004488 else
Eric Paris48c62af2012-04-02 13:15:44 -04004489 ad.u.net->v6info.saddr = addr6->sin6_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004490
Paul Moore253bfae2010-04-22 14:46:19 -04004491 err = avc_has_perm(sksec->sid, sid,
4492 sksec->sclass, node_perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004493 if (err)
4494 goto out;
4495 }
4496out:
4497 return err;
4498}
4499
4500static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
4501{
Paul Moore014ab192008-10-10 10:16:33 -04004502 struct sock *sk = sock->sk;
Paul Moore253bfae2010-04-22 14:46:19 -04004503 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004504 int err;
4505
Paul Moore253bfae2010-04-22 14:46:19 -04004506 err = sock_has_perm(current, sk, SOCKET__CONNECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004507 if (err)
4508 return err;
4509
4510 /*
James Morris2ee92d42006-11-13 16:09:01 -08004511 * If a TCP or DCCP socket, check name_connect permission for the port.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004512 */
Paul Moore253bfae2010-04-22 14:46:19 -04004513 if (sksec->sclass == SECCLASS_TCP_SOCKET ||
4514 sksec->sclass == SECCLASS_DCCP_SOCKET) {
Thomas Liu2bf49692009-07-14 12:14:09 -04004515 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004516 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004517 struct sockaddr_in *addr4 = NULL;
4518 struct sockaddr_in6 *addr6 = NULL;
4519 unsigned short snum;
James Morris2ee92d42006-11-13 16:09:01 -08004520 u32 sid, perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004521
4522 if (sk->sk_family == PF_INET) {
4523 addr4 = (struct sockaddr_in *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004524 if (addrlen < sizeof(struct sockaddr_in))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004525 return -EINVAL;
4526 snum = ntohs(addr4->sin_port);
4527 } else {
4528 addr6 = (struct sockaddr_in6 *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004529 if (addrlen < SIN6_LEN_RFC2133)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004530 return -EINVAL;
4531 snum = ntohs(addr6->sin6_port);
4532 }
4533
Paul Moore3e1121722008-04-10 10:48:14 -04004534 err = sel_netport_sid(sk->sk_protocol, snum, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535 if (err)
4536 goto out;
4537
Paul Moore253bfae2010-04-22 14:46:19 -04004538 perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ?
James Morris2ee92d42006-11-13 16:09:01 -08004539 TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
4540
Eric Paris50c205f2012-04-04 15:01:43 -04004541 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004542 ad.u.net = &net;
4543 ad.u.net->dport = htons(snum);
4544 ad.u.net->family = sk->sk_family;
Paul Moore253bfae2010-04-22 14:46:19 -04004545 err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546 if (err)
4547 goto out;
4548 }
4549
Paul Moore014ab192008-10-10 10:16:33 -04004550 err = selinux_netlbl_socket_connect(sk, address);
4551
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552out:
4553 return err;
4554}
4555
4556static int selinux_socket_listen(struct socket *sock, int backlog)
4557{
Paul Moore253bfae2010-04-22 14:46:19 -04004558 return sock_has_perm(current, sock->sk, SOCKET__LISTEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004559}
4560
4561static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
4562{
4563 int err;
4564 struct inode_security_struct *isec;
4565 struct inode_security_struct *newisec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004566 u16 sclass;
4567 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004568
Paul Moore253bfae2010-04-22 14:46:19 -04004569 err = sock_has_perm(current, sock->sk, SOCKET__ACCEPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570 if (err)
4571 return err;
4572
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004573 isec = inode_security_novalidate(SOCK_INODE(sock));
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004574 spin_lock(&isec->lock);
4575 sclass = isec->sclass;
4576 sid = isec->sid;
4577 spin_unlock(&isec->lock);
4578
4579 newisec = inode_security_novalidate(SOCK_INODE(newsock));
4580 newisec->sclass = sclass;
4581 newisec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004582 newisec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583
4584 return 0;
4585}
4586
4587static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
Eric Paris828dfe12008-04-17 13:17:49 -04004588 int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004589{
Paul Moore253bfae2010-04-22 14:46:19 -04004590 return sock_has_perm(current, sock->sk, SOCKET__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004591}
4592
4593static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
4594 int size, int flags)
4595{
Paul Moore253bfae2010-04-22 14:46:19 -04004596 return sock_has_perm(current, sock->sk, SOCKET__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597}
4598
4599static int selinux_socket_getsockname(struct socket *sock)
4600{
Paul Moore253bfae2010-04-22 14:46:19 -04004601 return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602}
4603
4604static int selinux_socket_getpeername(struct socket *sock)
4605{
Paul Moore253bfae2010-04-22 14:46:19 -04004606 return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004607}
4608
Eric Paris828dfe12008-04-17 13:17:49 -04004609static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004610{
Paul Mooref8687af2006-10-30 15:22:15 -08004611 int err;
4612
Paul Moore253bfae2010-04-22 14:46:19 -04004613 err = sock_has_perm(current, sock->sk, SOCKET__SETOPT);
Paul Mooref8687af2006-10-30 15:22:15 -08004614 if (err)
4615 return err;
4616
4617 return selinux_netlbl_socket_setsockopt(sock, level, optname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618}
4619
4620static int selinux_socket_getsockopt(struct socket *sock, int level,
4621 int optname)
4622{
Paul Moore253bfae2010-04-22 14:46:19 -04004623 return sock_has_perm(current, sock->sk, SOCKET__GETOPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004624}
4625
4626static int selinux_socket_shutdown(struct socket *sock, int how)
4627{
Paul Moore253bfae2010-04-22 14:46:19 -04004628 return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004629}
4630
David S. Miller3610cda2011-01-05 15:38:53 -08004631static int selinux_socket_unix_stream_connect(struct sock *sock,
4632 struct sock *other,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004633 struct sock *newsk)
4634{
David S. Miller3610cda2011-01-05 15:38:53 -08004635 struct sk_security_struct *sksec_sock = sock->sk_security;
4636 struct sk_security_struct *sksec_other = other->sk_security;
Paul Moore4d1e2452010-04-22 14:46:18 -04004637 struct sk_security_struct *sksec_new = newsk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004638 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004639 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004640 int err;
4641
Eric Paris50c205f2012-04-04 15:01:43 -04004642 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004643 ad.u.net = &net;
4644 ad.u.net->sk = other;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004645
Paul Moore4d1e2452010-04-22 14:46:18 -04004646 err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
4647 sksec_other->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004648 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
4649 if (err)
4650 return err;
4651
Linus Torvalds1da177e2005-04-16 15:20:36 -07004652 /* server child socket */
Paul Moore4d1e2452010-04-22 14:46:18 -04004653 sksec_new->peer_sid = sksec_sock->sid;
4654 err = security_sid_mls_copy(sksec_other->sid, sksec_sock->sid,
4655 &sksec_new->sid);
4656 if (err)
4657 return err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004658
Paul Moore4d1e2452010-04-22 14:46:18 -04004659 /* connecting socket */
4660 sksec_sock->peer_sid = sksec_new->sid;
4661
4662 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004663}
4664
4665static int selinux_socket_unix_may_send(struct socket *sock,
4666 struct socket *other)
4667{
Paul Moore253bfae2010-04-22 14:46:19 -04004668 struct sk_security_struct *ssec = sock->sk->sk_security;
4669 struct sk_security_struct *osec = other->sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004670 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004671 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004672
Eric Paris50c205f2012-04-04 15:01:43 -04004673 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004674 ad.u.net = &net;
4675 ad.u.net->sk = other->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004676
Paul Moore253bfae2010-04-22 14:46:19 -04004677 return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
4678 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004679}
4680
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004681static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
4682 char *addrp, u16 family, u32 peer_sid,
Thomas Liu2bf49692009-07-14 12:14:09 -04004683 struct common_audit_data *ad)
Paul Mooreeffad8d2008-01-29 08:49:27 -05004684{
4685 int err;
4686 u32 if_sid;
4687 u32 node_sid;
4688
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004689 err = sel_netif_sid(ns, ifindex, &if_sid);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004690 if (err)
4691 return err;
4692 err = avc_has_perm(peer_sid, if_sid,
4693 SECCLASS_NETIF, NETIF__INGRESS, ad);
4694 if (err)
4695 return err;
4696
4697 err = sel_netnode_sid(addrp, family, &node_sid);
4698 if (err)
4699 return err;
4700 return avc_has_perm(peer_sid, node_sid,
4701 SECCLASS_NODE, NODE__RECVFROM, ad);
4702}
4703
Paul Moore220deb92008-01-29 08:38:23 -05004704static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
Paul Moored8395c82008-10-10 10:16:30 -04004705 u16 family)
Paul Moore220deb92008-01-29 08:38:23 -05004706{
Paul Moore277d3422008-12-31 12:54:11 -05004707 int err = 0;
Paul Moore220deb92008-01-29 08:38:23 -05004708 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004709 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004710 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004711 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04004712 char *addrp;
4713
Eric Paris50c205f2012-04-04 15:01:43 -04004714 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004715 ad.u.net = &net;
4716 ad.u.net->netif = skb->skb_iif;
4717 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04004718 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
4719 if (err)
4720 return err;
Paul Moore220deb92008-01-29 08:38:23 -05004721
Paul Moore58bfbb52009-03-27 17:10:41 -04004722 if (selinux_secmark_enabled()) {
Paul Moore220deb92008-01-29 08:38:23 -05004723 err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Moored8395c82008-10-10 10:16:30 -04004724 PACKET__RECV, &ad);
Paul Moore58bfbb52009-03-27 17:10:41 -04004725 if (err)
4726 return err;
4727 }
Paul Moore220deb92008-01-29 08:38:23 -05004728
Steffen Klassertb9679a72011-02-23 12:55:21 +01004729 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4730 if (err)
4731 return err;
4732 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004733
James Morris4e5ab4c2006-06-09 00:33:33 -07004734 return err;
4735}
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004736
James Morris4e5ab4c2006-06-09 00:33:33 -07004737static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4738{
Paul Moore220deb92008-01-29 08:38:23 -05004739 int err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004740 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004741 u16 family = sk->sk_family;
4742 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004743 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004744 struct lsm_network_audit net = {0,};
Paul Moore220deb92008-01-29 08:38:23 -05004745 char *addrp;
Paul Moored8395c82008-10-10 10:16:30 -04004746 u8 secmark_active;
4747 u8 peerlbl_active;
James Morris4e5ab4c2006-06-09 00:33:33 -07004748
James Morris4e5ab4c2006-06-09 00:33:33 -07004749 if (family != PF_INET && family != PF_INET6)
Paul Moore220deb92008-01-29 08:38:23 -05004750 return 0;
James Morris4e5ab4c2006-06-09 00:33:33 -07004751
4752 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
Al Viro87fcd702006-12-04 22:00:55 +00004753 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
James Morris4e5ab4c2006-06-09 00:33:33 -07004754 family = PF_INET;
4755
Paul Moored8395c82008-10-10 10:16:30 -04004756 /* If any sort of compatibility mode is enabled then handoff processing
4757 * to the selinux_sock_rcv_skb_compat() function to deal with the
4758 * special handling. We do this in an attempt to keep this function
4759 * as fast and as clean as possible. */
Paul Moore58bfbb52009-03-27 17:10:41 -04004760 if (!selinux_policycap_netpeer)
Paul Moored8395c82008-10-10 10:16:30 -04004761 return selinux_sock_rcv_skb_compat(sk, skb, family);
4762
4763 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04004764 peerlbl_active = selinux_peerlbl_enabled();
Paul Moored8395c82008-10-10 10:16:30 -04004765 if (!secmark_active && !peerlbl_active)
4766 return 0;
4767
Eric Paris50c205f2012-04-04 15:01:43 -04004768 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004769 ad.u.net = &net;
4770 ad.u.net->netif = skb->skb_iif;
4771 ad.u.net->family = family;
Paul Moore224dfbd2008-01-29 08:38:13 -05004772 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
James Morris4e5ab4c2006-06-09 00:33:33 -07004773 if (err)
Paul Moore220deb92008-01-29 08:38:23 -05004774 return err;
James Morris4e5ab4c2006-06-09 00:33:33 -07004775
Paul Moored8395c82008-10-10 10:16:30 -04004776 if (peerlbl_active) {
Paul Moored621d352008-01-29 08:43:36 -05004777 u32 peer_sid;
4778
4779 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
4780 if (err)
4781 return err;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004782 err = selinux_inet_sys_rcv_skb(sock_net(sk), skb->skb_iif,
4783 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04004784 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004785 selinux_netlbl_err(skb, family, err, 0);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004786 return err;
Paul Mooredfaebe92008-10-10 10:16:31 -04004787 }
Paul Moored621d352008-01-29 08:43:36 -05004788 err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
4789 PEER__RECV, &ad);
Chad Hanson46d01d62013-12-23 17:45:01 -05004790 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004791 selinux_netlbl_err(skb, family, err, 0);
Chad Hanson46d01d62013-12-23 17:45:01 -05004792 return err;
4793 }
Paul Moored621d352008-01-29 08:43:36 -05004794 }
4795
Paul Moored8395c82008-10-10 10:16:30 -04004796 if (secmark_active) {
Paul Mooreeffad8d2008-01-29 08:49:27 -05004797 err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
4798 PACKET__RECV, &ad);
4799 if (err)
4800 return err;
4801 }
4802
Paul Moored621d352008-01-29 08:43:36 -05004803 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004804}
4805
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004806static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
4807 int __user *optlen, unsigned len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004808{
4809 int err = 0;
4810 char *scontext;
4811 u32 scontext_len;
Paul Moore253bfae2010-04-22 14:46:19 -04004812 struct sk_security_struct *sksec = sock->sk->sk_security;
Paul Moore3de4bab2006-11-17 17:38:54 -05004813 u32 peer_sid = SECSID_NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004814
Paul Moore253bfae2010-04-22 14:46:19 -04004815 if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
4816 sksec->sclass == SECCLASS_TCP_SOCKET)
Eric Parisdd3e7832010-04-07 15:08:46 -04004817 peer_sid = sksec->peer_sid;
Paul Moore253bfae2010-04-22 14:46:19 -04004818 if (peer_sid == SECSID_NULL)
4819 return -ENOPROTOOPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004820
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004821 err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004822 if (err)
Paul Moore253bfae2010-04-22 14:46:19 -04004823 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004824
4825 if (scontext_len > len) {
4826 err = -ERANGE;
4827 goto out_len;
4828 }
4829
4830 if (copy_to_user(optval, scontext, scontext_len))
4831 err = -EFAULT;
4832
4833out_len:
4834 if (put_user(scontext_len, optlen))
4835 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004836 kfree(scontext);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004837 return err;
4838}
4839
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004840static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004841{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004842 u32 peer_secid = SECSID_NULL;
Paul Moore75e22912008-01-29 08:38:04 -05004843 u16 family;
Paul Moore899134f2016-03-28 15:19:10 -04004844 struct inode_security_struct *isec;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07004845
Paul Mooreaa862902008-10-10 10:16:29 -04004846 if (skb && skb->protocol == htons(ETH_P_IP))
4847 family = PF_INET;
4848 else if (skb && skb->protocol == htons(ETH_P_IPV6))
4849 family = PF_INET6;
4850 else if (sock)
Paul Moore75e22912008-01-29 08:38:04 -05004851 family = sock->sk->sk_family;
Paul Moore75e22912008-01-29 08:38:04 -05004852 else
4853 goto out;
4854
Paul Moore899134f2016-03-28 15:19:10 -04004855 if (sock && family == PF_UNIX) {
4856 isec = inode_security_novalidate(SOCK_INODE(sock));
4857 peer_secid = isec->sid;
4858 } else if (skb)
Paul Moore220deb92008-01-29 08:38:23 -05004859 selinux_skb_peerlbl_sid(skb, family, &peer_secid);
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004860
Paul Moore75e22912008-01-29 08:38:04 -05004861out:
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004862 *secid = peer_secid;
Paul Moore75e22912008-01-29 08:38:04 -05004863 if (peer_secid == SECSID_NULL)
4864 return -EINVAL;
4865 return 0;
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004866}
4867
Al Viro7d877f32005-10-21 03:20:43 -04004868static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004869{
Paul Moore84914b72010-04-22 14:46:18 -04004870 struct sk_security_struct *sksec;
4871
4872 sksec = kzalloc(sizeof(*sksec), priority);
4873 if (!sksec)
4874 return -ENOMEM;
4875
4876 sksec->peer_sid = SECINITSID_UNLABELED;
4877 sksec->sid = SECINITSID_UNLABELED;
Stephen Smalley5dee25d2015-07-10 17:19:57 -04004878 sksec->sclass = SECCLASS_SOCKET;
Paul Moore84914b72010-04-22 14:46:18 -04004879 selinux_netlbl_sk_security_reset(sksec);
4880 sk->sk_security = sksec;
4881
4882 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004883}
4884
4885static void selinux_sk_free_security(struct sock *sk)
4886{
Paul Moore84914b72010-04-22 14:46:18 -04004887 struct sk_security_struct *sksec = sk->sk_security;
4888
4889 sk->sk_security = NULL;
4890 selinux_netlbl_sk_security_free(sksec);
4891 kfree(sksec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004892}
4893
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004894static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
4895{
Eric Parisdd3e7832010-04-07 15:08:46 -04004896 struct sk_security_struct *sksec = sk->sk_security;
4897 struct sk_security_struct *newsksec = newsk->sk_security;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004898
Eric Parisdd3e7832010-04-07 15:08:46 -04004899 newsksec->sid = sksec->sid;
4900 newsksec->peer_sid = sksec->peer_sid;
4901 newsksec->sclass = sksec->sclass;
Paul Moore99f59ed2006-08-29 17:53:48 -07004902
Eric Parisdd3e7832010-04-07 15:08:46 -04004903 selinux_netlbl_sk_security_reset(newsksec);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004904}
4905
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004906static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004907{
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004908 if (!sk)
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004909 *secid = SECINITSID_ANY_SOCKET;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004910 else {
4911 struct sk_security_struct *sksec = sk->sk_security;
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004912
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004913 *secid = sksec->sid;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004914 }
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004915}
4916
Eric Paris828dfe12008-04-17 13:17:49 -04004917static void selinux_sock_graft(struct sock *sk, struct socket *parent)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004918{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004919 struct inode_security_struct *isec =
4920 inode_security_novalidate(SOCK_INODE(parent));
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004921 struct sk_security_struct *sksec = sk->sk_security;
4922
Paul Moore2873ead2014-07-28 10:42:48 -04004923 if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
4924 sk->sk_family == PF_UNIX)
David Woodhouse2148ccc2006-09-29 15:50:25 -07004925 isec->sid = sksec->sid;
Paul Moore220deb92008-01-29 08:38:23 -05004926 sksec->sclass = isec->sclass;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004927}
4928
Adrian Bunk9a673e52006-08-15 00:03:53 -07004929static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4930 struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004931{
4932 struct sk_security_struct *sksec = sk->sk_security;
4933 int err;
Paul Moore0b1f24e2013-12-03 11:39:13 -05004934 u16 family = req->rsk_ops->family;
Paul Moore446b8022013-12-04 16:10:51 -05004935 u32 connsid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004936 u32 peersid;
4937
Paul Mooreaa862902008-10-10 10:16:29 -04004938 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
Paul Moore220deb92008-01-29 08:38:23 -05004939 if (err)
4940 return err;
Paul Moore446b8022013-12-04 16:10:51 -05004941 err = selinux_conn_sid(sksec->sid, peersid, &connsid);
4942 if (err)
4943 return err;
4944 req->secid = connsid;
4945 req->peer_secid = peersid;
Venkat Yekkiralaa51c64f2006-07-27 22:01:34 -07004946
Paul Moore389fb8002009-03-27 17:10:34 -04004947 return selinux_netlbl_inet_conn_request(req, family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004948}
4949
Adrian Bunk9a673e52006-08-15 00:03:53 -07004950static void selinux_inet_csk_clone(struct sock *newsk,
4951 const struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004952{
4953 struct sk_security_struct *newsksec = newsk->sk_security;
4954
4955 newsksec->sid = req->secid;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06004956 newsksec->peer_sid = req->peer_secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004957 /* NOTE: Ideally, we should also get the isec->sid for the
4958 new socket in sync, but we don't have the isec available yet.
4959 So we will wait until sock_graft to do it, by which
4960 time it will have been created and available. */
Paul Moore99f59ed2006-08-29 17:53:48 -07004961
Paul Moore9f2ad662006-11-17 17:38:53 -05004962 /* We don't need to take any sort of lock here as we are the only
4963 * thread with access to newsksec */
Paul Moore389fb8002009-03-27 17:10:34 -04004964 selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004965}
4966
Paul Moore014ab192008-10-10 10:16:33 -04004967static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
Venkat Yekkirala6b877692006-11-08 17:04:09 -06004968{
Paul Mooreaa862902008-10-10 10:16:29 -04004969 u16 family = sk->sk_family;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06004970 struct sk_security_struct *sksec = sk->sk_security;
4971
Paul Mooreaa862902008-10-10 10:16:29 -04004972 /* handle mapped IPv4 packets arriving via IPv6 sockets */
4973 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
4974 family = PF_INET;
4975
4976 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
Venkat Yekkirala6b877692006-11-08 17:04:09 -06004977}
4978
Eric Paris2606fd12010-10-13 16:24:41 -04004979static int selinux_secmark_relabel_packet(u32 sid)
4980{
4981 const struct task_security_struct *__tsec;
4982 u32 tsid;
4983
4984 __tsec = current_security();
4985 tsid = __tsec->sid;
4986
4987 return avc_has_perm(tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO, NULL);
4988}
4989
4990static void selinux_secmark_refcount_inc(void)
4991{
4992 atomic_inc(&selinux_secmark_refcount);
4993}
4994
4995static void selinux_secmark_refcount_dec(void)
4996{
4997 atomic_dec(&selinux_secmark_refcount);
4998}
4999
Adrian Bunk9a673e52006-08-15 00:03:53 -07005000static void selinux_req_classify_flow(const struct request_sock *req,
5001 struct flowi *fl)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005002{
David S. Miller1d28f422011-03-12 00:29:39 -05005003 fl->flowi_secid = req->secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005004}
5005
Paul Moore5dbbaf22013-01-14 07:12:19 +00005006static int selinux_tun_dev_alloc_security(void **security)
5007{
5008 struct tun_security_struct *tunsec;
5009
5010 tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
5011 if (!tunsec)
5012 return -ENOMEM;
5013 tunsec->sid = current_sid();
5014
5015 *security = tunsec;
5016 return 0;
5017}
5018
5019static void selinux_tun_dev_free_security(void *security)
5020{
5021 kfree(security);
5022}
5023
Paul Mooreed6d76e2009-08-28 18:12:49 -04005024static int selinux_tun_dev_create(void)
5025{
5026 u32 sid = current_sid();
5027
5028 /* we aren't taking into account the "sockcreate" SID since the socket
5029 * that is being created here is not a socket in the traditional sense,
5030 * instead it is a private sock, accessible only to the kernel, and
5031 * representing a wide range of network traffic spanning multiple
5032 * connections unlike traditional sockets - check the TUN driver to
5033 * get a better understanding of why this socket is special */
5034
5035 return avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
5036 NULL);
5037}
5038
Paul Moore5dbbaf22013-01-14 07:12:19 +00005039static int selinux_tun_dev_attach_queue(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005040{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005041 struct tun_security_struct *tunsec = security;
5042
5043 return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
5044 TUN_SOCKET__ATTACH_QUEUE, NULL);
5045}
5046
5047static int selinux_tun_dev_attach(struct sock *sk, void *security)
5048{
5049 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005050 struct sk_security_struct *sksec = sk->sk_security;
5051
5052 /* we don't currently perform any NetLabel based labeling here and it
5053 * isn't clear that we would want to do so anyway; while we could apply
5054 * labeling without the support of the TUN user the resulting labeled
5055 * traffic from the other end of the connection would almost certainly
5056 * cause confusion to the TUN user that had no idea network labeling
5057 * protocols were being used */
5058
Paul Moore5dbbaf22013-01-14 07:12:19 +00005059 sksec->sid = tunsec->sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005060 sksec->sclass = SECCLASS_TUN_SOCKET;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005061
5062 return 0;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005063}
5064
Paul Moore5dbbaf22013-01-14 07:12:19 +00005065static int selinux_tun_dev_open(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005066{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005067 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005068 u32 sid = current_sid();
5069 int err;
5070
Paul Moore5dbbaf22013-01-14 07:12:19 +00005071 err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005072 TUN_SOCKET__RELABELFROM, NULL);
5073 if (err)
5074 return err;
5075 err = avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET,
5076 TUN_SOCKET__RELABELTO, NULL);
5077 if (err)
5078 return err;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005079 tunsec->sid = sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005080
5081 return 0;
5082}
5083
Linus Torvalds1da177e2005-04-16 15:20:36 -07005084static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
5085{
5086 int err = 0;
5087 u32 perm;
5088 struct nlmsghdr *nlh;
Paul Moore253bfae2010-04-22 14:46:19 -04005089 struct sk_security_struct *sksec = sk->sk_security;
Eric Paris828dfe12008-04-17 13:17:49 -04005090
Hong zhi guo77954982013-03-27 06:49:35 +00005091 if (skb->len < NLMSG_HDRLEN) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005092 err = -EINVAL;
5093 goto out;
5094 }
Arnaldo Carvalho de Melob529ccf2007-04-25 19:08:35 -07005095 nlh = nlmsg_hdr(skb);
Eric Paris828dfe12008-04-17 13:17:49 -04005096
Paul Moore253bfae2010-04-22 14:46:19 -04005097 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005098 if (err) {
5099 if (err == -EINVAL) {
Vladis Dronov76319942015-12-24 11:09:41 -05005100 pr_warn_ratelimited("SELinux: unrecognized netlink"
5101 " message: protocol=%hu nlmsg_type=%hu sclass=%s"
5102 " pig=%d comm=%s\n",
Marek Milkoviccded3ff2015-06-04 16:22:16 -04005103 sk->sk_protocol, nlh->nlmsg_type,
Vladis Dronov76319942015-12-24 11:09:41 -05005104 secclass_map[sksec->sclass - 1].name,
5105 task_pid_nr(current), current->comm);
Eric Paris39c9aed2008-11-05 09:34:42 -05005106 if (!selinux_enforcing || security_get_allow_unknown())
Linus Torvalds1da177e2005-04-16 15:20:36 -07005107 err = 0;
5108 }
5109
5110 /* Ignore */
5111 if (err == -ENOENT)
5112 err = 0;
5113 goto out;
5114 }
5115
Paul Moore253bfae2010-04-22 14:46:19 -04005116 err = sock_has_perm(current, sk, perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005117out:
5118 return err;
5119}
5120
5121#ifdef CONFIG_NETFILTER
5122
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005123static unsigned int selinux_ip_forward(struct sk_buff *skb,
5124 const struct net_device *indev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005125 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005126{
Paul Mooredfaebe92008-10-10 10:16:31 -04005127 int err;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005128 char *addrp;
5129 u32 peer_sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04005130 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005131 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005132 u8 secmark_active;
Paul Moore948bf852008-10-10 10:16:32 -04005133 u8 netlbl_active;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005134 u8 peerlbl_active;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005135
Paul Mooreeffad8d2008-01-29 08:49:27 -05005136 if (!selinux_policycap_netpeer)
5137 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005138
Paul Mooreeffad8d2008-01-29 08:49:27 -05005139 secmark_active = selinux_secmark_enabled();
Paul Moore948bf852008-10-10 10:16:32 -04005140 netlbl_active = netlbl_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005141 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005142 if (!secmark_active && !peerlbl_active)
5143 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005144
Paul Moored8395c82008-10-10 10:16:30 -04005145 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
5146 return NF_DROP;
5147
Eric Paris50c205f2012-04-04 15:01:43 -04005148 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005149 ad.u.net = &net;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005150 ad.u.net->netif = indev->ifindex;
Eric Paris48c62af2012-04-02 13:15:44 -04005151 ad.u.net->family = family;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005152 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
5153 return NF_DROP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005154
Paul Mooredfaebe92008-10-10 10:16:31 -04005155 if (peerlbl_active) {
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005156 err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
5157 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04005158 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04005159 selinux_netlbl_err(skb, family, err, 1);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005160 return NF_DROP;
Paul Mooredfaebe92008-10-10 10:16:31 -04005161 }
5162 }
Paul Mooreeffad8d2008-01-29 08:49:27 -05005163
5164 if (secmark_active)
5165 if (avc_has_perm(peer_sid, skb->secmark,
5166 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
5167 return NF_DROP;
5168
Paul Moore948bf852008-10-10 10:16:32 -04005169 if (netlbl_active)
5170 /* we do this in the FORWARD path and not the POST_ROUTING
5171 * path because we want to make sure we apply the necessary
5172 * labeling before IPsec is applied so we can leverage AH
5173 * protection */
5174 if (selinux_netlbl_skbuff_setsid(skb, family, peer_sid) != 0)
5175 return NF_DROP;
5176
Paul Mooreeffad8d2008-01-29 08:49:27 -05005177 return NF_ACCEPT;
5178}
5179
Eric W. Biederman06198b32015-09-18 14:33:06 -05005180static unsigned int selinux_ipv4_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005181 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005182 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005183{
David S. Miller238e54c2015-04-03 20:32:56 -04005184 return selinux_ip_forward(skb, state->in, PF_INET);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005185}
5186
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005187#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005188static unsigned int selinux_ipv6_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005189 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005190 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005191{
David S. Miller238e54c2015-04-03 20:32:56 -04005192 return selinux_ip_forward(skb, state->in, PF_INET6);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005193}
5194#endif /* IPV6 */
5195
Paul Moore948bf852008-10-10 10:16:32 -04005196static unsigned int selinux_ip_output(struct sk_buff *skb,
5197 u16 family)
5198{
Paul Moore47180062013-12-04 16:10:45 -05005199 struct sock *sk;
Paul Moore948bf852008-10-10 10:16:32 -04005200 u32 sid;
5201
5202 if (!netlbl_enabled())
5203 return NF_ACCEPT;
5204
5205 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
5206 * because we want to make sure we apply the necessary labeling
5207 * before IPsec is applied so we can leverage AH protection */
Paul Moore47180062013-12-04 16:10:45 -05005208 sk = skb->sk;
5209 if (sk) {
5210 struct sk_security_struct *sksec;
5211
Eric Dumazete446f9d2015-10-08 05:01:55 -07005212 if (sk_listener(sk))
Paul Moore47180062013-12-04 16:10:45 -05005213 /* if the socket is the listening state then this
5214 * packet is a SYN-ACK packet which means it needs to
5215 * be labeled based on the connection/request_sock and
5216 * not the parent socket. unfortunately, we can't
5217 * lookup the request_sock yet as it isn't queued on
5218 * the parent socket until after the SYN-ACK is sent.
5219 * the "solution" is to simply pass the packet as-is
5220 * as any IP option based labeling should be copied
5221 * from the initial connection request (in the IP
5222 * layer). it is far from ideal, but until we get a
5223 * security label in the packet itself this is the
5224 * best we can do. */
5225 return NF_ACCEPT;
5226
5227 /* standard practice, label using the parent socket */
5228 sksec = sk->sk_security;
Paul Moore948bf852008-10-10 10:16:32 -04005229 sid = sksec->sid;
5230 } else
5231 sid = SECINITSID_KERNEL;
5232 if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
5233 return NF_DROP;
5234
5235 return NF_ACCEPT;
5236}
5237
Eric W. Biederman06198b32015-09-18 14:33:06 -05005238static unsigned int selinux_ipv4_output(void *priv,
Paul Moore948bf852008-10-10 10:16:32 -04005239 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005240 const struct nf_hook_state *state)
Paul Moore948bf852008-10-10 10:16:32 -04005241{
5242 return selinux_ip_output(skb, PF_INET);
5243}
5244
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005245#if IS_ENABLED(CONFIG_IPV6)
Huw Davies2917f572016-06-27 15:06:15 -04005246static unsigned int selinux_ipv6_output(void *priv,
5247 struct sk_buff *skb,
5248 const struct nf_hook_state *state)
5249{
5250 return selinux_ip_output(skb, PF_INET6);
5251}
5252#endif /* IPV6 */
5253
Paul Mooreeffad8d2008-01-29 08:49:27 -05005254static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
5255 int ifindex,
Paul Moored8395c82008-10-10 10:16:30 -04005256 u16 family)
James Morris4e5ab4c2006-06-09 00:33:33 -07005257{
Eric Dumazet54abc682015-11-08 10:54:07 -08005258 struct sock *sk = skb_to_full_sk(skb);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005259 struct sk_security_struct *sksec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005260 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005261 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04005262 char *addrp;
5263 u8 proto;
James Morris4e5ab4c2006-06-09 00:33:33 -07005264
Paul Mooreeffad8d2008-01-29 08:49:27 -05005265 if (sk == NULL)
5266 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005267 sksec = sk->sk_security;
James Morris4e5ab4c2006-06-09 00:33:33 -07005268
Eric Paris50c205f2012-04-04 15:01:43 -04005269 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005270 ad.u.net = &net;
5271 ad.u.net->netif = ifindex;
5272 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005273 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
5274 return NF_DROP;
5275
Paul Moore58bfbb52009-03-27 17:10:41 -04005276 if (selinux_secmark_enabled())
Paul Mooreeffad8d2008-01-29 08:49:27 -05005277 if (avc_has_perm(sksec->sid, skb->secmark,
Paul Moored8395c82008-10-10 10:16:30 -04005278 SECCLASS_PACKET, PACKET__SEND, &ad))
Eric Paris2fe66ec2010-11-23 06:28:08 +00005279 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005280
Steffen Klassertb9679a72011-02-23 12:55:21 +01005281 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
5282 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005283
Paul Mooreeffad8d2008-01-29 08:49:27 -05005284 return NF_ACCEPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005285}
5286
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005287static unsigned int selinux_ip_postroute(struct sk_buff *skb,
5288 const struct net_device *outdev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005289 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005290{
Paul Mooreeffad8d2008-01-29 08:49:27 -05005291 u32 secmark_perm;
5292 u32 peer_sid;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005293 int ifindex = outdev->ifindex;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005294 struct sock *sk;
Thomas Liu2bf49692009-07-14 12:14:09 -04005295 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005296 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005297 char *addrp;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005298 u8 secmark_active;
5299 u8 peerlbl_active;
5300
Paul Mooreeffad8d2008-01-29 08:49:27 -05005301 /* If any sort of compatibility mode is enabled then handoff processing
5302 * to the selinux_ip_postroute_compat() function to deal with the
5303 * special handling. We do this in an attempt to keep this function
5304 * as fast and as clean as possible. */
Paul Moore58bfbb52009-03-27 17:10:41 -04005305 if (!selinux_policycap_netpeer)
Paul Moored8395c82008-10-10 10:16:30 -04005306 return selinux_ip_postroute_compat(skb, ifindex, family);
Paul Moorec0828e52013-12-10 14:58:01 -05005307
Paul Mooreeffad8d2008-01-29 08:49:27 -05005308 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005309 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005310 if (!secmark_active && !peerlbl_active)
5311 return NF_ACCEPT;
5312
Eric Dumazet54abc682015-11-08 10:54:07 -08005313 sk = skb_to_full_sk(skb);
Paul Moorec0828e52013-12-10 14:58:01 -05005314
Paul Mooreeffad8d2008-01-29 08:49:27 -05005315#ifdef CONFIG_XFRM
5316 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
5317 * packet transformation so allow the packet to pass without any checks
5318 * since we'll have another chance to perform access control checks
5319 * when the packet is on it's final way out.
5320 * NOTE: there appear to be some IPv6 multicast cases where skb->dst
Paul Moorec0828e52013-12-10 14:58:01 -05005321 * is NULL, in this case go ahead and apply access control.
5322 * NOTE: if this is a local socket (skb->sk != NULL) that is in the
5323 * TCP listening state we cannot wait until the XFRM processing
5324 * is done as we will miss out on the SA label if we do;
5325 * unfortunately, this means more work, but it is only once per
5326 * connection. */
5327 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
Eric Dumazete446f9d2015-10-08 05:01:55 -07005328 !(sk && sk_listener(sk)))
Paul Mooreeffad8d2008-01-29 08:49:27 -05005329 return NF_ACCEPT;
5330#endif
Paul Mooreeffad8d2008-01-29 08:49:27 -05005331
Paul Moored8395c82008-10-10 10:16:30 -04005332 if (sk == NULL) {
Paul Moore446b8022013-12-04 16:10:51 -05005333 /* Without an associated socket the packet is either coming
5334 * from the kernel or it is being forwarded; check the packet
5335 * to determine which and if the packet is being forwarded
5336 * query the packet directly to determine the security label. */
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005337 if (skb->skb_iif) {
5338 secmark_perm = PACKET__FORWARD_OUT;
Paul Moored8395c82008-10-10 10:16:30 -04005339 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005340 return NF_DROP;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005341 } else {
5342 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005343 peer_sid = SECINITSID_KERNEL;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005344 }
Eric Dumazete446f9d2015-10-08 05:01:55 -07005345 } else if (sk_listener(sk)) {
Paul Moore446b8022013-12-04 16:10:51 -05005346 /* Locally generated packet but the associated socket is in the
5347 * listening state which means this is a SYN-ACK packet. In
5348 * this particular case the correct security label is assigned
5349 * to the connection/request_sock but unfortunately we can't
5350 * query the request_sock as it isn't queued on the parent
5351 * socket until after the SYN-ACK packet is sent; the only
5352 * viable choice is to regenerate the label like we do in
5353 * selinux_inet_conn_request(). See also selinux_ip_output()
5354 * for similar problems. */
5355 u32 skb_sid;
Eric Dumazete446f9d2015-10-08 05:01:55 -07005356 struct sk_security_struct *sksec;
5357
Eric Dumazete446f9d2015-10-08 05:01:55 -07005358 sksec = sk->sk_security;
Paul Moore446b8022013-12-04 16:10:51 -05005359 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
5360 return NF_DROP;
Paul Moorec0828e52013-12-10 14:58:01 -05005361 /* At this point, if the returned skb peerlbl is SECSID_NULL
5362 * and the packet has been through at least one XFRM
5363 * transformation then we must be dealing with the "final"
5364 * form of labeled IPsec packet; since we've already applied
5365 * all of our access controls on this packet we can safely
5366 * pass the packet. */
5367 if (skb_sid == SECSID_NULL) {
5368 switch (family) {
5369 case PF_INET:
5370 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
5371 return NF_ACCEPT;
5372 break;
5373 case PF_INET6:
5374 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
5375 return NF_ACCEPT;
Paul Moorea7a91a12014-09-03 10:51:59 -04005376 break;
Paul Moorec0828e52013-12-10 14:58:01 -05005377 default:
5378 return NF_DROP_ERR(-ECONNREFUSED);
5379 }
5380 }
Paul Moore446b8022013-12-04 16:10:51 -05005381 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
5382 return NF_DROP;
5383 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005384 } else {
Paul Moore446b8022013-12-04 16:10:51 -05005385 /* Locally generated packet, fetch the security label from the
5386 * associated socket. */
Paul Mooreeffad8d2008-01-29 08:49:27 -05005387 struct sk_security_struct *sksec = sk->sk_security;
5388 peer_sid = sksec->sid;
5389 secmark_perm = PACKET__SEND;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005390 }
5391
Eric Paris50c205f2012-04-04 15:01:43 -04005392 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005393 ad.u.net = &net;
5394 ad.u.net->netif = ifindex;
5395 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005396 if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
Eric Paris04f6d702010-11-23 06:28:02 +00005397 return NF_DROP;
Paul Moored8395c82008-10-10 10:16:30 -04005398
Paul Mooreeffad8d2008-01-29 08:49:27 -05005399 if (secmark_active)
5400 if (avc_has_perm(peer_sid, skb->secmark,
5401 SECCLASS_PACKET, secmark_perm, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005402 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005403
5404 if (peerlbl_active) {
5405 u32 if_sid;
5406 u32 node_sid;
5407
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005408 if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005409 return NF_DROP;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005410 if (avc_has_perm(peer_sid, if_sid,
5411 SECCLASS_NETIF, NETIF__EGRESS, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005412 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005413
5414 if (sel_netnode_sid(addrp, family, &node_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005415 return NF_DROP;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005416 if (avc_has_perm(peer_sid, node_sid,
5417 SECCLASS_NODE, NODE__SENDTO, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005418 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005419 }
5420
5421 return NF_ACCEPT;
5422}
5423
Eric W. Biederman06198b32015-09-18 14:33:06 -05005424static unsigned int selinux_ipv4_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005425 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005426 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005427{
David S. Miller238e54c2015-04-03 20:32:56 -04005428 return selinux_ip_postroute(skb, state->out, PF_INET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005429}
5430
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005431#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005432static unsigned int selinux_ipv6_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005433 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005434 const struct nf_hook_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005435{
David S. Miller238e54c2015-04-03 20:32:56 -04005436 return selinux_ip_postroute(skb, state->out, PF_INET6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005437}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005438#endif /* IPV6 */
5439
5440#endif /* CONFIG_NETFILTER */
5441
Linus Torvalds1da177e2005-04-16 15:20:36 -07005442static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
5443{
Stephen Smalley941fc5b2009-10-01 14:48:23 -04005444 return selinux_nlmsg_perm(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005445}
5446
Linus Torvalds1da177e2005-04-16 15:20:36 -07005447static int ipc_alloc_security(struct task_struct *task,
5448 struct kern_ipc_perm *perm,
5449 u16 sclass)
5450{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005451 struct ipc_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +11005452 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005453
James Morris89d155e2005-10-30 14:59:21 -08005454 isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005455 if (!isec)
5456 return -ENOMEM;
5457
David Howells275bb412008-11-14 10:39:19 +11005458 sid = task_sid(task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005459 isec->sclass = sclass;
David Howells275bb412008-11-14 10:39:19 +11005460 isec->sid = sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005461 perm->security = isec;
5462
5463 return 0;
5464}
5465
5466static void ipc_free_security(struct kern_ipc_perm *perm)
5467{
5468 struct ipc_security_struct *isec = perm->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005469 perm->security = NULL;
5470 kfree(isec);
5471}
5472
5473static int msg_msg_alloc_security(struct msg_msg *msg)
5474{
5475 struct msg_security_struct *msec;
5476
James Morris89d155e2005-10-30 14:59:21 -08005477 msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005478 if (!msec)
5479 return -ENOMEM;
5480
Linus Torvalds1da177e2005-04-16 15:20:36 -07005481 msec->sid = SECINITSID_UNLABELED;
5482 msg->security = msec;
5483
5484 return 0;
5485}
5486
5487static void msg_msg_free_security(struct msg_msg *msg)
5488{
5489 struct msg_security_struct *msec = msg->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005490
5491 msg->security = NULL;
5492 kfree(msec);
5493}
5494
5495static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
Stephen Smalley6af963f2005-05-01 08:58:39 -07005496 u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005497{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005498 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005499 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005500 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005501
Linus Torvalds1da177e2005-04-16 15:20:36 -07005502 isec = ipc_perms->security;
5503
Eric Paris50c205f2012-04-04 15:01:43 -04005504 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005505 ad.u.ipc_id = ipc_perms->key;
5506
David Howells275bb412008-11-14 10:39:19 +11005507 return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005508}
5509
5510static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
5511{
5512 return msg_msg_alloc_security(msg);
5513}
5514
5515static void selinux_msg_msg_free_security(struct msg_msg *msg)
5516{
5517 msg_msg_free_security(msg);
5518}
5519
5520/* message queue security operations */
5521static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
5522{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005523 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005524 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005525 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005526 int rc;
5527
5528 rc = ipc_alloc_security(current, &msq->q_perm, SECCLASS_MSGQ);
5529 if (rc)
5530 return rc;
5531
Linus Torvalds1da177e2005-04-16 15:20:36 -07005532 isec = msq->q_perm.security;
5533
Eric Paris50c205f2012-04-04 15:01:43 -04005534 ad.type = LSM_AUDIT_DATA_IPC;
Eric Paris828dfe12008-04-17 13:17:49 -04005535 ad.u.ipc_id = msq->q_perm.key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005536
David Howells275bb412008-11-14 10:39:19 +11005537 rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005538 MSGQ__CREATE, &ad);
5539 if (rc) {
5540 ipc_free_security(&msq->q_perm);
5541 return rc;
5542 }
5543 return 0;
5544}
5545
5546static void selinux_msg_queue_free_security(struct msg_queue *msq)
5547{
5548 ipc_free_security(&msq->q_perm);
5549}
5550
5551static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
5552{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005553 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005554 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005555 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005556
Linus Torvalds1da177e2005-04-16 15:20:36 -07005557 isec = msq->q_perm.security;
5558
Eric Paris50c205f2012-04-04 15:01:43 -04005559 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005560 ad.u.ipc_id = msq->q_perm.key;
5561
David Howells275bb412008-11-14 10:39:19 +11005562 return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005563 MSGQ__ASSOCIATE, &ad);
5564}
5565
5566static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd)
5567{
5568 int err;
5569 int perms;
5570
Eric Paris828dfe12008-04-17 13:17:49 -04005571 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005572 case IPC_INFO:
5573 case MSG_INFO:
5574 /* No specific object, just general system-wide information. */
5575 return task_has_system(current, SYSTEM__IPC_INFO);
5576 case IPC_STAT:
5577 case MSG_STAT:
5578 perms = MSGQ__GETATTR | MSGQ__ASSOCIATE;
5579 break;
5580 case IPC_SET:
5581 perms = MSGQ__SETATTR;
5582 break;
5583 case IPC_RMID:
5584 perms = MSGQ__DESTROY;
5585 break;
5586 default:
5587 return 0;
5588 }
5589
Stephen Smalley6af963f2005-05-01 08:58:39 -07005590 err = ipc_has_perm(&msq->q_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005591 return err;
5592}
5593
5594static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, int msqflg)
5595{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005596 struct ipc_security_struct *isec;
5597 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005598 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005599 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005600 int rc;
5601
Linus Torvalds1da177e2005-04-16 15:20:36 -07005602 isec = msq->q_perm.security;
5603 msec = msg->security;
5604
5605 /*
5606 * First time through, need to assign label to the message
5607 */
5608 if (msec->sid == SECINITSID_UNLABELED) {
5609 /*
5610 * Compute new sid based on current process and
5611 * message queue this message will be stored in
5612 */
David Howells275bb412008-11-14 10:39:19 +11005613 rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG,
Eric Paris652bb9b2011-02-01 11:05:40 -05005614 NULL, &msec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005615 if (rc)
5616 return rc;
5617 }
5618
Eric Paris50c205f2012-04-04 15:01:43 -04005619 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005620 ad.u.ipc_id = msq->q_perm.key;
5621
5622 /* Can this process write to the queue? */
David Howells275bb412008-11-14 10:39:19 +11005623 rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005624 MSGQ__WRITE, &ad);
5625 if (!rc)
5626 /* Can this process send the message */
David Howells275bb412008-11-14 10:39:19 +11005627 rc = avc_has_perm(sid, msec->sid, SECCLASS_MSG,
5628 MSG__SEND, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005629 if (!rc)
5630 /* Can the message be put in the queue? */
David Howells275bb412008-11-14 10:39:19 +11005631 rc = avc_has_perm(msec->sid, isec->sid, SECCLASS_MSGQ,
5632 MSGQ__ENQUEUE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005633
5634 return rc;
5635}
5636
5637static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
5638 struct task_struct *target,
5639 long type, int mode)
5640{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005641 struct ipc_security_struct *isec;
5642 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005643 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005644 u32 sid = task_sid(target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005645 int rc;
5646
Linus Torvalds1da177e2005-04-16 15:20:36 -07005647 isec = msq->q_perm.security;
5648 msec = msg->security;
5649
Eric Paris50c205f2012-04-04 15:01:43 -04005650 ad.type = LSM_AUDIT_DATA_IPC;
Eric Paris828dfe12008-04-17 13:17:49 -04005651 ad.u.ipc_id = msq->q_perm.key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005652
David Howells275bb412008-11-14 10:39:19 +11005653 rc = avc_has_perm(sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005654 SECCLASS_MSGQ, MSGQ__READ, &ad);
5655 if (!rc)
David Howells275bb412008-11-14 10:39:19 +11005656 rc = avc_has_perm(sid, msec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005657 SECCLASS_MSG, MSG__RECEIVE, &ad);
5658 return rc;
5659}
5660
5661/* Shared Memory security operations */
5662static int selinux_shm_alloc_security(struct shmid_kernel *shp)
5663{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005664 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005665 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005666 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005667 int rc;
5668
5669 rc = ipc_alloc_security(current, &shp->shm_perm, SECCLASS_SHM);
5670 if (rc)
5671 return rc;
5672
Linus Torvalds1da177e2005-04-16 15:20:36 -07005673 isec = shp->shm_perm.security;
5674
Eric Paris50c205f2012-04-04 15:01:43 -04005675 ad.type = LSM_AUDIT_DATA_IPC;
Eric Paris828dfe12008-04-17 13:17:49 -04005676 ad.u.ipc_id = shp->shm_perm.key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005677
David Howells275bb412008-11-14 10:39:19 +11005678 rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005679 SHM__CREATE, &ad);
5680 if (rc) {
5681 ipc_free_security(&shp->shm_perm);
5682 return rc;
5683 }
5684 return 0;
5685}
5686
5687static void selinux_shm_free_security(struct shmid_kernel *shp)
5688{
5689 ipc_free_security(&shp->shm_perm);
5690}
5691
5692static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
5693{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005694 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005695 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005696 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005697
Linus Torvalds1da177e2005-04-16 15:20:36 -07005698 isec = shp->shm_perm.security;
5699
Eric Paris50c205f2012-04-04 15:01:43 -04005700 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005701 ad.u.ipc_id = shp->shm_perm.key;
5702
David Howells275bb412008-11-14 10:39:19 +11005703 return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005704 SHM__ASSOCIATE, &ad);
5705}
5706
5707/* Note, at this point, shp is locked down */
5708static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd)
5709{
5710 int perms;
5711 int err;
5712
Eric Paris828dfe12008-04-17 13:17:49 -04005713 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005714 case IPC_INFO:
5715 case SHM_INFO:
5716 /* No specific object, just general system-wide information. */
5717 return task_has_system(current, SYSTEM__IPC_INFO);
5718 case IPC_STAT:
5719 case SHM_STAT:
5720 perms = SHM__GETATTR | SHM__ASSOCIATE;
5721 break;
5722 case IPC_SET:
5723 perms = SHM__SETATTR;
5724 break;
5725 case SHM_LOCK:
5726 case SHM_UNLOCK:
5727 perms = SHM__LOCK;
5728 break;
5729 case IPC_RMID:
5730 perms = SHM__DESTROY;
5731 break;
5732 default:
5733 return 0;
5734 }
5735
Stephen Smalley6af963f2005-05-01 08:58:39 -07005736 err = ipc_has_perm(&shp->shm_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005737 return err;
5738}
5739
5740static int selinux_shm_shmat(struct shmid_kernel *shp,
5741 char __user *shmaddr, int shmflg)
5742{
5743 u32 perms;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005744
5745 if (shmflg & SHM_RDONLY)
5746 perms = SHM__READ;
5747 else
5748 perms = SHM__READ | SHM__WRITE;
5749
Stephen Smalley6af963f2005-05-01 08:58:39 -07005750 return ipc_has_perm(&shp->shm_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005751}
5752
5753/* Semaphore security operations */
5754static int selinux_sem_alloc_security(struct sem_array *sma)
5755{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005756 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005757 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005758 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005759 int rc;
5760
5761 rc = ipc_alloc_security(current, &sma->sem_perm, SECCLASS_SEM);
5762 if (rc)
5763 return rc;
5764
Linus Torvalds1da177e2005-04-16 15:20:36 -07005765 isec = sma->sem_perm.security;
5766
Eric Paris50c205f2012-04-04 15:01:43 -04005767 ad.type = LSM_AUDIT_DATA_IPC;
Eric Paris828dfe12008-04-17 13:17:49 -04005768 ad.u.ipc_id = sma->sem_perm.key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005769
David Howells275bb412008-11-14 10:39:19 +11005770 rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005771 SEM__CREATE, &ad);
5772 if (rc) {
5773 ipc_free_security(&sma->sem_perm);
5774 return rc;
5775 }
5776 return 0;
5777}
5778
5779static void selinux_sem_free_security(struct sem_array *sma)
5780{
5781 ipc_free_security(&sma->sem_perm);
5782}
5783
5784static int selinux_sem_associate(struct sem_array *sma, int semflg)
5785{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005786 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005787 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005788 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005789
Linus Torvalds1da177e2005-04-16 15:20:36 -07005790 isec = sma->sem_perm.security;
5791
Eric Paris50c205f2012-04-04 15:01:43 -04005792 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005793 ad.u.ipc_id = sma->sem_perm.key;
5794
David Howells275bb412008-11-14 10:39:19 +11005795 return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005796 SEM__ASSOCIATE, &ad);
5797}
5798
5799/* Note, at this point, sma is locked down */
5800static int selinux_sem_semctl(struct sem_array *sma, int cmd)
5801{
5802 int err;
5803 u32 perms;
5804
Eric Paris828dfe12008-04-17 13:17:49 -04005805 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005806 case IPC_INFO:
5807 case SEM_INFO:
5808 /* No specific object, just general system-wide information. */
5809 return task_has_system(current, SYSTEM__IPC_INFO);
5810 case GETPID:
5811 case GETNCNT:
5812 case GETZCNT:
5813 perms = SEM__GETATTR;
5814 break;
5815 case GETVAL:
5816 case GETALL:
5817 perms = SEM__READ;
5818 break;
5819 case SETVAL:
5820 case SETALL:
5821 perms = SEM__WRITE;
5822 break;
5823 case IPC_RMID:
5824 perms = SEM__DESTROY;
5825 break;
5826 case IPC_SET:
5827 perms = SEM__SETATTR;
5828 break;
5829 case IPC_STAT:
5830 case SEM_STAT:
5831 perms = SEM__GETATTR | SEM__ASSOCIATE;
5832 break;
5833 default:
5834 return 0;
5835 }
5836
Stephen Smalley6af963f2005-05-01 08:58:39 -07005837 err = ipc_has_perm(&sma->sem_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005838 return err;
5839}
5840
5841static int selinux_sem_semop(struct sem_array *sma,
5842 struct sembuf *sops, unsigned nsops, int alter)
5843{
5844 u32 perms;
5845
5846 if (alter)
5847 perms = SEM__READ | SEM__WRITE;
5848 else
5849 perms = SEM__READ;
5850
Stephen Smalley6af963f2005-05-01 08:58:39 -07005851 return ipc_has_perm(&sma->sem_perm, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005852}
5853
5854static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
5855{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005856 u32 av = 0;
5857
Linus Torvalds1da177e2005-04-16 15:20:36 -07005858 av = 0;
5859 if (flag & S_IRUGO)
5860 av |= IPC__UNIX_READ;
5861 if (flag & S_IWUGO)
5862 av |= IPC__UNIX_WRITE;
5863
5864 if (av == 0)
5865 return 0;
5866
Stephen Smalley6af963f2005-05-01 08:58:39 -07005867 return ipc_has_perm(ipcp, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005868}
5869
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02005870static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
5871{
5872 struct ipc_security_struct *isec = ipcp->security;
5873 *secid = isec->sid;
5874}
5875
Eric Paris828dfe12008-04-17 13:17:49 -04005876static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005877{
5878 if (inode)
5879 inode_doinit_with_dentry(inode, dentry);
5880}
5881
5882static int selinux_getprocattr(struct task_struct *p,
Al Viro04ff9702007-03-12 16:17:58 +00005883 char *name, char **value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005884{
David Howells275bb412008-11-14 10:39:19 +11005885 const struct task_security_struct *__tsec;
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00005886 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005887 int error;
Al Viro04ff9702007-03-12 16:17:58 +00005888 unsigned len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005889
5890 if (current != p) {
David Howells3b11a1d2008-11-14 10:39:26 +11005891 error = current_has_perm(p, PROCESS__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005892 if (error)
5893 return error;
5894 }
5895
David Howells275bb412008-11-14 10:39:19 +11005896 rcu_read_lock();
5897 __tsec = __task_cred(p)->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005898
5899 if (!strcmp(name, "current"))
David Howells275bb412008-11-14 10:39:19 +11005900 sid = __tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005901 else if (!strcmp(name, "prev"))
David Howells275bb412008-11-14 10:39:19 +11005902 sid = __tsec->osid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005903 else if (!strcmp(name, "exec"))
David Howells275bb412008-11-14 10:39:19 +11005904 sid = __tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005905 else if (!strcmp(name, "fscreate"))
David Howells275bb412008-11-14 10:39:19 +11005906 sid = __tsec->create_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07005907 else if (!strcmp(name, "keycreate"))
David Howells275bb412008-11-14 10:39:19 +11005908 sid = __tsec->keycreate_sid;
Eric Paris42c3e032006-06-26 00:26:03 -07005909 else if (!strcmp(name, "sockcreate"))
David Howells275bb412008-11-14 10:39:19 +11005910 sid = __tsec->sockcreate_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005911 else
David Howells275bb412008-11-14 10:39:19 +11005912 goto invalid;
5913 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005914
5915 if (!sid)
5916 return 0;
5917
Al Viro04ff9702007-03-12 16:17:58 +00005918 error = security_sid_to_context(sid, value, &len);
5919 if (error)
5920 return error;
5921 return len;
David Howells275bb412008-11-14 10:39:19 +11005922
5923invalid:
5924 rcu_read_unlock();
5925 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005926}
5927
5928static int selinux_setprocattr(struct task_struct *p,
5929 char *name, void *value, size_t size)
5930{
5931 struct task_security_struct *tsec;
David Howellsd84f4f92008-11-14 10:39:23 +11005932 struct cred *new;
5933 u32 sid = 0, ptsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005934 int error;
5935 char *str = value;
5936
5937 if (current != p) {
5938 /* SELinux only allows a process to change its own
5939 security attributes. */
5940 return -EACCES;
5941 }
5942
5943 /*
5944 * Basic control over ability to set these attributes at all.
5945 * current == p, but we'll pass them separately in case the
5946 * above restriction is ever removed.
5947 */
5948 if (!strcmp(name, "exec"))
David Howells3b11a1d2008-11-14 10:39:26 +11005949 error = current_has_perm(p, PROCESS__SETEXEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005950 else if (!strcmp(name, "fscreate"))
David Howells3b11a1d2008-11-14 10:39:26 +11005951 error = current_has_perm(p, PROCESS__SETFSCREATE);
Michael LeMay4eb582c2006-06-26 00:24:57 -07005952 else if (!strcmp(name, "keycreate"))
David Howells3b11a1d2008-11-14 10:39:26 +11005953 error = current_has_perm(p, PROCESS__SETKEYCREATE);
Eric Paris42c3e032006-06-26 00:26:03 -07005954 else if (!strcmp(name, "sockcreate"))
David Howells3b11a1d2008-11-14 10:39:26 +11005955 error = current_has_perm(p, PROCESS__SETSOCKCREATE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005956 else if (!strcmp(name, "current"))
David Howells3b11a1d2008-11-14 10:39:26 +11005957 error = current_has_perm(p, PROCESS__SETCURRENT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005958 else
5959 error = -EINVAL;
5960 if (error)
5961 return error;
5962
5963 /* Obtain a SID for the context, if one was specified. */
5964 if (size && str[1] && str[1] != '\n') {
5965 if (str[size-1] == '\n') {
5966 str[size-1] = 0;
5967 size--;
5968 }
Nikolay Aleksandrov52a4c642014-03-07 12:44:19 +01005969 error = security_context_to_sid(value, size, &sid, GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04005970 if (error == -EINVAL && !strcmp(name, "fscreate")) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04005971 if (!capable(CAP_MAC_ADMIN)) {
5972 struct audit_buffer *ab;
5973 size_t audit_size;
5974
5975 /* We strip a nul only if it is at the end, otherwise the
5976 * context contains a nul and we should audit that */
5977 if (str[size - 1] == '\0')
5978 audit_size = size - 1;
5979 else
5980 audit_size = size;
5981 ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR);
5982 audit_log_format(ab, "op=fscreate invalid_context=");
5983 audit_log_n_untrustedstring(ab, value, audit_size);
5984 audit_log_end(ab);
5985
Stephen Smalley12b29f32008-05-07 13:03:20 -04005986 return error;
Eric Parisd6ea83e2012-04-04 13:45:49 -04005987 }
Stephen Smalley12b29f32008-05-07 13:03:20 -04005988 error = security_context_to_sid_force(value, size,
5989 &sid);
5990 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005991 if (error)
5992 return error;
5993 }
5994
David Howellsd84f4f92008-11-14 10:39:23 +11005995 new = prepare_creds();
5996 if (!new)
5997 return -ENOMEM;
5998
Linus Torvalds1da177e2005-04-16 15:20:36 -07005999 /* Permission checking based on the specified context is
6000 performed during the actual operation (execve,
6001 open/mkdir/...), when we know the full context of the
David Howellsd84f4f92008-11-14 10:39:23 +11006002 operation. See selinux_bprm_set_creds for the execve
Linus Torvalds1da177e2005-04-16 15:20:36 -07006003 checks and may_create for the file creation checks. The
6004 operation will then fail if the context is not permitted. */
David Howellsd84f4f92008-11-14 10:39:23 +11006005 tsec = new->security;
6006 if (!strcmp(name, "exec")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006007 tsec->exec_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006008 } else if (!strcmp(name, "fscreate")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006009 tsec->create_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006010 } else if (!strcmp(name, "keycreate")) {
Michael LeMay4eb582c2006-06-26 00:24:57 -07006011 error = may_create_key(sid, p);
6012 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006013 goto abort_change;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006014 tsec->keycreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006015 } else if (!strcmp(name, "sockcreate")) {
Eric Paris42c3e032006-06-26 00:26:03 -07006016 tsec->sockcreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006017 } else if (!strcmp(name, "current")) {
6018 error = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006019 if (sid == 0)
David Howellsd84f4f92008-11-14 10:39:23 +11006020 goto abort_change;
KaiGai Koheid9250de2008-08-28 16:35:57 +09006021
David Howellsd84f4f92008-11-14 10:39:23 +11006022 /* Only allow single threaded processes to change context */
6023 error = -EPERM;
Oleg Nesterov5bb459b2009-07-10 03:48:23 +02006024 if (!current_is_single_threaded()) {
David Howellsd84f4f92008-11-14 10:39:23 +11006025 error = security_bounded_transition(tsec->sid, sid);
6026 if (error)
6027 goto abort_change;
Eric Paris828dfe12008-04-17 13:17:49 -04006028 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006029
6030 /* Check permissions for the transition. */
6031 error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
Eric Paris828dfe12008-04-17 13:17:49 -04006032 PROCESS__DYNTRANSITION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006033 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006034 goto abort_change;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006035
6036 /* Check for ptracing, and update the task SID if ok.
6037 Otherwise, leave SID unchanged and fail. */
Paul Moore0c6181c2016-03-30 21:41:21 -04006038 ptsid = ptrace_parent_sid(p);
6039 if (ptsid != 0) {
David Howellsd84f4f92008-11-14 10:39:23 +11006040 error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS,
6041 PROCESS__PTRACE, NULL);
6042 if (error)
6043 goto abort_change;
6044 }
6045
6046 tsec->sid = sid;
6047 } else {
6048 error = -EINVAL;
6049 goto abort_change;
6050 }
6051
6052 commit_creds(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006053 return size;
David Howellsd84f4f92008-11-14 10:39:23 +11006054
6055abort_change:
6056 abort_creds(new);
6057 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006058}
6059
David Quigley746df9b2013-05-22 12:50:35 -04006060static int selinux_ismaclabel(const char *name)
6061{
6062 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
6063}
6064
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006065static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
6066{
6067 return security_sid_to_context(secid, secdata, seclen);
6068}
6069
David Howells7bf570d2008-04-29 20:52:51 +01006070static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
David Howells63cb3442008-01-15 23:47:35 +00006071{
Nikolay Aleksandrov52a4c642014-03-07 12:44:19 +01006072 return security_context_to_sid(secdata, seclen, secid, GFP_KERNEL);
David Howells63cb3442008-01-15 23:47:35 +00006073}
6074
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006075static void selinux_release_secctx(char *secdata, u32 seclen)
6076{
Paul Moore088999e2007-08-01 11:12:58 -04006077 kfree(secdata);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006078}
6079
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006080static void selinux_inode_invalidate_secctx(struct inode *inode)
6081{
6082 struct inode_security_struct *isec = inode->i_security;
6083
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006084 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006085 isec->initialized = LABEL_INVALID;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006086 spin_unlock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006087}
6088
David P. Quigley1ee65e32009-09-03 14:25:57 -04006089/*
6090 * called with inode->i_mutex locked
6091 */
6092static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
6093{
6094 return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
6095}
6096
6097/*
6098 * called with inode->i_mutex locked
6099 */
6100static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
6101{
6102 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
6103}
6104
6105static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
6106{
6107 int len = 0;
6108 len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
6109 ctx, true);
6110 if (len < 0)
6111 return len;
6112 *ctxlen = len;
6113 return 0;
6114}
Michael LeMayd7200242006-06-22 14:47:17 -07006115#ifdef CONFIG_KEYS
6116
David Howellsd84f4f92008-11-14 10:39:23 +11006117static int selinux_key_alloc(struct key *k, const struct cred *cred,
David Howells7e047ef2006-06-26 00:24:50 -07006118 unsigned long flags)
Michael LeMayd7200242006-06-22 14:47:17 -07006119{
David Howellsd84f4f92008-11-14 10:39:23 +11006120 const struct task_security_struct *tsec;
Michael LeMayd7200242006-06-22 14:47:17 -07006121 struct key_security_struct *ksec;
6122
6123 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
6124 if (!ksec)
6125 return -ENOMEM;
6126
David Howellsd84f4f92008-11-14 10:39:23 +11006127 tsec = cred->security;
6128 if (tsec->keycreate_sid)
6129 ksec->sid = tsec->keycreate_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006130 else
David Howellsd84f4f92008-11-14 10:39:23 +11006131 ksec->sid = tsec->sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006132
David Howells275bb412008-11-14 10:39:19 +11006133 k->security = ksec;
Michael LeMayd7200242006-06-22 14:47:17 -07006134 return 0;
6135}
6136
6137static void selinux_key_free(struct key *k)
6138{
6139 struct key_security_struct *ksec = k->security;
6140
6141 k->security = NULL;
6142 kfree(ksec);
6143}
6144
6145static int selinux_key_permission(key_ref_t key_ref,
David Howellsd84f4f92008-11-14 10:39:23 +11006146 const struct cred *cred,
David Howellsf5895942014-03-14 17:44:49 +00006147 unsigned perm)
Michael LeMayd7200242006-06-22 14:47:17 -07006148{
6149 struct key *key;
Michael LeMayd7200242006-06-22 14:47:17 -07006150 struct key_security_struct *ksec;
David Howells275bb412008-11-14 10:39:19 +11006151 u32 sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006152
6153 /* if no specific permissions are requested, we skip the
6154 permission check. No serious, additional covert channels
6155 appear to be created. */
6156 if (perm == 0)
6157 return 0;
6158
David Howellsd84f4f92008-11-14 10:39:23 +11006159 sid = cred_sid(cred);
David Howells275bb412008-11-14 10:39:19 +11006160
6161 key = key_ref_to_ptr(key_ref);
6162 ksec = key->security;
6163
6164 return avc_has_perm(sid, ksec->sid, SECCLASS_KEY, perm, NULL);
Michael LeMayd7200242006-06-22 14:47:17 -07006165}
6166
David Howells70a5bb72008-04-29 01:01:26 -07006167static int selinux_key_getsecurity(struct key *key, char **_buffer)
6168{
6169 struct key_security_struct *ksec = key->security;
6170 char *context = NULL;
6171 unsigned len;
6172 int rc;
6173
6174 rc = security_sid_to_context(ksec->sid, &context, &len);
6175 if (!rc)
6176 rc = len;
6177 *_buffer = context;
6178 return rc;
6179}
6180
Michael LeMayd7200242006-06-22 14:47:17 -07006181#endif
6182
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07006183static struct security_hook_list selinux_hooks[] = {
Casey Schauflere20b0432015-05-02 15:11:36 -07006184 LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
6185 LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
6186 LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
6187 LSM_HOOK_INIT(binder_transfer_file, selinux_binder_transfer_file),
Ahmed S. Darwish076c54c2008-03-06 18:09:10 +02006188
Casey Schauflere20b0432015-05-02 15:11:36 -07006189 LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
6190 LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
6191 LSM_HOOK_INIT(capget, selinux_capget),
6192 LSM_HOOK_INIT(capset, selinux_capset),
6193 LSM_HOOK_INIT(capable, selinux_capable),
6194 LSM_HOOK_INIT(quotactl, selinux_quotactl),
6195 LSM_HOOK_INIT(quota_on, selinux_quota_on),
6196 LSM_HOOK_INIT(syslog, selinux_syslog),
6197 LSM_HOOK_INIT(vm_enough_memory, selinux_vm_enough_memory),
Stephen Smalley79af7302015-01-21 10:54:10 -05006198
Casey Schauflere20b0432015-05-02 15:11:36 -07006199 LSM_HOOK_INIT(netlink_send, selinux_netlink_send),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006200
Casey Schauflere20b0432015-05-02 15:11:36 -07006201 LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds),
6202 LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds),
6203 LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds),
6204 LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006205
Casey Schauflere20b0432015-05-02 15:11:36 -07006206 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),
6207 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
6208 LSM_HOOK_INIT(sb_copy_data, selinux_sb_copy_data),
6209 LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
6210 LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
6211 LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options),
6212 LSM_HOOK_INIT(sb_statfs, selinux_sb_statfs),
6213 LSM_HOOK_INIT(sb_mount, selinux_mount),
6214 LSM_HOOK_INIT(sb_umount, selinux_umount),
6215 LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts),
6216 LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts),
6217 LSM_HOOK_INIT(sb_parse_opts_str, selinux_parse_opts_str),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006218
Casey Schauflere20b0432015-05-02 15:11:36 -07006219 LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
Vivek Goyala518b0a2016-07-13 10:44:53 -04006220 LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
Eric Parise0007522008-03-05 10:31:54 -05006221
Casey Schauflere20b0432015-05-02 15:11:36 -07006222 LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
6223 LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
6224 LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security),
6225 LSM_HOOK_INIT(inode_create, selinux_inode_create),
6226 LSM_HOOK_INIT(inode_link, selinux_inode_link),
6227 LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink),
6228 LSM_HOOK_INIT(inode_symlink, selinux_inode_symlink),
6229 LSM_HOOK_INIT(inode_mkdir, selinux_inode_mkdir),
6230 LSM_HOOK_INIT(inode_rmdir, selinux_inode_rmdir),
6231 LSM_HOOK_INIT(inode_mknod, selinux_inode_mknod),
6232 LSM_HOOK_INIT(inode_rename, selinux_inode_rename),
6233 LSM_HOOK_INIT(inode_readlink, selinux_inode_readlink),
6234 LSM_HOOK_INIT(inode_follow_link, selinux_inode_follow_link),
6235 LSM_HOOK_INIT(inode_permission, selinux_inode_permission),
6236 LSM_HOOK_INIT(inode_setattr, selinux_inode_setattr),
6237 LSM_HOOK_INIT(inode_getattr, selinux_inode_getattr),
6238 LSM_HOOK_INIT(inode_setxattr, selinux_inode_setxattr),
6239 LSM_HOOK_INIT(inode_post_setxattr, selinux_inode_post_setxattr),
6240 LSM_HOOK_INIT(inode_getxattr, selinux_inode_getxattr),
6241 LSM_HOOK_INIT(inode_listxattr, selinux_inode_listxattr),
6242 LSM_HOOK_INIT(inode_removexattr, selinux_inode_removexattr),
6243 LSM_HOOK_INIT(inode_getsecurity, selinux_inode_getsecurity),
6244 LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity),
6245 LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
6246 LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
Vivek Goyal56909eb2016-07-13 10:44:48 -04006247 LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
Vivek Goyal19472b62016-07-13 10:44:50 -04006248 LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006249
Casey Schauflere20b0432015-05-02 15:11:36 -07006250 LSM_HOOK_INIT(file_permission, selinux_file_permission),
6251 LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
6252 LSM_HOOK_INIT(file_free_security, selinux_file_free_security),
6253 LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
6254 LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
6255 LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),
6256 LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
6257 LSM_HOOK_INIT(file_lock, selinux_file_lock),
6258 LSM_HOOK_INIT(file_fcntl, selinux_file_fcntl),
6259 LSM_HOOK_INIT(file_set_fowner, selinux_file_set_fowner),
6260 LSM_HOOK_INIT(file_send_sigiotask, selinux_file_send_sigiotask),
6261 LSM_HOOK_INIT(file_receive, selinux_file_receive),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006262
Casey Schauflere20b0432015-05-02 15:11:36 -07006263 LSM_HOOK_INIT(file_open, selinux_file_open),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006264
Casey Schauflere20b0432015-05-02 15:11:36 -07006265 LSM_HOOK_INIT(task_create, selinux_task_create),
6266 LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank),
6267 LSM_HOOK_INIT(cred_free, selinux_cred_free),
6268 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
6269 LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
6270 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
6271 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
6272 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07006273 LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file),
Casey Schauflere20b0432015-05-02 15:11:36 -07006274 LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
6275 LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
6276 LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
6277 LSM_HOOK_INIT(task_getsecid, selinux_task_getsecid),
6278 LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
6279 LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
6280 LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
6281 LSM_HOOK_INIT(task_setrlimit, selinux_task_setrlimit),
6282 LSM_HOOK_INIT(task_setscheduler, selinux_task_setscheduler),
6283 LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler),
6284 LSM_HOOK_INIT(task_movememory, selinux_task_movememory),
6285 LSM_HOOK_INIT(task_kill, selinux_task_kill),
6286 LSM_HOOK_INIT(task_wait, selinux_task_wait),
6287 LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode),
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09006288
Casey Schauflere20b0432015-05-02 15:11:36 -07006289 LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission),
6290 LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006291
Casey Schauflere20b0432015-05-02 15:11:36 -07006292 LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security),
6293 LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006294
Casey Schauflere20b0432015-05-02 15:11:36 -07006295 LSM_HOOK_INIT(msg_queue_alloc_security,
6296 selinux_msg_queue_alloc_security),
6297 LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security),
6298 LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate),
6299 LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl),
6300 LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd),
6301 LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006302
Casey Schauflere20b0432015-05-02 15:11:36 -07006303 LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security),
6304 LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security),
6305 LSM_HOOK_INIT(shm_associate, selinux_shm_associate),
6306 LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl),
6307 LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006308
Casey Schauflere20b0432015-05-02 15:11:36 -07006309 LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
6310 LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security),
6311 LSM_HOOK_INIT(sem_associate, selinux_sem_associate),
6312 LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl),
6313 LSM_HOOK_INIT(sem_semop, selinux_sem_semop),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006314
Casey Schauflere20b0432015-05-02 15:11:36 -07006315 LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006316
Casey Schauflere20b0432015-05-02 15:11:36 -07006317 LSM_HOOK_INIT(getprocattr, selinux_getprocattr),
6318 LSM_HOOK_INIT(setprocattr, selinux_setprocattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006319
Casey Schauflere20b0432015-05-02 15:11:36 -07006320 LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel),
6321 LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
6322 LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
6323 LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006324 LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
Casey Schauflere20b0432015-05-02 15:11:36 -07006325 LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
6326 LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx),
6327 LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006328
Casey Schauflere20b0432015-05-02 15:11:36 -07006329 LSM_HOOK_INIT(unix_stream_connect, selinux_socket_unix_stream_connect),
6330 LSM_HOOK_INIT(unix_may_send, selinux_socket_unix_may_send),
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006331
Casey Schauflere20b0432015-05-02 15:11:36 -07006332 LSM_HOOK_INIT(socket_create, selinux_socket_create),
6333 LSM_HOOK_INIT(socket_post_create, selinux_socket_post_create),
6334 LSM_HOOK_INIT(socket_bind, selinux_socket_bind),
6335 LSM_HOOK_INIT(socket_connect, selinux_socket_connect),
6336 LSM_HOOK_INIT(socket_listen, selinux_socket_listen),
6337 LSM_HOOK_INIT(socket_accept, selinux_socket_accept),
6338 LSM_HOOK_INIT(socket_sendmsg, selinux_socket_sendmsg),
6339 LSM_HOOK_INIT(socket_recvmsg, selinux_socket_recvmsg),
6340 LSM_HOOK_INIT(socket_getsockname, selinux_socket_getsockname),
6341 LSM_HOOK_INIT(socket_getpeername, selinux_socket_getpeername),
6342 LSM_HOOK_INIT(socket_getsockopt, selinux_socket_getsockopt),
6343 LSM_HOOK_INIT(socket_setsockopt, selinux_socket_setsockopt),
6344 LSM_HOOK_INIT(socket_shutdown, selinux_socket_shutdown),
6345 LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
6346 LSM_HOOK_INIT(socket_getpeersec_stream,
6347 selinux_socket_getpeersec_stream),
6348 LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram),
6349 LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
6350 LSM_HOOK_INIT(sk_free_security, selinux_sk_free_security),
6351 LSM_HOOK_INIT(sk_clone_security, selinux_sk_clone_security),
6352 LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid),
6353 LSM_HOOK_INIT(sock_graft, selinux_sock_graft),
6354 LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request),
6355 LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone),
6356 LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),
6357 LSM_HOOK_INIT(secmark_relabel_packet, selinux_secmark_relabel_packet),
6358 LSM_HOOK_INIT(secmark_refcount_inc, selinux_secmark_refcount_inc),
6359 LSM_HOOK_INIT(secmark_refcount_dec, selinux_secmark_refcount_dec),
6360 LSM_HOOK_INIT(req_classify_flow, selinux_req_classify_flow),
6361 LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
6362 LSM_HOOK_INIT(tun_dev_free_security, selinux_tun_dev_free_security),
6363 LSM_HOOK_INIT(tun_dev_create, selinux_tun_dev_create),
6364 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
6365 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
6366 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
Trent Jaegerd28d1e02005-12-13 23:12:40 -08006367
6368#ifdef CONFIG_SECURITY_NETWORK_XFRM
Casey Schauflere20b0432015-05-02 15:11:36 -07006369 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
6370 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone),
6371 LSM_HOOK_INIT(xfrm_policy_free_security, selinux_xfrm_policy_free),
6372 LSM_HOOK_INIT(xfrm_policy_delete_security, selinux_xfrm_policy_delete),
6373 LSM_HOOK_INIT(xfrm_state_alloc, selinux_xfrm_state_alloc),
6374 LSM_HOOK_INIT(xfrm_state_alloc_acquire,
6375 selinux_xfrm_state_alloc_acquire),
6376 LSM_HOOK_INIT(xfrm_state_free_security, selinux_xfrm_state_free),
6377 LSM_HOOK_INIT(xfrm_state_delete_security, selinux_xfrm_state_delete),
6378 LSM_HOOK_INIT(xfrm_policy_lookup, selinux_xfrm_policy_lookup),
6379 LSM_HOOK_INIT(xfrm_state_pol_flow_match,
6380 selinux_xfrm_state_pol_flow_match),
6381 LSM_HOOK_INIT(xfrm_decode_session, selinux_xfrm_decode_session),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006382#endif
Michael LeMayd7200242006-06-22 14:47:17 -07006383
6384#ifdef CONFIG_KEYS
Casey Schauflere20b0432015-05-02 15:11:36 -07006385 LSM_HOOK_INIT(key_alloc, selinux_key_alloc),
6386 LSM_HOOK_INIT(key_free, selinux_key_free),
6387 LSM_HOOK_INIT(key_permission, selinux_key_permission),
6388 LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity),
Michael LeMayd7200242006-06-22 14:47:17 -07006389#endif
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006390
6391#ifdef CONFIG_AUDIT
Casey Schauflere20b0432015-05-02 15:11:36 -07006392 LSM_HOOK_INIT(audit_rule_init, selinux_audit_rule_init),
6393 LSM_HOOK_INIT(audit_rule_known, selinux_audit_rule_known),
6394 LSM_HOOK_INIT(audit_rule_match, selinux_audit_rule_match),
6395 LSM_HOOK_INIT(audit_rule_free, selinux_audit_rule_free),
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006396#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07006397};
6398
6399static __init int selinux_init(void)
6400{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07006401 if (!security_module_enable("selinux")) {
Ahmed S. Darwish076c54c2008-03-06 18:09:10 +02006402 selinux_enabled = 0;
6403 return 0;
6404 }
6405
Linus Torvalds1da177e2005-04-16 15:20:36 -07006406 if (!selinux_enabled) {
6407 printk(KERN_INFO "SELinux: Disabled at boot.\n");
6408 return 0;
6409 }
6410
6411 printk(KERN_INFO "SELinux: Initializing.\n");
6412
6413 /* Set the security state for the initial task. */
David Howellsd84f4f92008-11-14 10:39:23 +11006414 cred_init_security();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006415
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04006416 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
6417
James Morris7cae7e22006-03-22 00:09:22 -08006418 sel_inode_cache = kmem_cache_create("selinux_inode_security",
6419 sizeof(struct inode_security_struct),
Paul Mundt20c2df82007-07-20 10:11:58 +09006420 0, SLAB_PANIC, NULL);
Sangwoo63205652015-10-21 17:44:30 -04006421 file_security_cache = kmem_cache_create("selinux_file_security",
6422 sizeof(struct file_security_struct),
6423 0, SLAB_PANIC, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006424 avc_init();
6425
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07006426 security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006427
Paul Moore615e51f2014-06-26 14:33:56 -04006428 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6429 panic("SELinux: Unable to register AVC netcache callback\n");
6430
Eric Paris828dfe12008-04-17 13:17:49 -04006431 if (selinux_enforcing)
Eric Parisfadcdb42007-02-22 18:11:31 -05006432 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
Eric Paris828dfe12008-04-17 13:17:49 -04006433 else
Eric Parisfadcdb42007-02-22 18:11:31 -05006434 printk(KERN_DEBUG "SELinux: Starting in permissive mode\n");
Michael LeMayd7200242006-06-22 14:47:17 -07006435
Linus Torvalds1da177e2005-04-16 15:20:36 -07006436 return 0;
6437}
6438
Al Viroe8c26252010-03-23 06:36:54 -04006439static void delayed_superblock_init(struct super_block *sb, void *unused)
6440{
6441 superblock_doinit(sb, NULL);
6442}
6443
Linus Torvalds1da177e2005-04-16 15:20:36 -07006444void selinux_complete_init(void)
6445{
Eric Parisfadcdb42007-02-22 18:11:31 -05006446 printk(KERN_DEBUG "SELinux: Completing initialization.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006447
6448 /* Set up any superblocks initialized prior to the policy load. */
Eric Parisfadcdb42007-02-22 18:11:31 -05006449 printk(KERN_DEBUG "SELinux: Setting up existing superblocks.\n");
Al Viroe8c26252010-03-23 06:36:54 -04006450 iterate_supers(delayed_superblock_init, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006451}
6452
6453/* SELinux requires early initialization in order to label
6454 all processes and objects when they are created. */
6455security_initcall(selinux_init);
6456
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006457#if defined(CONFIG_NETFILTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006458
Jiri Pirko25db6be2014-09-03 17:42:13 +02006459static struct nf_hook_ops selinux_nf_ops[] = {
Paul Mooreeffad8d2008-01-29 08:49:27 -05006460 {
6461 .hook = selinux_ipv4_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00006462 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006463 .hooknum = NF_INET_POST_ROUTING,
6464 .priority = NF_IP_PRI_SELINUX_LAST,
6465 },
6466 {
6467 .hook = selinux_ipv4_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00006468 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006469 .hooknum = NF_INET_FORWARD,
6470 .priority = NF_IP_PRI_SELINUX_FIRST,
Paul Moore948bf852008-10-10 10:16:32 -04006471 },
6472 {
6473 .hook = selinux_ipv4_output,
Alban Crequy2597a832012-05-14 03:56:39 +00006474 .pf = NFPROTO_IPV4,
Paul Moore948bf852008-10-10 10:16:32 -04006475 .hooknum = NF_INET_LOCAL_OUT,
6476 .priority = NF_IP_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02006477 },
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04006478#if IS_ENABLED(CONFIG_IPV6)
Paul Mooreeffad8d2008-01-29 08:49:27 -05006479 {
6480 .hook = selinux_ipv6_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00006481 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006482 .hooknum = NF_INET_POST_ROUTING,
6483 .priority = NF_IP6_PRI_SELINUX_LAST,
6484 },
6485 {
6486 .hook = selinux_ipv6_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00006487 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006488 .hooknum = NF_INET_FORWARD,
6489 .priority = NF_IP6_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02006490 },
Huw Davies2917f572016-06-27 15:06:15 -04006491 {
6492 .hook = selinux_ipv6_output,
6493 .pf = NFPROTO_IPV6,
6494 .hooknum = NF_INET_LOCAL_OUT,
6495 .priority = NF_IP6_PRI_SELINUX_FIRST,
6496 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07006497#endif /* IPV6 */
Jiri Pirko25db6be2014-09-03 17:42:13 +02006498};
Linus Torvalds1da177e2005-04-16 15:20:36 -07006499
6500static int __init selinux_nf_ip_init(void)
6501{
Jiri Pirko25db6be2014-09-03 17:42:13 +02006502 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006503
6504 if (!selinux_enabled)
Jiri Pirko25db6be2014-09-03 17:42:13 +02006505 return 0;
Eric Parisfadcdb42007-02-22 18:11:31 -05006506
6507 printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n");
6508
Jiri Pirko25db6be2014-09-03 17:42:13 +02006509 err = nf_register_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops));
Alexey Dobriyan6c5a9d22008-07-26 17:48:15 -07006510 if (err)
Jiri Pirko25db6be2014-09-03 17:42:13 +02006511 panic("SELinux: nf_register_hooks: error %d\n", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006512
Jiri Pirko25db6be2014-09-03 17:42:13 +02006513 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006514}
6515
6516__initcall(selinux_nf_ip_init);
6517
6518#ifdef CONFIG_SECURITY_SELINUX_DISABLE
6519static void selinux_nf_ip_exit(void)
6520{
Eric Parisfadcdb42007-02-22 18:11:31 -05006521 printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006522
Jiri Pirko25db6be2014-09-03 17:42:13 +02006523 nf_unregister_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006524}
6525#endif
6526
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006527#else /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006528
6529#ifdef CONFIG_SECURITY_SELINUX_DISABLE
6530#define selinux_nf_ip_exit()
6531#endif
6532
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006533#endif /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006534
6535#ifdef CONFIG_SECURITY_SELINUX_DISABLE
Eric Paris828dfe12008-04-17 13:17:49 -04006536static int selinux_disabled;
6537
Linus Torvalds1da177e2005-04-16 15:20:36 -07006538int selinux_disable(void)
6539{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540 if (ss_initialized) {
6541 /* Not permitted after initial policy load. */
6542 return -EINVAL;
6543 }
6544
6545 if (selinux_disabled) {
6546 /* Only do this once. */
6547 return -EINVAL;
6548 }
6549
6550 printk(KERN_INFO "SELinux: Disabled at runtime.\n");
6551
6552 selinux_disabled = 1;
Stephen Smalley30d55282006-05-03 10:52:36 -04006553 selinux_enabled = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006554
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07006555 security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006556
Eric Parisaf8ff042009-09-20 21:23:01 -04006557 /* Try to destroy the avc node cache */
6558 avc_disable();
6559
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560 /* Unregister netfilter hooks. */
6561 selinux_nf_ip_exit();
6562
6563 /* Unregister selinuxfs. */
6564 exit_sel_fs();
6565
6566 return 0;
6567}
6568#endif