blob: 169cf5b3334bef7822c0d7756207266ccb1c031c [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 *
Stephen Smalley7efbb602017-08-17 13:32:36 -04006 * Authors: Stephen Smalley, <sds@tycho.nsa.gov>
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>
Daniel Jurgens3a976fa2017-05-19 15:48:56 +030020 * Copyright (C) 2016 Mellanox Technologies
Linus Torvalds1da177e2005-04-16 15:20:36 -070021 *
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License version 2,
Eric Paris828dfe12008-04-17 13:17:49 -040024 * as published by the Free Software Foundation.
Linus Torvalds1da177e2005-04-16 15:20:36 -070025 */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/init.h>
Eric Paris0b24dcb2011-02-25 15:39:20 -050028#include <linux/kd.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/kernel.h>
Roland McGrath0d094ef2008-07-25 19:45:49 -070030#include <linux/tracehook.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/errno.h>
Ingo Molnar3f07c012017-02-08 18:51:30 +010032#include <linux/sched/signal.h>
Ingo Molnar29930022017-02-08 18:51:36 +010033#include <linux/sched/task.h>
Casey Schaufler3c4ed7b2015-05-02 15:10:46 -070034#include <linux/lsm_hooks.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#include <linux/xattr.h>
36#include <linux/capability.h>
37#include <linux/unistd.h>
38#include <linux/mm.h>
39#include <linux/mman.h>
40#include <linux/slab.h>
41#include <linux/pagemap.h>
Eric Paris0b24dcb2011-02-25 15:39:20 -050042#include <linux/proc_fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/swap.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <linux/spinlock.h>
45#include <linux/syscalls.h>
Eric Paris2a7dba32011-02-01 11:05:39 -050046#include <linux/dcache.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <linux/file.h>
Al Viro9f3acc32008-04-24 07:44:08 -040048#include <linux/fdtable.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <linux/namei.h>
50#include <linux/mount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include <linux/netfilter_ipv4.h>
52#include <linux/netfilter_ipv6.h>
53#include <linux/tty.h>
54#include <net/icmp.h>
Stephen Hemminger227b60f2007-10-10 17:30:46 -070055#include <net/ip.h> /* for local_port_range[] */
Linus Torvalds1da177e2005-04-16 15:20:36 -070056#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
Paul Moore47180062013-12-04 16:10:45 -050057#include <net/inet_connection_sock.h>
Paul Moore220deb92008-01-29 08:38:23 -050058#include <net/net_namespace.h>
Paul Moored621d352008-01-29 08:43:36 -050059#include <net/netlabel.h>
Eric Parisf5269712008-05-14 11:27:45 -040060#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070061#include <asm/ioctls.h>
Arun Sharma600634972011-07-26 16:09:06 -070062#include <linux/atomic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070063#include <linux/bitops.h>
64#include <linux/interrupt.h>
65#include <linux/netdevice.h> /* for network interface checks */
Hong zhi guo77954982013-03-27 06:49:35 +000066#include <net/netlink.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070067#include <linux/tcp.h>
68#include <linux/udp.h>
James Morris2ee92d42006-11-13 16:09:01 -080069#include <linux/dccp.h>
Richard Hainesd4529302018-02-13 20:57:18 +000070#include <linux/sctp.h>
71#include <net/sctp/structs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070072#include <linux/quota.h>
73#include <linux/un.h> /* for Unix socket types */
74#include <net/af_unix.h> /* for Unix socket types */
75#include <linux/parser.h>
76#include <linux/nfs_mount.h>
77#include <net/ipv6.h>
78#include <linux/hugetlb.h>
79#include <linux/personality.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070080#include <linux/audit.h>
Eric Paris6931dfc2005-06-30 02:58:51 -070081#include <linux/string.h>
Eric Paris23970742006-09-25 23:32:01 -070082#include <linux/mutex.h>
Frank Mayharf06febc2008-09-12 09:54:39 -070083#include <linux/posix-timers.h>
Kees Cook00234592010-02-03 15:36:43 -080084#include <linux/syslog.h>
Serge E. Hallyn34867402011-03-23 16:43:17 -070085#include <linux/user_namespace.h>
Paul Gortmaker44fc7ea2011-05-26 20:52:10 -040086#include <linux/export.h>
Al Viro40401532012-02-13 03:58:52 +000087#include <linux/msg.h>
88#include <linux/shm.h>
Chenbo Fengec27c352017-10-18 13:00:25 -070089#include <linux/bpf.h>
David Howellse262e32d2018-11-01 23:07:23 +000090#include <uapi/linux/mount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
92#include "avc.h"
93#include "objsec.h"
94#include "netif.h"
Paul Moore224dfbd2008-01-29 08:38:13 -050095#include "netnode.h"
Paul Moore3e1121722008-04-10 10:48:14 -040096#include "netport.h"
Daniel Jurgens409dcf32017-05-19 15:48:59 +030097#include "ibpkey.h"
Trent Jaegerd28d1e02005-12-13 23:12:40 -080098#include "xfrm.h"
Paul Moorec60475b2007-02-28 15:14:23 -050099#include "netlabel.h"
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +0200100#include "audit.h"
James Morris7b98a582011-08-30 12:52:32 +1000101#include "avc_ss.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500103struct selinux_state selinux_state;
104
Paul Moored621d352008-01-29 08:43:36 -0500105/* SECMARK reference count */
James Morris56a4ca92011-08-17 11:08:43 +1000106static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
Paul Moored621d352008-01-29 08:43:36 -0500107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500109static int selinux_enforcing_boot;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
111static int __init enforcing_setup(char *str)
112{
Eric Parisf5269712008-05-14 11:27:45 -0400113 unsigned long enforcing;
Jingoo Han29707b22014-02-05 15:13:14 +0900114 if (!kstrtoul(str, 0, &enforcing))
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500115 selinux_enforcing_boot = enforcing ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 return 1;
117}
118__setup("enforcing=", enforcing_setup);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500119#else
120#define selinux_enforcing_boot 1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121#endif
122
Kees Cookbe6ec882018-10-01 17:08:57 -0700123int selinux_enabled __lsm_ro_after_init = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125static int __init selinux_enabled_setup(char *str)
126{
Eric Parisf5269712008-05-14 11:27:45 -0400127 unsigned long enabled;
Jingoo Han29707b22014-02-05 15:13:14 +0900128 if (!kstrtoul(str, 0, &enabled))
Eric Parisf5269712008-05-14 11:27:45 -0400129 selinux_enabled = enabled ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 return 1;
131}
132__setup("selinux=", selinux_enabled_setup);
133#endif
134
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500135static unsigned int selinux_checkreqprot_boot =
136 CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
137
138static int __init checkreqprot_setup(char *str)
139{
140 unsigned long checkreqprot;
141
142 if (!kstrtoul(str, 0, &checkreqprot))
143 selinux_checkreqprot_boot = checkreqprot ? 1 : 0;
144 return 1;
145}
146__setup("checkreqprot=", checkreqprot_setup);
147
Christoph Lametere18b8902006-12-06 20:33:20 -0800148static struct kmem_cache *sel_inode_cache;
Sangwoo63205652015-10-21 17:44:30 -0400149static struct kmem_cache *file_security_cache;
James Morris7cae7e22006-03-22 00:09:22 -0800150
Paul Moored621d352008-01-29 08:43:36 -0500151/**
152 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
153 *
154 * Description:
155 * This function checks the SECMARK reference counter to see if any SECMARK
156 * targets are currently configured, if the reference counter is greater than
157 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
Chris PeBenito2be4d742013-05-03 09:05:39 -0400158 * enabled, false (0) if SECMARK is disabled. If the always_check_network
159 * policy capability is enabled, SECMARK is always considered enabled.
Paul Moored621d352008-01-29 08:43:36 -0500160 *
161 */
162static int selinux_secmark_enabled(void)
163{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500164 return (selinux_policycap_alwaysnetwork() ||
165 atomic_read(&selinux_secmark_refcount));
Chris PeBenito2be4d742013-05-03 09:05:39 -0400166}
167
168/**
169 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
170 *
171 * Description:
172 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
173 * (1) if any are enabled or false (0) if neither are enabled. If the
174 * always_check_network policy capability is enabled, peer labeling
175 * is always considered enabled.
176 *
177 */
178static int selinux_peerlbl_enabled(void)
179{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500180 return (selinux_policycap_alwaysnetwork() ||
181 netlbl_enabled() || selinux_xfrm_enabled());
Paul Moored621d352008-01-29 08:43:36 -0500182}
183
Paul Moore615e51f2014-06-26 14:33:56 -0400184static int selinux_netcache_avc_callback(u32 event)
185{
186 if (event == AVC_CALLBACK_RESET) {
187 sel_netif_flush();
188 sel_netnode_flush();
189 sel_netport_flush();
190 synchronize_net();
191 }
192 return 0;
193}
194
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300195static int selinux_lsm_notifier_avc_callback(u32 event)
196{
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300197 if (event == AVC_CALLBACK_RESET) {
198 sel_ib_pkey_flush();
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300199 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300200 }
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300201
202 return 0;
203}
204
David Howellsd84f4f92008-11-14 10:39:23 +1100205/*
206 * initialise the security for the init task
207 */
208static void cred_init_security(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209{
David Howells3b11a1d2008-11-14 10:39:26 +1100210 struct cred *cred = (struct cred *) current->real_cred;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 struct task_security_struct *tsec;
212
James Morris89d155e2005-10-30 14:59:21 -0800213 tsec = kzalloc(sizeof(struct task_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 if (!tsec)
David Howellsd84f4f92008-11-14 10:39:23 +1100215 panic("SELinux: Failed to initialize initial task.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
David Howellsd84f4f92008-11-14 10:39:23 +1100217 tsec->osid = tsec->sid = SECINITSID_KERNEL;
David Howellsf1752ee2008-11-14 10:39:17 +1100218 cred->security = tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219}
220
David Howells275bb412008-11-14 10:39:19 +1100221/*
David Howells88e67f32008-11-14 10:39:21 +1100222 * get the security ID of a set of credentials
223 */
224static inline u32 cred_sid(const struct cred *cred)
225{
226 const struct task_security_struct *tsec;
227
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700228 tsec = selinux_cred(cred);
David Howells88e67f32008-11-14 10:39:21 +1100229 return tsec->sid;
230}
231
232/*
David Howells3b11a1d2008-11-14 10:39:26 +1100233 * get the objective security ID of a task
David Howells275bb412008-11-14 10:39:19 +1100234 */
235static inline u32 task_sid(const struct task_struct *task)
236{
David Howells275bb412008-11-14 10:39:19 +1100237 u32 sid;
238
239 rcu_read_lock();
David Howells88e67f32008-11-14 10:39:21 +1100240 sid = cred_sid(__task_cred(task));
David Howells275bb412008-11-14 10:39:19 +1100241 rcu_read_unlock();
242 return sid;
243}
244
David Howells88e67f32008-11-14 10:39:21 +1100245/* Allocate and free functions for each kind of security blob. */
246
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247static int inode_alloc_security(struct inode *inode)
248{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 struct inode_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +1100250 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251
Josef Bacika02fe132008-04-04 09:35:05 +1100252 isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 if (!isec)
254 return -ENOMEM;
255
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +0100256 spin_lock_init(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 INIT_LIST_HEAD(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 isec->inode = inode;
259 isec->sid = SECINITSID_UNLABELED;
260 isec->sclass = SECCLASS_FILE;
David Howells275bb412008-11-14 10:39:19 +1100261 isec->task_sid = sid;
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100262 isec->initialized = LABEL_INVALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 inode->i_security = isec;
264
265 return 0;
266}
267
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500268static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
269
270/*
271 * Try reloading inode security labels that have been marked as invalid. The
272 * @may_sleep parameter indicates when sleeping and thus reloading labels is
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100273 * allowed; when set to false, returns -ECHILD when the label is
Al Viroe9193282018-04-24 21:31:02 -0400274 * invalid. The @dentry parameter should be set to a dentry of the inode.
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500275 */
276static int __inode_security_revalidate(struct inode *inode,
Al Viroe9193282018-04-24 21:31:02 -0400277 struct dentry *dentry,
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500278 bool may_sleep)
279{
280 struct inode_security_struct *isec = inode->i_security;
281
282 might_sleep_if(may_sleep);
283
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500284 if (selinux_state.initialized &&
285 isec->initialized != LABEL_INITIALIZED) {
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500286 if (!may_sleep)
287 return -ECHILD;
288
289 /*
290 * Try reloading the inode security label. This will fail if
291 * @opt_dentry is NULL and no dentry for this inode can be
292 * found; in that case, continue using the old label.
293 */
Al Viroe9193282018-04-24 21:31:02 -0400294 inode_doinit_with_dentry(inode, dentry);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500295 }
296 return 0;
297}
298
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500299static struct inode_security_struct *inode_security_novalidate(struct inode *inode)
300{
301 return inode->i_security;
302}
303
304static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu)
305{
306 int error;
307
308 error = __inode_security_revalidate(inode, NULL, !rcu);
309 if (error)
310 return ERR_PTR(error);
311 return inode->i_security;
312}
313
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500314/*
315 * Get the security label of an inode.
316 */
317static struct inode_security_struct *inode_security(struct inode *inode)
318{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500319 __inode_security_revalidate(inode, NULL, true);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500320 return inode->i_security;
321}
322
Paul Moore2c971652016-04-19 16:36:28 -0400323static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry)
324{
325 struct inode *inode = d_backing_inode(dentry);
326
327 return inode->i_security;
328}
329
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500330/*
331 * Get the security label of a dentry's backing inode.
332 */
333static struct inode_security_struct *backing_inode_security(struct dentry *dentry)
334{
335 struct inode *inode = d_backing_inode(dentry);
336
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500337 __inode_security_revalidate(inode, dentry, true);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500338 return inode->i_security;
339}
340
Steven Rostedt3dc91d42014-01-09 21:46:34 -0500341static void inode_free_rcu(struct rcu_head *head)
342{
343 struct inode_security_struct *isec;
344
345 isec = container_of(head, struct inode_security_struct, rcu);
346 kmem_cache_free(sel_inode_cache, isec);
347}
348
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349static void inode_free_security(struct inode *inode)
350{
351 struct inode_security_struct *isec = inode->i_security;
352 struct superblock_security_struct *sbsec = inode->i_sb->s_security;
353
Waiman Long9629d042015-07-10 17:19:56 -0400354 /*
355 * As not all inode security structures are in a list, we check for
356 * empty list outside of the lock to make sure that we won't waste
357 * time taking a lock doing nothing.
358 *
359 * The list_del_init() function can be safely called more than once.
360 * It should not be possible for this function to be called with
361 * concurrent list_add(), but for better safety against future changes
362 * in the code, we use list_empty_careful() here.
363 */
364 if (!list_empty_careful(&isec->list)) {
365 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 list_del_init(&isec->list);
Waiman Long9629d042015-07-10 17:19:56 -0400367 spin_unlock(&sbsec->isec_lock);
368 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369
Steven Rostedt3dc91d42014-01-09 21:46:34 -0500370 /*
371 * The inode may still be referenced in a path walk and
372 * a call to selinux_inode_permission() can be made
373 * after inode_free_security() is called. Ideally, the VFS
374 * wouldn't do this, but fixing that is a much harder
375 * job. For now, simply free the i_security via RCU, and
376 * leave the current inode->i_security pointer intact.
377 * The inode will be freed after the RCU grace period too.
378 */
379 call_rcu(&isec->rcu, inode_free_rcu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380}
381
382static int file_alloc_security(struct file *file)
383{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 struct file_security_struct *fsec;
David Howells275bb412008-11-14 10:39:19 +1100385 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Sangwoo63205652015-10-21 17:44:30 -0400387 fsec = kmem_cache_zalloc(file_security_cache, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 if (!fsec)
389 return -ENOMEM;
390
David Howells275bb412008-11-14 10:39:19 +1100391 fsec->sid = sid;
392 fsec->fown_sid = sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 file->f_security = fsec;
394
395 return 0;
396}
397
398static void file_free_security(struct file *file)
399{
400 struct file_security_struct *fsec = file->f_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 file->f_security = NULL;
Sangwoo63205652015-10-21 17:44:30 -0400402 kmem_cache_free(file_security_cache, fsec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403}
404
405static int superblock_alloc_security(struct super_block *sb)
406{
407 struct superblock_security_struct *sbsec;
408
James Morris89d155e2005-10-30 14:59:21 -0800409 sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 if (!sbsec)
411 return -ENOMEM;
412
Eric Parisbc7e9822006-09-25 23:32:02 -0700413 mutex_init(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 INIT_LIST_HEAD(&sbsec->isec_head);
415 spin_lock_init(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 sbsec->sb = sb;
417 sbsec->sid = SECINITSID_UNLABELED;
418 sbsec->def_sid = SECINITSID_FILE;
Eric Parisc312feb2006-07-10 04:43:53 -0700419 sbsec->mntpoint_sid = SECINITSID_UNLABELED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 sb->s_security = sbsec;
421
422 return 0;
423}
424
425static void superblock_free_security(struct super_block *sb)
426{
427 struct superblock_security_struct *sbsec = sb->s_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 sb->s_security = NULL;
429 kfree(sbsec);
430}
431
Al Virobd323652018-12-13 15:04:59 -0500432struct selinux_mnt_opts {
433 const char *fscontext, *context, *rootcontext, *defcontext;
434};
435
Al Viro204cc0c2018-12-13 13:41:47 -0500436static void selinux_free_mnt_opts(void *mnt_opts)
437{
Al Virobd323652018-12-13 15:04:59 -0500438 struct selinux_mnt_opts *opts = mnt_opts;
439 kfree(opts->fscontext);
440 kfree(opts->context);
441 kfree(opts->rootcontext);
442 kfree(opts->defcontext);
Al Viro204cc0c2018-12-13 13:41:47 -0500443 kfree(opts);
444}
445
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446static inline int inode_doinit(struct inode *inode)
447{
448 return inode_doinit_with_dentry(inode, NULL);
449}
450
451enum {
Eric Paris31e87932007-09-19 17:19:12 -0400452 Opt_error = -1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 Opt_context = 1,
454 Opt_fscontext = 2,
Eric Parisc9180a52007-11-30 13:00:35 -0500455 Opt_defcontext = 3,
456 Opt_rootcontext = 4,
Al Viroda3d76a2018-12-17 10:14:16 -0500457 Opt_seclabel = 5,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458};
459
Al Viroda3d76a2018-12-17 10:14:16 -0500460#define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg}
Al Viro169d68efb2018-12-14 22:44:50 -0500461static struct {
462 const char *name;
463 int len;
464 int opt;
465 bool has_arg;
466} tokens[] = {
Al Viroda3d76a2018-12-17 10:14:16 -0500467 A(context, true),
468 A(fscontext, true),
469 A(defcontext, true),
470 A(rootcontext, true),
471 A(seclabel, false),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472};
Al Viro169d68efb2018-12-14 22:44:50 -0500473#undef A
474
475static int match_opt_prefix(char *s, int l, char **arg)
476{
477 int i;
478
479 for (i = 0; i < ARRAY_SIZE(tokens); i++) {
480 size_t len = tokens[i].len;
481 if (len > l || memcmp(s, tokens[i].name, len))
482 continue;
483 if (tokens[i].has_arg) {
484 if (len == l || s[len] != '=')
485 continue;
486 *arg = s + len + 1;
487 } else if (len != l)
488 continue;
489 return tokens[i].opt;
490 }
491 return Opt_error;
492}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493
494#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
495
Eric Parisc312feb2006-07-10 04:43:53 -0700496static int may_context_mount_sb_relabel(u32 sid,
497 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100498 const struct cred *cred)
Eric Parisc312feb2006-07-10 04:43:53 -0700499{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700500 const struct task_security_struct *tsec = selinux_cred(cred);
Eric Parisc312feb2006-07-10 04:43:53 -0700501 int rc;
502
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500503 rc = avc_has_perm(&selinux_state,
504 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700505 FILESYSTEM__RELABELFROM, NULL);
506 if (rc)
507 return rc;
508
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500509 rc = avc_has_perm(&selinux_state,
510 tsec->sid, sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700511 FILESYSTEM__RELABELTO, NULL);
512 return rc;
513}
514
Eric Paris08089252006-07-10 04:43:55 -0700515static int may_context_mount_inode_relabel(u32 sid,
516 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100517 const struct cred *cred)
Eric Paris08089252006-07-10 04:43:55 -0700518{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700519 const struct task_security_struct *tsec = selinux_cred(cred);
Eric Paris08089252006-07-10 04:43:55 -0700520 int rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500521 rc = avc_has_perm(&selinux_state,
522 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700523 FILESYSTEM__RELABELFROM, NULL);
524 if (rc)
525 return rc;
526
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500527 rc = avc_has_perm(&selinux_state,
528 sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700529 FILESYSTEM__ASSOCIATE, NULL);
530 return rc;
531}
532
Eric Parisb43e7252012-10-10 14:27:35 -0400533static int selinux_is_sblabel_mnt(struct super_block *sb)
534{
535 struct superblock_security_struct *sbsec = sb->s_security;
536
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500537 return sbsec->behavior == SECURITY_FS_USE_XATTR ||
538 sbsec->behavior == SECURITY_FS_USE_TRANS ||
539 sbsec->behavior == SECURITY_FS_USE_TASK ||
J. Bruce Fields9fc2b4b2015-06-04 15:57:25 -0400540 sbsec->behavior == SECURITY_FS_USE_NATIVE ||
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500541 /* Special handling. Genfs but also in-core setxattr handler */
542 !strcmp(sb->s_type->name, "sysfs") ||
543 !strcmp(sb->s_type->name, "pstore") ||
544 !strcmp(sb->s_type->name, "debugfs") ||
Yongqin Liua2c7c6f2017-01-09 10:07:30 -0500545 !strcmp(sb->s_type->name, "tracefs") ||
Stephen Smalley2651225b2017-02-28 10:35:56 -0500546 !strcmp(sb->s_type->name, "rootfs") ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500547 (selinux_policycap_cgroupseclabel() &&
Stephen Smalley2651225b2017-02-28 10:35:56 -0500548 (!strcmp(sb->s_type->name, "cgroup") ||
549 !strcmp(sb->s_type->name, "cgroup2")));
Eric Parisb43e7252012-10-10 14:27:35 -0400550}
551
Eric Parisc9180a52007-11-30 13:00:35 -0500552static int sb_finish_set_opts(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553{
554 struct superblock_security_struct *sbsec = sb->s_security;
555 struct dentry *root = sb->s_root;
David Howellsc6f493d2015-03-17 22:26:22 +0000556 struct inode *root_inode = d_backing_inode(root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 int rc = 0;
558
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
560 /* Make sure that the xattr handler exists and that no
561 error other than -ENODATA is returned by getxattr on
562 the root directory. -ENODATA is ok, as this may be
563 the first boot of the SELinux kernel before we have
564 assigned xattr values to the filesystem. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200565 if (!(root_inode->i_opflags & IOP_XATTR)) {
peter enderborgc103a912018-06-12 10:09:03 +0200566 pr_warn("SELinux: (dev %s, type %s) has no "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800567 "xattr support\n", sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 rc = -EOPNOTSUPP;
569 goto out;
570 }
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200571
572 rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 if (rc < 0 && rc != -ENODATA) {
574 if (rc == -EOPNOTSUPP)
peter enderborgc103a912018-06-12 10:09:03 +0200575 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800576 "%s) has no security xattr handler\n",
577 sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 else
peter enderborgc103a912018-06-12 10:09:03 +0200579 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800580 "%s) getxattr errno %d\n", sb->s_id,
581 sb->s_type->name, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 goto out;
583 }
584 }
585
Eric Pariseadcabc2012-08-24 15:59:14 -0400586 sbsec->flags |= SE_SBINITIALIZED;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400587
588 /*
589 * Explicitly set or clear SBLABEL_MNT. It's not sufficient to simply
590 * leave the flag untouched because sb_clone_mnt_opts might be handing
591 * us a superblock that needs the flag to be cleared.
592 */
Eric Parisb43e7252012-10-10 14:27:35 -0400593 if (selinux_is_sblabel_mnt(sb))
Eric Paris12f348b2012-10-09 10:56:25 -0400594 sbsec->flags |= SBLABEL_MNT;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400595 else
596 sbsec->flags &= ~SBLABEL_MNT;
David P. Quigleyddd29ec2009-09-09 14:25:37 -0400597
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 /* Initialize the root inode. */
Eric Parisc9180a52007-11-30 13:00:35 -0500599 rc = inode_doinit_with_dentry(root_inode, root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
601 /* Initialize any other inodes associated with the superblock, e.g.
602 inodes created prior to initial policy load or inodes created
603 during get_sb by a pseudo filesystem that directly
604 populates itself. */
605 spin_lock(&sbsec->isec_lock);
Al Viro8d641242018-12-10 15:34:12 -0500606 while (!list_empty(&sbsec->isec_head)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 struct inode_security_struct *isec =
Al Viro8d641242018-12-10 15:34:12 -0500608 list_first_entry(&sbsec->isec_head,
Eric Parisc9180a52007-11-30 13:00:35 -0500609 struct inode_security_struct, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 struct inode *inode = isec->inode;
Stephen Smalley923190d2014-10-06 16:32:52 -0400611 list_del_init(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 spin_unlock(&sbsec->isec_lock);
613 inode = igrab(inode);
614 if (inode) {
Eric Parisc9180a52007-11-30 13:00:35 -0500615 if (!IS_PRIVATE(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 inode_doinit(inode);
617 iput(inode);
618 }
619 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 }
621 spin_unlock(&sbsec->isec_lock);
622out:
Eric Parisc9180a52007-11-30 13:00:35 -0500623 return rc;
624}
625
Eric Parisc9180a52007-11-30 13:00:35 -0500626static int bad_option(struct superblock_security_struct *sbsec, char flag,
627 u32 old_sid, u32 new_sid)
628{
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500629 char mnt_flags = sbsec->flags & SE_MNTMASK;
630
Eric Parisc9180a52007-11-30 13:00:35 -0500631 /* check if the old mount command had the same options */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500632 if (sbsec->flags & SE_SBINITIALIZED)
Eric Parisc9180a52007-11-30 13:00:35 -0500633 if (!(sbsec->flags & flag) ||
634 (old_sid != new_sid))
635 return 1;
636
637 /* check if we were passed the same options twice,
638 * aka someone passed context=a,context=b
639 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500640 if (!(sbsec->flags & SE_SBINITIALIZED))
641 if (mnt_flags & flag)
Eric Parisc9180a52007-11-30 13:00:35 -0500642 return 1;
643 return 0;
644}
Eric Parise0007522008-03-05 10:31:54 -0500645
Al Virobd323652018-12-13 15:04:59 -0500646static int parse_sid(struct super_block *sb, const char *s, u32 *sid)
647{
648 int rc = security_context_str_to_sid(&selinux_state, s,
649 sid, GFP_KERNEL);
650 if (rc)
651 pr_warn("SELinux: security_context_str_to_sid"
652 "(%s) failed for (dev %s, type %s) errno=%d\n",
653 s, sb->s_id, sb->s_type->name, rc);
654 return rc;
655}
656
Eric Parisc9180a52007-11-30 13:00:35 -0500657/*
658 * Allow filesystems with binary mount data to explicitly set mount point
659 * labeling information.
660 */
Eric Parise0007522008-03-05 10:31:54 -0500661static int selinux_set_mnt_opts(struct super_block *sb,
Al Viro204cc0c2018-12-13 13:41:47 -0500662 void *mnt_opts,
David Quigley649f6e72013-05-22 12:50:36 -0400663 unsigned long kern_flags,
664 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500665{
David Howells275bb412008-11-14 10:39:19 +1100666 const struct cred *cred = current_cred();
Eric Parisc9180a52007-11-30 13:00:35 -0500667 struct superblock_security_struct *sbsec = sb->s_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500668 struct dentry *root = sbsec->sb->s_root;
Al Virobd323652018-12-13 15:04:59 -0500669 struct selinux_mnt_opts *opts = mnt_opts;
Paul Moore2c971652016-04-19 16:36:28 -0400670 struct inode_security_struct *root_isec;
Eric Parisc9180a52007-11-30 13:00:35 -0500671 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
672 u32 defcontext_sid = 0;
Al Virobd323652018-12-13 15:04:59 -0500673 int rc = 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500674
675 mutex_lock(&sbsec->lock);
676
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500677 if (!selinux_state.initialized) {
Al Virobd323652018-12-13 15:04:59 -0500678 if (!opts) {
Eric Parisc9180a52007-11-30 13:00:35 -0500679 /* Defer initialization until selinux_complete_init,
680 after the initial policy is loaded and the security
681 server is ready to handle calls. */
Eric Parisc9180a52007-11-30 13:00:35 -0500682 goto out;
683 }
684 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200685 pr_warn("SELinux: Unable to set superblock options "
Eric Paris744ba352008-04-17 11:52:44 -0400686 "before the security server is initialized\n");
Eric Parisc9180a52007-11-30 13:00:35 -0500687 goto out;
688 }
David Quigley649f6e72013-05-22 12:50:36 -0400689 if (kern_flags && !set_kern_flags) {
690 /* Specifying internal flags without providing a place to
691 * place the results is not allowed */
692 rc = -EINVAL;
693 goto out;
694 }
Eric Parisc9180a52007-11-30 13:00:35 -0500695
696 /*
Eric Parise0007522008-03-05 10:31:54 -0500697 * Binary mount data FS will come through this function twice. Once
698 * from an explicit call and once from the generic calls from the vfs.
699 * Since the generic VFS calls will not contain any security mount data
700 * we need to skip the double mount verification.
701 *
702 * This does open a hole in which we will not notice if the first
703 * mount using this sb set explict options and a second mount using
704 * this sb does not set any security options. (The first options
705 * will be used for both mounts)
706 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500707 if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
Al Virobd323652018-12-13 15:04:59 -0500708 && !opts)
Eric Parisf5269712008-05-14 11:27:45 -0400709 goto out;
Eric Parise0007522008-03-05 10:31:54 -0500710
Paul Moore2c971652016-04-19 16:36:28 -0400711 root_isec = backing_inode_security_novalidate(root);
712
Eric Parise0007522008-03-05 10:31:54 -0500713 /*
Eric Parisc9180a52007-11-30 13:00:35 -0500714 * parse the mount options, check if they are valid sids.
715 * also check if someone is trying to mount the same sb more
716 * than once with different security options.
717 */
Al Virobd323652018-12-13 15:04:59 -0500718 if (opts) {
719 if (opts->fscontext) {
720 rc = parse_sid(sb, opts->fscontext, &fscontext_sid);
721 if (rc)
722 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500723 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
724 fscontext_sid))
725 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500726 sbsec->flags |= FSCONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500727 }
728 if (opts->context) {
729 rc = parse_sid(sb, opts->context, &context_sid);
730 if (rc)
731 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500732 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
733 context_sid))
734 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500735 sbsec->flags |= CONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500736 }
737 if (opts->rootcontext) {
738 rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid);
739 if (rc)
740 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500741 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
742 rootcontext_sid))
743 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500744 sbsec->flags |= ROOTCONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500745 }
746 if (opts->defcontext) {
747 rc = parse_sid(sb, opts->defcontext, &defcontext_sid);
748 if (rc)
749 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500750 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
751 defcontext_sid))
752 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500753 sbsec->flags |= DEFCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500754 }
755 }
756
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500757 if (sbsec->flags & SE_SBINITIALIZED) {
Eric Parisc9180a52007-11-30 13:00:35 -0500758 /* previously mounted with options, but not on this attempt? */
Al Virobd323652018-12-13 15:04:59 -0500759 if ((sbsec->flags & SE_MNTMASK) && !opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500760 goto out_double_mount;
761 rc = 0;
762 goto out;
763 }
764
James Morris089be432008-07-15 18:32:49 +1000765 if (strcmp(sb->s_type->name, "proc") == 0)
Stephen Smalley134509d2015-06-04 16:22:17 -0400766 sbsec->flags |= SE_SBPROC | SE_SBGENFS;
767
Stephen Smalley8e014722015-06-04 16:22:17 -0400768 if (!strcmp(sb->s_type->name, "debugfs") ||
Jeff Vander Stoep6a391182017-06-20 09:35:33 -0700769 !strcmp(sb->s_type->name, "tracefs") ||
Stephen Smalley8e014722015-06-04 16:22:17 -0400770 !strcmp(sb->s_type->name, "sysfs") ||
Antonio Murdaca901ef842017-02-09 17:02:42 +0100771 !strcmp(sb->s_type->name, "pstore") ||
772 !strcmp(sb->s_type->name, "cgroup") ||
773 !strcmp(sb->s_type->name, "cgroup2"))
Stephen Smalley134509d2015-06-04 16:22:17 -0400774 sbsec->flags |= SE_SBGENFS;
Eric Parisc9180a52007-11-30 13:00:35 -0500775
David Quigleyeb9ae682013-05-22 12:50:37 -0400776 if (!sbsec->behavior) {
777 /*
778 * Determine the labeling behavior to use for this
779 * filesystem type.
780 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500781 rc = security_fs_use(&selinux_state, sb);
David Quigleyeb9ae682013-05-22 12:50:37 -0400782 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +0200783 pr_warn("%s: security_fs_use(%s) returned %d\n",
David Quigleyeb9ae682013-05-22 12:50:37 -0400784 __func__, sb->s_type->name, rc);
785 goto out;
786 }
Eric Parisc9180a52007-11-30 13:00:35 -0500787 }
Seth Forsheeaad82892016-04-26 14:36:20 -0500788
789 /*
Stephen Smalley01593d32017-01-09 10:07:31 -0500790 * If this is a user namespace mount and the filesystem type is not
791 * explicitly whitelisted, then no contexts are allowed on the command
792 * line and security labels must be ignored.
Seth Forsheeaad82892016-04-26 14:36:20 -0500793 */
Stephen Smalley01593d32017-01-09 10:07:31 -0500794 if (sb->s_user_ns != &init_user_ns &&
795 strcmp(sb->s_type->name, "tmpfs") &&
796 strcmp(sb->s_type->name, "ramfs") &&
797 strcmp(sb->s_type->name, "devpts")) {
Seth Forsheeaad82892016-04-26 14:36:20 -0500798 if (context_sid || fscontext_sid || rootcontext_sid ||
799 defcontext_sid) {
800 rc = -EACCES;
801 goto out;
802 }
803 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
804 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500805 rc = security_transition_sid(&selinux_state,
806 current_sid(),
807 current_sid(),
Seth Forsheeaad82892016-04-26 14:36:20 -0500808 SECCLASS_FILE, NULL,
809 &sbsec->mntpoint_sid);
810 if (rc)
811 goto out;
812 }
813 goto out_set_opts;
814 }
815
Eric Parisc9180a52007-11-30 13:00:35 -0500816 /* sets the context of the superblock for the fs being mounted. */
817 if (fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100818 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500819 if (rc)
820 goto out;
821
822 sbsec->sid = fscontext_sid;
823 }
824
825 /*
826 * Switch to using mount point labeling behavior.
827 * sets the label used on all file below the mountpoint, and will set
828 * the superblock context if not already set.
829 */
David Quigleyeb9ae682013-05-22 12:50:37 -0400830 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
831 sbsec->behavior = SECURITY_FS_USE_NATIVE;
832 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
833 }
834
Eric Parisc9180a52007-11-30 13:00:35 -0500835 if (context_sid) {
836 if (!fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100837 rc = may_context_mount_sb_relabel(context_sid, sbsec,
838 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500839 if (rc)
840 goto out;
841 sbsec->sid = context_sid;
842 } else {
David Howells275bb412008-11-14 10:39:19 +1100843 rc = may_context_mount_inode_relabel(context_sid, sbsec,
844 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500845 if (rc)
846 goto out;
847 }
848 if (!rootcontext_sid)
849 rootcontext_sid = context_sid;
850
851 sbsec->mntpoint_sid = context_sid;
852 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
853 }
854
855 if (rootcontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100856 rc = may_context_mount_inode_relabel(rootcontext_sid, sbsec,
857 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500858 if (rc)
859 goto out;
860
861 root_isec->sid = rootcontext_sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -0500862 root_isec->initialized = LABEL_INITIALIZED;
Eric Parisc9180a52007-11-30 13:00:35 -0500863 }
864
865 if (defcontext_sid) {
David Quigleyeb9ae682013-05-22 12:50:37 -0400866 if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
867 sbsec->behavior != SECURITY_FS_USE_NATIVE) {
Eric Parisc9180a52007-11-30 13:00:35 -0500868 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200869 pr_warn("SELinux: defcontext option is "
Eric Parisc9180a52007-11-30 13:00:35 -0500870 "invalid for this filesystem type\n");
871 goto out;
872 }
873
874 if (defcontext_sid != sbsec->def_sid) {
875 rc = may_context_mount_inode_relabel(defcontext_sid,
David Howells275bb412008-11-14 10:39:19 +1100876 sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500877 if (rc)
878 goto out;
879 }
880
881 sbsec->def_sid = defcontext_sid;
882 }
883
Seth Forsheeaad82892016-04-26 14:36:20 -0500884out_set_opts:
Eric Parisc9180a52007-11-30 13:00:35 -0500885 rc = sb_finish_set_opts(sb);
886out:
Eric Parisbc7e9822006-09-25 23:32:02 -0700887 mutex_unlock(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -0500889out_double_mount:
890 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200891 pr_warn("SELinux: mount invalid. Same superblock, different "
Al Virobd323652018-12-13 15:04:59 -0500892 "security settings for (dev %s, type %s)\n", sb->s_id,
893 sb->s_type->name);
Eric Parisc9180a52007-11-30 13:00:35 -0500894 goto out;
895}
896
Jeff Layton094f7b62013-04-01 08:14:24 -0400897static int selinux_cmp_sb_context(const struct super_block *oldsb,
898 const struct super_block *newsb)
899{
900 struct superblock_security_struct *old = oldsb->s_security;
901 struct superblock_security_struct *new = newsb->s_security;
902 char oldflags = old->flags & SE_MNTMASK;
903 char newflags = new->flags & SE_MNTMASK;
904
905 if (oldflags != newflags)
906 goto mismatch;
907 if ((oldflags & FSCONTEXT_MNT) && old->sid != new->sid)
908 goto mismatch;
909 if ((oldflags & CONTEXT_MNT) && old->mntpoint_sid != new->mntpoint_sid)
910 goto mismatch;
911 if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid)
912 goto mismatch;
913 if (oldflags & ROOTCONTEXT_MNT) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500914 struct inode_security_struct *oldroot = backing_inode_security(oldsb->s_root);
915 struct inode_security_struct *newroot = backing_inode_security(newsb->s_root);
Jeff Layton094f7b62013-04-01 08:14:24 -0400916 if (oldroot->sid != newroot->sid)
917 goto mismatch;
918 }
919 return 0;
920mismatch:
peter enderborgc103a912018-06-12 10:09:03 +0200921 pr_warn("SELinux: mount invalid. Same superblock, "
Jeff Layton094f7b62013-04-01 08:14:24 -0400922 "different security settings for (dev %s, "
923 "type %s)\n", newsb->s_id, newsb->s_type->name);
924 return -EBUSY;
925}
926
927static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400928 struct super_block *newsb,
929 unsigned long kern_flags,
930 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500931{
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400932 int rc = 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500933 const struct superblock_security_struct *oldsbsec = oldsb->s_security;
934 struct superblock_security_struct *newsbsec = newsb->s_security;
935
936 int set_fscontext = (oldsbsec->flags & FSCONTEXT_MNT);
937 int set_context = (oldsbsec->flags & CONTEXT_MNT);
938 int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT);
939
Eric Paris0f5e6422008-04-21 16:24:11 -0400940 /*
941 * if the parent was able to be mounted it clearly had no special lsm
Al Viroe8c26252010-03-23 06:36:54 -0400942 * mount options. thus we can safely deal with this superblock later
Eric Paris0f5e6422008-04-21 16:24:11 -0400943 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500944 if (!selinux_state.initialized)
Jeff Layton094f7b62013-04-01 08:14:24 -0400945 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500946
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400947 /*
948 * Specifying internal flags without providing a place to
949 * place the results is not allowed.
950 */
951 if (kern_flags && !set_kern_flags)
952 return -EINVAL;
953
Eric Parisc9180a52007-11-30 13:00:35 -0500954 /* how can we clone if the old one wasn't set up?? */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500955 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
Eric Parisc9180a52007-11-30 13:00:35 -0500956
Jeff Layton094f7b62013-04-01 08:14:24 -0400957 /* if fs is reusing a sb, make sure that the contexts match */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500958 if (newsbsec->flags & SE_SBINITIALIZED)
Jeff Layton094f7b62013-04-01 08:14:24 -0400959 return selinux_cmp_sb_context(oldsb, newsb);
Eric Paris5a552612008-04-09 14:08:35 -0400960
Eric Parisc9180a52007-11-30 13:00:35 -0500961 mutex_lock(&newsbsec->lock);
962
963 newsbsec->flags = oldsbsec->flags;
964
965 newsbsec->sid = oldsbsec->sid;
966 newsbsec->def_sid = oldsbsec->def_sid;
967 newsbsec->behavior = oldsbsec->behavior;
968
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400969 if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
970 !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500971 rc = security_fs_use(&selinux_state, newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400972 if (rc)
973 goto out;
974 }
975
976 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !set_context) {
977 newsbsec->behavior = SECURITY_FS_USE_NATIVE;
978 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
979 }
980
Eric Parisc9180a52007-11-30 13:00:35 -0500981 if (set_context) {
982 u32 sid = oldsbsec->mntpoint_sid;
983
984 if (!set_fscontext)
985 newsbsec->sid = sid;
986 if (!set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500987 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -0500988 newisec->sid = sid;
989 }
990 newsbsec->mntpoint_sid = sid;
991 }
992 if (set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500993 const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root);
994 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -0500995
996 newisec->sid = oldisec->sid;
997 }
998
999 sb_finish_set_opts(newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -04001000out:
Eric Parisc9180a52007-11-30 13:00:35 -05001001 mutex_unlock(&newsbsec->lock);
Scott Mayhew0b4d3452017-06-05 11:45:04 -04001002 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -05001003}
1004
Al Viroba641862018-12-14 20:28:15 -05001005static int selinux_add_opt(int token, const char *s, void **mnt_opts)
Eric Parisc9180a52007-11-30 13:00:35 -05001006{
Al Viroba641862018-12-14 20:28:15 -05001007 struct selinux_mnt_opts *opts = *mnt_opts;
Eric Parisc9180a52007-11-30 13:00:35 -05001008
Al Viroda3d76a2018-12-17 10:14:16 -05001009 if (token == Opt_seclabel) /* eaten and completely ignored */
Al Viro169d68efb2018-12-14 22:44:50 -05001010 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -05001011
Al Viroba641862018-12-14 20:28:15 -05001012 if (!opts) {
1013 opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL);
1014 if (!opts)
1015 return -ENOMEM;
1016 *mnt_opts = opts;
1017 }
1018 if (!s)
1019 return -ENOMEM;
1020 switch (token) {
1021 case Opt_context:
1022 if (opts->context || opts->defcontext)
1023 goto Einval;
1024 opts->context = s;
1025 break;
1026 case Opt_fscontext:
1027 if (opts->fscontext)
1028 goto Einval;
1029 opts->fscontext = s;
1030 break;
1031 case Opt_rootcontext:
1032 if (opts->rootcontext)
1033 goto Einval;
1034 opts->rootcontext = s;
1035 break;
1036 case Opt_defcontext:
1037 if (opts->context || opts->defcontext)
1038 goto Einval;
1039 opts->defcontext = s;
1040 break;
1041 }
1042 return 0;
1043Einval:
1044 pr_warn(SEL_MOUNT_FAIL_MSG);
Al Viroba641862018-12-14 20:28:15 -05001045 return -EINVAL;
1046}
Eric Parisc9180a52007-11-30 13:00:35 -05001047
Al Viro757cbe52018-12-14 23:42:21 -05001048static int selinux_add_mnt_opt(const char *option, const char *val, int len,
1049 void **mnt_opts)
Eric Parisc9180a52007-11-30 13:00:35 -05001050{
Al Viro757cbe52018-12-14 23:42:21 -05001051 int token = Opt_error;
1052 int rc, i;
Eric Parisc9180a52007-11-30 13:00:35 -05001053
Al Viro757cbe52018-12-14 23:42:21 -05001054 for (i = 0; i < ARRAY_SIZE(tokens); i++) {
1055 if (strcmp(option, tokens[i].name) == 0) {
1056 token = tokens[i].opt;
Eric Parisc9180a52007-11-30 13:00:35 -05001057 break;
Eric Parisc9180a52007-11-30 13:00:35 -05001058 }
1059 }
1060
Al Viro757cbe52018-12-14 23:42:21 -05001061 if (token == Opt_error)
1062 return -EINVAL;
Eric Parise0007522008-03-05 10:31:54 -05001063
Al Viro757cbe52018-12-14 23:42:21 -05001064 if (token != Opt_seclabel)
1065 val = kmemdup_nul(val, len, GFP_KERNEL);
1066 rc = selinux_add_opt(token, val, mnt_opts);
1067 if (unlikely(rc)) {
1068 kfree(val);
1069 if (*mnt_opts) {
1070 selinux_free_mnt_opts(*mnt_opts);
1071 *mnt_opts = NULL;
1072 }
1073 }
1074 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
Al Viroe3489f82018-12-13 00:24:36 -05001077static int show_sid(struct seq_file *m, u32 sid)
Eric Paris2069f452008-07-04 09:47:13 +10001078{
Al Viroe3489f82018-12-13 00:24:36 -05001079 char *context = NULL;
1080 u32 len;
1081 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082
Al Viroe3489f82018-12-13 00:24:36 -05001083 rc = security_sid_to_context(&selinux_state, sid,
1084 &context, &len);
1085 if (!rc) {
1086 bool has_comma = context && strchr(context, ',');
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
Eric Paris2069f452008-07-04 09:47:13 +10001088 if (has_comma)
1089 seq_putc(m, '\"');
Al Viroe3489f82018-12-13 00:24:36 -05001090 seq_escape(m, context, "\"\n\\");
Eric Paris2069f452008-07-04 09:47:13 +10001091 if (has_comma)
1092 seq_putc(m, '\"');
1093 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 kfree(context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 return rc;
1096}
Eric Paris2069f452008-07-04 09:47:13 +10001097
1098static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
1099{
Al Viroe3489f82018-12-13 00:24:36 -05001100 struct superblock_security_struct *sbsec = sb->s_security;
Eric Paris2069f452008-07-04 09:47:13 +10001101 int rc;
1102
Al Viroe3489f82018-12-13 00:24:36 -05001103 if (!(sbsec->flags & SE_SBINITIALIZED))
1104 return 0;
1105
1106 if (!selinux_state.initialized)
1107 return 0;
1108
1109 if (sbsec->flags & FSCONTEXT_MNT) {
1110 seq_putc(m, ',');
1111 seq_puts(m, FSCONTEXT_STR);
1112 rc = show_sid(m, sbsec->sid);
1113 if (rc)
1114 return rc;
Eric Paris383795c2008-07-29 17:07:26 -04001115 }
Al Viroe3489f82018-12-13 00:24:36 -05001116 if (sbsec->flags & CONTEXT_MNT) {
1117 seq_putc(m, ',');
1118 seq_puts(m, CONTEXT_STR);
1119 rc = show_sid(m, sbsec->mntpoint_sid);
1120 if (rc)
1121 return rc;
1122 }
1123 if (sbsec->flags & DEFCONTEXT_MNT) {
1124 seq_putc(m, ',');
1125 seq_puts(m, DEFCONTEXT_STR);
1126 rc = show_sid(m, sbsec->def_sid);
1127 if (rc)
1128 return rc;
1129 }
1130 if (sbsec->flags & ROOTCONTEXT_MNT) {
1131 struct dentry *root = sbsec->sb->s_root;
1132 struct inode_security_struct *isec = backing_inode_security(root);
1133 seq_putc(m, ',');
1134 seq_puts(m, ROOTCONTEXT_STR);
1135 rc = show_sid(m, isec->sid);
1136 if (rc)
1137 return rc;
1138 }
1139 if (sbsec->flags & SBLABEL_MNT) {
1140 seq_putc(m, ',');
1141 seq_puts(m, LABELSUPP_STR);
1142 }
1143 return 0;
Eric Paris2069f452008-07-04 09:47:13 +10001144}
1145
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146static inline u16 inode_mode_to_security_class(umode_t mode)
1147{
1148 switch (mode & S_IFMT) {
1149 case S_IFSOCK:
1150 return SECCLASS_SOCK_FILE;
1151 case S_IFLNK:
1152 return SECCLASS_LNK_FILE;
1153 case S_IFREG:
1154 return SECCLASS_FILE;
1155 case S_IFBLK:
1156 return SECCLASS_BLK_FILE;
1157 case S_IFDIR:
1158 return SECCLASS_DIR;
1159 case S_IFCHR:
1160 return SECCLASS_CHR_FILE;
1161 case S_IFIFO:
1162 return SECCLASS_FIFO_FILE;
1163
1164 }
1165
1166 return SECCLASS_FILE;
1167}
1168
James Morris13402582005-09-30 14:24:34 -04001169static inline int default_protocol_stream(int protocol)
1170{
1171 return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP);
1172}
1173
1174static inline int default_protocol_dgram(int protocol)
1175{
1176 return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP);
1177}
1178
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179static inline u16 socket_type_to_security_class(int family, int type, int protocol)
1180{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001181 int extsockclass = selinux_policycap_extsockclass();
Stephen Smalleyda69a532017-01-09 10:07:30 -05001182
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 switch (family) {
1184 case PF_UNIX:
1185 switch (type) {
1186 case SOCK_STREAM:
1187 case SOCK_SEQPACKET:
1188 return SECCLASS_UNIX_STREAM_SOCKET;
1189 case SOCK_DGRAM:
Luis Ressel2a764b52017-07-25 15:13:41 -04001190 case SOCK_RAW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 return SECCLASS_UNIX_DGRAM_SOCKET;
1192 }
1193 break;
1194 case PF_INET:
1195 case PF_INET6:
1196 switch (type) {
1197 case SOCK_STREAM:
Stephen Smalleyda69a532017-01-09 10:07:30 -05001198 case SOCK_SEQPACKET:
James Morris13402582005-09-30 14:24:34 -04001199 if (default_protocol_stream(protocol))
1200 return SECCLASS_TCP_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001201 else if (extsockclass && protocol == IPPROTO_SCTP)
1202 return SECCLASS_SCTP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001203 else
1204 return SECCLASS_RAWIP_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 case SOCK_DGRAM:
James Morris13402582005-09-30 14:24:34 -04001206 if (default_protocol_dgram(protocol))
1207 return SECCLASS_UDP_SOCKET;
Stephen Smalleyef379792017-01-09 10:07:31 -05001208 else if (extsockclass && (protocol == IPPROTO_ICMP ||
1209 protocol == IPPROTO_ICMPV6))
Stephen Smalleyda69a532017-01-09 10:07:30 -05001210 return SECCLASS_ICMP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001211 else
1212 return SECCLASS_RAWIP_SOCKET;
James Morris2ee92d42006-11-13 16:09:01 -08001213 case SOCK_DCCP:
1214 return SECCLASS_DCCP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001215 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 return SECCLASS_RAWIP_SOCKET;
1217 }
1218 break;
1219 case PF_NETLINK:
1220 switch (protocol) {
1221 case NETLINK_ROUTE:
1222 return SECCLASS_NETLINK_ROUTE_SOCKET;
Pavel Emelyanov7f1fb602011-12-06 07:56:43 +00001223 case NETLINK_SOCK_DIAG:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 return SECCLASS_NETLINK_TCPDIAG_SOCKET;
1225 case NETLINK_NFLOG:
1226 return SECCLASS_NETLINK_NFLOG_SOCKET;
1227 case NETLINK_XFRM:
1228 return SECCLASS_NETLINK_XFRM_SOCKET;
1229 case NETLINK_SELINUX:
1230 return SECCLASS_NETLINK_SELINUX_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001231 case NETLINK_ISCSI:
1232 return SECCLASS_NETLINK_ISCSI_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 case NETLINK_AUDIT:
1234 return SECCLASS_NETLINK_AUDIT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001235 case NETLINK_FIB_LOOKUP:
1236 return SECCLASS_NETLINK_FIB_LOOKUP_SOCKET;
1237 case NETLINK_CONNECTOR:
1238 return SECCLASS_NETLINK_CONNECTOR_SOCKET;
1239 case NETLINK_NETFILTER:
1240 return SECCLASS_NETLINK_NETFILTER_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 case NETLINK_DNRTMSG:
1242 return SECCLASS_NETLINK_DNRT_SOCKET;
James Morris0c9b7942005-04-16 15:24:13 -07001243 case NETLINK_KOBJECT_UEVENT:
1244 return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001245 case NETLINK_GENERIC:
1246 return SECCLASS_NETLINK_GENERIC_SOCKET;
1247 case NETLINK_SCSITRANSPORT:
1248 return SECCLASS_NETLINK_SCSITRANSPORT_SOCKET;
1249 case NETLINK_RDMA:
1250 return SECCLASS_NETLINK_RDMA_SOCKET;
1251 case NETLINK_CRYPTO:
1252 return SECCLASS_NETLINK_CRYPTO_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 default:
1254 return SECCLASS_NETLINK_SOCKET;
1255 }
1256 case PF_PACKET:
1257 return SECCLASS_PACKET_SOCKET;
1258 case PF_KEY:
1259 return SECCLASS_KEY_SOCKET;
Christopher J. PeBenito3e3ff152006-06-09 00:25:03 -07001260 case PF_APPLETALK:
1261 return SECCLASS_APPLETALK_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262 }
1263
Stephen Smalleyda69a532017-01-09 10:07:30 -05001264 if (extsockclass) {
1265 switch (family) {
1266 case PF_AX25:
1267 return SECCLASS_AX25_SOCKET;
1268 case PF_IPX:
1269 return SECCLASS_IPX_SOCKET;
1270 case PF_NETROM:
1271 return SECCLASS_NETROM_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001272 case PF_ATMPVC:
1273 return SECCLASS_ATMPVC_SOCKET;
1274 case PF_X25:
1275 return SECCLASS_X25_SOCKET;
1276 case PF_ROSE:
1277 return SECCLASS_ROSE_SOCKET;
1278 case PF_DECnet:
1279 return SECCLASS_DECNET_SOCKET;
1280 case PF_ATMSVC:
1281 return SECCLASS_ATMSVC_SOCKET;
1282 case PF_RDS:
1283 return SECCLASS_RDS_SOCKET;
1284 case PF_IRDA:
1285 return SECCLASS_IRDA_SOCKET;
1286 case PF_PPPOX:
1287 return SECCLASS_PPPOX_SOCKET;
1288 case PF_LLC:
1289 return SECCLASS_LLC_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001290 case PF_CAN:
1291 return SECCLASS_CAN_SOCKET;
1292 case PF_TIPC:
1293 return SECCLASS_TIPC_SOCKET;
1294 case PF_BLUETOOTH:
1295 return SECCLASS_BLUETOOTH_SOCKET;
1296 case PF_IUCV:
1297 return SECCLASS_IUCV_SOCKET;
1298 case PF_RXRPC:
1299 return SECCLASS_RXRPC_SOCKET;
1300 case PF_ISDN:
1301 return SECCLASS_ISDN_SOCKET;
1302 case PF_PHONET:
1303 return SECCLASS_PHONET_SOCKET;
1304 case PF_IEEE802154:
1305 return SECCLASS_IEEE802154_SOCKET;
1306 case PF_CAIF:
1307 return SECCLASS_CAIF_SOCKET;
1308 case PF_ALG:
1309 return SECCLASS_ALG_SOCKET;
1310 case PF_NFC:
1311 return SECCLASS_NFC_SOCKET;
1312 case PF_VSOCK:
1313 return SECCLASS_VSOCK_SOCKET;
1314 case PF_KCM:
1315 return SECCLASS_KCM_SOCKET;
1316 case PF_QIPCRTR:
1317 return SECCLASS_QIPCRTR_SOCKET;
Linus Torvalds3051bf32017-02-22 10:15:09 -08001318 case PF_SMC:
1319 return SECCLASS_SMC_SOCKET;
Björn Töpel68e8b842018-05-02 13:01:22 +02001320 case PF_XDP:
1321 return SECCLASS_XDP_SOCKET;
1322#if PF_MAX > 45
Stephen Smalleyda69a532017-01-09 10:07:30 -05001323#error New address family defined, please update this function.
1324#endif
1325 }
1326 }
1327
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 return SECCLASS_SOCKET;
1329}
1330
Stephen Smalley134509d2015-06-04 16:22:17 -04001331static int selinux_genfs_get_sid(struct dentry *dentry,
1332 u16 tclass,
1333 u16 flags,
1334 u32 *sid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335{
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001336 int rc;
Al Virofc640052016-04-10 01:33:30 -04001337 struct super_block *sb = dentry->d_sb;
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001338 char *buffer, *path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339
Eric Paris828dfe12008-04-17 13:17:49 -04001340 buffer = (char *)__get_free_page(GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 if (!buffer)
1342 return -ENOMEM;
1343
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001344 path = dentry_path_raw(dentry, buffer, PAGE_SIZE);
1345 if (IS_ERR(path))
1346 rc = PTR_ERR(path);
1347 else {
Stephen Smalley134509d2015-06-04 16:22:17 -04001348 if (flags & SE_SBPROC) {
1349 /* each process gets a /proc/PID/ entry. Strip off the
1350 * PID part to get a valid selinux labeling.
1351 * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
1352 while (path[1] >= '0' && path[1] <= '9') {
1353 path[1] = '/';
1354 path++;
1355 }
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001356 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001357 rc = security_genfs_sid(&selinux_state, sb->s_type->name,
1358 path, tclass, sid);
Stephen Smalley7bb185e2018-09-04 16:51:36 -04001359 if (rc == -ENOENT) {
1360 /* No match in policy, mark as unlabeled. */
1361 *sid = SECINITSID_UNLABELED;
1362 rc = 0;
1363 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 free_page((unsigned long)buffer);
1366 return rc;
1367}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368
1369/* The inode's security attributes must be initialized before first use. */
1370static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
1371{
1372 struct superblock_security_struct *sbsec = NULL;
1373 struct inode_security_struct *isec = inode->i_security;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001374 u32 task_sid, sid = 0;
1375 u16 sclass;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 struct dentry *dentry;
1377#define INITCONTEXTLEN 255
1378 char *context = NULL;
1379 unsigned len = 0;
1380 int rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001382 if (isec->initialized == LABEL_INITIALIZED)
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001383 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001385 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001386 if (isec->initialized == LABEL_INITIALIZED)
Eric Paris23970742006-09-25 23:32:01 -07001387 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001389 if (isec->sclass == SECCLASS_FILE)
1390 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1391
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 sbsec = inode->i_sb->s_security;
David P. Quigley0d90a7e2009-01-16 09:22:02 -05001393 if (!(sbsec->flags & SE_SBINITIALIZED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 /* Defer initialization until selinux_complete_init,
1395 after the initial policy is loaded and the security
1396 server is ready to handle calls. */
1397 spin_lock(&sbsec->isec_lock);
1398 if (list_empty(&isec->list))
1399 list_add(&isec->list, &sbsec->isec_head);
1400 spin_unlock(&sbsec->isec_lock);
Eric Paris23970742006-09-25 23:32:01 -07001401 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 }
1403
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001404 sclass = isec->sclass;
1405 task_sid = isec->task_sid;
1406 sid = isec->sid;
1407 isec->initialized = LABEL_PENDING;
1408 spin_unlock(&isec->lock);
1409
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 switch (sbsec->behavior) {
David Quigleyeb9ae682013-05-22 12:50:37 -04001411 case SECURITY_FS_USE_NATIVE:
1412 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 case SECURITY_FS_USE_XATTR:
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001414 if (!(inode->i_opflags & IOP_XATTR)) {
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001415 sid = sbsec->def_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416 break;
1417 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 /* Need a dentry, since the xattr API requires one.
1419 Life would be simpler if we could just pass the inode. */
1420 if (opt_dentry) {
1421 /* Called from d_instantiate or d_splice_alias. */
1422 dentry = dget(opt_dentry);
1423 } else {
Al Virob1271252018-04-25 10:28:38 -04001424 /*
1425 * Called from selinux_complete_init, try to find a dentry.
1426 * Some filesystems really want a connected one, so try
1427 * that first. We could split SECURITY_FS_USE_XATTR in
1428 * two, depending upon that...
1429 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001431 if (!dentry)
1432 dentry = d_find_any_alias(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433 }
1434 if (!dentry) {
Eric Parisdf7f54c2009-03-09 14:35:58 -04001435 /*
1436 * this is can be hit on boot when a file is accessed
1437 * before the policy is loaded. When we load policy we
1438 * may find inodes that have no dentry on the
1439 * sbsec->isec_head list. No reason to complain as these
1440 * will get fixed up the next time we go through
1441 * inode_doinit with a dentry, before these inodes could
1442 * be used again by userspace.
1443 */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001444 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 }
1446
1447 len = INITCONTEXTLEN;
Eric Paris4cb912f2009-02-12 14:50:05 -05001448 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 if (!context) {
1450 rc = -ENOMEM;
1451 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001452 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001454 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001455 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 if (rc == -ERANGE) {
James Morris314dabb2009-08-10 22:00:13 +10001457 kfree(context);
1458
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 /* Need a larger buffer. Query for the right size. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001460 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461 if (rc < 0) {
1462 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001463 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 len = rc;
Eric Paris4cb912f2009-02-12 14:50:05 -05001466 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 if (!context) {
1468 rc = -ENOMEM;
1469 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001470 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001472 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001473 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 }
1475 dput(dentry);
1476 if (rc < 0) {
1477 if (rc != -ENODATA) {
peter enderborgc103a912018-06-12 10:09:03 +02001478 pr_warn("SELinux: %s: getxattr returned "
Harvey Harrisondd6f9532008-03-06 10:03:59 +11001479 "%d for dev=%s ino=%ld\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 -rc, inode->i_sb->s_id, inode->i_ino);
1481 kfree(context);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001482 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 }
1484 /* Map ENODATA to the default file SID */
1485 sid = sbsec->def_sid;
1486 rc = 0;
1487 } else {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001488 rc = security_context_to_sid_default(&selinux_state,
1489 context, rc, &sid,
Stephen Smalley869ab512008-04-04 08:46:05 -04001490 sbsec->def_sid,
1491 GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 if (rc) {
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001493 char *dev = inode->i_sb->s_id;
1494 unsigned long ino = inode->i_ino;
1495
1496 if (rc == -EINVAL) {
1497 if (printk_ratelimit())
peter enderborgc103a912018-06-12 10:09:03 +02001498 pr_notice("SELinux: inode=%lu on dev=%s was found to have an invalid "
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001499 "context=%s. This indicates you may need to relabel the inode or the "
1500 "filesystem in question.\n", ino, dev, context);
1501 } else {
peter enderborgc103a912018-06-12 10:09:03 +02001502 pr_warn("SELinux: %s: context_to_sid(%s) "
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001503 "returned %d for dev=%s ino=%ld\n",
1504 __func__, context, -rc, dev, ino);
1505 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 kfree(context);
1507 /* Leave with the unlabeled SID */
1508 rc = 0;
1509 break;
1510 }
1511 }
1512 kfree(context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 break;
1514 case SECURITY_FS_USE_TASK:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001515 sid = task_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 break;
1517 case SECURITY_FS_USE_TRANS:
1518 /* Default to the fs SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001519 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520
1521 /* Try to obtain a transition SID. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001522 rc = security_transition_sid(&selinux_state, task_sid, sid,
1523 sclass, NULL, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001525 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 break;
Eric Parisc312feb2006-07-10 04:43:53 -07001527 case SECURITY_FS_USE_MNTPOINT:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001528 sid = sbsec->mntpoint_sid;
Eric Parisc312feb2006-07-10 04:43:53 -07001529 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 default:
Eric Parisc312feb2006-07-10 04:43:53 -07001531 /* Default to the fs superblock SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001532 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533
Stephen Smalley134509d2015-06-04 16:22:17 -04001534 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
Paul Mooref64410e2014-03-19 16:46:18 -04001535 /* We must have a dentry to determine the label on
1536 * procfs inodes */
Al Virob1271252018-04-25 10:28:38 -04001537 if (opt_dentry) {
Paul Mooref64410e2014-03-19 16:46:18 -04001538 /* Called from d_instantiate or
1539 * d_splice_alias. */
1540 dentry = dget(opt_dentry);
Al Virob1271252018-04-25 10:28:38 -04001541 } else {
Paul Mooref64410e2014-03-19 16:46:18 -04001542 /* Called from selinux_complete_init, try to
Al Virob1271252018-04-25 10:28:38 -04001543 * find a dentry. Some filesystems really want
1544 * a connected one, so try that first.
1545 */
Paul Mooref64410e2014-03-19 16:46:18 -04001546 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001547 if (!dentry)
1548 dentry = d_find_any_alias(inode);
1549 }
Paul Mooref64410e2014-03-19 16:46:18 -04001550 /*
1551 * This can be hit on boot when a file is accessed
1552 * before the policy is loaded. When we load policy we
1553 * may find inodes that have no dentry on the
1554 * sbsec->isec_head list. No reason to complain as
1555 * these will get fixed up the next time we go through
1556 * inode_doinit() with a dentry, before these inodes
1557 * could be used again by userspace.
1558 */
1559 if (!dentry)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001560 goto out;
1561 rc = selinux_genfs_get_sid(dentry, sclass,
Stephen Smalley134509d2015-06-04 16:22:17 -04001562 sbsec->flags, &sid);
Paul Mooref64410e2014-03-19 16:46:18 -04001563 dput(dentry);
1564 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001565 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 }
1567 break;
1568 }
1569
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001570out:
1571 spin_lock(&isec->lock);
1572 if (isec->initialized == LABEL_PENDING) {
1573 if (!sid || rc) {
1574 isec->initialized = LABEL_INVALID;
1575 goto out_unlock;
1576 }
1577
1578 isec->initialized = LABEL_INITIALIZED;
1579 isec->sid = sid;
1580 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581
Eric Paris23970742006-09-25 23:32:01 -07001582out_unlock:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001583 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 return rc;
1585}
1586
1587/* Convert a Linux signal to an access vector. */
1588static inline u32 signal_to_av(int sig)
1589{
1590 u32 perm = 0;
1591
1592 switch (sig) {
1593 case SIGCHLD:
1594 /* Commonly granted from child to parent. */
1595 perm = PROCESS__SIGCHLD;
1596 break;
1597 case SIGKILL:
1598 /* Cannot be caught or ignored */
1599 perm = PROCESS__SIGKILL;
1600 break;
1601 case SIGSTOP:
1602 /* Cannot be caught or ignored */
1603 perm = PROCESS__SIGSTOP;
1604 break;
1605 default:
1606 /* All other signals. */
1607 perm = PROCESS__SIGNAL;
1608 break;
1609 }
1610
1611 return perm;
1612}
1613
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001614#if CAP_LAST_CAP > 63
1615#error Fix SELinux to handle capabilities > 63.
1616#endif
1617
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618/* Check whether a task is allowed to use a capability. */
Eric Paris6a9de492012-01-03 12:25:14 -05001619static int cred_has_capability(const struct cred *cred,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001620 int cap, int audit, bool initns)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621{
Thomas Liu2bf49692009-07-14 12:14:09 -04001622 struct common_audit_data ad;
Eric Paris06112162008-11-11 22:02:50 +11001623 struct av_decision avd;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001624 u16 sclass;
David Howells3699c532009-01-06 22:27:01 +00001625 u32 sid = cred_sid(cred);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001626 u32 av = CAP_TO_MASK(cap);
Eric Paris06112162008-11-11 22:02:50 +11001627 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628
Eric Paris50c205f2012-04-04 15:01:43 -04001629 ad.type = LSM_AUDIT_DATA_CAP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 ad.u.cap = cap;
1631
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001632 switch (CAP_TO_INDEX(cap)) {
1633 case 0:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001634 sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001635 break;
1636 case 1:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001637 sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001638 break;
1639 default:
peter enderborgc103a912018-06-12 10:09:03 +02001640 pr_err("SELinux: out of range capability %d\n", cap);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001641 BUG();
Eric Parisa35c6c832011-04-20 10:21:28 -04001642 return -EINVAL;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001643 }
Eric Paris06112162008-11-11 22:02:50 +11001644
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001645 rc = avc_has_perm_noaudit(&selinux_state,
1646 sid, sid, sclass, av, 0, &avd);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001647 if (audit == SECURITY_CAP_AUDIT) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001648 int rc2 = avc_audit(&selinux_state,
1649 sid, sid, sclass, av, &avd, rc, &ad, 0);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001650 if (rc2)
1651 return rc2;
1652 }
Eric Paris06112162008-11-11 22:02:50 +11001653 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654}
1655
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656/* Check whether a task has a particular permission to an inode.
1657 The 'adp' parameter is optional and allows other audit
1658 data to be passed (e.g. the dentry). */
David Howells88e67f32008-11-14 10:39:21 +11001659static int inode_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 struct inode *inode,
1661 u32 perms,
Linus Torvalds19e49832013-10-04 12:54:11 -07001662 struct common_audit_data *adp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 struct inode_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +11001665 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666
David Howellse0e81732009-09-02 09:13:40 +01001667 validate_creds(cred);
1668
Eric Paris828dfe12008-04-17 13:17:49 -04001669 if (unlikely(IS_PRIVATE(inode)))
Stephen Smalleybbaca6c2007-02-14 00:34:16 -08001670 return 0;
1671
David Howells88e67f32008-11-14 10:39:21 +11001672 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 isec = inode->i_security;
1674
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001675 return avc_has_perm(&selinux_state,
1676 sid, isec->sid, isec->sclass, perms, adp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677}
1678
1679/* Same as inode_has_perm, but pass explicit audit data containing
1680 the dentry to help the auditing code to more easily generate the
1681 pathname if needed. */
David Howells88e67f32008-11-14 10:39:21 +11001682static inline int dentry_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 struct dentry *dentry,
1684 u32 av)
1685{
David Howellsc6f493d2015-03-17 22:26:22 +00001686 struct inode *inode = d_backing_inode(dentry);
Thomas Liu2bf49692009-07-14 12:14:09 -04001687 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001688
Eric Paris50c205f2012-04-04 15:01:43 -04001689 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Paris2875fa02011-04-28 16:04:24 -04001690 ad.u.dentry = dentry;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001691 __inode_security_revalidate(inode, dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001692 return inode_has_perm(cred, inode, av, &ad);
Eric Paris2875fa02011-04-28 16:04:24 -04001693}
1694
1695/* Same as inode_has_perm, but pass explicit audit data containing
1696 the path to help the auditing code to more easily generate the
1697 pathname if needed. */
1698static inline int path_has_perm(const struct cred *cred,
Al Viro3f7036a2015-03-08 19:28:30 -04001699 const struct path *path,
Eric Paris2875fa02011-04-28 16:04:24 -04001700 u32 av)
1701{
David Howellsc6f493d2015-03-17 22:26:22 +00001702 struct inode *inode = d_backing_inode(path->dentry);
Eric Paris2875fa02011-04-28 16:04:24 -04001703 struct common_audit_data ad;
1704
Eric Paris50c205f2012-04-04 15:01:43 -04001705 ad.type = LSM_AUDIT_DATA_PATH;
Eric Paris2875fa02011-04-28 16:04:24 -04001706 ad.u.path = *path;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001707 __inode_security_revalidate(inode, path->dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001708 return inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709}
1710
David Howells13f8e982013-06-13 23:37:55 +01001711/* Same as path_has_perm, but uses the inode from the file struct. */
1712static inline int file_path_has_perm(const struct cred *cred,
1713 struct file *file,
1714 u32 av)
1715{
1716 struct common_audit_data ad;
1717
Vivek Goyal43af5de2016-09-09 11:37:49 -04001718 ad.type = LSM_AUDIT_DATA_FILE;
1719 ad.u.file = file;
Linus Torvalds19e49832013-10-04 12:54:11 -07001720 return inode_has_perm(cred, file_inode(file), av, &ad);
David Howells13f8e982013-06-13 23:37:55 +01001721}
1722
Chenbo Fengf66e4482017-10-18 13:00:26 -07001723#ifdef CONFIG_BPF_SYSCALL
1724static int bpf_fd_pass(struct file *file, u32 sid);
1725#endif
1726
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727/* Check whether a task can use an open file descriptor to
1728 access an inode in a given way. Check access to the
1729 descriptor itself, and then use dentry_has_perm to
1730 check a particular permission to the file.
1731 Access to the descriptor is implicitly granted if it
1732 has the same SID as the process. If av is zero, then
1733 access to the file is not checked, e.g. for cases
1734 where only the descriptor is affected like seek. */
David Howells88e67f32008-11-14 10:39:21 +11001735static int file_has_perm(const struct cred *cred,
1736 struct file *file,
1737 u32 av)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 struct file_security_struct *fsec = file->f_security;
Al Viro496ad9a2013-01-23 17:07:38 -05001740 struct inode *inode = file_inode(file);
Thomas Liu2bf49692009-07-14 12:14:09 -04001741 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001742 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 int rc;
1744
Vivek Goyal43af5de2016-09-09 11:37:49 -04001745 ad.type = LSM_AUDIT_DATA_FILE;
1746 ad.u.file = file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
David Howells275bb412008-11-14 10:39:19 +11001748 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001749 rc = avc_has_perm(&selinux_state,
1750 sid, fsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 SECCLASS_FD,
1752 FD__USE,
1753 &ad);
1754 if (rc)
David Howells88e67f32008-11-14 10:39:21 +11001755 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 }
1757
Chenbo Fengf66e4482017-10-18 13:00:26 -07001758#ifdef CONFIG_BPF_SYSCALL
1759 rc = bpf_fd_pass(file, cred_sid(cred));
1760 if (rc)
1761 return rc;
1762#endif
1763
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 /* av is zero if only checking access to the descriptor. */
David Howells88e67f32008-11-14 10:39:21 +11001765 rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 if (av)
Linus Torvalds19e49832013-10-04 12:54:11 -07001767 rc = inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768
David Howells88e67f32008-11-14 10:39:21 +11001769out:
1770 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771}
1772
David Howellsc3c188b2015-07-10 17:19:58 -04001773/*
1774 * Determine the label for an inode that might be unioned.
1775 */
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001776static int
1777selinux_determine_inode_label(const struct task_security_struct *tsec,
1778 struct inode *dir,
1779 const struct qstr *name, u16 tclass,
1780 u32 *_new_isid)
David Howellsc3c188b2015-07-10 17:19:58 -04001781{
1782 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
David Howellsc3c188b2015-07-10 17:19:58 -04001783
1784 if ((sbsec->flags & SE_SBINITIALIZED) &&
1785 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
1786 *_new_isid = sbsec->mntpoint_sid;
1787 } else if ((sbsec->flags & SBLABEL_MNT) &&
1788 tsec->create_sid) {
1789 *_new_isid = tsec->create_sid;
1790 } else {
Paul Moore20cdef82016-04-04 14:14:42 -04001791 const struct inode_security_struct *dsec = inode_security(dir);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001792 return security_transition_sid(&selinux_state, tsec->sid,
1793 dsec->sid, tclass,
David Howellsc3c188b2015-07-10 17:19:58 -04001794 name, _new_isid);
1795 }
1796
1797 return 0;
1798}
1799
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800/* Check whether a task can create a file. */
1801static int may_create(struct inode *dir,
1802 struct dentry *dentry,
1803 u16 tclass)
1804{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07001805 const struct task_security_struct *tsec = selinux_cred(current_cred());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 struct inode_security_struct *dsec;
1807 struct superblock_security_struct *sbsec;
David Howells275bb412008-11-14 10:39:19 +11001808 u32 sid, newsid;
Thomas Liu2bf49692009-07-14 12:14:09 -04001809 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 int rc;
1811
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001812 dsec = inode_security(dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 sbsec = dir->i_sb->s_security;
1814
David Howells275bb412008-11-14 10:39:19 +11001815 sid = tsec->sid;
David Howells275bb412008-11-14 10:39:19 +11001816
Eric Paris50c205f2012-04-04 15:01:43 -04001817 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001818 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001820 rc = avc_has_perm(&selinux_state,
1821 sid, dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 DIR__ADD_NAME | DIR__SEARCH,
1823 &ad);
1824 if (rc)
1825 return rc;
1826
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07001827 rc = selinux_determine_inode_label(selinux_cred(current_cred()), dir,
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001828 &dentry->d_name, tclass, &newsid);
David Howellsc3c188b2015-07-10 17:19:58 -04001829 if (rc)
1830 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001832 rc = avc_has_perm(&selinux_state,
1833 sid, newsid, tclass, FILE__CREATE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 if (rc)
1835 return rc;
1836
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001837 return avc_has_perm(&selinux_state,
1838 newsid, sbsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 SECCLASS_FILESYSTEM,
1840 FILESYSTEM__ASSOCIATE, &ad);
1841}
1842
Eric Paris828dfe12008-04-17 13:17:49 -04001843#define MAY_LINK 0
1844#define MAY_UNLINK 1
1845#define MAY_RMDIR 2
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846
1847/* Check whether a task can link, unlink, or rmdir a file/directory. */
1848static int may_link(struct inode *dir,
1849 struct dentry *dentry,
1850 int kind)
1851
1852{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 struct inode_security_struct *dsec, *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04001854 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11001855 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 u32 av;
1857 int rc;
1858
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001859 dsec = inode_security(dir);
1860 isec = backing_inode_security(dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861
Eric Paris50c205f2012-04-04 15:01:43 -04001862 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001863 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864
1865 av = DIR__SEARCH;
1866 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001867 rc = avc_has_perm(&selinux_state,
1868 sid, dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 if (rc)
1870 return rc;
1871
1872 switch (kind) {
1873 case MAY_LINK:
1874 av = FILE__LINK;
1875 break;
1876 case MAY_UNLINK:
1877 av = FILE__UNLINK;
1878 break;
1879 case MAY_RMDIR:
1880 av = DIR__RMDIR;
1881 break;
1882 default:
peter enderborgc103a912018-06-12 10:09:03 +02001883 pr_warn("SELinux: %s: unrecognized kind %d\n",
Eric Paris744ba352008-04-17 11:52:44 -04001884 __func__, kind);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 return 0;
1886 }
1887
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001888 rc = avc_has_perm(&selinux_state,
1889 sid, isec->sid, isec->sclass, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 return rc;
1891}
1892
1893static inline int may_rename(struct inode *old_dir,
1894 struct dentry *old_dentry,
1895 struct inode *new_dir,
1896 struct dentry *new_dentry)
1897{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04001899 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11001900 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 u32 av;
1902 int old_is_dir, new_is_dir;
1903 int rc;
1904
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001905 old_dsec = inode_security(old_dir);
1906 old_isec = backing_inode_security(old_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00001907 old_is_dir = d_is_dir(old_dentry);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001908 new_dsec = inode_security(new_dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
Eric Paris50c205f2012-04-04 15:01:43 -04001910 ad.type = LSM_AUDIT_DATA_DENTRY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
Eric Parisa2694342011-04-25 13:10:27 -04001912 ad.u.dentry = old_dentry;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001913 rc = avc_has_perm(&selinux_state,
1914 sid, old_dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1916 if (rc)
1917 return rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001918 rc = avc_has_perm(&selinux_state,
1919 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 old_isec->sclass, FILE__RENAME, &ad);
1921 if (rc)
1922 return rc;
1923 if (old_is_dir && new_dir != old_dir) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001924 rc = avc_has_perm(&selinux_state,
1925 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 old_isec->sclass, DIR__REPARENT, &ad);
1927 if (rc)
1928 return rc;
1929 }
1930
Eric Parisa2694342011-04-25 13:10:27 -04001931 ad.u.dentry = new_dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 av = DIR__ADD_NAME | DIR__SEARCH;
David Howells2c616d42015-01-29 12:02:33 +00001933 if (d_is_positive(new_dentry))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 av |= DIR__REMOVE_NAME;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001935 rc = avc_has_perm(&selinux_state,
1936 sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 if (rc)
1938 return rc;
David Howells2c616d42015-01-29 12:02:33 +00001939 if (d_is_positive(new_dentry)) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001940 new_isec = backing_inode_security(new_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00001941 new_is_dir = d_is_dir(new_dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001942 rc = avc_has_perm(&selinux_state,
1943 sid, new_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 new_isec->sclass,
1945 (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
1946 if (rc)
1947 return rc;
1948 }
1949
1950 return 0;
1951}
1952
1953/* Check whether a task can perform a filesystem operation. */
David Howells88e67f32008-11-14 10:39:21 +11001954static int superblock_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 struct super_block *sb,
1956 u32 perms,
Thomas Liu2bf49692009-07-14 12:14:09 -04001957 struct common_audit_data *ad)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 struct superblock_security_struct *sbsec;
David Howells88e67f32008-11-14 10:39:21 +11001960 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 sbsec = sb->s_security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001963 return avc_has_perm(&selinux_state,
1964 sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965}
1966
1967/* Convert a Linux mode and permission mask to an access vector. */
1968static inline u32 file_mask_to_av(int mode, int mask)
1969{
1970 u32 av = 0;
1971
Al Virodba19c62011-07-25 20:49:29 -04001972 if (!S_ISDIR(mode)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973 if (mask & MAY_EXEC)
1974 av |= FILE__EXECUTE;
1975 if (mask & MAY_READ)
1976 av |= FILE__READ;
1977
1978 if (mask & MAY_APPEND)
1979 av |= FILE__APPEND;
1980 else if (mask & MAY_WRITE)
1981 av |= FILE__WRITE;
1982
1983 } else {
1984 if (mask & MAY_EXEC)
1985 av |= DIR__SEARCH;
1986 if (mask & MAY_WRITE)
1987 av |= DIR__WRITE;
1988 if (mask & MAY_READ)
1989 av |= DIR__READ;
1990 }
1991
1992 return av;
1993}
1994
1995/* Convert a Linux file to an access vector. */
1996static inline u32 file_to_av(struct file *file)
1997{
1998 u32 av = 0;
1999
2000 if (file->f_mode & FMODE_READ)
2001 av |= FILE__READ;
2002 if (file->f_mode & FMODE_WRITE) {
2003 if (file->f_flags & O_APPEND)
2004 av |= FILE__APPEND;
2005 else
2006 av |= FILE__WRITE;
2007 }
Stephen Smalley0794c662008-03-17 08:55:18 -04002008 if (!av) {
2009 /*
2010 * Special file opened with flags 3 for ioctl-only use.
2011 */
2012 av = FILE__IOCTL;
2013 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014
2015 return av;
2016}
2017
Eric Paris8b6a5a32008-10-29 17:06:46 -04002018/*
2019 * Convert a file to an access vector and include the correct open
2020 * open permission.
2021 */
2022static inline u32 open_file_to_av(struct file *file)
2023{
2024 u32 av = file_to_av(file);
Stephen Smalleyccb54472017-05-12 12:41:24 -04002025 struct inode *inode = file_inode(file);
Eric Paris8b6a5a32008-10-29 17:06:46 -04002026
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002027 if (selinux_policycap_openperm() &&
2028 inode->i_sb->s_magic != SOCKFS_MAGIC)
Eric Paris49b7b8d2010-07-23 11:44:09 -04002029 av |= FILE__OPEN;
2030
Eric Paris8b6a5a32008-10-29 17:06:46 -04002031 return av;
2032}
2033
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034/* Hook functions begin here. */
2035
Stephen Smalley79af7302015-01-21 10:54:10 -05002036static int selinux_binder_set_context_mgr(struct task_struct *mgr)
2037{
2038 u32 mysid = current_sid();
2039 u32 mgrsid = task_sid(mgr);
2040
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002041 return avc_has_perm(&selinux_state,
2042 mysid, mgrsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002043 BINDER__SET_CONTEXT_MGR, NULL);
2044}
2045
2046static int selinux_binder_transaction(struct task_struct *from,
2047 struct task_struct *to)
2048{
2049 u32 mysid = current_sid();
2050 u32 fromsid = task_sid(from);
2051 u32 tosid = task_sid(to);
2052 int rc;
2053
2054 if (mysid != fromsid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002055 rc = avc_has_perm(&selinux_state,
2056 mysid, fromsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002057 BINDER__IMPERSONATE, NULL);
2058 if (rc)
2059 return rc;
2060 }
2061
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002062 return avc_has_perm(&selinux_state,
2063 fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
Stephen Smalley79af7302015-01-21 10:54:10 -05002064 NULL);
2065}
2066
2067static int selinux_binder_transfer_binder(struct task_struct *from,
2068 struct task_struct *to)
2069{
2070 u32 fromsid = task_sid(from);
2071 u32 tosid = task_sid(to);
2072
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002073 return avc_has_perm(&selinux_state,
2074 fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002075 NULL);
2076}
2077
2078static int selinux_binder_transfer_file(struct task_struct *from,
2079 struct task_struct *to,
2080 struct file *file)
2081{
2082 u32 sid = task_sid(to);
2083 struct file_security_struct *fsec = file->f_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002084 struct dentry *dentry = file->f_path.dentry;
Paul Moore20cdef82016-04-04 14:14:42 -04002085 struct inode_security_struct *isec;
Stephen Smalley79af7302015-01-21 10:54:10 -05002086 struct common_audit_data ad;
2087 int rc;
2088
2089 ad.type = LSM_AUDIT_DATA_PATH;
2090 ad.u.path = file->f_path;
2091
2092 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002093 rc = avc_has_perm(&selinux_state,
2094 sid, fsec->sid,
Stephen Smalley79af7302015-01-21 10:54:10 -05002095 SECCLASS_FD,
2096 FD__USE,
2097 &ad);
2098 if (rc)
2099 return rc;
2100 }
2101
Chenbo Fengf66e4482017-10-18 13:00:26 -07002102#ifdef CONFIG_BPF_SYSCALL
2103 rc = bpf_fd_pass(file, sid);
2104 if (rc)
2105 return rc;
2106#endif
2107
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002108 if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
Stephen Smalley79af7302015-01-21 10:54:10 -05002109 return 0;
2110
Paul Moore20cdef82016-04-04 14:14:42 -04002111 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002112 return avc_has_perm(&selinux_state,
2113 sid, isec->sid, isec->sclass, file_to_av(file),
Stephen Smalley79af7302015-01-21 10:54:10 -05002114 &ad);
2115}
2116
Ingo Molnar9e488582009-05-07 19:26:19 +10002117static int selinux_ptrace_access_check(struct task_struct *child,
David Howells5cd9c582008-08-14 11:37:28 +01002118 unsigned int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002120 u32 sid = current_sid();
2121 u32 csid = task_sid(child);
Stephen Smalley006ebb42008-05-19 08:32:49 -04002122
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002123 if (mode & PTRACE_MODE_READ)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002124 return avc_has_perm(&selinux_state,
2125 sid, csid, SECCLASS_FILE, FILE__READ, NULL);
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002126
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002127 return avc_has_perm(&selinux_state,
2128 sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
David Howells5cd9c582008-08-14 11:37:28 +01002129}
2130
2131static int selinux_ptrace_traceme(struct task_struct *parent)
2132{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002133 return avc_has_perm(&selinux_state,
2134 task_sid(parent), current_sid(), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002135 PROCESS__PTRACE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136}
2137
2138static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
Eric Paris828dfe12008-04-17 13:17:49 -04002139 kernel_cap_t *inheritable, kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002141 return avc_has_perm(&selinux_state,
2142 current_sid(), task_sid(target), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002143 PROCESS__GETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144}
2145
David Howellsd84f4f92008-11-14 10:39:23 +11002146static int selinux_capset(struct cred *new, const struct cred *old,
2147 const kernel_cap_t *effective,
2148 const kernel_cap_t *inheritable,
2149 const kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002151 return avc_has_perm(&selinux_state,
2152 cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002153 PROCESS__SETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154}
2155
James Morris5626d3e2009-01-30 10:05:06 +11002156/*
2157 * (This comment used to live with the selinux_task_setuid hook,
2158 * which was removed).
2159 *
2160 * Since setuid only affects the current process, and since the SELinux
2161 * controls are not based on the Linux identity attributes, SELinux does not
2162 * need to control this operation. However, SELinux does control the use of
2163 * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
2164 */
2165
Eric Paris6a9de492012-01-03 12:25:14 -05002166static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
2167 int cap, int audit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168{
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04002169 return cred_has_capability(cred, cap, audit, ns == &init_user_ns);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170}
2171
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
2173{
David Howells88e67f32008-11-14 10:39:21 +11002174 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175 int rc = 0;
2176
2177 if (!sb)
2178 return 0;
2179
2180 switch (cmds) {
Eric Paris828dfe12008-04-17 13:17:49 -04002181 case Q_SYNC:
2182 case Q_QUOTAON:
2183 case Q_QUOTAOFF:
2184 case Q_SETINFO:
2185 case Q_SETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002186 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAMOD, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002187 break;
2188 case Q_GETFMT:
2189 case Q_GETINFO:
2190 case Q_GETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002191 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAGET, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002192 break;
2193 default:
2194 rc = 0; /* let the kernel handle invalid cmds */
2195 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 }
2197 return rc;
2198}
2199
2200static int selinux_quota_on(struct dentry *dentry)
2201{
David Howells88e67f32008-11-14 10:39:21 +11002202 const struct cred *cred = current_cred();
2203
Eric Paris2875fa02011-04-28 16:04:24 -04002204 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205}
2206
Eric Paris12b30522010-11-15 18:36:29 -05002207static int selinux_syslog(int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 switch (type) {
Kees Cookd78ca3c2010-02-03 15:37:13 -08002210 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
2211 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002212 return avc_has_perm(&selinux_state,
2213 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002214 SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, NULL);
Kees Cookd78ca3c2010-02-03 15:37:13 -08002215 case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
2216 case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
2217 /* Set level of messages printed to console */
2218 case SYSLOG_ACTION_CONSOLE_LEVEL:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002219 return avc_has_perm(&selinux_state,
2220 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002221 SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE,
2222 NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223 }
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002224 /* All other syslog types */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002225 return avc_has_perm(&selinux_state,
2226 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002227 SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228}
2229
2230/*
2231 * Check that a process has enough memory to allocate a new virtual
2232 * mapping. 0 means there is enough memory for the allocation to
2233 * succeed and -ENOMEM implies there is not.
2234 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235 * Do not audit the selinux permission check, as this is applied to all
2236 * processes that allocate mappings.
2237 */
Alan Cox34b4e4a2007-08-22 14:01:28 -07002238static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239{
2240 int rc, cap_sys_admin = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002242 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04002243 SECURITY_CAP_NOAUDIT, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244 if (rc == 0)
2245 cap_sys_admin = 1;
2246
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002247 return cap_sys_admin;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248}
2249
2250/* binprm security operations */
2251
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002252static u32 ptrace_parent_sid(void)
Paul Moore0c6181c2016-03-30 21:41:21 -04002253{
2254 u32 sid = 0;
2255 struct task_struct *tracer;
2256
2257 rcu_read_lock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002258 tracer = ptrace_parent(current);
Paul Moore0c6181c2016-03-30 21:41:21 -04002259 if (tracer)
2260 sid = task_sid(tracer);
2261 rcu_read_unlock();
2262
2263 return sid;
2264}
2265
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002266static int check_nnp_nosuid(const struct linux_binprm *bprm,
2267 const struct task_security_struct *old_tsec,
2268 const struct task_security_struct *new_tsec)
2269{
2270 int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
Andy Lutomirski380cf5b2016-06-23 16:41:05 -05002271 int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002272 int rc;
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002273 u32 av;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002274
2275 if (!nnp && !nosuid)
2276 return 0; /* neither NNP nor nosuid */
2277
2278 if (new_tsec->sid == old_tsec->sid)
2279 return 0; /* No change in credentials */
2280
2281 /*
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002282 * If the policy enables the nnp_nosuid_transition policy capability,
2283 * then we permit transitions under NNP or nosuid if the
2284 * policy allows the corresponding permission between
2285 * the old and new contexts.
2286 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002287 if (selinux_policycap_nnp_nosuid_transition()) {
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002288 av = 0;
2289 if (nnp)
2290 av |= PROCESS2__NNP_TRANSITION;
2291 if (nosuid)
2292 av |= PROCESS2__NOSUID_TRANSITION;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002293 rc = avc_has_perm(&selinux_state,
2294 old_tsec->sid, new_tsec->sid,
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002295 SECCLASS_PROCESS2, av, NULL);
2296 if (!rc)
2297 return 0;
2298 }
2299
2300 /*
2301 * We also permit NNP or nosuid transitions to bounded SIDs,
2302 * i.e. SIDs that are guaranteed to only be allowed a subset
2303 * of the permissions of the current SID.
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002304 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002305 rc = security_bounded_transition(&selinux_state, old_tsec->sid,
2306 new_tsec->sid);
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002307 if (!rc)
2308 return 0;
2309
2310 /*
2311 * On failure, preserve the errno values for NNP vs nosuid.
2312 * NNP: Operation not permitted for caller.
2313 * nosuid: Permission denied to file.
2314 */
2315 if (nnp)
2316 return -EPERM;
2317 return -EACCES;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002318}
2319
David Howellsa6f76f22008-11-14 10:39:24 +11002320static int selinux_bprm_set_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321{
David Howellsa6f76f22008-11-14 10:39:24 +11002322 const struct task_security_struct *old_tsec;
2323 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 struct inode_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04002325 struct common_audit_data ad;
Al Viro496ad9a2013-01-23 17:07:38 -05002326 struct inode *inode = file_inode(bprm->file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327 int rc;
2328
David Howellsa6f76f22008-11-14 10:39:24 +11002329 /* SELinux context only depends on initial program or script and not
2330 * the script interpreter */
Kees Cookddb4a142017-07-18 15:25:23 -07002331 if (bprm->called_set_creds)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 return 0;
2333
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002334 old_tsec = selinux_cred(current_cred());
2335 new_tsec = selinux_cred(bprm->cred);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002336 isec = inode_security(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337
2338 /* Default to the current task SID. */
David Howellsa6f76f22008-11-14 10:39:24 +11002339 new_tsec->sid = old_tsec->sid;
2340 new_tsec->osid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341
Michael LeMay28eba5b2006-06-27 02:53:42 -07002342 /* Reset fs, key, and sock SIDs on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002343 new_tsec->create_sid = 0;
2344 new_tsec->keycreate_sid = 0;
2345 new_tsec->sockcreate_sid = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346
David Howellsa6f76f22008-11-14 10:39:24 +11002347 if (old_tsec->exec_sid) {
2348 new_tsec->sid = old_tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349 /* Reset exec SID on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002350 new_tsec->exec_sid = 0;
Andy Lutomirski259e5e62012-04-12 16:47:50 -05002351
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002352 /* Fail on NNP or nosuid if not an allowed transition. */
2353 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2354 if (rc)
2355 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002356 } else {
2357 /* Check for a default transition on this program. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002358 rc = security_transition_sid(&selinux_state, old_tsec->sid,
2359 isec->sid, SECCLASS_PROCESS, NULL,
Eric Paris652bb9b2011-02-01 11:05:40 -05002360 &new_tsec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 if (rc)
2362 return rc;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002363
2364 /*
2365 * Fallback to old SID on NNP or nosuid if not an allowed
2366 * transition.
2367 */
2368 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2369 if (rc)
2370 new_tsec->sid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371 }
2372
Vivek Goyal43af5de2016-09-09 11:37:49 -04002373 ad.type = LSM_AUDIT_DATA_FILE;
2374 ad.u.file = bprm->file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375
David Howellsa6f76f22008-11-14 10:39:24 +11002376 if (new_tsec->sid == old_tsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002377 rc = avc_has_perm(&selinux_state,
2378 old_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
2380 if (rc)
2381 return rc;
2382 } else {
2383 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002384 rc = avc_has_perm(&selinux_state,
2385 old_tsec->sid, new_tsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002386 SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
2387 if (rc)
2388 return rc;
2389
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002390 rc = avc_has_perm(&selinux_state,
2391 new_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392 SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
2393 if (rc)
2394 return rc;
2395
David Howellsa6f76f22008-11-14 10:39:24 +11002396 /* Check for shared state */
2397 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002398 rc = avc_has_perm(&selinux_state,
2399 old_tsec->sid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002400 SECCLASS_PROCESS, PROCESS__SHARE,
2401 NULL);
2402 if (rc)
2403 return -EPERM;
2404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405
David Howellsa6f76f22008-11-14 10:39:24 +11002406 /* Make sure that anyone attempting to ptrace over a task that
2407 * changes its SID has the appropriate permit */
Eric W. Biederman9227dd22017-01-23 17:26:31 +13002408 if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002409 u32 ptsid = ptrace_parent_sid();
David Howellsa6f76f22008-11-14 10:39:24 +11002410 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002411 rc = avc_has_perm(&selinux_state,
2412 ptsid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002413 SECCLASS_PROCESS,
2414 PROCESS__PTRACE, NULL);
2415 if (rc)
2416 return -EPERM;
2417 }
2418 }
2419
2420 /* Clear any possibly unsafe personality bits on exec: */
2421 bprm->per_clear |= PER_CLEAR_ON_SETID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423 /* Enable secure mode for SIDs transitions unless
2424 the noatsecure permission is granted between
2425 the two SIDs, i.e. ahp returns 0. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002426 rc = avc_has_perm(&selinux_state,
2427 old_tsec->sid, new_tsec->sid,
Kees Cook62874c32017-07-18 15:25:25 -07002428 SECCLASS_PROCESS, PROCESS__NOATSECURE,
2429 NULL);
2430 bprm->secureexec |= !!rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431 }
2432
Kees Cook62874c32017-07-18 15:25:25 -07002433 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434}
2435
Al Viroc3c073f2012-08-21 22:32:06 -04002436static int match_file(const void *p, struct file *file, unsigned fd)
2437{
2438 return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0;
2439}
2440
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441/* Derived from fs/exec.c:flush_old_files. */
David Howells745ca242008-11-14 10:39:22 +11002442static inline void flush_unauthorized_files(const struct cred *cred,
2443 struct files_struct *files)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445 struct file *file, *devnull = NULL;
Stephen Smalleyb20c8122006-09-25 23:32:03 -07002446 struct tty_struct *tty;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002447 int drop_tty = 0;
Al Viroc3c073f2012-08-21 22:32:06 -04002448 unsigned n;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002450 tty = get_current_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451 if (tty) {
Peter Hurley4a510962016-01-09 21:35:23 -08002452 spin_lock(&tty->files_lock);
Eric Paris37dd0bd2008-10-31 17:40:00 -04002453 if (!list_empty(&tty->tty_files)) {
Nick Piggind996b622010-08-18 04:37:36 +10002454 struct tty_file_private *file_priv;
Eric Paris37dd0bd2008-10-31 17:40:00 -04002455
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 /* Revalidate access to controlling tty.
David Howells13f8e982013-06-13 23:37:55 +01002457 Use file_path_has_perm on the tty path directly
2458 rather than using file_has_perm, as this particular
2459 open file may belong to another process and we are
2460 only interested in the inode-based check here. */
Nick Piggind996b622010-08-18 04:37:36 +10002461 file_priv = list_first_entry(&tty->tty_files,
2462 struct tty_file_private, list);
2463 file = file_priv->file;
David Howells13f8e982013-06-13 23:37:55 +01002464 if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE))
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002465 drop_tty = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002466 }
Peter Hurley4a510962016-01-09 21:35:23 -08002467 spin_unlock(&tty->files_lock);
Alan Cox452a00d2008-10-13 10:39:13 +01002468 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469 }
Eric W. Biederman98a27ba2007-05-08 00:26:56 -07002470 /* Reset controlling tty. */
2471 if (drop_tty)
2472 no_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473
2474 /* Revalidate access to inherited open files. */
Al Viroc3c073f2012-08-21 22:32:06 -04002475 n = iterate_fd(files, 0, match_file, cred);
2476 if (!n) /* none found? */
2477 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478
Al Viroc3c073f2012-08-21 22:32:06 -04002479 devnull = dentry_open(&selinux_null, O_RDWR, cred);
Al Viro45525b22012-10-16 13:30:07 -04002480 if (IS_ERR(devnull))
2481 devnull = NULL;
2482 /* replace all the matching ones with this */
2483 do {
2484 replace_fd(n - 1, devnull, 0);
2485 } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
2486 if (devnull)
Al Viroc3c073f2012-08-21 22:32:06 -04002487 fput(devnull);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488}
2489
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490/*
David Howellsa6f76f22008-11-14 10:39:24 +11002491 * Prepare a process for imminent new credential changes due to exec
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492 */
David Howellsa6f76f22008-11-14 10:39:24 +11002493static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494{
David Howellsa6f76f22008-11-14 10:39:24 +11002495 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496 struct rlimit *rlim, *initrlim;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497 int rc, i;
2498
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002499 new_tsec = selinux_cred(bprm->cred);
David Howellsa6f76f22008-11-14 10:39:24 +11002500 if (new_tsec->sid == new_tsec->osid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501 return;
2502
2503 /* Close files for which the new task SID is not authorized. */
David Howellsa6f76f22008-11-14 10:39:24 +11002504 flush_unauthorized_files(bprm->cred, current->files);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505
David Howellsa6f76f22008-11-14 10:39:24 +11002506 /* Always clear parent death signal on SID transitions. */
2507 current->pdeath_signal = 0;
2508
2509 /* Check whether the new SID can inherit resource limits from the old
2510 * SID. If not, reset all soft limits to the lower of the current
2511 * task's hard limit and the init task's soft limit.
2512 *
2513 * Note that the setting of hard limits (even to lower them) can be
2514 * controlled by the setrlimit check. The inclusion of the init task's
2515 * soft limit into the computation is to avoid resetting soft limits
2516 * higher than the default soft limit for cases where the default is
2517 * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
2518 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002519 rc = avc_has_perm(&selinux_state,
2520 new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
David Howellsa6f76f22008-11-14 10:39:24 +11002521 PROCESS__RLIMITINH, NULL);
2522 if (rc) {
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002523 /* protect against do_prlimit() */
2524 task_lock(current);
David Howellsa6f76f22008-11-14 10:39:24 +11002525 for (i = 0; i < RLIM_NLIMITS; i++) {
2526 rlim = current->signal->rlim + i;
2527 initrlim = init_task.signal->rlim + i;
2528 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2529 }
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002530 task_unlock(current);
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002531 if (IS_ENABLED(CONFIG_POSIX_TIMERS))
2532 update_rlimit_cpu(current, rlimit(RLIMIT_CPU));
David Howellsa6f76f22008-11-14 10:39:24 +11002533 }
2534}
2535
2536/*
2537 * Clean up the process immediately after the installation of new credentials
2538 * due to exec
2539 */
2540static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2541{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002542 const struct task_security_struct *tsec = selinux_cred(current_cred());
David Howellsa6f76f22008-11-14 10:39:24 +11002543 struct itimerval itimer;
David Howellsa6f76f22008-11-14 10:39:24 +11002544 u32 osid, sid;
2545 int rc, i;
David Howellsa6f76f22008-11-14 10:39:24 +11002546
David Howellsa6f76f22008-11-14 10:39:24 +11002547 osid = tsec->osid;
2548 sid = tsec->sid;
2549
2550 if (sid == osid)
2551 return;
2552
2553 /* Check whether the new SID can inherit signal state from the old SID.
2554 * If not, clear itimers to avoid subsequent signal generation and
2555 * flush and unblock signals.
2556 *
2557 * This must occur _after_ the task SID has been updated so that any
2558 * kill done after the flush will be checked against the new SID.
2559 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002560 rc = avc_has_perm(&selinux_state,
2561 osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562 if (rc) {
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002563 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
2564 memset(&itimer, 0, sizeof itimer);
2565 for (i = 0; i < 3; i++)
2566 do_setitimer(i, &itimer, NULL);
2567 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568 spin_lock_irq(&current->sighand->siglock);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002569 if (!fatal_signal_pending(current)) {
2570 flush_sigqueue(&current->pending);
2571 flush_sigqueue(&current->signal->shared_pending);
David Howells3bcac022009-04-29 13:45:05 +01002572 flush_signal_handlers(current, 1);
2573 sigemptyset(&current->blocked);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002574 recalc_sigpending();
David Howells3bcac022009-04-29 13:45:05 +01002575 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 spin_unlock_irq(&current->sighand->siglock);
2577 }
2578
David Howellsa6f76f22008-11-14 10:39:24 +11002579 /* Wake up the parent if it is waiting so that it can recheck
2580 * wait permission to the new task SID. */
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002581 read_lock(&tasklist_lock);
Oleg Nesterov0b7570e2009-09-23 15:56:46 -07002582 __wake_up_parent(current, current->real_parent);
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002583 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584}
2585
2586/* superblock security operations */
2587
2588static int selinux_sb_alloc_security(struct super_block *sb)
2589{
2590 return superblock_alloc_security(sb);
2591}
2592
2593static void selinux_sb_free_security(struct super_block *sb)
2594{
2595 superblock_free_security(sb);
2596}
2597
Al Viro99dbbb52018-12-14 21:56:23 -05002598static inline int opt_len(const char *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599{
Al Viro99dbbb52018-12-14 21:56:23 -05002600 bool open_quote = false;
2601 int len;
2602 char c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603
Al Viro99dbbb52018-12-14 21:56:23 -05002604 for (len = 0; (c = s[len]) != '\0'; len++) {
2605 if (c == '"')
Cory Olmo3528a952006-09-29 01:58:44 -07002606 open_quote = !open_quote;
Al Viro99dbbb52018-12-14 21:56:23 -05002607 if (c == ',' && !open_quote)
2608 break;
2609 }
2610 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611}
2612
Al Viro204cc0c2018-12-13 13:41:47 -05002613static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts)
Eric Paris026eb162011-03-03 16:09:14 -05002614{
Al Viro99dbbb52018-12-14 21:56:23 -05002615 char *from = options;
2616 char *to = options;
2617 bool first = true;
Al Viro5b400232018-12-12 20:13:29 -05002618
Al Viro99dbbb52018-12-14 21:56:23 -05002619 while (1) {
2620 int len = opt_len(from);
2621 int token, rc;
2622 char *arg = NULL;
2623
2624 token = match_opt_prefix(from, len, &arg);
2625
2626 if (token != Opt_error) {
2627 char *p, *q;
2628
2629 /* strip quotes */
2630 if (arg) {
2631 for (p = q = arg; p < from + len; p++) {
2632 char c = *p;
2633 if (c != '"')
2634 *q++ = c;
2635 }
2636 arg = kmemdup_nul(arg, q - arg, GFP_KERNEL);
2637 }
2638 rc = selinux_add_opt(token, arg, mnt_opts);
2639 if (unlikely(rc)) {
2640 kfree(arg);
2641 if (*mnt_opts) {
2642 selinux_free_mnt_opts(*mnt_opts);
2643 *mnt_opts = NULL;
2644 }
2645 return rc;
2646 }
2647 } else {
2648 if (!first) { // copy with preceding comma
2649 from--;
2650 len++;
2651 }
2652 if (to != from)
2653 memmove(to, from, len);
2654 to += len;
2655 first = false;
2656 }
2657 if (!from[len])
2658 break;
2659 from += len + 1;
2660 }
2661 *to = '\0';
2662 return 0;
Al Viro5b400232018-12-12 20:13:29 -05002663}
2664
Al Viro204cc0c2018-12-13 13:41:47 -05002665static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
Eric Paris026eb162011-03-03 16:09:14 -05002666{
Al Virobd323652018-12-13 15:04:59 -05002667 struct selinux_mnt_opts *opts = mnt_opts;
Eric Paris026eb162011-03-03 16:09:14 -05002668 struct superblock_security_struct *sbsec = sb->s_security;
Al Virobd323652018-12-13 15:04:59 -05002669 u32 sid;
2670 int rc;
Eric Paris026eb162011-03-03 16:09:14 -05002671
2672 if (!(sbsec->flags & SE_SBINITIALIZED))
2673 return 0;
2674
Al Viro204cc0c2018-12-13 13:41:47 -05002675 if (!opts)
Eric Paris026eb162011-03-03 16:09:14 -05002676 return 0;
2677
Al Virobd323652018-12-13 15:04:59 -05002678 if (opts->fscontext) {
2679 rc = parse_sid(sb, opts->fscontext, &sid);
2680 if (rc)
Al Viroc039bc32018-12-01 23:06:57 -05002681 return rc;
Al Virobd323652018-12-13 15:04:59 -05002682 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
2683 goto out_bad_option;
Eric Paris026eb162011-03-03 16:09:14 -05002684 }
Al Virobd323652018-12-13 15:04:59 -05002685 if (opts->context) {
2686 rc = parse_sid(sb, opts->context, &sid);
2687 if (rc)
2688 return rc;
2689 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
2690 goto out_bad_option;
2691 }
2692 if (opts->rootcontext) {
2693 struct inode_security_struct *root_isec;
2694 root_isec = backing_inode_security(sb->s_root);
2695 rc = parse_sid(sb, opts->rootcontext, &sid);
2696 if (rc)
2697 return rc;
2698 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
2699 goto out_bad_option;
2700 }
2701 if (opts->defcontext) {
2702 rc = parse_sid(sb, opts->defcontext, &sid);
2703 if (rc)
2704 return rc;
2705 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
2706 goto out_bad_option;
Eric Paris026eb162011-03-03 16:09:14 -05002707 }
Al Viroc039bc32018-12-01 23:06:57 -05002708 return 0;
Eric Paris026eb162011-03-03 16:09:14 -05002709
Eric Paris026eb162011-03-03 16:09:14 -05002710out_bad_option:
peter enderborgc103a912018-06-12 10:09:03 +02002711 pr_warn("SELinux: unable to change security options "
Linus Torvalds29b1deb2013-12-15 11:17:45 -08002712 "during remount (dev %s, type=%s)\n", sb->s_id,
2713 sb->s_type->name);
Al Viroc039bc32018-12-01 23:06:57 -05002714 return -EINVAL;
Eric Paris026eb162011-03-03 16:09:14 -05002715}
2716
Al Viroa10d7c22018-12-05 11:58:35 -05002717static int selinux_sb_kern_mount(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002718{
David Howells88e67f32008-11-14 10:39:21 +11002719 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002720 struct common_audit_data ad;
James Morris74192242008-12-19 11:41:10 +11002721
Eric Paris50c205f2012-04-04 15:01:43 -04002722 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002723 ad.u.dentry = sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002724 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725}
2726
David Howells726c3342006-06-23 02:02:58 -07002727static int selinux_sb_statfs(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728{
David Howells88e67f32008-11-14 10:39:21 +11002729 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002730 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731
Eric Paris50c205f2012-04-04 15:01:43 -04002732 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002733 ad.u.dentry = dentry->d_sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002734 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002735}
2736
Al Viro808d4e32012-10-11 11:42:01 -04002737static int selinux_mount(const char *dev_name,
Al Viro8a04c432016-03-25 14:52:53 -04002738 const struct path *path,
Al Viro808d4e32012-10-11 11:42:01 -04002739 const char *type,
Eric Paris828dfe12008-04-17 13:17:49 -04002740 unsigned long flags,
2741 void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742{
David Howells88e67f32008-11-14 10:39:21 +11002743 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744
2745 if (flags & MS_REMOUNT)
Al Virod8c95842011-12-07 18:16:57 -05002746 return superblock_has_perm(cred, path->dentry->d_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002747 FILESYSTEM__REMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748 else
Eric Paris2875fa02011-04-28 16:04:24 -04002749 return path_has_perm(cred, path, FILE__MOUNTON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750}
2751
2752static int selinux_umount(struct vfsmount *mnt, int flags)
2753{
David Howells88e67f32008-11-14 10:39:21 +11002754 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755
David Howells88e67f32008-11-14 10:39:21 +11002756 return superblock_has_perm(cred, mnt->mnt_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002757 FILESYSTEM__UNMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758}
2759
2760/* inode security operations */
2761
2762static int selinux_inode_alloc_security(struct inode *inode)
2763{
2764 return inode_alloc_security(inode);
2765}
2766
2767static void selinux_inode_free_security(struct inode *inode)
2768{
2769 inode_free_security(inode);
2770}
2771
David Quigleyd47be3d2013-05-22 12:50:34 -04002772static int selinux_dentry_init_security(struct dentry *dentry, int mode,
Al Viro4f3ccd72016-07-20 16:06:15 -04002773 const struct qstr *name, void **ctx,
David Quigleyd47be3d2013-05-22 12:50:34 -04002774 u32 *ctxlen)
2775{
David Quigleyd47be3d2013-05-22 12:50:34 -04002776 u32 newsid;
2777 int rc;
2778
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002779 rc = selinux_determine_inode_label(selinux_cred(current_cred()),
Vivek Goyalc957f6d2016-07-13 10:44:51 -04002780 d_inode(dentry->d_parent), name,
David Howellsc3c188b2015-07-10 17:19:58 -04002781 inode_mode_to_security_class(mode),
2782 &newsid);
2783 if (rc)
2784 return rc;
David Quigleyd47be3d2013-05-22 12:50:34 -04002785
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002786 return security_sid_to_context(&selinux_state, newsid, (char **)ctx,
2787 ctxlen);
David Quigleyd47be3d2013-05-22 12:50:34 -04002788}
2789
Vivek Goyala518b0a2016-07-13 10:44:53 -04002790static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
2791 struct qstr *name,
2792 const struct cred *old,
2793 struct cred *new)
2794{
2795 u32 newsid;
2796 int rc;
2797 struct task_security_struct *tsec;
2798
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002799 rc = selinux_determine_inode_label(selinux_cred(old),
Vivek Goyala518b0a2016-07-13 10:44:53 -04002800 d_inode(dentry->d_parent), name,
2801 inode_mode_to_security_class(mode),
2802 &newsid);
2803 if (rc)
2804 return rc;
2805
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002806 tsec = selinux_cred(new);
Vivek Goyala518b0a2016-07-13 10:44:53 -04002807 tsec->create_sid = newsid;
2808 return 0;
2809}
2810
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002811static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
Tetsuo Handa95489062013-07-25 05:44:02 +09002812 const struct qstr *qstr,
2813 const char **name,
Eric Paris2a7dba32011-02-01 11:05:39 -05002814 void **value, size_t *len)
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002815{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002816 const struct task_security_struct *tsec = selinux_cred(current_cred());
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002817 struct superblock_security_struct *sbsec;
Corentin LABBEc0d4f462017-10-04 20:32:17 +02002818 u32 newsid, clen;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002819 int rc;
Tetsuo Handa95489062013-07-25 05:44:02 +09002820 char *context;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002821
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002822 sbsec = dir->i_sb->s_security;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002823
David Howells275bb412008-11-14 10:39:19 +11002824 newsid = tsec->create_sid;
2825
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002826 rc = selinux_determine_inode_label(selinux_cred(current_cred()),
David Howellsc3c188b2015-07-10 17:19:58 -04002827 dir, qstr,
2828 inode_mode_to_security_class(inode->i_mode),
2829 &newsid);
2830 if (rc)
2831 return rc;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002832
Eric Paris296fddf2006-09-25 23:32:00 -07002833 /* Possibly defer initialization to selinux_complete_init. */
David P. Quigley0d90a7e2009-01-16 09:22:02 -05002834 if (sbsec->flags & SE_SBINITIALIZED) {
Eric Paris296fddf2006-09-25 23:32:00 -07002835 struct inode_security_struct *isec = inode->i_security;
2836 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2837 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05002838 isec->initialized = LABEL_INITIALIZED;
Eric Paris296fddf2006-09-25 23:32:00 -07002839 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002840
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002841 if (!selinux_state.initialized || !(sbsec->flags & SBLABEL_MNT))
Stephen Smalley25a74f32005-11-08 21:34:33 -08002842 return -EOPNOTSUPP;
2843
Tetsuo Handa95489062013-07-25 05:44:02 +09002844 if (name)
2845 *name = XATTR_SELINUX_SUFFIX;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002846
2847 if (value && len) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002848 rc = security_sid_to_context_force(&selinux_state, newsid,
2849 &context, &clen);
Tetsuo Handa95489062013-07-25 05:44:02 +09002850 if (rc)
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002851 return rc;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002852 *value = context;
2853 *len = clen;
2854 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002855
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002856 return 0;
2857}
2858
Al Viro4acdaf22011-07-26 01:42:34 -04002859static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860{
2861 return may_create(dir, dentry, SECCLASS_FILE);
2862}
2863
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
2865{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 return may_link(dir, old_dentry, MAY_LINK);
2867}
2868
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
2870{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 return may_link(dir, dentry, MAY_UNLINK);
2872}
2873
2874static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
2875{
2876 return may_create(dir, dentry, SECCLASS_LNK_FILE);
2877}
2878
Al Viro18bb1db2011-07-26 01:41:39 -04002879static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880{
2881 return may_create(dir, dentry, SECCLASS_DIR);
2882}
2883
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
2885{
2886 return may_link(dir, dentry, MAY_RMDIR);
2887}
2888
Al Viro1a67aaf2011-07-26 01:52:52 -04002889static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891 return may_create(dir, dentry, inode_mode_to_security_class(mode));
2892}
2893
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
Eric Paris828dfe12008-04-17 13:17:49 -04002895 struct inode *new_inode, struct dentry *new_dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896{
2897 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
2898}
2899
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900static int selinux_inode_readlink(struct dentry *dentry)
2901{
David Howells88e67f32008-11-14 10:39:21 +11002902 const struct cred *cred = current_cred();
2903
Eric Paris2875fa02011-04-28 16:04:24 -04002904 return dentry_has_perm(cred, dentry, FILE__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905}
2906
NeilBrownbda0be72015-03-23 13:37:39 +11002907static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
2908 bool rcu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909{
David Howells88e67f32008-11-14 10:39:21 +11002910 const struct cred *cred = current_cred();
NeilBrownbda0be72015-03-23 13:37:39 +11002911 struct common_audit_data ad;
2912 struct inode_security_struct *isec;
2913 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914
NeilBrownbda0be72015-03-23 13:37:39 +11002915 validate_creds(cred);
2916
2917 ad.type = LSM_AUDIT_DATA_DENTRY;
2918 ad.u.dentry = dentry;
2919 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05002920 isec = inode_security_rcu(inode, rcu);
2921 if (IS_ERR(isec))
2922 return PTR_ERR(isec);
NeilBrownbda0be72015-03-23 13:37:39 +11002923
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002924 return avc_has_perm_flags(&selinux_state,
2925 sid, isec->sid, isec->sclass, FILE__READ, &ad,
NeilBrownbda0be72015-03-23 13:37:39 +11002926 rcu ? MAY_NOT_BLOCK : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927}
2928
Eric Parisd4cf970d2012-04-04 15:01:42 -04002929static noinline int audit_inode_permission(struct inode *inode,
2930 u32 perms, u32 audited, u32 denied,
Stephen Smalley626b9742014-04-29 11:29:04 -07002931 int result,
Eric Parisd4cf970d2012-04-04 15:01:42 -04002932 unsigned flags)
2933{
2934 struct common_audit_data ad;
Eric Parisd4cf970d2012-04-04 15:01:42 -04002935 struct inode_security_struct *isec = inode->i_security;
2936 int rc;
2937
Eric Paris50c205f2012-04-04 15:01:43 -04002938 ad.type = LSM_AUDIT_DATA_INODE;
Eric Parisd4cf970d2012-04-04 15:01:42 -04002939 ad.u.inode = inode;
2940
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002941 rc = slow_avc_audit(&selinux_state,
2942 current_sid(), isec->sid, isec->sclass, perms,
Stephen Smalley626b9742014-04-29 11:29:04 -07002943 audited, denied, result, &ad, flags);
Eric Parisd4cf970d2012-04-04 15:01:42 -04002944 if (rc)
2945 return rc;
2946 return 0;
2947}
2948
Al Viroe74f71e2011-06-20 19:38:15 -04002949static int selinux_inode_permission(struct inode *inode, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950{
David Howells88e67f32008-11-14 10:39:21 +11002951 const struct cred *cred = current_cred();
Eric Parisb782e0a2010-07-23 11:44:03 -04002952 u32 perms;
2953 bool from_access;
Al Virocf1dd1d2011-06-20 19:44:08 -04002954 unsigned flags = mask & MAY_NOT_BLOCK;
Eric Paris2e334052012-04-04 15:01:42 -04002955 struct inode_security_struct *isec;
2956 u32 sid;
2957 struct av_decision avd;
2958 int rc, rc2;
2959 u32 audited, denied;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960
Eric Parisb782e0a2010-07-23 11:44:03 -04002961 from_access = mask & MAY_ACCESS;
Eric Parisd09ca732010-07-23 11:43:57 -04002962 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
2963
Eric Parisb782e0a2010-07-23 11:44:03 -04002964 /* No permission to check. Existence test. */
2965 if (!mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967
Eric Paris2e334052012-04-04 15:01:42 -04002968 validate_creds(cred);
Eric Parisb782e0a2010-07-23 11:44:03 -04002969
Eric Paris2e334052012-04-04 15:01:42 -04002970 if (unlikely(IS_PRIVATE(inode)))
2971 return 0;
Eric Parisb782e0a2010-07-23 11:44:03 -04002972
2973 perms = file_mask_to_av(inode->i_mode, mask);
2974
Eric Paris2e334052012-04-04 15:01:42 -04002975 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05002976 isec = inode_security_rcu(inode, flags & MAY_NOT_BLOCK);
2977 if (IS_ERR(isec))
2978 return PTR_ERR(isec);
Eric Paris2e334052012-04-04 15:01:42 -04002979
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002980 rc = avc_has_perm_noaudit(&selinux_state,
2981 sid, isec->sid, isec->sclass, perms, 0, &avd);
Eric Paris2e334052012-04-04 15:01:42 -04002982 audited = avc_audit_required(perms, &avd, rc,
2983 from_access ? FILE__AUDIT_ACCESS : 0,
2984 &denied);
2985 if (likely(!audited))
2986 return rc;
2987
Stephen Smalley626b9742014-04-29 11:29:04 -07002988 rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
Eric Paris2e334052012-04-04 15:01:42 -04002989 if (rc2)
2990 return rc2;
2991 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992}
2993
2994static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2995{
David Howells88e67f32008-11-14 10:39:21 +11002996 const struct cred *cred = current_cred();
Stephen Smalleyccb54472017-05-12 12:41:24 -04002997 struct inode *inode = d_backing_inode(dentry);
Amerigo Wangbc6a6002009-08-20 19:29:02 -07002998 unsigned int ia_valid = iattr->ia_valid;
Eric Paris95dbf732012-04-04 13:45:34 -04002999 __u32 av = FILE__WRITE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003001 /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
3002 if (ia_valid & ATTR_FORCE) {
3003 ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE |
3004 ATTR_FORCE);
3005 if (!ia_valid)
3006 return 0;
3007 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008
Amerigo Wangbc6a6002009-08-20 19:29:02 -07003009 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
3010 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
Eric Paris2875fa02011-04-28 16:04:24 -04003011 return dentry_has_perm(cred, dentry, FILE__SETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003013 if (selinux_policycap_openperm() &&
Stephen Smalleyccb54472017-05-12 12:41:24 -04003014 inode->i_sb->s_magic != SOCKFS_MAGIC &&
3015 (ia_valid & ATTR_SIZE) &&
3016 !(ia_valid & ATTR_FILE))
Eric Paris95dbf732012-04-04 13:45:34 -04003017 av |= FILE__OPEN;
3018
3019 return dentry_has_perm(cred, dentry, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020}
3021
Al Viro3f7036a2015-03-08 19:28:30 -04003022static int selinux_inode_getattr(const struct path *path)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023{
Al Viro3f7036a2015-03-08 19:28:30 -04003024 return path_has_perm(current_cred(), path, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003025}
3026
Stephen Smalleydb590002017-04-20 11:31:30 -04003027static bool has_cap_mac_admin(bool audit)
3028{
3029 const struct cred *cred = current_cred();
3030 int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT;
3031
3032 if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit))
3033 return false;
3034 if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true))
3035 return false;
3036 return true;
3037}
3038
David Howells8f0cfa52008-04-29 00:59:41 -07003039static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3040 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003041{
David Howellsc6f493d2015-03-17 22:26:22 +00003042 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003043 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003044 struct superblock_security_struct *sbsec;
Thomas Liu2bf49692009-07-14 12:14:09 -04003045 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11003046 u32 newsid, sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047 int rc = 0;
3048
Eric W. Biederman6b240302017-10-02 09:38:20 -05003049 if (strcmp(name, XATTR_NAME_SELINUX)) {
3050 rc = cap_inode_setxattr(dentry, name, value, size, flags);
3051 if (rc)
3052 return rc;
3053
3054 /* Not an attribute we recognize, so just check the
3055 ordinary setattr permission. */
3056 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3057 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058
3059 sbsec = inode->i_sb->s_security;
Eric Paris12f348b2012-10-09 10:56:25 -04003060 if (!(sbsec->flags & SBLABEL_MNT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061 return -EOPNOTSUPP;
3062
Serge E. Hallyn2e149672011-03-23 16:43:26 -07003063 if (!inode_owner_or_capable(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064 return -EPERM;
3065
Eric Paris50c205f2012-04-04 15:01:43 -04003066 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04003067 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068
Paul Moore20cdef82016-04-04 14:14:42 -04003069 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003070 rc = avc_has_perm(&selinux_state,
3071 sid, isec->sid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 FILE__RELABELFROM, &ad);
3073 if (rc)
3074 return rc;
3075
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003076 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3077 GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003078 if (rc == -EINVAL) {
Stephen Smalleydb590002017-04-20 11:31:30 -04003079 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04003080 struct audit_buffer *ab;
3081 size_t audit_size;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003082
3083 /* We strip a nul only if it is at the end, otherwise the
3084 * context contains a nul and we should audit that */
Al Viroe3fea3f2012-06-09 08:15:16 +01003085 if (value) {
Colin Ian Kingadd24372017-10-14 13:46:55 +01003086 const char *str = value;
3087
Al Viroe3fea3f2012-06-09 08:15:16 +01003088 if (str[size - 1] == '\0')
3089 audit_size = size - 1;
3090 else
3091 audit_size = size;
3092 } else {
Al Viroe3fea3f2012-06-09 08:15:16 +01003093 audit_size = 0;
3094 }
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04003095 ab = audit_log_start(audit_context(),
3096 GFP_ATOMIC, AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04003097 audit_log_format(ab, "op=setxattr invalid_context=");
3098 audit_log_n_untrustedstring(ab, value, audit_size);
3099 audit_log_end(ab);
3100
Stephen Smalley12b29f32008-05-07 13:03:20 -04003101 return rc;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003102 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003103 rc = security_context_to_sid_force(&selinux_state, value,
3104 size, &newsid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003105 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003106 if (rc)
3107 return rc;
3108
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003109 rc = avc_has_perm(&selinux_state,
3110 sid, newsid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111 FILE__RELABELTO, &ad);
3112 if (rc)
3113 return rc;
3114
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003115 rc = security_validate_transition(&selinux_state, isec->sid, newsid,
3116 sid, isec->sclass);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003117 if (rc)
3118 return rc;
3119
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003120 return avc_has_perm(&selinux_state,
3121 newsid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122 sbsec->sid,
3123 SECCLASS_FILESYSTEM,
3124 FILESYSTEM__ASSOCIATE,
3125 &ad);
3126}
3127
David Howells8f0cfa52008-04-29 00:59:41 -07003128static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
Eric Parisf5269712008-05-14 11:27:45 -04003129 const void *value, size_t size,
David Howells8f0cfa52008-04-29 00:59:41 -07003130 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131{
David Howellsc6f493d2015-03-17 22:26:22 +00003132 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003133 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 u32 newsid;
3135 int rc;
3136
3137 if (strcmp(name, XATTR_NAME_SELINUX)) {
3138 /* Not an attribute we recognize, so nothing to do. */
3139 return;
3140 }
3141
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003142 rc = security_context_to_sid_force(&selinux_state, value, size,
3143 &newsid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +02003145 pr_err("SELinux: unable to map context to SID"
Stephen Smalley12b29f32008-05-07 13:03:20 -04003146 "for (%s, %lu), rc=%d\n",
3147 inode->i_sb->s_id, inode->i_ino, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148 return;
3149 }
3150
Paul Moore20cdef82016-04-04 14:14:42 -04003151 isec = backing_inode_security(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003152 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003153 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003155 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003156 spin_unlock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003157
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158 return;
3159}
3160
David Howells8f0cfa52008-04-29 00:59:41 -07003161static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003162{
David Howells88e67f32008-11-14 10:39:21 +11003163 const struct cred *cred = current_cred();
3164
Eric Paris2875fa02011-04-28 16:04:24 -04003165 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166}
3167
Eric Paris828dfe12008-04-17 13:17:49 -04003168static int selinux_inode_listxattr(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169{
David Howells88e67f32008-11-14 10:39:21 +11003170 const struct cred *cred = current_cred();
3171
Eric Paris2875fa02011-04-28 16:04:24 -04003172 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173}
3174
David Howells8f0cfa52008-04-29 00:59:41 -07003175static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003176{
Eric W. Biederman6b240302017-10-02 09:38:20 -05003177 if (strcmp(name, XATTR_NAME_SELINUX)) {
3178 int rc = cap_inode_removexattr(dentry, name);
3179 if (rc)
3180 return rc;
3181
3182 /* Not an attribute we recognize, so just check the
3183 ordinary setattr permission. */
3184 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3185 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186
3187 /* No one is allowed to remove a SELinux security label.
3188 You can change the label, but all data must be labeled. */
3189 return -EACCES;
3190}
3191
James Morrisd381d8a2005-10-30 14:59:22 -08003192/*
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003193 * Copy the inode security context value to the user.
James Morrisd381d8a2005-10-30 14:59:22 -08003194 *
3195 * Permission check is handled by selinux_inode_getxattr hook.
3196 */
Andreas Gruenbacherea861df2015-12-24 11:09:39 -05003197static int selinux_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198{
David P. Quigley42492592008-02-04 22:29:39 -08003199 u32 size;
3200 int error;
3201 char *context = NULL;
Paul Moore20cdef82016-04-04 14:14:42 -04003202 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00003204 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3205 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003206
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003207 /*
3208 * If the caller has CAP_MAC_ADMIN, then get the raw context
3209 * value even if it is not defined by current policy; otherwise,
3210 * use the in-core value under current policy.
3211 * Use the non-auditing forms of the permission checks since
3212 * getxattr may be called by unprivileged processes commonly
3213 * and lack of permission just means that we fall back to the
3214 * in-core context value, not a denial.
3215 */
Paul Moore20cdef82016-04-04 14:14:42 -04003216 isec = inode_security(inode);
Stephen Smalleydb590002017-04-20 11:31:30 -04003217 if (has_cap_mac_admin(false))
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003218 error = security_sid_to_context_force(&selinux_state,
3219 isec->sid, &context,
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003220 &size);
3221 else
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003222 error = security_sid_to_context(&selinux_state, isec->sid,
3223 &context, &size);
David P. Quigley42492592008-02-04 22:29:39 -08003224 if (error)
3225 return error;
3226 error = size;
3227 if (alloc) {
3228 *buffer = context;
3229 goto out_nofree;
3230 }
3231 kfree(context);
3232out_nofree:
3233 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003234}
3235
3236static int selinux_inode_setsecurity(struct inode *inode, const char *name,
Eric Paris828dfe12008-04-17 13:17:49 -04003237 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238{
Paul Moore2c971652016-04-19 16:36:28 -04003239 struct inode_security_struct *isec = inode_security_novalidate(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240 u32 newsid;
3241 int rc;
3242
3243 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3244 return -EOPNOTSUPP;
3245
3246 if (!value || !size)
3247 return -EACCES;
3248
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003249 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3250 GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003251 if (rc)
3252 return rc;
3253
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003254 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003255 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003257 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003258 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003259 return 0;
3260}
3261
3262static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
3263{
3264 const int len = sizeof(XATTR_NAME_SELINUX);
3265 if (buffer && len <= buffer_size)
3266 memcpy(buffer, XATTR_NAME_SELINUX, len);
3267 return len;
3268}
3269
Andreas Gruenbacherd6335d72015-12-24 11:09:39 -05003270static void selinux_inode_getsecid(struct inode *inode, u32 *secid)
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003271{
Andreas Gruenbachere817c2f2016-02-18 12:04:08 +01003272 struct inode_security_struct *isec = inode_security_novalidate(inode);
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003273 *secid = isec->sid;
3274}
3275
Vivek Goyal56909eb2016-07-13 10:44:48 -04003276static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
3277{
3278 u32 sid;
3279 struct task_security_struct *tsec;
3280 struct cred *new_creds = *new;
3281
3282 if (new_creds == NULL) {
3283 new_creds = prepare_creds();
3284 if (!new_creds)
3285 return -ENOMEM;
3286 }
3287
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003288 tsec = selinux_cred(new_creds);
Vivek Goyal56909eb2016-07-13 10:44:48 -04003289 /* Get label from overlay inode and set it in create_sid */
3290 selinux_inode_getsecid(d_inode(src), &sid);
3291 tsec->create_sid = sid;
3292 *new = new_creds;
3293 return 0;
3294}
3295
Vivek Goyal19472b62016-07-13 10:44:50 -04003296static int selinux_inode_copy_up_xattr(const char *name)
3297{
3298 /* The copy_up hook above sets the initial context on an inode, but we
3299 * don't then want to overwrite it by blindly copying all the lower
3300 * xattrs up. Instead, we have to filter out SELinux-related xattrs.
3301 */
3302 if (strcmp(name, XATTR_NAME_SELINUX) == 0)
3303 return 1; /* Discard */
3304 /*
3305 * Any other attribute apart from SELINUX is not claimed, supported
3306 * by selinux.
3307 */
3308 return -EOPNOTSUPP;
3309}
3310
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311/* file security operations */
3312
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003313static int selinux_revalidate_file_permission(struct file *file, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003314{
David Howells88e67f32008-11-14 10:39:21 +11003315 const struct cred *cred = current_cred();
Al Viro496ad9a2013-01-23 17:07:38 -05003316 struct inode *inode = file_inode(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317
Linus Torvalds1da177e2005-04-16 15:20:36 -07003318 /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */
3319 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
3320 mask |= MAY_APPEND;
3321
Paul Moore389fb8002009-03-27 17:10:34 -04003322 return file_has_perm(cred, file,
3323 file_mask_to_av(inode->i_mode, mask));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003324}
3325
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003326static int selinux_file_permission(struct file *file, int mask)
3327{
Al Viro496ad9a2013-01-23 17:07:38 -05003328 struct inode *inode = file_inode(file);
Stephen Smalley20dda182009-06-22 14:54:53 -04003329 struct file_security_struct *fsec = file->f_security;
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003330 struct inode_security_struct *isec;
Stephen Smalley20dda182009-06-22 14:54:53 -04003331 u32 sid = current_sid();
3332
Paul Moore389fb8002009-03-27 17:10:34 -04003333 if (!mask)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003334 /* No permission to check. Existence test. */
3335 return 0;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003336
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003337 isec = inode_security(inode);
Stephen Smalley20dda182009-06-22 14:54:53 -04003338 if (sid == fsec->sid && fsec->isid == isec->sid &&
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003339 fsec->pseqno == avc_policy_seqno(&selinux_state))
Eric Paris83d49852012-04-04 13:45:40 -04003340 /* No change since file_open check. */
Stephen Smalley20dda182009-06-22 14:54:53 -04003341 return 0;
3342
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003343 return selinux_revalidate_file_permission(file, mask);
3344}
3345
Linus Torvalds1da177e2005-04-16 15:20:36 -07003346static int selinux_file_alloc_security(struct file *file)
3347{
3348 return file_alloc_security(file);
3349}
3350
3351static void selinux_file_free_security(struct file *file)
3352{
3353 file_free_security(file);
3354}
3355
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003356/*
3357 * Check whether a task has the ioctl permission and cmd
3358 * operation to an inode.
3359 */
Geliang Tang1d2a1682015-10-21 17:44:27 -04003360static int ioctl_has_perm(const struct cred *cred, struct file *file,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003361 u32 requested, u16 cmd)
3362{
3363 struct common_audit_data ad;
3364 struct file_security_struct *fsec = file->f_security;
3365 struct inode *inode = file_inode(file);
Paul Moore20cdef82016-04-04 14:14:42 -04003366 struct inode_security_struct *isec;
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003367 struct lsm_ioctlop_audit ioctl;
3368 u32 ssid = cred_sid(cred);
3369 int rc;
3370 u8 driver = cmd >> 8;
3371 u8 xperm = cmd & 0xff;
3372
3373 ad.type = LSM_AUDIT_DATA_IOCTL_OP;
3374 ad.u.op = &ioctl;
3375 ad.u.op->cmd = cmd;
3376 ad.u.op->path = file->f_path;
3377
3378 if (ssid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003379 rc = avc_has_perm(&selinux_state,
3380 ssid, fsec->sid,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003381 SECCLASS_FD,
3382 FD__USE,
3383 &ad);
3384 if (rc)
3385 goto out;
3386 }
3387
3388 if (unlikely(IS_PRIVATE(inode)))
3389 return 0;
3390
Paul Moore20cdef82016-04-04 14:14:42 -04003391 isec = inode_security(inode);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003392 rc = avc_has_extended_perms(&selinux_state,
3393 ssid, isec->sid, isec->sclass,
3394 requested, driver, xperm, &ad);
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003395out:
3396 return rc;
3397}
3398
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3400 unsigned long arg)
3401{
David Howells88e67f32008-11-14 10:39:21 +11003402 const struct cred *cred = current_cred();
Eric Paris0b24dcb2011-02-25 15:39:20 -05003403 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003404
Eric Paris0b24dcb2011-02-25 15:39:20 -05003405 switch (cmd) {
3406 case FIONREAD:
3407 /* fall through */
3408 case FIBMAP:
3409 /* fall through */
3410 case FIGETBSZ:
3411 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003412 case FS_IOC_GETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003413 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003414 case FS_IOC_GETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003415 error = file_has_perm(cred, file, FILE__GETATTR);
3416 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003417
Al Viro2f99c362012-03-23 16:04:05 -04003418 case FS_IOC_SETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003419 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003420 case FS_IOC_SETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003421 error = file_has_perm(cred, file, FILE__SETATTR);
3422 break;
3423
3424 /* sys_ioctl() checks */
3425 case FIONBIO:
3426 /* fall through */
3427 case FIOASYNC:
3428 error = file_has_perm(cred, file, 0);
3429 break;
3430
3431 case KDSKBENT:
3432 case KDSKBSENT:
Eric Paris6a9de492012-01-03 12:25:14 -05003433 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04003434 SECURITY_CAP_AUDIT, true);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003435 break;
3436
3437 /* default case assumes that the command will go
3438 * to the file's ioctl() function.
3439 */
3440 default:
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003441 error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003442 }
3443 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003444}
3445
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003446static int default_noexec;
3447
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
3449{
David Howells88e67f32008-11-14 10:39:21 +11003450 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003451 u32 sid = cred_sid(cred);
David Howellsd84f4f92008-11-14 10:39:23 +11003452 int rc = 0;
David Howells88e67f32008-11-14 10:39:21 +11003453
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003454 if (default_noexec &&
Stephen Smalley892e8ca2015-07-10 09:40:59 -04003455 (prot & PROT_EXEC) && (!file || IS_PRIVATE(file_inode(file)) ||
3456 (!shared && (prot & PROT_WRITE)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003457 /*
3458 * We are making executable an anonymous mapping or a
3459 * private file mapping that will also be writable.
3460 * This has an additional check.
3461 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003462 rc = avc_has_perm(&selinux_state,
3463 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003464 PROCESS__EXECMEM, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003465 if (rc)
David Howellsd84f4f92008-11-14 10:39:23 +11003466 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468
3469 if (file) {
3470 /* read access is always possible with a mapping */
3471 u32 av = FILE__READ;
3472
3473 /* write access only matters if the mapping is shared */
3474 if (shared && (prot & PROT_WRITE))
3475 av |= FILE__WRITE;
3476
3477 if (prot & PROT_EXEC)
3478 av |= FILE__EXECUTE;
3479
David Howells88e67f32008-11-14 10:39:21 +11003480 return file_has_perm(cred, file, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003481 }
David Howellsd84f4f92008-11-14 10:39:23 +11003482
3483error:
3484 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003485}
3486
Al Viroe5467852012-05-30 13:30:51 -04003487static int selinux_mmap_addr(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003488{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07003489 int rc = 0;
Paul Moore98883bf2014-03-19 16:46:11 -04003490
3491 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
3492 u32 sid = current_sid();
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003493 rc = avc_has_perm(&selinux_state,
3494 sid, sid, SECCLASS_MEMPROTECT,
Paul Moore98883bf2014-03-19 16:46:11 -04003495 MEMPROTECT__MMAP_ZERO, NULL);
3496 }
3497
3498 return rc;
Al Viroe5467852012-05-30 13:30:51 -04003499}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500
Al Viroe5467852012-05-30 13:30:51 -04003501static int selinux_mmap_file(struct file *file, unsigned long reqprot,
3502 unsigned long prot, unsigned long flags)
3503{
Stephen Smalley3ba4bf52017-05-05 09:14:48 -04003504 struct common_audit_data ad;
3505 int rc;
3506
3507 if (file) {
3508 ad.type = LSM_AUDIT_DATA_FILE;
3509 ad.u.file = file;
3510 rc = inode_has_perm(current_cred(), file_inode(file),
3511 FILE__MAP, &ad);
3512 if (rc)
3513 return rc;
3514 }
3515
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003516 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003517 prot = reqprot;
3518
3519 return file_map_prot_check(file, prot,
3520 (flags & MAP_TYPE) == MAP_SHARED);
3521}
3522
3523static int selinux_file_mprotect(struct vm_area_struct *vma,
3524 unsigned long reqprot,
3525 unsigned long prot)
3526{
David Howells88e67f32008-11-14 10:39:21 +11003527 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003528 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003529
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003530 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003531 prot = reqprot;
3532
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003533 if (default_noexec &&
3534 (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
James Morrisd541bbe2009-01-29 12:19:51 +11003535 int rc = 0;
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003536 if (vma->vm_start >= vma->vm_mm->start_brk &&
3537 vma->vm_end <= vma->vm_mm->brk) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003538 rc = avc_has_perm(&selinux_state,
3539 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003540 PROCESS__EXECHEAP, NULL);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003541 } else if (!vma->vm_file &&
Stephen Smalleyc2316db2016-04-08 13:55:03 -04003542 ((vma->vm_start <= vma->vm_mm->start_stack &&
3543 vma->vm_end >= vma->vm_mm->start_stack) ||
Andy Lutomirskid17af502016-09-30 10:58:58 -07003544 vma_is_stack_for_current(vma))) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003545 rc = avc_has_perm(&selinux_state,
3546 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003547 PROCESS__EXECSTACK, NULL);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003548 } else if (vma->vm_file && vma->anon_vma) {
3549 /*
3550 * We are making executable a file mapping that has
3551 * had some COW done. Since pages might have been
3552 * written, check ability to execute the possibly
3553 * modified content. This typically should only
3554 * occur for text relocations.
3555 */
David Howellsd84f4f92008-11-14 10:39:23 +11003556 rc = file_has_perm(cred, vma->vm_file, FILE__EXECMOD);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003557 }
Lorenzo Hernandez García-Hierro6b992192005-06-25 14:54:34 -07003558 if (rc)
3559 return rc;
3560 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003561
3562 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
3563}
3564
3565static int selinux_file_lock(struct file *file, unsigned int cmd)
3566{
David Howells88e67f32008-11-14 10:39:21 +11003567 const struct cred *cred = current_cred();
3568
3569 return file_has_perm(cred, file, FILE__LOCK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003570}
3571
3572static int selinux_file_fcntl(struct file *file, unsigned int cmd,
3573 unsigned long arg)
3574{
David Howells88e67f32008-11-14 10:39:21 +11003575 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003576 int err = 0;
3577
3578 switch (cmd) {
Eric Paris828dfe12008-04-17 13:17:49 -04003579 case F_SETFL:
Eric Paris828dfe12008-04-17 13:17:49 -04003580 if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
David Howells88e67f32008-11-14 10:39:21 +11003581 err = file_has_perm(cred, file, FILE__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003583 }
3584 /* fall through */
3585 case F_SETOWN:
3586 case F_SETSIG:
3587 case F_GETFL:
3588 case F_GETOWN:
3589 case F_GETSIG:
Cyrill Gorcunov1d151c32012-07-30 14:43:00 -07003590 case F_GETOWNER_UIDS:
Eric Paris828dfe12008-04-17 13:17:49 -04003591 /* Just check FD__USE permission */
David Howells88e67f32008-11-14 10:39:21 +11003592 err = file_has_perm(cred, file, 0);
Eric Paris828dfe12008-04-17 13:17:49 -04003593 break;
3594 case F_GETLK:
3595 case F_SETLK:
3596 case F_SETLKW:
Jeff Layton0d3f7a22014-04-22 08:23:58 -04003597 case F_OFD_GETLK:
3598 case F_OFD_SETLK:
3599 case F_OFD_SETLKW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600#if BITS_PER_LONG == 32
Eric Paris828dfe12008-04-17 13:17:49 -04003601 case F_GETLK64:
3602 case F_SETLK64:
3603 case F_SETLKW64:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604#endif
David Howells88e67f32008-11-14 10:39:21 +11003605 err = file_has_perm(cred, file, FILE__LOCK);
Eric Paris828dfe12008-04-17 13:17:49 -04003606 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003607 }
3608
3609 return err;
3610}
3611
Jeff Laytone0b93ed2014-08-22 11:27:32 -04003612static void selinux_file_set_fowner(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003613{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003614 struct file_security_struct *fsec;
3615
Linus Torvalds1da177e2005-04-16 15:20:36 -07003616 fsec = file->f_security;
David Howells275bb412008-11-14 10:39:19 +11003617 fsec->fown_sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618}
3619
3620static int selinux_file_send_sigiotask(struct task_struct *tsk,
3621 struct fown_struct *fown, int signum)
3622{
Eric Paris828dfe12008-04-17 13:17:49 -04003623 struct file *file;
Stephen Smalley65c90bc2009-05-04 15:43:18 -04003624 u32 sid = task_sid(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003625 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626 struct file_security_struct *fsec;
3627
3628 /* struct fown_struct is never outside the context of a struct file */
Eric Paris828dfe12008-04-17 13:17:49 -04003629 file = container_of(fown, struct file, f_owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630
Linus Torvalds1da177e2005-04-16 15:20:36 -07003631 fsec = file->f_security;
3632
3633 if (!signum)
3634 perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
3635 else
3636 perm = signal_to_av(signum);
3637
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003638 return avc_has_perm(&selinux_state,
3639 fsec->fown_sid, sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 SECCLASS_PROCESS, perm, NULL);
3641}
3642
3643static int selinux_file_receive(struct file *file)
3644{
David Howells88e67f32008-11-14 10:39:21 +11003645 const struct cred *cred = current_cred();
3646
3647 return file_has_perm(cred, file, file_to_av(file));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648}
3649
Al Viro94817692018-07-10 14:13:18 -04003650static int selinux_file_open(struct file *file)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003651{
3652 struct file_security_struct *fsec;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003653 struct inode_security_struct *isec;
David Howellsd84f4f92008-11-14 10:39:23 +11003654
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003655 fsec = file->f_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003656 isec = inode_security(file_inode(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003657 /*
3658 * Save inode label and policy sequence number
3659 * at open-time so that selinux_file_permission
3660 * can determine whether revalidation is necessary.
3661 * Task label is already saved in the file security
3662 * struct as its SID.
3663 */
3664 fsec->isid = isec->sid;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003665 fsec->pseqno = avc_policy_seqno(&selinux_state);
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003666 /*
3667 * Since the inode label or policy seqno may have changed
3668 * between the selinux_inode_permission check and the saving
3669 * of state above, recheck that access is still permitted.
3670 * Otherwise, access might never be revalidated against the
3671 * new inode label or new policy.
3672 * This check is not redundant - do not remove.
3673 */
Al Viro94817692018-07-10 14:13:18 -04003674 return file_path_has_perm(file->f_cred, file, open_file_to_av(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003675}
3676
Linus Torvalds1da177e2005-04-16 15:20:36 -07003677/* task security operations */
3678
Tetsuo Handaa79be232017-03-28 23:08:45 +09003679static int selinux_task_alloc(struct task_struct *task,
3680 unsigned long clone_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003682 u32 sid = current_sid();
3683
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003684 return avc_has_perm(&selinux_state,
3685 sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003686}
3687
David Howellsf1752ee2008-11-14 10:39:17 +11003688/*
David Howellsee18d642009-09-02 09:14:21 +01003689 * allocate the SELinux part of blank credentials
3690 */
3691static int selinux_cred_alloc_blank(struct cred *cred, gfp_t gfp)
3692{
3693 struct task_security_struct *tsec;
3694
3695 tsec = kzalloc(sizeof(struct task_security_struct), gfp);
3696 if (!tsec)
3697 return -ENOMEM;
3698
3699 cred->security = tsec;
3700 return 0;
3701}
3702
3703/*
David Howellsf1752ee2008-11-14 10:39:17 +11003704 * detach and free the LSM part of a set of credentials
3705 */
3706static void selinux_cred_free(struct cred *cred)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003708 struct task_security_struct *tsec = selinux_cred(cred);
David Howellse0e81732009-09-02 09:13:40 +01003709
David Howellsf1752ee2008-11-14 10:39:17 +11003710 kfree(tsec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003711}
3712
David Howellsd84f4f92008-11-14 10:39:23 +11003713/*
3714 * prepare a new set of credentials for modification
3715 */
3716static int selinux_cred_prepare(struct cred *new, const struct cred *old,
3717 gfp_t gfp)
3718{
3719 const struct task_security_struct *old_tsec;
3720 struct task_security_struct *tsec;
3721
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003722 old_tsec = selinux_cred(old);
David Howellsd84f4f92008-11-14 10:39:23 +11003723
3724 tsec = kmemdup(old_tsec, sizeof(struct task_security_struct), gfp);
3725 if (!tsec)
3726 return -ENOMEM;
3727
3728 new->security = tsec;
3729 return 0;
3730}
3731
3732/*
David Howellsee18d642009-09-02 09:14:21 +01003733 * transfer the SELinux data to a blank set of creds
3734 */
3735static void selinux_cred_transfer(struct cred *new, const struct cred *old)
3736{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003737 const struct task_security_struct *old_tsec = selinux_cred(old);
3738 struct task_security_struct *tsec = selinux_cred(new);
David Howellsee18d642009-09-02 09:14:21 +01003739
3740 *tsec = *old_tsec;
3741}
3742
Matthew Garrett3ec30112018-01-08 13:36:19 -08003743static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
3744{
3745 *secid = cred_sid(c);
3746}
3747
David Howellsee18d642009-09-02 09:14:21 +01003748/*
David Howells3a3b7ce2008-11-14 10:39:28 +11003749 * set the security data for a kernel service
3750 * - all the creation contexts are set to unlabelled
3751 */
3752static int selinux_kernel_act_as(struct cred *new, u32 secid)
3753{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003754 struct task_security_struct *tsec = selinux_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11003755 u32 sid = current_sid();
3756 int ret;
3757
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003758 ret = avc_has_perm(&selinux_state,
3759 sid, secid,
David Howells3a3b7ce2008-11-14 10:39:28 +11003760 SECCLASS_KERNEL_SERVICE,
3761 KERNEL_SERVICE__USE_AS_OVERRIDE,
3762 NULL);
3763 if (ret == 0) {
3764 tsec->sid = secid;
3765 tsec->create_sid = 0;
3766 tsec->keycreate_sid = 0;
3767 tsec->sockcreate_sid = 0;
3768 }
3769 return ret;
3770}
3771
3772/*
3773 * set the file creation context in a security record to the same as the
3774 * objective context of the specified inode
3775 */
3776static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3777{
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003778 struct inode_security_struct *isec = inode_security(inode);
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003779 struct task_security_struct *tsec = selinux_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11003780 u32 sid = current_sid();
3781 int ret;
3782
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003783 ret = avc_has_perm(&selinux_state,
3784 sid, isec->sid,
David Howells3a3b7ce2008-11-14 10:39:28 +11003785 SECCLASS_KERNEL_SERVICE,
3786 KERNEL_SERVICE__CREATE_FILES_AS,
3787 NULL);
3788
3789 if (ret == 0)
3790 tsec->create_sid = isec->sid;
David Howellsef574712010-02-26 01:56:16 +00003791 return ret;
David Howells3a3b7ce2008-11-14 10:39:28 +11003792}
3793
Eric Parisdd8dbf22009-11-03 16:35:32 +11003794static int selinux_kernel_module_request(char *kmod_name)
Eric Paris25354c42009-08-13 09:45:03 -04003795{
Eric Parisdd8dbf22009-11-03 16:35:32 +11003796 struct common_audit_data ad;
3797
Eric Paris50c205f2012-04-04 15:01:43 -04003798 ad.type = LSM_AUDIT_DATA_KMOD;
Eric Parisdd8dbf22009-11-03 16:35:32 +11003799 ad.u.kmod_name = kmod_name;
3800
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003801 return avc_has_perm(&selinux_state,
3802 current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM,
Eric Parisdd8dbf22009-11-03 16:35:32 +11003803 SYSTEM__MODULE_REQUEST, &ad);
Eric Paris25354c42009-08-13 09:45:03 -04003804}
3805
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003806static int selinux_kernel_module_from_file(struct file *file)
3807{
3808 struct common_audit_data ad;
3809 struct inode_security_struct *isec;
3810 struct file_security_struct *fsec;
3811 u32 sid = current_sid();
3812 int rc;
3813
3814 /* init_module */
3815 if (file == NULL)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003816 return avc_has_perm(&selinux_state,
3817 sid, sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003818 SYSTEM__MODULE_LOAD, NULL);
3819
3820 /* finit_module */
Paul Moore20cdef82016-04-04 14:14:42 -04003821
Vivek Goyal43af5de2016-09-09 11:37:49 -04003822 ad.type = LSM_AUDIT_DATA_FILE;
3823 ad.u.file = file;
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003824
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003825 fsec = file->f_security;
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003826 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003827 rc = avc_has_perm(&selinux_state,
3828 sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003829 if (rc)
3830 return rc;
3831 }
3832
Paul Moore20cdef82016-04-04 14:14:42 -04003833 isec = inode_security(file_inode(file));
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003834 return avc_has_perm(&selinux_state,
3835 sid, isec->sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003836 SYSTEM__MODULE_LOAD, &ad);
3837}
3838
3839static int selinux_kernel_read_file(struct file *file,
3840 enum kernel_read_file_id id)
3841{
3842 int rc = 0;
3843
3844 switch (id) {
3845 case READING_MODULE:
3846 rc = selinux_kernel_module_from_file(file);
3847 break;
3848 default:
3849 break;
3850 }
3851
3852 return rc;
3853}
3854
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04003855static int selinux_kernel_load_data(enum kernel_load_data_id id)
3856{
3857 int rc = 0;
3858
3859 switch (id) {
3860 case LOADING_MODULE:
3861 rc = selinux_kernel_module_from_file(NULL);
3862 default:
3863 break;
3864 }
3865
3866 return rc;
3867}
3868
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3870{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003871 return avc_has_perm(&selinux_state,
3872 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003873 PROCESS__SETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874}
3875
3876static int selinux_task_getpgid(struct task_struct *p)
3877{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003878 return avc_has_perm(&selinux_state,
3879 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003880 PROCESS__GETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003881}
3882
3883static int selinux_task_getsid(struct task_struct *p)
3884{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003885 return avc_has_perm(&selinux_state,
3886 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003887 PROCESS__GETSESSION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888}
3889
David Quigleyf9008e4c2006-06-30 01:55:46 -07003890static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
3891{
David Howells275bb412008-11-14 10:39:19 +11003892 *secid = task_sid(p);
David Quigleyf9008e4c2006-06-30 01:55:46 -07003893}
3894
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895static int selinux_task_setnice(struct task_struct *p, int nice)
3896{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003897 return avc_has_perm(&selinux_state,
3898 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003899 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900}
3901
James Morris03e68062006-06-23 02:03:58 -07003902static int selinux_task_setioprio(struct task_struct *p, int ioprio)
3903{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003904 return avc_has_perm(&selinux_state,
3905 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003906 PROCESS__SETSCHED, NULL);
James Morris03e68062006-06-23 02:03:58 -07003907}
3908
David Quigleya1836a42006-06-30 01:55:49 -07003909static int selinux_task_getioprio(struct task_struct *p)
3910{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003911 return avc_has_perm(&selinux_state,
3912 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003913 PROCESS__GETSCHED, NULL);
David Quigleya1836a42006-06-30 01:55:49 -07003914}
3915
Corentin LABBE42985552017-10-04 20:32:18 +02003916static int selinux_task_prlimit(const struct cred *cred, const struct cred *tcred,
3917 unsigned int flags)
Stephen Smalley791ec492017-02-17 07:57:00 -05003918{
3919 u32 av = 0;
3920
Stephen Smalley84e68852017-02-28 09:35:08 -05003921 if (!flags)
3922 return 0;
Stephen Smalley791ec492017-02-17 07:57:00 -05003923 if (flags & LSM_PRLIMIT_WRITE)
3924 av |= PROCESS__SETRLIMIT;
3925 if (flags & LSM_PRLIMIT_READ)
3926 av |= PROCESS__GETRLIMIT;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003927 return avc_has_perm(&selinux_state,
3928 cred_sid(cred), cred_sid(tcred),
Stephen Smalley791ec492017-02-17 07:57:00 -05003929 SECCLASS_PROCESS, av, NULL);
3930}
3931
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003932static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
3933 struct rlimit *new_rlim)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934{
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003935 struct rlimit *old_rlim = p->signal->rlim + resource;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936
3937 /* Control the ability to change the hard limit (whether
3938 lowering or raising it), so that the hard limit can
3939 later be used as a safe reset point for the soft limit
David Howellsd84f4f92008-11-14 10:39:23 +11003940 upon context transitions. See selinux_bprm_committing_creds. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003941 if (old_rlim->rlim_max != new_rlim->rlim_max)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003942 return avc_has_perm(&selinux_state,
3943 current_sid(), task_sid(p),
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003944 SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945
3946 return 0;
3947}
3948
KOSAKI Motohirob0ae1982010-10-15 04:21:18 +09003949static int selinux_task_setscheduler(struct task_struct *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003950{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003951 return avc_has_perm(&selinux_state,
3952 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003953 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003954}
3955
3956static int selinux_task_getscheduler(struct task_struct *p)
3957{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003958 return avc_has_perm(&selinux_state,
3959 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003960 PROCESS__GETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961}
3962
David Quigley35601542006-06-23 02:04:01 -07003963static int selinux_task_movememory(struct task_struct *p)
3964{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003965 return avc_has_perm(&selinux_state,
3966 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003967 PROCESS__SETSCHED, NULL);
David Quigley35601542006-06-23 02:04:01 -07003968}
3969
Eric W. Biedermanae7795b2018-09-25 11:27:20 +02003970static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003971 int sig, const struct cred *cred)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972{
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003973 u32 secid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976 if (!sig)
3977 perm = PROCESS__SIGNULL; /* null signal; existence test */
3978 else
3979 perm = signal_to_av(sig);
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003980 if (!cred)
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003981 secid = current_sid();
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003982 else
3983 secid = cred_sid(cred);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003984 return avc_has_perm(&selinux_state,
3985 secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986}
3987
Linus Torvalds1da177e2005-04-16 15:20:36 -07003988static void selinux_task_to_inode(struct task_struct *p,
3989 struct inode *inode)
3990{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003991 struct inode_security_struct *isec = inode->i_security;
David Howells275bb412008-11-14 10:39:19 +11003992 u32 sid = task_sid(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003994 spin_lock(&isec->lock);
Andreas Gruenbacherdb978da2016-11-10 22:18:28 +01003995 isec->sclass = inode_mode_to_security_class(inode->i_mode);
David Howells275bb412008-11-14 10:39:19 +11003996 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003997 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003998 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003999}
4000
Linus Torvalds1da177e2005-04-16 15:20:36 -07004001/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004002static int selinux_parse_skb_ipv4(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004003 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004{
4005 int offset, ihlen, ret = -EINVAL;
4006 struct iphdr _iph, *ih;
4007
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004008 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004009 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
4010 if (ih == NULL)
4011 goto out;
4012
4013 ihlen = ih->ihl * 4;
4014 if (ihlen < sizeof(_iph))
4015 goto out;
4016
Eric Paris48c62af2012-04-02 13:15:44 -04004017 ad->u.net->v4info.saddr = ih->saddr;
4018 ad->u.net->v4info.daddr = ih->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019 ret = 0;
4020
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004021 if (proto)
4022 *proto = ih->protocol;
4023
Linus Torvalds1da177e2005-04-16 15:20:36 -07004024 switch (ih->protocol) {
Eric Paris828dfe12008-04-17 13:17:49 -04004025 case IPPROTO_TCP: {
4026 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027
Eric Paris828dfe12008-04-17 13:17:49 -04004028 if (ntohs(ih->frag_off) & IP_OFFSET)
4029 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004030
4031 offset += ihlen;
4032 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4033 if (th == NULL)
4034 break;
4035
Eric Paris48c62af2012-04-02 13:15:44 -04004036 ad->u.net->sport = th->source;
4037 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004038 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004039 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004040
Eric Paris828dfe12008-04-17 13:17:49 -04004041 case IPPROTO_UDP: {
4042 struct udphdr _udph, *uh;
4043
4044 if (ntohs(ih->frag_off) & IP_OFFSET)
4045 break;
4046
4047 offset += ihlen;
4048 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4049 if (uh == NULL)
4050 break;
4051
Eric Paris48c62af2012-04-02 13:15:44 -04004052 ad->u.net->sport = uh->source;
4053 ad->u.net->dport = uh->dest;
Eric Paris828dfe12008-04-17 13:17:49 -04004054 break;
4055 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004056
James Morris2ee92d42006-11-13 16:09:01 -08004057 case IPPROTO_DCCP: {
4058 struct dccp_hdr _dccph, *dh;
4059
4060 if (ntohs(ih->frag_off) & IP_OFFSET)
4061 break;
4062
4063 offset += ihlen;
4064 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4065 if (dh == NULL)
4066 break;
4067
Eric Paris48c62af2012-04-02 13:15:44 -04004068 ad->u.net->sport = dh->dccph_sport;
4069 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004070 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004071 }
James Morris2ee92d42006-11-13 16:09:01 -08004072
Richard Hainesd4529302018-02-13 20:57:18 +00004073#if IS_ENABLED(CONFIG_IP_SCTP)
4074 case IPPROTO_SCTP: {
4075 struct sctphdr _sctph, *sh;
4076
4077 if (ntohs(ih->frag_off) & IP_OFFSET)
4078 break;
4079
4080 offset += ihlen;
4081 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4082 if (sh == NULL)
4083 break;
4084
4085 ad->u.net->sport = sh->source;
4086 ad->u.net->dport = sh->dest;
4087 break;
4088 }
4089#endif
Eric Paris828dfe12008-04-17 13:17:49 -04004090 default:
4091 break;
4092 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004093out:
4094 return ret;
4095}
4096
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004097#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004098
4099/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004100static int selinux_parse_skb_ipv6(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004101 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004102{
4103 u8 nexthdr;
4104 int ret = -EINVAL, offset;
4105 struct ipv6hdr _ipv6h, *ip6;
Jesse Gross75f28112011-11-30 17:05:51 -08004106 __be16 frag_off;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004107
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004108 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004109 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
4110 if (ip6 == NULL)
4111 goto out;
4112
Eric Paris48c62af2012-04-02 13:15:44 -04004113 ad->u.net->v6info.saddr = ip6->saddr;
4114 ad->u.net->v6info.daddr = ip6->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115 ret = 0;
4116
4117 nexthdr = ip6->nexthdr;
4118 offset += sizeof(_ipv6h);
Jesse Gross75f28112011-11-30 17:05:51 -08004119 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120 if (offset < 0)
4121 goto out;
4122
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004123 if (proto)
4124 *proto = nexthdr;
4125
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 switch (nexthdr) {
4127 case IPPROTO_TCP: {
Eric Paris828dfe12008-04-17 13:17:49 -04004128 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129
4130 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4131 if (th == NULL)
4132 break;
4133
Eric Paris48c62af2012-04-02 13:15:44 -04004134 ad->u.net->sport = th->source;
4135 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 break;
4137 }
4138
4139 case IPPROTO_UDP: {
4140 struct udphdr _udph, *uh;
4141
4142 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4143 if (uh == NULL)
4144 break;
4145
Eric Paris48c62af2012-04-02 13:15:44 -04004146 ad->u.net->sport = uh->source;
4147 ad->u.net->dport = uh->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 break;
4149 }
4150
James Morris2ee92d42006-11-13 16:09:01 -08004151 case IPPROTO_DCCP: {
4152 struct dccp_hdr _dccph, *dh;
4153
4154 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4155 if (dh == NULL)
4156 break;
4157
Eric Paris48c62af2012-04-02 13:15:44 -04004158 ad->u.net->sport = dh->dccph_sport;
4159 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004160 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004161 }
James Morris2ee92d42006-11-13 16:09:01 -08004162
Richard Hainesd4529302018-02-13 20:57:18 +00004163#if IS_ENABLED(CONFIG_IP_SCTP)
4164 case IPPROTO_SCTP: {
4165 struct sctphdr _sctph, *sh;
4166
4167 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4168 if (sh == NULL)
4169 break;
4170
4171 ad->u.net->sport = sh->source;
4172 ad->u.net->dport = sh->dest;
4173 break;
4174 }
4175#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07004176 /* includes fragments */
4177 default:
4178 break;
4179 }
4180out:
4181 return ret;
4182}
4183
4184#endif /* IPV6 */
4185
Thomas Liu2bf49692009-07-14 12:14:09 -04004186static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
David Howellscf9481e2008-07-27 21:31:07 +10004187 char **_addrp, int src, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004188{
David Howellscf9481e2008-07-27 21:31:07 +10004189 char *addrp;
4190 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004191
Eric Paris48c62af2012-04-02 13:15:44 -04004192 switch (ad->u.net->family) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004193 case PF_INET:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004194 ret = selinux_parse_skb_ipv4(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004195 if (ret)
4196 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004197 addrp = (char *)(src ? &ad->u.net->v4info.saddr :
4198 &ad->u.net->v4info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004199 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004200
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004201#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004202 case PF_INET6:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004203 ret = selinux_parse_skb_ipv6(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004204 if (ret)
4205 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004206 addrp = (char *)(src ? &ad->u.net->v6info.saddr :
4207 &ad->u.net->v6info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004208 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209#endif /* IPV6 */
4210 default:
David Howellscf9481e2008-07-27 21:31:07 +10004211 addrp = NULL;
4212 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213 }
4214
David Howellscf9481e2008-07-27 21:31:07 +10004215parse_error:
peter enderborgc103a912018-06-12 10:09:03 +02004216 pr_warn(
David Howellscf9481e2008-07-27 21:31:07 +10004217 "SELinux: failure in selinux_parse_skb(),"
4218 " unable to parse packet\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219 return ret;
David Howellscf9481e2008-07-27 21:31:07 +10004220
4221okay:
4222 if (_addrp)
4223 *_addrp = addrp;
4224 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004225}
4226
Paul Moore4f6a9932007-03-01 14:35:22 -05004227/**
Paul Moore220deb92008-01-29 08:38:23 -05004228 * selinux_skb_peerlbl_sid - Determine the peer label of a packet
Paul Moore4f6a9932007-03-01 14:35:22 -05004229 * @skb: the packet
Paul Moore75e22912008-01-29 08:38:04 -05004230 * @family: protocol family
Paul Moore220deb92008-01-29 08:38:23 -05004231 * @sid: the packet's peer label SID
Paul Moore4f6a9932007-03-01 14:35:22 -05004232 *
4233 * Description:
Paul Moore220deb92008-01-29 08:38:23 -05004234 * Check the various different forms of network peer labeling and determine
4235 * the peer label/SID for the packet; most of the magic actually occurs in
4236 * the security server function security_net_peersid_cmp(). The function
4237 * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
4238 * or -EACCES if @sid is invalid due to inconsistencies with the different
4239 * peer labels.
Paul Moore4f6a9932007-03-01 14:35:22 -05004240 *
4241 */
Paul Moore220deb92008-01-29 08:38:23 -05004242static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
Paul Moore4f6a9932007-03-01 14:35:22 -05004243{
Paul Moore71f1cb02008-01-29 08:51:16 -05004244 int err;
Paul Moore4f6a9932007-03-01 14:35:22 -05004245 u32 xfrm_sid;
4246 u32 nlbl_sid;
Paul Moore220deb92008-01-29 08:38:23 -05004247 u32 nlbl_type;
Paul Moore4f6a9932007-03-01 14:35:22 -05004248
Paul Moore817eff72013-12-10 14:57:54 -05004249 err = selinux_xfrm_skb_sid(skb, &xfrm_sid);
Paul Moorebed4d7e2013-07-23 17:38:40 -04004250 if (unlikely(err))
4251 return -EACCES;
4252 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
4253 if (unlikely(err))
4254 return -EACCES;
Paul Moore220deb92008-01-29 08:38:23 -05004255
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004256 err = security_net_peersid_resolve(&selinux_state, nlbl_sid,
4257 nlbl_type, xfrm_sid, sid);
Paul Moore71f1cb02008-01-29 08:51:16 -05004258 if (unlikely(err)) {
peter enderborgc103a912018-06-12 10:09:03 +02004259 pr_warn(
Paul Moore71f1cb02008-01-29 08:51:16 -05004260 "SELinux: failure in selinux_skb_peerlbl_sid(),"
4261 " unable to determine packet's peer label\n");
Paul Moore220deb92008-01-29 08:38:23 -05004262 return -EACCES;
Paul Moore71f1cb02008-01-29 08:51:16 -05004263 }
Paul Moore220deb92008-01-29 08:38:23 -05004264
4265 return 0;
Paul Moore4f6a9932007-03-01 14:35:22 -05004266}
4267
Paul Moore446b8022013-12-04 16:10:51 -05004268/**
4269 * selinux_conn_sid - Determine the child socket label for a connection
4270 * @sk_sid: the parent socket's SID
4271 * @skb_sid: the packet's SID
4272 * @conn_sid: the resulting connection SID
4273 *
4274 * If @skb_sid is valid then the user:role:type information from @sk_sid is
4275 * combined with the MLS information from @skb_sid in order to create
4276 * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy
4277 * of @sk_sid. Returns zero on success, negative values on failure.
4278 *
4279 */
4280static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
4281{
4282 int err = 0;
4283
4284 if (skb_sid != SECSID_NULL)
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004285 err = security_sid_mls_copy(&selinux_state, sk_sid, skb_sid,
4286 conn_sid);
Paul Moore446b8022013-12-04 16:10:51 -05004287 else
4288 *conn_sid = sk_sid;
4289
4290 return err;
4291}
4292
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293/* socket security operations */
Paul Moored4f2d972010-04-22 14:46:18 -04004294
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004295static int socket_sockcreate_sid(const struct task_security_struct *tsec,
4296 u16 secclass, u32 *socksid)
Paul Moored4f2d972010-04-22 14:46:18 -04004297{
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004298 if (tsec->sockcreate_sid > SECSID_NULL) {
4299 *socksid = tsec->sockcreate_sid;
4300 return 0;
4301 }
4302
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004303 return security_transition_sid(&selinux_state, tsec->sid, tsec->sid,
4304 secclass, NULL, socksid);
Paul Moored4f2d972010-04-22 14:46:18 -04004305}
4306
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004307static int sock_has_perm(struct sock *sk, u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308{
Paul Moore253bfae2010-04-22 14:46:19 -04004309 struct sk_security_struct *sksec = sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004310 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004311 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312
Paul Moore253bfae2010-04-22 14:46:19 -04004313 if (sksec->sid == SECINITSID_KERNEL)
4314 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315
Eric Paris50c205f2012-04-04 15:01:43 -04004316 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004317 ad.u.net = &net;
4318 ad.u.net->sk = sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004320 return avc_has_perm(&selinux_state,
4321 current_sid(), sksec->sid, sksec->sclass, perms,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004322 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323}
4324
4325static int selinux_socket_create(int family, int type,
4326 int protocol, int kern)
4327{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07004328 const struct task_security_struct *tsec = selinux_cred(current_cred());
Paul Moored4f2d972010-04-22 14:46:18 -04004329 u32 newsid;
David Howells275bb412008-11-14 10:39:19 +11004330 u16 secclass;
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004331 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332
4333 if (kern)
Paul Moored4f2d972010-04-22 14:46:18 -04004334 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004335
David Howells275bb412008-11-14 10:39:19 +11004336 secclass = socket_type_to_security_class(family, type, protocol);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004337 rc = socket_sockcreate_sid(tsec, secclass, &newsid);
4338 if (rc)
4339 return rc;
4340
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004341 return avc_has_perm(&selinux_state,
4342 tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343}
4344
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004345static int selinux_socket_post_create(struct socket *sock, int family,
4346 int type, int protocol, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004347{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07004348 const struct task_security_struct *tsec = selinux_cred(current_cred());
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004349 struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock));
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004350 struct sk_security_struct *sksec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004351 u16 sclass = socket_type_to_security_class(family, type, protocol);
4352 u32 sid = SECINITSID_KERNEL;
David Howells275bb412008-11-14 10:39:19 +11004353 int err = 0;
4354
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004355 if (!kern) {
4356 err = socket_sockcreate_sid(tsec, sclass, &sid);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004357 if (err)
4358 return err;
4359 }
David Howells275bb412008-11-14 10:39:19 +11004360
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004361 isec->sclass = sclass;
4362 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004363 isec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004364
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004365 if (sock->sk) {
4366 sksec = sock->sk->sk_security;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004367 sksec->sclass = sclass;
4368 sksec->sid = sid;
Richard Hainesd4529302018-02-13 20:57:18 +00004369 /* Allows detection of the first association on this socket */
4370 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4371 sksec->sctp_assoc_state = SCTP_ASSOC_UNSET;
4372
Paul Moore389fb8002009-03-27 17:10:34 -04004373 err = selinux_netlbl_socket_post_create(sock->sk, family);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004374 }
4375
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004376 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004377}
4378
David Herrmann0b811db2018-05-04 16:28:21 +02004379static int selinux_socket_socketpair(struct socket *socka,
4380 struct socket *sockb)
4381{
4382 struct sk_security_struct *sksec_a = socka->sk->sk_security;
4383 struct sk_security_struct *sksec_b = sockb->sk->sk_security;
4384
4385 sksec_a->peer_sid = sksec_b->sid;
4386 sksec_b->peer_sid = sksec_a->sid;
4387
4388 return 0;
4389}
4390
Linus Torvalds1da177e2005-04-16 15:20:36 -07004391/* Range of port numbers used to automatically bind.
4392 Need to determine whether we should perform a name_bind
4393 permission check between the socket and the port number. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004394
4395static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
4396{
Paul Moore253bfae2010-04-22 14:46:19 -04004397 struct sock *sk = sock->sk;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004398 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004399 u16 family;
4400 int err;
4401
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004402 err = sock_has_perm(sk, SOCKET__BIND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004403 if (err)
4404 goto out;
4405
Richard Hainesd4529302018-02-13 20:57:18 +00004406 /* If PF_INET or PF_INET6, check name_bind permission for the port. */
Paul Moore253bfae2010-04-22 14:46:19 -04004407 family = sk->sk_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408 if (family == PF_INET || family == PF_INET6) {
4409 char *addrp;
Thomas Liu2bf49692009-07-14 12:14:09 -04004410 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004411 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004412 struct sockaddr_in *addr4 = NULL;
4413 struct sockaddr_in6 *addr6 = NULL;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004414 u16 family_sa = address->sa_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004415 unsigned short snum;
James Morrise399f982008-06-12 01:39:58 +10004416 u32 sid, node_perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004417
Richard Hainesd4529302018-02-13 20:57:18 +00004418 /*
4419 * sctp_bindx(3) calls via selinux_sctp_bind_connect()
4420 * that validates multiple binding addresses. Because of this
4421 * need to check address->sa_family as it is possible to have
4422 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4423 */
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004424 switch (family_sa) {
4425 case AF_UNSPEC:
Richard Haines68741a8a2018-03-02 19:54:34 +00004426 case AF_INET:
4427 if (addrlen < sizeof(struct sockaddr_in))
4428 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004429 addr4 = (struct sockaddr_in *)address;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004430 if (family_sa == AF_UNSPEC) {
4431 /* see __inet_bind(), we only want to allow
4432 * AF_UNSPEC if the address is INADDR_ANY
4433 */
4434 if (addr4->sin_addr.s_addr != htonl(INADDR_ANY))
4435 goto err_af;
4436 family_sa = AF_INET;
4437 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438 snum = ntohs(addr4->sin_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004439 addrp = (char *)&addr4->sin_addr.s_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004440 break;
4441 case AF_INET6:
4442 if (addrlen < SIN6_LEN_RFC2133)
4443 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004444 addr6 = (struct sockaddr_in6 *)address;
4445 snum = ntohs(addr6->sin6_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004446 addrp = (char *)&addr6->sin6_addr.s6_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004447 break;
4448 default:
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004449 goto err_af;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004450 }
4451
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004452 ad.type = LSM_AUDIT_DATA_NET;
4453 ad.u.net = &net;
4454 ad.u.net->sport = htons(snum);
4455 ad.u.net->family = family_sa;
4456
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004457 if (snum) {
4458 int low, high;
4459
Eric W. Biederman0bbf87d2013-09-28 14:10:59 -07004460 inet_get_local_port_range(sock_net(sk), &low, &high);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004461
Krister Johansen4548b682017-01-20 17:49:11 -08004462 if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
4463 snum > high) {
Paul Moore3e1121722008-04-10 10:48:14 -04004464 err = sel_netport_sid(sk->sk_protocol,
4465 snum, &sid);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004466 if (err)
4467 goto out;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004468 err = avc_has_perm(&selinux_state,
4469 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004470 sksec->sclass,
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004471 SOCKET__NAME_BIND, &ad);
4472 if (err)
4473 goto out;
4474 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004475 }
Eric Paris828dfe12008-04-17 13:17:49 -04004476
Paul Moore253bfae2010-04-22 14:46:19 -04004477 switch (sksec->sclass) {
James Morris13402582005-09-30 14:24:34 -04004478 case SECCLASS_TCP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004479 node_perm = TCP_SOCKET__NODE_BIND;
4480 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004481
James Morris13402582005-09-30 14:24:34 -04004482 case SECCLASS_UDP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004483 node_perm = UDP_SOCKET__NODE_BIND;
4484 break;
James Morris2ee92d42006-11-13 16:09:01 -08004485
4486 case SECCLASS_DCCP_SOCKET:
4487 node_perm = DCCP_SOCKET__NODE_BIND;
4488 break;
4489
Richard Hainesd4529302018-02-13 20:57:18 +00004490 case SECCLASS_SCTP_SOCKET:
4491 node_perm = SCTP_SOCKET__NODE_BIND;
4492 break;
4493
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494 default:
4495 node_perm = RAWIP_SOCKET__NODE_BIND;
4496 break;
4497 }
Eric Paris828dfe12008-04-17 13:17:49 -04004498
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004499 err = sel_netnode_sid(addrp, family_sa, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004500 if (err)
4501 goto out;
Eric Paris828dfe12008-04-17 13:17:49 -04004502
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004503 if (family_sa == AF_INET)
Eric Paris48c62af2012-04-02 13:15:44 -04004504 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004505 else
Eric Paris48c62af2012-04-02 13:15:44 -04004506 ad.u.net->v6info.saddr = addr6->sin6_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004507
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004508 err = avc_has_perm(&selinux_state,
4509 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004510 sksec->sclass, node_perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004511 if (err)
4512 goto out;
4513 }
4514out:
4515 return err;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004516err_af:
4517 /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */
4518 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4519 return -EINVAL;
4520 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004521}
4522
Richard Hainesd4529302018-02-13 20:57:18 +00004523/* This supports connect(2) and SCTP connect services such as sctp_connectx(3)
Mauro Carvalho Chehab5fb94e92018-05-08 15:14:57 -03004524 * and sctp_sendmsg(3) as described in Documentation/security/LSM-sctp.rst
Richard Hainesd4529302018-02-13 20:57:18 +00004525 */
4526static int selinux_socket_connect_helper(struct socket *sock,
4527 struct sockaddr *address, int addrlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004528{
Paul Moore014ab192008-10-10 10:16:33 -04004529 struct sock *sk = sock->sk;
Paul Moore253bfae2010-04-22 14:46:19 -04004530 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004531 int err;
4532
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004533 err = sock_has_perm(sk, SOCKET__CONNECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004534 if (err)
4535 return err;
4536
4537 /*
Richard Hainesd4529302018-02-13 20:57:18 +00004538 * If a TCP, DCCP or SCTP socket, check name_connect permission
4539 * for the port.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004540 */
Paul Moore253bfae2010-04-22 14:46:19 -04004541 if (sksec->sclass == SECCLASS_TCP_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00004542 sksec->sclass == SECCLASS_DCCP_SOCKET ||
4543 sksec->sclass == SECCLASS_SCTP_SOCKET) {
Thomas Liu2bf49692009-07-14 12:14:09 -04004544 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004545 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546 struct sockaddr_in *addr4 = NULL;
4547 struct sockaddr_in6 *addr6 = NULL;
4548 unsigned short snum;
James Morris2ee92d42006-11-13 16:09:01 -08004549 u32 sid, perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550
Richard Hainesd4529302018-02-13 20:57:18 +00004551 /* sctp_connectx(3) calls via selinux_sctp_bind_connect()
4552 * that validates multiple connect addresses. Because of this
4553 * need to check address->sa_family as it is possible to have
4554 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4555 */
Richard Haines68741a8a2018-03-02 19:54:34 +00004556 switch (address->sa_family) {
4557 case AF_INET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004558 addr4 = (struct sockaddr_in *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004559 if (addrlen < sizeof(struct sockaddr_in))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004560 return -EINVAL;
4561 snum = ntohs(addr4->sin_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004562 break;
4563 case AF_INET6:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004564 addr6 = (struct sockaddr_in6 *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004565 if (addrlen < SIN6_LEN_RFC2133)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004566 return -EINVAL;
4567 snum = ntohs(addr6->sin6_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004568 break;
4569 default:
4570 /* Note that SCTP services expect -EINVAL, whereas
4571 * others expect -EAFNOSUPPORT.
4572 */
4573 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4574 return -EINVAL;
4575 else
4576 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004577 }
4578
Paul Moore3e1121722008-04-10 10:48:14 -04004579 err = sel_netport_sid(sk->sk_protocol, snum, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004580 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004581 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004582
Richard Hainesd4529302018-02-13 20:57:18 +00004583 switch (sksec->sclass) {
4584 case SECCLASS_TCP_SOCKET:
4585 perm = TCP_SOCKET__NAME_CONNECT;
4586 break;
4587 case SECCLASS_DCCP_SOCKET:
4588 perm = DCCP_SOCKET__NAME_CONNECT;
4589 break;
4590 case SECCLASS_SCTP_SOCKET:
4591 perm = SCTP_SOCKET__NAME_CONNECT;
4592 break;
4593 }
James Morris2ee92d42006-11-13 16:09:01 -08004594
Eric Paris50c205f2012-04-04 15:01:43 -04004595 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004596 ad.u.net = &net;
4597 ad.u.net->dport = htons(snum);
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004598 ad.u.net->family = address->sa_family;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004599 err = avc_has_perm(&selinux_state,
4600 sksec->sid, sid, sksec->sclass, perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004601 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004602 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004603 }
4604
Richard Hainesd4529302018-02-13 20:57:18 +00004605 return 0;
4606}
Paul Moore014ab192008-10-10 10:16:33 -04004607
Richard Hainesd4529302018-02-13 20:57:18 +00004608/* Supports connect(2), see comments in selinux_socket_connect_helper() */
4609static int selinux_socket_connect(struct socket *sock,
4610 struct sockaddr *address, int addrlen)
4611{
4612 int err;
4613 struct sock *sk = sock->sk;
4614
4615 err = selinux_socket_connect_helper(sock, address, addrlen);
4616 if (err)
4617 return err;
4618
4619 return selinux_netlbl_socket_connect(sk, address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004620}
4621
4622static int selinux_socket_listen(struct socket *sock, int backlog)
4623{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004624 return sock_has_perm(sock->sk, SOCKET__LISTEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004625}
4626
4627static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
4628{
4629 int err;
4630 struct inode_security_struct *isec;
4631 struct inode_security_struct *newisec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004632 u16 sclass;
4633 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004634
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004635 err = sock_has_perm(sock->sk, SOCKET__ACCEPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004636 if (err)
4637 return err;
4638
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004639 isec = inode_security_novalidate(SOCK_INODE(sock));
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004640 spin_lock(&isec->lock);
4641 sclass = isec->sclass;
4642 sid = isec->sid;
4643 spin_unlock(&isec->lock);
4644
4645 newisec = inode_security_novalidate(SOCK_INODE(newsock));
4646 newisec->sclass = sclass;
4647 newisec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004648 newisec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004649
4650 return 0;
4651}
4652
4653static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
Eric Paris828dfe12008-04-17 13:17:49 -04004654 int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004655{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004656 return sock_has_perm(sock->sk, SOCKET__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004657}
4658
4659static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
4660 int size, int flags)
4661{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004662 return sock_has_perm(sock->sk, SOCKET__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004663}
4664
4665static int selinux_socket_getsockname(struct socket *sock)
4666{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004667 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004668}
4669
4670static int selinux_socket_getpeername(struct socket *sock)
4671{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004672 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004673}
4674
Eric Paris828dfe12008-04-17 13:17:49 -04004675static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004676{
Paul Mooref8687af2006-10-30 15:22:15 -08004677 int err;
4678
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004679 err = sock_has_perm(sock->sk, SOCKET__SETOPT);
Paul Mooref8687af2006-10-30 15:22:15 -08004680 if (err)
4681 return err;
4682
4683 return selinux_netlbl_socket_setsockopt(sock, level, optname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004684}
4685
4686static int selinux_socket_getsockopt(struct socket *sock, int level,
4687 int optname)
4688{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004689 return sock_has_perm(sock->sk, SOCKET__GETOPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004690}
4691
4692static int selinux_socket_shutdown(struct socket *sock, int how)
4693{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004694 return sock_has_perm(sock->sk, SOCKET__SHUTDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004695}
4696
David S. Miller3610cda2011-01-05 15:38:53 -08004697static int selinux_socket_unix_stream_connect(struct sock *sock,
4698 struct sock *other,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004699 struct sock *newsk)
4700{
David S. Miller3610cda2011-01-05 15:38:53 -08004701 struct sk_security_struct *sksec_sock = sock->sk_security;
4702 struct sk_security_struct *sksec_other = other->sk_security;
Paul Moore4d1e2452010-04-22 14:46:18 -04004703 struct sk_security_struct *sksec_new = newsk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004704 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004705 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004706 int err;
4707
Eric Paris50c205f2012-04-04 15:01:43 -04004708 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004709 ad.u.net = &net;
4710 ad.u.net->sk = other;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004711
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004712 err = avc_has_perm(&selinux_state,
4713 sksec_sock->sid, sksec_other->sid,
Paul Moore4d1e2452010-04-22 14:46:18 -04004714 sksec_other->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004715 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
4716 if (err)
4717 return err;
4718
Linus Torvalds1da177e2005-04-16 15:20:36 -07004719 /* server child socket */
Paul Moore4d1e2452010-04-22 14:46:18 -04004720 sksec_new->peer_sid = sksec_sock->sid;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004721 err = security_sid_mls_copy(&selinux_state, sksec_other->sid,
4722 sksec_sock->sid, &sksec_new->sid);
Paul Moore4d1e2452010-04-22 14:46:18 -04004723 if (err)
4724 return err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004725
Paul Moore4d1e2452010-04-22 14:46:18 -04004726 /* connecting socket */
4727 sksec_sock->peer_sid = sksec_new->sid;
4728
4729 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004730}
4731
4732static int selinux_socket_unix_may_send(struct socket *sock,
4733 struct socket *other)
4734{
Paul Moore253bfae2010-04-22 14:46:19 -04004735 struct sk_security_struct *ssec = sock->sk->sk_security;
4736 struct sk_security_struct *osec = other->sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004737 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004738 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004739
Eric Paris50c205f2012-04-04 15:01:43 -04004740 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004741 ad.u.net = &net;
4742 ad.u.net->sk = other->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004743
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004744 return avc_has_perm(&selinux_state,
4745 ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
Paul Moore253bfae2010-04-22 14:46:19 -04004746 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004747}
4748
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004749static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
4750 char *addrp, u16 family, u32 peer_sid,
Thomas Liu2bf49692009-07-14 12:14:09 -04004751 struct common_audit_data *ad)
Paul Mooreeffad8d2008-01-29 08:49:27 -05004752{
4753 int err;
4754 u32 if_sid;
4755 u32 node_sid;
4756
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004757 err = sel_netif_sid(ns, ifindex, &if_sid);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004758 if (err)
4759 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004760 err = avc_has_perm(&selinux_state,
4761 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004762 SECCLASS_NETIF, NETIF__INGRESS, ad);
4763 if (err)
4764 return err;
4765
4766 err = sel_netnode_sid(addrp, family, &node_sid);
4767 if (err)
4768 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004769 return avc_has_perm(&selinux_state,
4770 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004771 SECCLASS_NODE, NODE__RECVFROM, ad);
4772}
4773
Paul Moore220deb92008-01-29 08:38:23 -05004774static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
Paul Moored8395c82008-10-10 10:16:30 -04004775 u16 family)
Paul Moore220deb92008-01-29 08:38:23 -05004776{
Paul Moore277d3422008-12-31 12:54:11 -05004777 int err = 0;
Paul Moore220deb92008-01-29 08:38:23 -05004778 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004779 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004780 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004781 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04004782 char *addrp;
4783
Eric Paris50c205f2012-04-04 15:01:43 -04004784 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004785 ad.u.net = &net;
4786 ad.u.net->netif = skb->skb_iif;
4787 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04004788 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
4789 if (err)
4790 return err;
Paul Moore220deb92008-01-29 08:38:23 -05004791
Paul Moore58bfbb52009-03-27 17:10:41 -04004792 if (selinux_secmark_enabled()) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004793 err = avc_has_perm(&selinux_state,
4794 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Moored8395c82008-10-10 10:16:30 -04004795 PACKET__RECV, &ad);
Paul Moore58bfbb52009-03-27 17:10:41 -04004796 if (err)
4797 return err;
4798 }
Paul Moore220deb92008-01-29 08:38:23 -05004799
Steffen Klassertb9679a72011-02-23 12:55:21 +01004800 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4801 if (err)
4802 return err;
4803 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004804
James Morris4e5ab4c2006-06-09 00:33:33 -07004805 return err;
4806}
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004807
James Morris4e5ab4c2006-06-09 00:33:33 -07004808static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4809{
Paul Moore220deb92008-01-29 08:38:23 -05004810 int err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004811 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004812 u16 family = sk->sk_family;
4813 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004814 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004815 struct lsm_network_audit net = {0,};
Paul Moore220deb92008-01-29 08:38:23 -05004816 char *addrp;
Paul Moored8395c82008-10-10 10:16:30 -04004817 u8 secmark_active;
4818 u8 peerlbl_active;
James Morris4e5ab4c2006-06-09 00:33:33 -07004819
James Morris4e5ab4c2006-06-09 00:33:33 -07004820 if (family != PF_INET && family != PF_INET6)
Paul Moore220deb92008-01-29 08:38:23 -05004821 return 0;
James Morris4e5ab4c2006-06-09 00:33:33 -07004822
4823 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
Al Viro87fcd702006-12-04 22:00:55 +00004824 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
James Morris4e5ab4c2006-06-09 00:33:33 -07004825 family = PF_INET;
4826
Paul Moored8395c82008-10-10 10:16:30 -04004827 /* If any sort of compatibility mode is enabled then handoff processing
4828 * to the selinux_sock_rcv_skb_compat() function to deal with the
4829 * special handling. We do this in an attempt to keep this function
4830 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004831 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04004832 return selinux_sock_rcv_skb_compat(sk, skb, family);
4833
4834 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04004835 peerlbl_active = selinux_peerlbl_enabled();
Paul Moored8395c82008-10-10 10:16:30 -04004836 if (!secmark_active && !peerlbl_active)
4837 return 0;
4838
Eric Paris50c205f2012-04-04 15:01:43 -04004839 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004840 ad.u.net = &net;
4841 ad.u.net->netif = skb->skb_iif;
4842 ad.u.net->family = family;
Paul Moore224dfbd2008-01-29 08:38:13 -05004843 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
James Morris4e5ab4c2006-06-09 00:33:33 -07004844 if (err)
Paul Moore220deb92008-01-29 08:38:23 -05004845 return err;
James Morris4e5ab4c2006-06-09 00:33:33 -07004846
Paul Moored8395c82008-10-10 10:16:30 -04004847 if (peerlbl_active) {
Paul Moored621d352008-01-29 08:43:36 -05004848 u32 peer_sid;
4849
4850 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
4851 if (err)
4852 return err;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004853 err = selinux_inet_sys_rcv_skb(sock_net(sk), skb->skb_iif,
4854 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04004855 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004856 selinux_netlbl_err(skb, family, err, 0);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004857 return err;
Paul Mooredfaebe92008-10-10 10:16:31 -04004858 }
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004859 err = avc_has_perm(&selinux_state,
4860 sk_sid, peer_sid, SECCLASS_PEER,
Paul Moored621d352008-01-29 08:43:36 -05004861 PEER__RECV, &ad);
Chad Hanson46d01d62013-12-23 17:45:01 -05004862 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004863 selinux_netlbl_err(skb, family, err, 0);
Chad Hanson46d01d62013-12-23 17:45:01 -05004864 return err;
4865 }
Paul Moored621d352008-01-29 08:43:36 -05004866 }
4867
Paul Moored8395c82008-10-10 10:16:30 -04004868 if (secmark_active) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004869 err = avc_has_perm(&selinux_state,
4870 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004871 PACKET__RECV, &ad);
4872 if (err)
4873 return err;
4874 }
4875
Paul Moored621d352008-01-29 08:43:36 -05004876 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004877}
4878
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004879static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
4880 int __user *optlen, unsigned len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004881{
4882 int err = 0;
4883 char *scontext;
4884 u32 scontext_len;
Paul Moore253bfae2010-04-22 14:46:19 -04004885 struct sk_security_struct *sksec = sock->sk->sk_security;
Paul Moore3de4bab2006-11-17 17:38:54 -05004886 u32 peer_sid = SECSID_NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004887
Paul Moore253bfae2010-04-22 14:46:19 -04004888 if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00004889 sksec->sclass == SECCLASS_TCP_SOCKET ||
4890 sksec->sclass == SECCLASS_SCTP_SOCKET)
Eric Parisdd3e7832010-04-07 15:08:46 -04004891 peer_sid = sksec->peer_sid;
Paul Moore253bfae2010-04-22 14:46:19 -04004892 if (peer_sid == SECSID_NULL)
4893 return -ENOPROTOOPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004894
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004895 err = security_sid_to_context(&selinux_state, peer_sid, &scontext,
4896 &scontext_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004897 if (err)
Paul Moore253bfae2010-04-22 14:46:19 -04004898 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004899
4900 if (scontext_len > len) {
4901 err = -ERANGE;
4902 goto out_len;
4903 }
4904
4905 if (copy_to_user(optval, scontext, scontext_len))
4906 err = -EFAULT;
4907
4908out_len:
4909 if (put_user(scontext_len, optlen))
4910 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004911 kfree(scontext);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004912 return err;
4913}
4914
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004915static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004916{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004917 u32 peer_secid = SECSID_NULL;
Paul Moore75e22912008-01-29 08:38:04 -05004918 u16 family;
Paul Moore899134f2016-03-28 15:19:10 -04004919 struct inode_security_struct *isec;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07004920
Paul Mooreaa862902008-10-10 10:16:29 -04004921 if (skb && skb->protocol == htons(ETH_P_IP))
4922 family = PF_INET;
4923 else if (skb && skb->protocol == htons(ETH_P_IPV6))
4924 family = PF_INET6;
4925 else if (sock)
Paul Moore75e22912008-01-29 08:38:04 -05004926 family = sock->sk->sk_family;
Paul Moore75e22912008-01-29 08:38:04 -05004927 else
4928 goto out;
4929
Paul Moore899134f2016-03-28 15:19:10 -04004930 if (sock && family == PF_UNIX) {
4931 isec = inode_security_novalidate(SOCK_INODE(sock));
4932 peer_secid = isec->sid;
4933 } else if (skb)
Paul Moore220deb92008-01-29 08:38:23 -05004934 selinux_skb_peerlbl_sid(skb, family, &peer_secid);
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004935
Paul Moore75e22912008-01-29 08:38:04 -05004936out:
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004937 *secid = peer_secid;
Paul Moore75e22912008-01-29 08:38:04 -05004938 if (peer_secid == SECSID_NULL)
4939 return -EINVAL;
4940 return 0;
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004941}
4942
Al Viro7d877f32005-10-21 03:20:43 -04004943static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004944{
Paul Moore84914b72010-04-22 14:46:18 -04004945 struct sk_security_struct *sksec;
4946
4947 sksec = kzalloc(sizeof(*sksec), priority);
4948 if (!sksec)
4949 return -ENOMEM;
4950
4951 sksec->peer_sid = SECINITSID_UNLABELED;
4952 sksec->sid = SECINITSID_UNLABELED;
Stephen Smalley5dee25d2015-07-10 17:19:57 -04004953 sksec->sclass = SECCLASS_SOCKET;
Paul Moore84914b72010-04-22 14:46:18 -04004954 selinux_netlbl_sk_security_reset(sksec);
4955 sk->sk_security = sksec;
4956
4957 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004958}
4959
4960static void selinux_sk_free_security(struct sock *sk)
4961{
Paul Moore84914b72010-04-22 14:46:18 -04004962 struct sk_security_struct *sksec = sk->sk_security;
4963
4964 sk->sk_security = NULL;
4965 selinux_netlbl_sk_security_free(sksec);
4966 kfree(sksec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004967}
4968
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004969static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
4970{
Eric Parisdd3e7832010-04-07 15:08:46 -04004971 struct sk_security_struct *sksec = sk->sk_security;
4972 struct sk_security_struct *newsksec = newsk->sk_security;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004973
Eric Parisdd3e7832010-04-07 15:08:46 -04004974 newsksec->sid = sksec->sid;
4975 newsksec->peer_sid = sksec->peer_sid;
4976 newsksec->sclass = sksec->sclass;
Paul Moore99f59ed2006-08-29 17:53:48 -07004977
Eric Parisdd3e7832010-04-07 15:08:46 -04004978 selinux_netlbl_sk_security_reset(newsksec);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004979}
4980
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004981static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004982{
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004983 if (!sk)
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004984 *secid = SECINITSID_ANY_SOCKET;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004985 else {
4986 struct sk_security_struct *sksec = sk->sk_security;
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004987
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004988 *secid = sksec->sid;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004989 }
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004990}
4991
Eric Paris828dfe12008-04-17 13:17:49 -04004992static void selinux_sock_graft(struct sock *sk, struct socket *parent)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004993{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004994 struct inode_security_struct *isec =
4995 inode_security_novalidate(SOCK_INODE(parent));
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004996 struct sk_security_struct *sksec = sk->sk_security;
4997
Paul Moore2873ead2014-07-28 10:42:48 -04004998 if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
4999 sk->sk_family == PF_UNIX)
David Woodhouse2148ccc2006-09-29 15:50:25 -07005000 isec->sid = sksec->sid;
Paul Moore220deb92008-01-29 08:38:23 -05005001 sksec->sclass = isec->sclass;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005002}
5003
Richard Hainesd4529302018-02-13 20:57:18 +00005004/* Called whenever SCTP receives an INIT chunk. This happens when an incoming
5005 * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association
5006 * already present).
5007 */
5008static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
5009 struct sk_buff *skb)
5010{
5011 struct sk_security_struct *sksec = ep->base.sk->sk_security;
5012 struct common_audit_data ad;
5013 struct lsm_network_audit net = {0,};
5014 u8 peerlbl_active;
5015 u32 peer_sid = SECINITSID_UNLABELED;
5016 u32 conn_sid;
5017 int err = 0;
5018
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005019 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005020 return 0;
5021
5022 peerlbl_active = selinux_peerlbl_enabled();
5023
5024 if (peerlbl_active) {
5025 /* This will return peer_sid = SECSID_NULL if there are
5026 * no peer labels, see security_net_peersid_resolve().
5027 */
5028 err = selinux_skb_peerlbl_sid(skb, ep->base.sk->sk_family,
5029 &peer_sid);
5030 if (err)
5031 return err;
5032
5033 if (peer_sid == SECSID_NULL)
5034 peer_sid = SECINITSID_UNLABELED;
5035 }
5036
5037 if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) {
5038 sksec->sctp_assoc_state = SCTP_ASSOC_SET;
5039
5040 /* Here as first association on socket. As the peer SID
5041 * was allowed by peer recv (and the netif/node checks),
5042 * then it is approved by policy and used as the primary
5043 * peer SID for getpeercon(3).
5044 */
5045 sksec->peer_sid = peer_sid;
5046 } else if (sksec->peer_sid != peer_sid) {
5047 /* Other association peer SIDs are checked to enforce
5048 * consistency among the peer SIDs.
5049 */
5050 ad.type = LSM_AUDIT_DATA_NET;
5051 ad.u.net = &net;
5052 ad.u.net->sk = ep->base.sk;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005053 err = avc_has_perm(&selinux_state,
5054 sksec->peer_sid, peer_sid, sksec->sclass,
Richard Hainesd4529302018-02-13 20:57:18 +00005055 SCTP_SOCKET__ASSOCIATION, &ad);
5056 if (err)
5057 return err;
5058 }
5059
5060 /* Compute the MLS component for the connection and store
5061 * the information in ep. This will be used by SCTP TCP type
5062 * sockets and peeled off connections as they cause a new
5063 * socket to be generated. selinux_sctp_sk_clone() will then
5064 * plug this into the new socket.
5065 */
5066 err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid);
5067 if (err)
5068 return err;
5069
5070 ep->secid = conn_sid;
5071 ep->peer_secid = peer_sid;
5072
5073 /* Set any NetLabel labels including CIPSO/CALIPSO options. */
5074 return selinux_netlbl_sctp_assoc_request(ep, skb);
5075}
5076
5077/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
5078 * based on their @optname.
5079 */
5080static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5081 struct sockaddr *address,
5082 int addrlen)
5083{
5084 int len, err = 0, walk_size = 0;
5085 void *addr_buf;
5086 struct sockaddr *addr;
5087 struct socket *sock;
5088
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005089 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005090 return 0;
5091
5092 /* Process one or more addresses that may be IPv4 or IPv6 */
5093 sock = sk->sk_socket;
5094 addr_buf = address;
5095
5096 while (walk_size < addrlen) {
Ondrej Mosnacekc1383252018-11-13 16:16:08 +01005097 if (walk_size + sizeof(sa_family_t) > addrlen)
5098 return -EINVAL;
5099
Richard Hainesd4529302018-02-13 20:57:18 +00005100 addr = addr_buf;
5101 switch (addr->sa_family) {
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005102 case AF_UNSPEC:
Richard Hainesd4529302018-02-13 20:57:18 +00005103 case AF_INET:
5104 len = sizeof(struct sockaddr_in);
5105 break;
5106 case AF_INET6:
5107 len = sizeof(struct sockaddr_in6);
5108 break;
5109 default:
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005110 return -EINVAL;
Richard Hainesd4529302018-02-13 20:57:18 +00005111 }
5112
5113 err = -EINVAL;
5114 switch (optname) {
5115 /* Bind checks */
5116 case SCTP_PRIMARY_ADDR:
5117 case SCTP_SET_PEER_PRIMARY_ADDR:
5118 case SCTP_SOCKOPT_BINDX_ADD:
5119 err = selinux_socket_bind(sock, addr, len);
5120 break;
5121 /* Connect checks */
5122 case SCTP_SOCKOPT_CONNECTX:
5123 case SCTP_PARAM_SET_PRIMARY:
5124 case SCTP_PARAM_ADD_IP:
5125 case SCTP_SENDMSG_CONNECT:
5126 err = selinux_socket_connect_helper(sock, addr, len);
5127 if (err)
5128 return err;
5129
5130 /* As selinux_sctp_bind_connect() is called by the
5131 * SCTP protocol layer, the socket is already locked,
5132 * therefore selinux_netlbl_socket_connect_locked() is
5133 * is called here. The situations handled are:
5134 * sctp_connectx(3), sctp_sendmsg(3), sendmsg(2),
5135 * whenever a new IP address is added or when a new
5136 * primary address is selected.
5137 * Note that an SCTP connect(2) call happens before
5138 * the SCTP protocol layer and is handled via
5139 * selinux_socket_connect().
5140 */
5141 err = selinux_netlbl_socket_connect_locked(sk, addr);
5142 break;
5143 }
5144
5145 if (err)
5146 return err;
5147
5148 addr_buf += len;
5149 walk_size += len;
5150 }
5151
5152 return 0;
5153}
5154
5155/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */
5156static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
5157 struct sock *newsk)
5158{
5159 struct sk_security_struct *sksec = sk->sk_security;
5160 struct sk_security_struct *newsksec = newsk->sk_security;
5161
5162 /* If policy does not support SECCLASS_SCTP_SOCKET then call
5163 * the non-sctp clone version.
5164 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005165 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005166 return selinux_sk_clone_security(sk, newsk);
5167
5168 newsksec->sid = ep->secid;
5169 newsksec->peer_sid = ep->peer_secid;
5170 newsksec->sclass = sksec->sclass;
5171 selinux_netlbl_sctp_sk_clone(sk, newsk);
5172}
5173
Adrian Bunk9a673e52006-08-15 00:03:53 -07005174static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
5175 struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005176{
5177 struct sk_security_struct *sksec = sk->sk_security;
5178 int err;
Paul Moore0b1f24e2013-12-03 11:39:13 -05005179 u16 family = req->rsk_ops->family;
Paul Moore446b8022013-12-04 16:10:51 -05005180 u32 connsid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005181 u32 peersid;
5182
Paul Mooreaa862902008-10-10 10:16:29 -04005183 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
Paul Moore220deb92008-01-29 08:38:23 -05005184 if (err)
5185 return err;
Paul Moore446b8022013-12-04 16:10:51 -05005186 err = selinux_conn_sid(sksec->sid, peersid, &connsid);
5187 if (err)
5188 return err;
5189 req->secid = connsid;
5190 req->peer_secid = peersid;
Venkat Yekkiralaa51c64f2006-07-27 22:01:34 -07005191
Paul Moore389fb8002009-03-27 17:10:34 -04005192 return selinux_netlbl_inet_conn_request(req, family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005193}
5194
Adrian Bunk9a673e52006-08-15 00:03:53 -07005195static void selinux_inet_csk_clone(struct sock *newsk,
5196 const struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005197{
5198 struct sk_security_struct *newsksec = newsk->sk_security;
5199
5200 newsksec->sid = req->secid;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005201 newsksec->peer_sid = req->peer_secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005202 /* NOTE: Ideally, we should also get the isec->sid for the
5203 new socket in sync, but we don't have the isec available yet.
5204 So we will wait until sock_graft to do it, by which
5205 time it will have been created and available. */
Paul Moore99f59ed2006-08-29 17:53:48 -07005206
Paul Moore9f2ad662006-11-17 17:38:53 -05005207 /* We don't need to take any sort of lock here as we are the only
5208 * thread with access to newsksec */
Paul Moore389fb8002009-03-27 17:10:34 -04005209 selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005210}
5211
Paul Moore014ab192008-10-10 10:16:33 -04005212static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005213{
Paul Mooreaa862902008-10-10 10:16:29 -04005214 u16 family = sk->sk_family;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005215 struct sk_security_struct *sksec = sk->sk_security;
5216
Paul Mooreaa862902008-10-10 10:16:29 -04005217 /* handle mapped IPv4 packets arriving via IPv6 sockets */
5218 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
5219 family = PF_INET;
5220
5221 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005222}
5223
Eric Paris2606fd12010-10-13 16:24:41 -04005224static int selinux_secmark_relabel_packet(u32 sid)
5225{
5226 const struct task_security_struct *__tsec;
5227 u32 tsid;
5228
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07005229 __tsec = selinux_cred(current_cred());
Eric Paris2606fd12010-10-13 16:24:41 -04005230 tsid = __tsec->sid;
5231
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005232 return avc_has_perm(&selinux_state,
5233 tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
5234 NULL);
Eric Paris2606fd12010-10-13 16:24:41 -04005235}
5236
5237static void selinux_secmark_refcount_inc(void)
5238{
5239 atomic_inc(&selinux_secmark_refcount);
5240}
5241
5242static void selinux_secmark_refcount_dec(void)
5243{
5244 atomic_dec(&selinux_secmark_refcount);
5245}
5246
Adrian Bunk9a673e52006-08-15 00:03:53 -07005247static void selinux_req_classify_flow(const struct request_sock *req,
5248 struct flowi *fl)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005249{
David S. Miller1d28f422011-03-12 00:29:39 -05005250 fl->flowi_secid = req->secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005251}
5252
Paul Moore5dbbaf22013-01-14 07:12:19 +00005253static int selinux_tun_dev_alloc_security(void **security)
5254{
5255 struct tun_security_struct *tunsec;
5256
5257 tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
5258 if (!tunsec)
5259 return -ENOMEM;
5260 tunsec->sid = current_sid();
5261
5262 *security = tunsec;
5263 return 0;
5264}
5265
5266static void selinux_tun_dev_free_security(void *security)
5267{
5268 kfree(security);
5269}
5270
Paul Mooreed6d76e2009-08-28 18:12:49 -04005271static int selinux_tun_dev_create(void)
5272{
5273 u32 sid = current_sid();
5274
5275 /* we aren't taking into account the "sockcreate" SID since the socket
5276 * that is being created here is not a socket in the traditional sense,
5277 * instead it is a private sock, accessible only to the kernel, and
5278 * representing a wide range of network traffic spanning multiple
5279 * connections unlike traditional sockets - check the TUN driver to
5280 * get a better understanding of why this socket is special */
5281
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005282 return avc_has_perm(&selinux_state,
5283 sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005284 NULL);
5285}
5286
Paul Moore5dbbaf22013-01-14 07:12:19 +00005287static int selinux_tun_dev_attach_queue(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005288{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005289 struct tun_security_struct *tunsec = security;
5290
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005291 return avc_has_perm(&selinux_state,
5292 current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Moore5dbbaf22013-01-14 07:12:19 +00005293 TUN_SOCKET__ATTACH_QUEUE, NULL);
5294}
5295
5296static int selinux_tun_dev_attach(struct sock *sk, void *security)
5297{
5298 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005299 struct sk_security_struct *sksec = sk->sk_security;
5300
5301 /* we don't currently perform any NetLabel based labeling here and it
5302 * isn't clear that we would want to do so anyway; while we could apply
5303 * labeling without the support of the TUN user the resulting labeled
5304 * traffic from the other end of the connection would almost certainly
5305 * cause confusion to the TUN user that had no idea network labeling
5306 * protocols were being used */
5307
Paul Moore5dbbaf22013-01-14 07:12:19 +00005308 sksec->sid = tunsec->sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005309 sksec->sclass = SECCLASS_TUN_SOCKET;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005310
5311 return 0;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005312}
5313
Paul Moore5dbbaf22013-01-14 07:12:19 +00005314static int selinux_tun_dev_open(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005315{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005316 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005317 u32 sid = current_sid();
5318 int err;
5319
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005320 err = avc_has_perm(&selinux_state,
5321 sid, tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005322 TUN_SOCKET__RELABELFROM, NULL);
5323 if (err)
5324 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005325 err = avc_has_perm(&selinux_state,
5326 sid, sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005327 TUN_SOCKET__RELABELTO, NULL);
5328 if (err)
5329 return err;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005330 tunsec->sid = sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005331
5332 return 0;
5333}
5334
Linus Torvalds1da177e2005-04-16 15:20:36 -07005335static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
5336{
5337 int err = 0;
5338 u32 perm;
5339 struct nlmsghdr *nlh;
Paul Moore253bfae2010-04-22 14:46:19 -04005340 struct sk_security_struct *sksec = sk->sk_security;
Eric Paris828dfe12008-04-17 13:17:49 -04005341
Hong zhi guo77954982013-03-27 06:49:35 +00005342 if (skb->len < NLMSG_HDRLEN) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005343 err = -EINVAL;
5344 goto out;
5345 }
Arnaldo Carvalho de Melob529ccf2007-04-25 19:08:35 -07005346 nlh = nlmsg_hdr(skb);
Eric Paris828dfe12008-04-17 13:17:49 -04005347
Paul Moore253bfae2010-04-22 14:46:19 -04005348 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005349 if (err) {
5350 if (err == -EINVAL) {
Vladis Dronov76319942015-12-24 11:09:41 -05005351 pr_warn_ratelimited("SELinux: unrecognized netlink"
5352 " message: protocol=%hu nlmsg_type=%hu sclass=%s"
5353 " pig=%d comm=%s\n",
Marek Milkoviccded3ff2015-06-04 16:22:16 -04005354 sk->sk_protocol, nlh->nlmsg_type,
Vladis Dronov76319942015-12-24 11:09:41 -05005355 secclass_map[sksec->sclass - 1].name,
5356 task_pid_nr(current), current->comm);
Paul Mooree5a5ca92018-03-01 17:38:30 -05005357 if (!enforcing_enabled(&selinux_state) ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005358 security_get_allow_unknown(&selinux_state))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005359 err = 0;
5360 }
5361
5362 /* Ignore */
5363 if (err == -ENOENT)
5364 err = 0;
5365 goto out;
5366 }
5367
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005368 err = sock_has_perm(sk, perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005369out:
5370 return err;
5371}
5372
5373#ifdef CONFIG_NETFILTER
5374
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005375static unsigned int selinux_ip_forward(struct sk_buff *skb,
5376 const struct net_device *indev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005377 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005378{
Paul Mooredfaebe92008-10-10 10:16:31 -04005379 int err;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005380 char *addrp;
5381 u32 peer_sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04005382 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005383 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005384 u8 secmark_active;
Paul Moore948bf852008-10-10 10:16:32 -04005385 u8 netlbl_active;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005386 u8 peerlbl_active;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005387
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005388 if (!selinux_policycap_netpeer())
Paul Mooreeffad8d2008-01-29 08:49:27 -05005389 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005390
Paul Mooreeffad8d2008-01-29 08:49:27 -05005391 secmark_active = selinux_secmark_enabled();
Paul Moore948bf852008-10-10 10:16:32 -04005392 netlbl_active = netlbl_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005393 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005394 if (!secmark_active && !peerlbl_active)
5395 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005396
Paul Moored8395c82008-10-10 10:16:30 -04005397 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
5398 return NF_DROP;
5399
Eric Paris50c205f2012-04-04 15:01:43 -04005400 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005401 ad.u.net = &net;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005402 ad.u.net->netif = indev->ifindex;
Eric Paris48c62af2012-04-02 13:15:44 -04005403 ad.u.net->family = family;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005404 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
5405 return NF_DROP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005406
Paul Mooredfaebe92008-10-10 10:16:31 -04005407 if (peerlbl_active) {
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005408 err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
5409 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04005410 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04005411 selinux_netlbl_err(skb, family, err, 1);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005412 return NF_DROP;
Paul Mooredfaebe92008-10-10 10:16:31 -04005413 }
5414 }
Paul Mooreeffad8d2008-01-29 08:49:27 -05005415
5416 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005417 if (avc_has_perm(&selinux_state,
5418 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005419 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
5420 return NF_DROP;
5421
Paul Moore948bf852008-10-10 10:16:32 -04005422 if (netlbl_active)
5423 /* we do this in the FORWARD path and not the POST_ROUTING
5424 * path because we want to make sure we apply the necessary
5425 * labeling before IPsec is applied so we can leverage AH
5426 * protection */
5427 if (selinux_netlbl_skbuff_setsid(skb, family, peer_sid) != 0)
5428 return NF_DROP;
5429
Paul Mooreeffad8d2008-01-29 08:49:27 -05005430 return NF_ACCEPT;
5431}
5432
Eric W. Biederman06198b32015-09-18 14:33:06 -05005433static unsigned int selinux_ipv4_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005434 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005435 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005436{
David S. Miller238e54c2015-04-03 20:32:56 -04005437 return selinux_ip_forward(skb, state->in, PF_INET);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005438}
5439
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005440#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005441static unsigned int selinux_ipv6_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005442 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005443 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005444{
David S. Miller238e54c2015-04-03 20:32:56 -04005445 return selinux_ip_forward(skb, state->in, PF_INET6);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005446}
5447#endif /* IPV6 */
5448
Paul Moore948bf852008-10-10 10:16:32 -04005449static unsigned int selinux_ip_output(struct sk_buff *skb,
5450 u16 family)
5451{
Paul Moore47180062013-12-04 16:10:45 -05005452 struct sock *sk;
Paul Moore948bf852008-10-10 10:16:32 -04005453 u32 sid;
5454
5455 if (!netlbl_enabled())
5456 return NF_ACCEPT;
5457
5458 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
5459 * because we want to make sure we apply the necessary labeling
5460 * before IPsec is applied so we can leverage AH protection */
Paul Moore47180062013-12-04 16:10:45 -05005461 sk = skb->sk;
5462 if (sk) {
5463 struct sk_security_struct *sksec;
5464
Eric Dumazete446f9d2015-10-08 05:01:55 -07005465 if (sk_listener(sk))
Paul Moore47180062013-12-04 16:10:45 -05005466 /* if the socket is the listening state then this
5467 * packet is a SYN-ACK packet which means it needs to
5468 * be labeled based on the connection/request_sock and
5469 * not the parent socket. unfortunately, we can't
5470 * lookup the request_sock yet as it isn't queued on
5471 * the parent socket until after the SYN-ACK is sent.
5472 * the "solution" is to simply pass the packet as-is
5473 * as any IP option based labeling should be copied
5474 * from the initial connection request (in the IP
5475 * layer). it is far from ideal, but until we get a
5476 * security label in the packet itself this is the
5477 * best we can do. */
5478 return NF_ACCEPT;
5479
5480 /* standard practice, label using the parent socket */
5481 sksec = sk->sk_security;
Paul Moore948bf852008-10-10 10:16:32 -04005482 sid = sksec->sid;
5483 } else
5484 sid = SECINITSID_KERNEL;
5485 if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
5486 return NF_DROP;
5487
5488 return NF_ACCEPT;
5489}
5490
Eric W. Biederman06198b32015-09-18 14:33:06 -05005491static unsigned int selinux_ipv4_output(void *priv,
Paul Moore948bf852008-10-10 10:16:32 -04005492 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005493 const struct nf_hook_state *state)
Paul Moore948bf852008-10-10 10:16:32 -04005494{
5495 return selinux_ip_output(skb, PF_INET);
5496}
5497
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005498#if IS_ENABLED(CONFIG_IPV6)
Huw Davies2917f572016-06-27 15:06:15 -04005499static unsigned int selinux_ipv6_output(void *priv,
5500 struct sk_buff *skb,
5501 const struct nf_hook_state *state)
5502{
5503 return selinux_ip_output(skb, PF_INET6);
5504}
5505#endif /* IPV6 */
5506
Paul Mooreeffad8d2008-01-29 08:49:27 -05005507static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
5508 int ifindex,
Paul Moored8395c82008-10-10 10:16:30 -04005509 u16 family)
James Morris4e5ab4c2006-06-09 00:33:33 -07005510{
Eric Dumazet54abc682015-11-08 10:54:07 -08005511 struct sock *sk = skb_to_full_sk(skb);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005512 struct sk_security_struct *sksec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005513 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005514 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04005515 char *addrp;
5516 u8 proto;
James Morris4e5ab4c2006-06-09 00:33:33 -07005517
Paul Mooreeffad8d2008-01-29 08:49:27 -05005518 if (sk == NULL)
5519 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005520 sksec = sk->sk_security;
James Morris4e5ab4c2006-06-09 00:33:33 -07005521
Eric Paris50c205f2012-04-04 15:01:43 -04005522 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005523 ad.u.net = &net;
5524 ad.u.net->netif = ifindex;
5525 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005526 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
5527 return NF_DROP;
5528
Paul Moore58bfbb52009-03-27 17:10:41 -04005529 if (selinux_secmark_enabled())
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005530 if (avc_has_perm(&selinux_state,
5531 sksec->sid, skb->secmark,
Paul Moored8395c82008-10-10 10:16:30 -04005532 SECCLASS_PACKET, PACKET__SEND, &ad))
Eric Paris2fe66ec2010-11-23 06:28:08 +00005533 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005534
Steffen Klassertb9679a72011-02-23 12:55:21 +01005535 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
5536 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005537
Paul Mooreeffad8d2008-01-29 08:49:27 -05005538 return NF_ACCEPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005539}
5540
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005541static unsigned int selinux_ip_postroute(struct sk_buff *skb,
5542 const struct net_device *outdev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005543 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005544{
Paul Mooreeffad8d2008-01-29 08:49:27 -05005545 u32 secmark_perm;
5546 u32 peer_sid;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005547 int ifindex = outdev->ifindex;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005548 struct sock *sk;
Thomas Liu2bf49692009-07-14 12:14:09 -04005549 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005550 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005551 char *addrp;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005552 u8 secmark_active;
5553 u8 peerlbl_active;
5554
Paul Mooreeffad8d2008-01-29 08:49:27 -05005555 /* If any sort of compatibility mode is enabled then handoff processing
5556 * to the selinux_ip_postroute_compat() function to deal with the
5557 * special handling. We do this in an attempt to keep this function
5558 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005559 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04005560 return selinux_ip_postroute_compat(skb, ifindex, family);
Paul Moorec0828e52013-12-10 14:58:01 -05005561
Paul Mooreeffad8d2008-01-29 08:49:27 -05005562 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005563 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005564 if (!secmark_active && !peerlbl_active)
5565 return NF_ACCEPT;
5566
Eric Dumazet54abc682015-11-08 10:54:07 -08005567 sk = skb_to_full_sk(skb);
Paul Moorec0828e52013-12-10 14:58:01 -05005568
Paul Mooreeffad8d2008-01-29 08:49:27 -05005569#ifdef CONFIG_XFRM
5570 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
5571 * packet transformation so allow the packet to pass without any checks
5572 * since we'll have another chance to perform access control checks
5573 * when the packet is on it's final way out.
5574 * NOTE: there appear to be some IPv6 multicast cases where skb->dst
Paul Moorec0828e52013-12-10 14:58:01 -05005575 * is NULL, in this case go ahead and apply access control.
5576 * NOTE: if this is a local socket (skb->sk != NULL) that is in the
5577 * TCP listening state we cannot wait until the XFRM processing
5578 * is done as we will miss out on the SA label if we do;
5579 * unfortunately, this means more work, but it is only once per
5580 * connection. */
5581 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
Eric Dumazete446f9d2015-10-08 05:01:55 -07005582 !(sk && sk_listener(sk)))
Paul Mooreeffad8d2008-01-29 08:49:27 -05005583 return NF_ACCEPT;
5584#endif
Paul Mooreeffad8d2008-01-29 08:49:27 -05005585
Paul Moored8395c82008-10-10 10:16:30 -04005586 if (sk == NULL) {
Paul Moore446b8022013-12-04 16:10:51 -05005587 /* Without an associated socket the packet is either coming
5588 * from the kernel or it is being forwarded; check the packet
5589 * to determine which and if the packet is being forwarded
5590 * query the packet directly to determine the security label. */
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005591 if (skb->skb_iif) {
5592 secmark_perm = PACKET__FORWARD_OUT;
Paul Moored8395c82008-10-10 10:16:30 -04005593 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005594 return NF_DROP;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005595 } else {
5596 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005597 peer_sid = SECINITSID_KERNEL;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005598 }
Eric Dumazete446f9d2015-10-08 05:01:55 -07005599 } else if (sk_listener(sk)) {
Paul Moore446b8022013-12-04 16:10:51 -05005600 /* Locally generated packet but the associated socket is in the
5601 * listening state which means this is a SYN-ACK packet. In
5602 * this particular case the correct security label is assigned
5603 * to the connection/request_sock but unfortunately we can't
5604 * query the request_sock as it isn't queued on the parent
5605 * socket until after the SYN-ACK packet is sent; the only
5606 * viable choice is to regenerate the label like we do in
5607 * selinux_inet_conn_request(). See also selinux_ip_output()
5608 * for similar problems. */
5609 u32 skb_sid;
Eric Dumazete446f9d2015-10-08 05:01:55 -07005610 struct sk_security_struct *sksec;
5611
Eric Dumazete446f9d2015-10-08 05:01:55 -07005612 sksec = sk->sk_security;
Paul Moore446b8022013-12-04 16:10:51 -05005613 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
5614 return NF_DROP;
Paul Moorec0828e52013-12-10 14:58:01 -05005615 /* At this point, if the returned skb peerlbl is SECSID_NULL
5616 * and the packet has been through at least one XFRM
5617 * transformation then we must be dealing with the "final"
5618 * form of labeled IPsec packet; since we've already applied
5619 * all of our access controls on this packet we can safely
5620 * pass the packet. */
5621 if (skb_sid == SECSID_NULL) {
5622 switch (family) {
5623 case PF_INET:
5624 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
5625 return NF_ACCEPT;
5626 break;
5627 case PF_INET6:
5628 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
5629 return NF_ACCEPT;
Paul Moorea7a91a12014-09-03 10:51:59 -04005630 break;
Paul Moorec0828e52013-12-10 14:58:01 -05005631 default:
5632 return NF_DROP_ERR(-ECONNREFUSED);
5633 }
5634 }
Paul Moore446b8022013-12-04 16:10:51 -05005635 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
5636 return NF_DROP;
5637 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005638 } else {
Paul Moore446b8022013-12-04 16:10:51 -05005639 /* Locally generated packet, fetch the security label from the
5640 * associated socket. */
Paul Mooreeffad8d2008-01-29 08:49:27 -05005641 struct sk_security_struct *sksec = sk->sk_security;
5642 peer_sid = sksec->sid;
5643 secmark_perm = PACKET__SEND;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005644 }
5645
Eric Paris50c205f2012-04-04 15:01:43 -04005646 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005647 ad.u.net = &net;
5648 ad.u.net->netif = ifindex;
5649 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005650 if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
Eric Paris04f6d702010-11-23 06:28:02 +00005651 return NF_DROP;
Paul Moored8395c82008-10-10 10:16:30 -04005652
Paul Mooreeffad8d2008-01-29 08:49:27 -05005653 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005654 if (avc_has_perm(&selinux_state,
5655 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005656 SECCLASS_PACKET, secmark_perm, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005657 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005658
5659 if (peerlbl_active) {
5660 u32 if_sid;
5661 u32 node_sid;
5662
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005663 if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005664 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005665 if (avc_has_perm(&selinux_state,
5666 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005667 SECCLASS_NETIF, NETIF__EGRESS, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005668 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005669
5670 if (sel_netnode_sid(addrp, family, &node_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005671 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005672 if (avc_has_perm(&selinux_state,
5673 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005674 SECCLASS_NODE, NODE__SENDTO, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005675 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005676 }
5677
5678 return NF_ACCEPT;
5679}
5680
Eric W. Biederman06198b32015-09-18 14:33:06 -05005681static unsigned int selinux_ipv4_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005682 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005683 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005684{
David S. Miller238e54c2015-04-03 20:32:56 -04005685 return selinux_ip_postroute(skb, state->out, PF_INET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005686}
5687
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005688#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005689static unsigned int selinux_ipv6_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005690 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005691 const struct nf_hook_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005692{
David S. Miller238e54c2015-04-03 20:32:56 -04005693 return selinux_ip_postroute(skb, state->out, PF_INET6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005694}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005695#endif /* IPV6 */
5696
5697#endif /* CONFIG_NETFILTER */
5698
Linus Torvalds1da177e2005-04-16 15:20:36 -07005699static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
5700{
Stephen Smalley941fc5b2009-10-01 14:48:23 -04005701 return selinux_nlmsg_perm(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005702}
5703
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005704static int ipc_alloc_security(struct kern_ipc_perm *perm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005705 u16 sclass)
5706{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005707 struct ipc_security_struct *isec;
5708
James Morris89d155e2005-10-30 14:59:21 -08005709 isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005710 if (!isec)
5711 return -ENOMEM;
5712
Linus Torvalds1da177e2005-04-16 15:20:36 -07005713 isec->sclass = sclass;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005714 isec->sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005715 perm->security = isec;
5716
5717 return 0;
5718}
5719
5720static void ipc_free_security(struct kern_ipc_perm *perm)
5721{
5722 struct ipc_security_struct *isec = perm->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005723 perm->security = NULL;
5724 kfree(isec);
5725}
5726
5727static int msg_msg_alloc_security(struct msg_msg *msg)
5728{
5729 struct msg_security_struct *msec;
5730
James Morris89d155e2005-10-30 14:59:21 -08005731 msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005732 if (!msec)
5733 return -ENOMEM;
5734
Linus Torvalds1da177e2005-04-16 15:20:36 -07005735 msec->sid = SECINITSID_UNLABELED;
5736 msg->security = msec;
5737
5738 return 0;
5739}
5740
5741static void msg_msg_free_security(struct msg_msg *msg)
5742{
5743 struct msg_security_struct *msec = msg->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005744
5745 msg->security = NULL;
5746 kfree(msec);
5747}
5748
5749static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
Stephen Smalley6af963f2005-05-01 08:58:39 -07005750 u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005751{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005752 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005753 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005754 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005755
Linus Torvalds1da177e2005-04-16 15:20:36 -07005756 isec = ipc_perms->security;
5757
Eric Paris50c205f2012-04-04 15:01:43 -04005758 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005759 ad.u.ipc_id = ipc_perms->key;
5760
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005761 return avc_has_perm(&selinux_state,
5762 sid, isec->sid, isec->sclass, perms, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763}
5764
5765static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
5766{
5767 return msg_msg_alloc_security(msg);
5768}
5769
5770static void selinux_msg_msg_free_security(struct msg_msg *msg)
5771{
5772 msg_msg_free_security(msg);
5773}
5774
5775/* message queue security operations */
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005776static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005777{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005778 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005779 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005780 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005781 int rc;
5782
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005783 rc = ipc_alloc_security(msq, SECCLASS_MSGQ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005784 if (rc)
5785 return rc;
5786
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005787 isec = msq->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005788
Eric Paris50c205f2012-04-04 15:01:43 -04005789 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005790 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005791
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005792 rc = avc_has_perm(&selinux_state,
5793 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005794 MSGQ__CREATE, &ad);
5795 if (rc) {
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005796 ipc_free_security(msq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005797 return rc;
5798 }
5799 return 0;
5800}
5801
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005802static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005803{
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005804 ipc_free_security(msq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005805}
5806
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005807static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005808{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005809 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005810 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005811 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005812
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005813 isec = msq->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005814
Eric Paris50c205f2012-04-04 15:01:43 -04005815 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005816 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005817
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005818 return avc_has_perm(&selinux_state,
5819 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005820 MSGQ__ASSOCIATE, &ad);
5821}
5822
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005823static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005824{
5825 int err;
5826 int perms;
5827
Eric Paris828dfe12008-04-17 13:17:49 -04005828 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005829 case IPC_INFO:
5830 case MSG_INFO:
5831 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005832 return avc_has_perm(&selinux_state,
5833 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005834 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005835 case IPC_STAT:
5836 case MSG_STAT:
Davidlohr Bueso23c8cec2018-04-10 16:35:30 -07005837 case MSG_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005838 perms = MSGQ__GETATTR | MSGQ__ASSOCIATE;
5839 break;
5840 case IPC_SET:
5841 perms = MSGQ__SETATTR;
5842 break;
5843 case IPC_RMID:
5844 perms = MSGQ__DESTROY;
5845 break;
5846 default:
5847 return 0;
5848 }
5849
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005850 err = ipc_has_perm(msq, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005851 return err;
5852}
5853
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005854static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005855{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005856 struct ipc_security_struct *isec;
5857 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005858 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005859 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005860 int rc;
5861
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005862 isec = msq->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005863 msec = msg->security;
5864
5865 /*
5866 * First time through, need to assign label to the message
5867 */
5868 if (msec->sid == SECINITSID_UNLABELED) {
5869 /*
5870 * Compute new sid based on current process and
5871 * message queue this message will be stored in
5872 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005873 rc = security_transition_sid(&selinux_state, sid, isec->sid,
5874 SECCLASS_MSG, NULL, &msec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005875 if (rc)
5876 return rc;
5877 }
5878
Eric Paris50c205f2012-04-04 15:01:43 -04005879 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005880 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005881
5882 /* Can this process write to the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005883 rc = avc_has_perm(&selinux_state,
5884 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005885 MSGQ__WRITE, &ad);
5886 if (!rc)
5887 /* Can this process send the message */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005888 rc = avc_has_perm(&selinux_state,
5889 sid, msec->sid, SECCLASS_MSG,
David Howells275bb412008-11-14 10:39:19 +11005890 MSG__SEND, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005891 if (!rc)
5892 /* Can the message be put in the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005893 rc = avc_has_perm(&selinux_state,
5894 msec->sid, isec->sid, SECCLASS_MSGQ,
David Howells275bb412008-11-14 10:39:19 +11005895 MSGQ__ENQUEUE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005896
5897 return rc;
5898}
5899
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005900static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005901 struct task_struct *target,
5902 long type, int mode)
5903{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005904 struct ipc_security_struct *isec;
5905 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005906 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005907 u32 sid = task_sid(target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005908 int rc;
5909
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005910 isec = msq->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005911 msec = msg->security;
5912
Eric Paris50c205f2012-04-04 15:01:43 -04005913 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005914 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005915
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005916 rc = avc_has_perm(&selinux_state,
5917 sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005918 SECCLASS_MSGQ, MSGQ__READ, &ad);
5919 if (!rc)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005920 rc = avc_has_perm(&selinux_state,
5921 sid, msec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005922 SECCLASS_MSG, MSG__RECEIVE, &ad);
5923 return rc;
5924}
5925
5926/* Shared Memory security operations */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005927static int selinux_shm_alloc_security(struct kern_ipc_perm *shp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005928{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005929 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005930 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005931 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005932 int rc;
5933
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005934 rc = ipc_alloc_security(shp, SECCLASS_SHM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005935 if (rc)
5936 return rc;
5937
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005938 isec = shp->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005939
Eric Paris50c205f2012-04-04 15:01:43 -04005940 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005941 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005942
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005943 rc = avc_has_perm(&selinux_state,
5944 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005945 SHM__CREATE, &ad);
5946 if (rc) {
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005947 ipc_free_security(shp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005948 return rc;
5949 }
5950 return 0;
5951}
5952
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005953static void selinux_shm_free_security(struct kern_ipc_perm *shp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005954{
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005955 ipc_free_security(shp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005956}
5957
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005958static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005959{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005960 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005961 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005962 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005963
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005964 isec = shp->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005965
Eric Paris50c205f2012-04-04 15:01:43 -04005966 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005967 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005968
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005969 return avc_has_perm(&selinux_state,
5970 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005971 SHM__ASSOCIATE, &ad);
5972}
5973
5974/* Note, at this point, shp is locked down */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005975static int selinux_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005976{
5977 int perms;
5978 int err;
5979
Eric Paris828dfe12008-04-17 13:17:49 -04005980 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005981 case IPC_INFO:
5982 case SHM_INFO:
5983 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005984 return avc_has_perm(&selinux_state,
5985 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005986 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005987 case IPC_STAT:
5988 case SHM_STAT:
Davidlohr Buesoc21a6972018-04-10 16:35:23 -07005989 case SHM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005990 perms = SHM__GETATTR | SHM__ASSOCIATE;
5991 break;
5992 case IPC_SET:
5993 perms = SHM__SETATTR;
5994 break;
5995 case SHM_LOCK:
5996 case SHM_UNLOCK:
5997 perms = SHM__LOCK;
5998 break;
5999 case IPC_RMID:
6000 perms = SHM__DESTROY;
6001 break;
6002 default:
6003 return 0;
6004 }
6005
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006006 err = ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006007 return err;
6008}
6009
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006010static int selinux_shm_shmat(struct kern_ipc_perm *shp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006011 char __user *shmaddr, int shmflg)
6012{
6013 u32 perms;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006014
6015 if (shmflg & SHM_RDONLY)
6016 perms = SHM__READ;
6017 else
6018 perms = SHM__READ | SHM__WRITE;
6019
Eric W. Biederman7191adf2018-03-22 21:08:27 -05006020 return ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006021}
6022
6023/* Semaphore security operations */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006024static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006025{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006026 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006027 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006028 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006029 int rc;
6030
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006031 rc = ipc_alloc_security(sma, SECCLASS_SEM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006032 if (rc)
6033 return rc;
6034
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006035 isec = sma->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006036
Eric Paris50c205f2012-04-04 15:01:43 -04006037 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006038 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006039
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006040 rc = avc_has_perm(&selinux_state,
6041 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006042 SEM__CREATE, &ad);
6043 if (rc) {
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006044 ipc_free_security(sma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006045 return rc;
6046 }
6047 return 0;
6048}
6049
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006050static void selinux_sem_free_security(struct kern_ipc_perm *sma)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006051{
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006052 ipc_free_security(sma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006053}
6054
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006055static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006056{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006057 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04006058 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11006059 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006060
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006061 isec = sma->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006062
Eric Paris50c205f2012-04-04 15:01:43 -04006063 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006064 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006065
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006066 return avc_has_perm(&selinux_state,
6067 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006068 SEM__ASSOCIATE, &ad);
6069}
6070
6071/* Note, at this point, sma is locked down */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006072static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006073{
6074 int err;
6075 u32 perms;
6076
Eric Paris828dfe12008-04-17 13:17:49 -04006077 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006078 case IPC_INFO:
6079 case SEM_INFO:
6080 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006081 return avc_has_perm(&selinux_state,
6082 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006083 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006084 case GETPID:
6085 case GETNCNT:
6086 case GETZCNT:
6087 perms = SEM__GETATTR;
6088 break;
6089 case GETVAL:
6090 case GETALL:
6091 perms = SEM__READ;
6092 break;
6093 case SETVAL:
6094 case SETALL:
6095 perms = SEM__WRITE;
6096 break;
6097 case IPC_RMID:
6098 perms = SEM__DESTROY;
6099 break;
6100 case IPC_SET:
6101 perms = SEM__SETATTR;
6102 break;
6103 case IPC_STAT:
6104 case SEM_STAT:
Davidlohr Buesoa280d6d2018-04-10 16:35:26 -07006105 case SEM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006106 perms = SEM__GETATTR | SEM__ASSOCIATE;
6107 break;
6108 default:
6109 return 0;
6110 }
6111
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006112 err = ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006113 return err;
6114}
6115
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006116static int selinux_sem_semop(struct kern_ipc_perm *sma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006117 struct sembuf *sops, unsigned nsops, int alter)
6118{
6119 u32 perms;
6120
6121 if (alter)
6122 perms = SEM__READ | SEM__WRITE;
6123 else
6124 perms = SEM__READ;
6125
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006126 return ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006127}
6128
6129static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
6130{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006131 u32 av = 0;
6132
Linus Torvalds1da177e2005-04-16 15:20:36 -07006133 av = 0;
6134 if (flag & S_IRUGO)
6135 av |= IPC__UNIX_READ;
6136 if (flag & S_IWUGO)
6137 av |= IPC__UNIX_WRITE;
6138
6139 if (av == 0)
6140 return 0;
6141
Stephen Smalley6af963f2005-05-01 08:58:39 -07006142 return ipc_has_perm(ipcp, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006143}
6144
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02006145static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
6146{
6147 struct ipc_security_struct *isec = ipcp->security;
6148 *secid = isec->sid;
6149}
6150
Eric Paris828dfe12008-04-17 13:17:49 -04006151static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006152{
6153 if (inode)
6154 inode_doinit_with_dentry(inode, dentry);
6155}
6156
6157static int selinux_getprocattr(struct task_struct *p,
Al Viro04ff9702007-03-12 16:17:58 +00006158 char *name, char **value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006159{
David Howells275bb412008-11-14 10:39:19 +11006160 const struct task_security_struct *__tsec;
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00006161 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006162 int error;
Al Viro04ff9702007-03-12 16:17:58 +00006163 unsigned len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006164
David Howells275bb412008-11-14 10:39:19 +11006165 rcu_read_lock();
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006166 __tsec = selinux_cred(__task_cred(p));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006167
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006168 if (current != p) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006169 error = avc_has_perm(&selinux_state,
6170 current_sid(), __tsec->sid,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006171 SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
6172 if (error)
6173 goto bad;
6174 }
6175
Linus Torvalds1da177e2005-04-16 15:20:36 -07006176 if (!strcmp(name, "current"))
David Howells275bb412008-11-14 10:39:19 +11006177 sid = __tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006178 else if (!strcmp(name, "prev"))
David Howells275bb412008-11-14 10:39:19 +11006179 sid = __tsec->osid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006180 else if (!strcmp(name, "exec"))
David Howells275bb412008-11-14 10:39:19 +11006181 sid = __tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006182 else if (!strcmp(name, "fscreate"))
David Howells275bb412008-11-14 10:39:19 +11006183 sid = __tsec->create_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006184 else if (!strcmp(name, "keycreate"))
David Howells275bb412008-11-14 10:39:19 +11006185 sid = __tsec->keycreate_sid;
Eric Paris42c3e032006-06-26 00:26:03 -07006186 else if (!strcmp(name, "sockcreate"))
David Howells275bb412008-11-14 10:39:19 +11006187 sid = __tsec->sockcreate_sid;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006188 else {
6189 error = -EINVAL;
6190 goto bad;
6191 }
David Howells275bb412008-11-14 10:39:19 +11006192 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006193
6194 if (!sid)
6195 return 0;
6196
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006197 error = security_sid_to_context(&selinux_state, sid, value, &len);
Al Viro04ff9702007-03-12 16:17:58 +00006198 if (error)
6199 return error;
6200 return len;
David Howells275bb412008-11-14 10:39:19 +11006201
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006202bad:
David Howells275bb412008-11-14 10:39:19 +11006203 rcu_read_unlock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006204 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006205}
6206
Stephen Smalleyb21507e2017-01-09 10:07:31 -05006207static int selinux_setprocattr(const char *name, void *value, size_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006208{
6209 struct task_security_struct *tsec;
David Howellsd84f4f92008-11-14 10:39:23 +11006210 struct cred *new;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006211 u32 mysid = current_sid(), sid = 0, ptsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006212 int error;
6213 char *str = value;
6214
Linus Torvalds1da177e2005-04-16 15:20:36 -07006215 /*
6216 * Basic control over ability to set these attributes at all.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006217 */
6218 if (!strcmp(name, "exec"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006219 error = avc_has_perm(&selinux_state,
6220 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006221 PROCESS__SETEXEC, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006222 else if (!strcmp(name, "fscreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006223 error = avc_has_perm(&selinux_state,
6224 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006225 PROCESS__SETFSCREATE, NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006226 else if (!strcmp(name, "keycreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006227 error = avc_has_perm(&selinux_state,
6228 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006229 PROCESS__SETKEYCREATE, NULL);
Eric Paris42c3e032006-06-26 00:26:03 -07006230 else if (!strcmp(name, "sockcreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006231 error = avc_has_perm(&selinux_state,
6232 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006233 PROCESS__SETSOCKCREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006234 else if (!strcmp(name, "current"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006235 error = avc_has_perm(&selinux_state,
6236 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006237 PROCESS__SETCURRENT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006238 else
6239 error = -EINVAL;
6240 if (error)
6241 return error;
6242
6243 /* Obtain a SID for the context, if one was specified. */
Stephen Smalleya050a572017-01-31 11:54:04 -05006244 if (size && str[0] && str[0] != '\n') {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006245 if (str[size-1] == '\n') {
6246 str[size-1] = 0;
6247 size--;
6248 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006249 error = security_context_to_sid(&selinux_state, value, size,
6250 &sid, GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006251 if (error == -EINVAL && !strcmp(name, "fscreate")) {
Stephen Smalleydb590002017-04-20 11:31:30 -04006252 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04006253 struct audit_buffer *ab;
6254 size_t audit_size;
6255
6256 /* We strip a nul only if it is at the end, otherwise the
6257 * context contains a nul and we should audit that */
6258 if (str[size - 1] == '\0')
6259 audit_size = size - 1;
6260 else
6261 audit_size = size;
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04006262 ab = audit_log_start(audit_context(),
6263 GFP_ATOMIC,
6264 AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04006265 audit_log_format(ab, "op=fscreate invalid_context=");
6266 audit_log_n_untrustedstring(ab, value, audit_size);
6267 audit_log_end(ab);
6268
Stephen Smalley12b29f32008-05-07 13:03:20 -04006269 return error;
Eric Parisd6ea83e2012-04-04 13:45:49 -04006270 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006271 error = security_context_to_sid_force(
6272 &selinux_state,
6273 value, size, &sid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006274 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006275 if (error)
6276 return error;
6277 }
6278
David Howellsd84f4f92008-11-14 10:39:23 +11006279 new = prepare_creds();
6280 if (!new)
6281 return -ENOMEM;
6282
Linus Torvalds1da177e2005-04-16 15:20:36 -07006283 /* Permission checking based on the specified context is
6284 performed during the actual operation (execve,
6285 open/mkdir/...), when we know the full context of the
David Howellsd84f4f92008-11-14 10:39:23 +11006286 operation. See selinux_bprm_set_creds for the execve
Linus Torvalds1da177e2005-04-16 15:20:36 -07006287 checks and may_create for the file creation checks. The
6288 operation will then fail if the context is not permitted. */
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006289 tsec = selinux_cred(new);
David Howellsd84f4f92008-11-14 10:39:23 +11006290 if (!strcmp(name, "exec")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006291 tsec->exec_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006292 } else if (!strcmp(name, "fscreate")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006293 tsec->create_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006294 } else if (!strcmp(name, "keycreate")) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006295 error = avc_has_perm(&selinux_state,
6296 mysid, sid, SECCLASS_KEY, KEY__CREATE,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006297 NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006298 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006299 goto abort_change;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006300 tsec->keycreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006301 } else if (!strcmp(name, "sockcreate")) {
Eric Paris42c3e032006-06-26 00:26:03 -07006302 tsec->sockcreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006303 } else if (!strcmp(name, "current")) {
6304 error = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006305 if (sid == 0)
David Howellsd84f4f92008-11-14 10:39:23 +11006306 goto abort_change;
KaiGai Koheid9250de2008-08-28 16:35:57 +09006307
David Howellsd84f4f92008-11-14 10:39:23 +11006308 /* Only allow single threaded processes to change context */
6309 error = -EPERM;
Oleg Nesterov5bb459b2009-07-10 03:48:23 +02006310 if (!current_is_single_threaded()) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006311 error = security_bounded_transition(&selinux_state,
6312 tsec->sid, sid);
David Howellsd84f4f92008-11-14 10:39:23 +11006313 if (error)
6314 goto abort_change;
Eric Paris828dfe12008-04-17 13:17:49 -04006315 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006316
6317 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006318 error = avc_has_perm(&selinux_state,
6319 tsec->sid, sid, SECCLASS_PROCESS,
Eric Paris828dfe12008-04-17 13:17:49 -04006320 PROCESS__DYNTRANSITION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006321 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006322 goto abort_change;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006323
6324 /* Check for ptracing, and update the task SID if ok.
6325 Otherwise, leave SID unchanged and fail. */
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006326 ptsid = ptrace_parent_sid();
Paul Moore0c6181c2016-03-30 21:41:21 -04006327 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006328 error = avc_has_perm(&selinux_state,
6329 ptsid, sid, SECCLASS_PROCESS,
David Howellsd84f4f92008-11-14 10:39:23 +11006330 PROCESS__PTRACE, NULL);
6331 if (error)
6332 goto abort_change;
6333 }
6334
6335 tsec->sid = sid;
6336 } else {
6337 error = -EINVAL;
6338 goto abort_change;
6339 }
6340
6341 commit_creds(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006342 return size;
David Howellsd84f4f92008-11-14 10:39:23 +11006343
6344abort_change:
6345 abort_creds(new);
6346 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006347}
6348
David Quigley746df9b2013-05-22 12:50:35 -04006349static int selinux_ismaclabel(const char *name)
6350{
6351 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
6352}
6353
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006354static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
6355{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006356 return security_sid_to_context(&selinux_state, secid,
6357 secdata, seclen);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006358}
6359
David Howells7bf570d2008-04-29 20:52:51 +01006360static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
David Howells63cb3442008-01-15 23:47:35 +00006361{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006362 return security_context_to_sid(&selinux_state, secdata, seclen,
6363 secid, GFP_KERNEL);
David Howells63cb3442008-01-15 23:47:35 +00006364}
6365
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006366static void selinux_release_secctx(char *secdata, u32 seclen)
6367{
Paul Moore088999e2007-08-01 11:12:58 -04006368 kfree(secdata);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006369}
6370
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006371static void selinux_inode_invalidate_secctx(struct inode *inode)
6372{
6373 struct inode_security_struct *isec = inode->i_security;
6374
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006375 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006376 isec->initialized = LABEL_INVALID;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006377 spin_unlock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006378}
6379
David P. Quigley1ee65e32009-09-03 14:25:57 -04006380/*
6381 * called with inode->i_mutex locked
6382 */
6383static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
6384{
6385 return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
6386}
6387
6388/*
6389 * called with inode->i_mutex locked
6390 */
6391static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
6392{
6393 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
6394}
6395
6396static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
6397{
6398 int len = 0;
6399 len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
6400 ctx, true);
6401 if (len < 0)
6402 return len;
6403 *ctxlen = len;
6404 return 0;
6405}
Michael LeMayd7200242006-06-22 14:47:17 -07006406#ifdef CONFIG_KEYS
6407
David Howellsd84f4f92008-11-14 10:39:23 +11006408static int selinux_key_alloc(struct key *k, const struct cred *cred,
David Howells7e047ef2006-06-26 00:24:50 -07006409 unsigned long flags)
Michael LeMayd7200242006-06-22 14:47:17 -07006410{
David Howellsd84f4f92008-11-14 10:39:23 +11006411 const struct task_security_struct *tsec;
Michael LeMayd7200242006-06-22 14:47:17 -07006412 struct key_security_struct *ksec;
6413
6414 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
6415 if (!ksec)
6416 return -ENOMEM;
6417
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006418 tsec = selinux_cred(cred);
David Howellsd84f4f92008-11-14 10:39:23 +11006419 if (tsec->keycreate_sid)
6420 ksec->sid = tsec->keycreate_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006421 else
David Howellsd84f4f92008-11-14 10:39:23 +11006422 ksec->sid = tsec->sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006423
David Howells275bb412008-11-14 10:39:19 +11006424 k->security = ksec;
Michael LeMayd7200242006-06-22 14:47:17 -07006425 return 0;
6426}
6427
6428static void selinux_key_free(struct key *k)
6429{
6430 struct key_security_struct *ksec = k->security;
6431
6432 k->security = NULL;
6433 kfree(ksec);
6434}
6435
6436static int selinux_key_permission(key_ref_t key_ref,
David Howellsd84f4f92008-11-14 10:39:23 +11006437 const struct cred *cred,
David Howellsf5895942014-03-14 17:44:49 +00006438 unsigned perm)
Michael LeMayd7200242006-06-22 14:47:17 -07006439{
6440 struct key *key;
Michael LeMayd7200242006-06-22 14:47:17 -07006441 struct key_security_struct *ksec;
David Howells275bb412008-11-14 10:39:19 +11006442 u32 sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006443
6444 /* if no specific permissions are requested, we skip the
6445 permission check. No serious, additional covert channels
6446 appear to be created. */
6447 if (perm == 0)
6448 return 0;
6449
David Howellsd84f4f92008-11-14 10:39:23 +11006450 sid = cred_sid(cred);
David Howells275bb412008-11-14 10:39:19 +11006451
6452 key = key_ref_to_ptr(key_ref);
6453 ksec = key->security;
6454
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006455 return avc_has_perm(&selinux_state,
6456 sid, ksec->sid, SECCLASS_KEY, perm, NULL);
Michael LeMayd7200242006-06-22 14:47:17 -07006457}
6458
David Howells70a5bb72008-04-29 01:01:26 -07006459static int selinux_key_getsecurity(struct key *key, char **_buffer)
6460{
6461 struct key_security_struct *ksec = key->security;
6462 char *context = NULL;
6463 unsigned len;
6464 int rc;
6465
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006466 rc = security_sid_to_context(&selinux_state, ksec->sid,
6467 &context, &len);
David Howells70a5bb72008-04-29 01:01:26 -07006468 if (!rc)
6469 rc = len;
6470 *_buffer = context;
6471 return rc;
6472}
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006473#endif
David Howells70a5bb72008-04-29 01:01:26 -07006474
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006475#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006476static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
6477{
6478 struct common_audit_data ad;
6479 int err;
6480 u32 sid = 0;
6481 struct ib_security_struct *sec = ib_sec;
6482 struct lsm_ibpkey_audit ibpkey;
6483
Daniel Jurgens409dcf32017-05-19 15:48:59 +03006484 err = sel_ib_pkey_sid(subnet_prefix, pkey_val, &sid);
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006485 if (err)
6486 return err;
6487
6488 ad.type = LSM_AUDIT_DATA_IBPKEY;
6489 ibpkey.subnet_prefix = subnet_prefix;
6490 ibpkey.pkey = pkey_val;
6491 ad.u.ibpkey = &ibpkey;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006492 return avc_has_perm(&selinux_state,
6493 sec->sid, sid,
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006494 SECCLASS_INFINIBAND_PKEY,
6495 INFINIBAND_PKEY__ACCESS, &ad);
6496}
6497
Daniel Jurgensab861df2017-05-19 15:48:58 +03006498static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
6499 u8 port_num)
6500{
6501 struct common_audit_data ad;
6502 int err;
6503 u32 sid = 0;
6504 struct ib_security_struct *sec = ib_sec;
6505 struct lsm_ibendport_audit ibendport;
6506
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006507 err = security_ib_endport_sid(&selinux_state, dev_name, port_num,
6508 &sid);
Daniel Jurgensab861df2017-05-19 15:48:58 +03006509
6510 if (err)
6511 return err;
6512
6513 ad.type = LSM_AUDIT_DATA_IBENDPORT;
6514 strncpy(ibendport.dev_name, dev_name, sizeof(ibendport.dev_name));
6515 ibendport.port = port_num;
6516 ad.u.ibendport = &ibendport;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006517 return avc_has_perm(&selinux_state,
6518 sec->sid, sid,
Daniel Jurgensab861df2017-05-19 15:48:58 +03006519 SECCLASS_INFINIBAND_ENDPORT,
6520 INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
6521}
6522
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006523static int selinux_ib_alloc_security(void **ib_sec)
6524{
6525 struct ib_security_struct *sec;
6526
6527 sec = kzalloc(sizeof(*sec), GFP_KERNEL);
6528 if (!sec)
6529 return -ENOMEM;
6530 sec->sid = current_sid();
6531
6532 *ib_sec = sec;
6533 return 0;
6534}
6535
6536static void selinux_ib_free_security(void *ib_sec)
6537{
6538 kfree(ib_sec);
6539}
Michael LeMayd7200242006-06-22 14:47:17 -07006540#endif
6541
Chenbo Fengec27c352017-10-18 13:00:25 -07006542#ifdef CONFIG_BPF_SYSCALL
6543static int selinux_bpf(int cmd, union bpf_attr *attr,
6544 unsigned int size)
6545{
6546 u32 sid = current_sid();
6547 int ret;
6548
6549 switch (cmd) {
6550 case BPF_MAP_CREATE:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006551 ret = avc_has_perm(&selinux_state,
6552 sid, sid, SECCLASS_BPF, BPF__MAP_CREATE,
Chenbo Fengec27c352017-10-18 13:00:25 -07006553 NULL);
6554 break;
6555 case BPF_PROG_LOAD:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006556 ret = avc_has_perm(&selinux_state,
6557 sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
Chenbo Fengec27c352017-10-18 13:00:25 -07006558 NULL);
6559 break;
6560 default:
6561 ret = 0;
6562 break;
6563 }
6564
6565 return ret;
6566}
6567
6568static u32 bpf_map_fmode_to_av(fmode_t fmode)
6569{
6570 u32 av = 0;
6571
6572 if (fmode & FMODE_READ)
6573 av |= BPF__MAP_READ;
6574 if (fmode & FMODE_WRITE)
6575 av |= BPF__MAP_WRITE;
6576 return av;
6577}
6578
Chenbo Fengf66e4482017-10-18 13:00:26 -07006579/* This function will check the file pass through unix socket or binder to see
6580 * if it is a bpf related object. And apply correspinding checks on the bpf
6581 * object based on the type. The bpf maps and programs, not like other files and
6582 * socket, are using a shared anonymous inode inside the kernel as their inode.
6583 * So checking that inode cannot identify if the process have privilege to
6584 * access the bpf object and that's why we have to add this additional check in
6585 * selinux_file_receive and selinux_binder_transfer_files.
6586 */
6587static int bpf_fd_pass(struct file *file, u32 sid)
6588{
6589 struct bpf_security_struct *bpfsec;
6590 struct bpf_prog *prog;
6591 struct bpf_map *map;
6592 int ret;
6593
6594 if (file->f_op == &bpf_map_fops) {
6595 map = file->private_data;
6596 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006597 ret = avc_has_perm(&selinux_state,
6598 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006599 bpf_map_fmode_to_av(file->f_mode), NULL);
6600 if (ret)
6601 return ret;
6602 } else if (file->f_op == &bpf_prog_fops) {
6603 prog = file->private_data;
6604 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006605 ret = avc_has_perm(&selinux_state,
6606 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006607 BPF__PROG_RUN, NULL);
6608 if (ret)
6609 return ret;
6610 }
6611 return 0;
6612}
6613
Chenbo Fengec27c352017-10-18 13:00:25 -07006614static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode)
6615{
6616 u32 sid = current_sid();
6617 struct bpf_security_struct *bpfsec;
6618
6619 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006620 return avc_has_perm(&selinux_state,
6621 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006622 bpf_map_fmode_to_av(fmode), NULL);
6623}
6624
6625static int selinux_bpf_prog(struct bpf_prog *prog)
6626{
6627 u32 sid = current_sid();
6628 struct bpf_security_struct *bpfsec;
6629
6630 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006631 return avc_has_perm(&selinux_state,
6632 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006633 BPF__PROG_RUN, NULL);
6634}
6635
6636static int selinux_bpf_map_alloc(struct bpf_map *map)
6637{
6638 struct bpf_security_struct *bpfsec;
6639
6640 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6641 if (!bpfsec)
6642 return -ENOMEM;
6643
6644 bpfsec->sid = current_sid();
6645 map->security = bpfsec;
6646
6647 return 0;
6648}
6649
6650static void selinux_bpf_map_free(struct bpf_map *map)
6651{
6652 struct bpf_security_struct *bpfsec = map->security;
6653
6654 map->security = NULL;
6655 kfree(bpfsec);
6656}
6657
6658static int selinux_bpf_prog_alloc(struct bpf_prog_aux *aux)
6659{
6660 struct bpf_security_struct *bpfsec;
6661
6662 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6663 if (!bpfsec)
6664 return -ENOMEM;
6665
6666 bpfsec->sid = current_sid();
6667 aux->security = bpfsec;
6668
6669 return 0;
6670}
6671
6672static void selinux_bpf_prog_free(struct bpf_prog_aux *aux)
6673{
6674 struct bpf_security_struct *bpfsec = aux->security;
6675
6676 aux->security = NULL;
6677 kfree(bpfsec);
6678}
6679#endif
6680
James Morrisca97d932017-02-15 00:18:51 +11006681static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
Casey Schauflere20b0432015-05-02 15:11:36 -07006682 LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
6683 LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
6684 LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
6685 LSM_HOOK_INIT(binder_transfer_file, selinux_binder_transfer_file),
Ahmed S. Darwish076c54c2008-03-06 18:09:10 +02006686
Casey Schauflere20b0432015-05-02 15:11:36 -07006687 LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
6688 LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
6689 LSM_HOOK_INIT(capget, selinux_capget),
6690 LSM_HOOK_INIT(capset, selinux_capset),
6691 LSM_HOOK_INIT(capable, selinux_capable),
6692 LSM_HOOK_INIT(quotactl, selinux_quotactl),
6693 LSM_HOOK_INIT(quota_on, selinux_quota_on),
6694 LSM_HOOK_INIT(syslog, selinux_syslog),
6695 LSM_HOOK_INIT(vm_enough_memory, selinux_vm_enough_memory),
Stephen Smalley79af7302015-01-21 10:54:10 -05006696
Casey Schauflere20b0432015-05-02 15:11:36 -07006697 LSM_HOOK_INIT(netlink_send, selinux_netlink_send),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006698
Casey Schauflere20b0432015-05-02 15:11:36 -07006699 LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds),
6700 LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds),
6701 LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006702
Casey Schauflere20b0432015-05-02 15:11:36 -07006703 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),
6704 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
Al Viro5b400232018-12-12 20:13:29 -05006705 LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts),
Al Viro204cc0c2018-12-13 13:41:47 -05006706 LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts),
Casey Schauflere20b0432015-05-02 15:11:36 -07006707 LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
6708 LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
6709 LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options),
6710 LSM_HOOK_INIT(sb_statfs, selinux_sb_statfs),
6711 LSM_HOOK_INIT(sb_mount, selinux_mount),
6712 LSM_HOOK_INIT(sb_umount, selinux_umount),
6713 LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts),
6714 LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts),
Al Viro757cbe52018-12-14 23:42:21 -05006715 LSM_HOOK_INIT(sb_add_mnt_opt, selinux_add_mnt_opt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006716
Casey Schauflere20b0432015-05-02 15:11:36 -07006717 LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
Vivek Goyala518b0a2016-07-13 10:44:53 -04006718 LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
Eric Parise0007522008-03-05 10:31:54 -05006719
Casey Schauflere20b0432015-05-02 15:11:36 -07006720 LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
6721 LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
6722 LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security),
6723 LSM_HOOK_INIT(inode_create, selinux_inode_create),
6724 LSM_HOOK_INIT(inode_link, selinux_inode_link),
6725 LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink),
6726 LSM_HOOK_INIT(inode_symlink, selinux_inode_symlink),
6727 LSM_HOOK_INIT(inode_mkdir, selinux_inode_mkdir),
6728 LSM_HOOK_INIT(inode_rmdir, selinux_inode_rmdir),
6729 LSM_HOOK_INIT(inode_mknod, selinux_inode_mknod),
6730 LSM_HOOK_INIT(inode_rename, selinux_inode_rename),
6731 LSM_HOOK_INIT(inode_readlink, selinux_inode_readlink),
6732 LSM_HOOK_INIT(inode_follow_link, selinux_inode_follow_link),
6733 LSM_HOOK_INIT(inode_permission, selinux_inode_permission),
6734 LSM_HOOK_INIT(inode_setattr, selinux_inode_setattr),
6735 LSM_HOOK_INIT(inode_getattr, selinux_inode_getattr),
6736 LSM_HOOK_INIT(inode_setxattr, selinux_inode_setxattr),
6737 LSM_HOOK_INIT(inode_post_setxattr, selinux_inode_post_setxattr),
6738 LSM_HOOK_INIT(inode_getxattr, selinux_inode_getxattr),
6739 LSM_HOOK_INIT(inode_listxattr, selinux_inode_listxattr),
6740 LSM_HOOK_INIT(inode_removexattr, selinux_inode_removexattr),
6741 LSM_HOOK_INIT(inode_getsecurity, selinux_inode_getsecurity),
6742 LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity),
6743 LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
6744 LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
Vivek Goyal56909eb2016-07-13 10:44:48 -04006745 LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
Vivek Goyal19472b62016-07-13 10:44:50 -04006746 LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006747
Casey Schauflere20b0432015-05-02 15:11:36 -07006748 LSM_HOOK_INIT(file_permission, selinux_file_permission),
6749 LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
6750 LSM_HOOK_INIT(file_free_security, selinux_file_free_security),
6751 LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
6752 LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
6753 LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),
6754 LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
6755 LSM_HOOK_INIT(file_lock, selinux_file_lock),
6756 LSM_HOOK_INIT(file_fcntl, selinux_file_fcntl),
6757 LSM_HOOK_INIT(file_set_fowner, selinux_file_set_fowner),
6758 LSM_HOOK_INIT(file_send_sigiotask, selinux_file_send_sigiotask),
6759 LSM_HOOK_INIT(file_receive, selinux_file_receive),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006760
Casey Schauflere20b0432015-05-02 15:11:36 -07006761 LSM_HOOK_INIT(file_open, selinux_file_open),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762
Tetsuo Handaa79be232017-03-28 23:08:45 +09006763 LSM_HOOK_INIT(task_alloc, selinux_task_alloc),
Casey Schauflere20b0432015-05-02 15:11:36 -07006764 LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank),
6765 LSM_HOOK_INIT(cred_free, selinux_cred_free),
6766 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
6767 LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
Matthew Garrett3ec30112018-01-08 13:36:19 -08006768 LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid),
Casey Schauflere20b0432015-05-02 15:11:36 -07006769 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
6770 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
6771 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04006772 LSM_HOOK_INIT(kernel_load_data, selinux_kernel_load_data),
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07006773 LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file),
Casey Schauflere20b0432015-05-02 15:11:36 -07006774 LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
6775 LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
6776 LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
6777 LSM_HOOK_INIT(task_getsecid, selinux_task_getsecid),
6778 LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
6779 LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
6780 LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
Stephen Smalley791ec492017-02-17 07:57:00 -05006781 LSM_HOOK_INIT(task_prlimit, selinux_task_prlimit),
Casey Schauflere20b0432015-05-02 15:11:36 -07006782 LSM_HOOK_INIT(task_setrlimit, selinux_task_setrlimit),
6783 LSM_HOOK_INIT(task_setscheduler, selinux_task_setscheduler),
6784 LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler),
6785 LSM_HOOK_INIT(task_movememory, selinux_task_movememory),
6786 LSM_HOOK_INIT(task_kill, selinux_task_kill),
Casey Schauflere20b0432015-05-02 15:11:36 -07006787 LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode),
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09006788
Casey Schauflere20b0432015-05-02 15:11:36 -07006789 LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission),
6790 LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006791
Casey Schauflere20b0432015-05-02 15:11:36 -07006792 LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security),
6793 LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006794
Casey Schauflere20b0432015-05-02 15:11:36 -07006795 LSM_HOOK_INIT(msg_queue_alloc_security,
6796 selinux_msg_queue_alloc_security),
6797 LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security),
6798 LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate),
6799 LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl),
6800 LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd),
6801 LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006802
Casey Schauflere20b0432015-05-02 15:11:36 -07006803 LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security),
6804 LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security),
6805 LSM_HOOK_INIT(shm_associate, selinux_shm_associate),
6806 LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl),
6807 LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006808
Casey Schauflere20b0432015-05-02 15:11:36 -07006809 LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
6810 LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security),
6811 LSM_HOOK_INIT(sem_associate, selinux_sem_associate),
6812 LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl),
6813 LSM_HOOK_INIT(sem_semop, selinux_sem_semop),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814
Casey Schauflere20b0432015-05-02 15:11:36 -07006815 LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816
Casey Schauflere20b0432015-05-02 15:11:36 -07006817 LSM_HOOK_INIT(getprocattr, selinux_getprocattr),
6818 LSM_HOOK_INIT(setprocattr, selinux_setprocattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006819
Casey Schauflere20b0432015-05-02 15:11:36 -07006820 LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel),
6821 LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
6822 LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
6823 LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006824 LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
Casey Schauflere20b0432015-05-02 15:11:36 -07006825 LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
6826 LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx),
6827 LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828
Casey Schauflere20b0432015-05-02 15:11:36 -07006829 LSM_HOOK_INIT(unix_stream_connect, selinux_socket_unix_stream_connect),
6830 LSM_HOOK_INIT(unix_may_send, selinux_socket_unix_may_send),
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006831
Casey Schauflere20b0432015-05-02 15:11:36 -07006832 LSM_HOOK_INIT(socket_create, selinux_socket_create),
6833 LSM_HOOK_INIT(socket_post_create, selinux_socket_post_create),
David Herrmann0b811db2018-05-04 16:28:21 +02006834 LSM_HOOK_INIT(socket_socketpair, selinux_socket_socketpair),
Casey Schauflere20b0432015-05-02 15:11:36 -07006835 LSM_HOOK_INIT(socket_bind, selinux_socket_bind),
6836 LSM_HOOK_INIT(socket_connect, selinux_socket_connect),
6837 LSM_HOOK_INIT(socket_listen, selinux_socket_listen),
6838 LSM_HOOK_INIT(socket_accept, selinux_socket_accept),
6839 LSM_HOOK_INIT(socket_sendmsg, selinux_socket_sendmsg),
6840 LSM_HOOK_INIT(socket_recvmsg, selinux_socket_recvmsg),
6841 LSM_HOOK_INIT(socket_getsockname, selinux_socket_getsockname),
6842 LSM_HOOK_INIT(socket_getpeername, selinux_socket_getpeername),
6843 LSM_HOOK_INIT(socket_getsockopt, selinux_socket_getsockopt),
6844 LSM_HOOK_INIT(socket_setsockopt, selinux_socket_setsockopt),
6845 LSM_HOOK_INIT(socket_shutdown, selinux_socket_shutdown),
6846 LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
6847 LSM_HOOK_INIT(socket_getpeersec_stream,
6848 selinux_socket_getpeersec_stream),
6849 LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram),
6850 LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
6851 LSM_HOOK_INIT(sk_free_security, selinux_sk_free_security),
6852 LSM_HOOK_INIT(sk_clone_security, selinux_sk_clone_security),
6853 LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid),
6854 LSM_HOOK_INIT(sock_graft, selinux_sock_graft),
Richard Hainesd4529302018-02-13 20:57:18 +00006855 LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request),
6856 LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone),
6857 LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect),
Casey Schauflere20b0432015-05-02 15:11:36 -07006858 LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request),
6859 LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone),
6860 LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),
6861 LSM_HOOK_INIT(secmark_relabel_packet, selinux_secmark_relabel_packet),
6862 LSM_HOOK_INIT(secmark_refcount_inc, selinux_secmark_refcount_inc),
6863 LSM_HOOK_INIT(secmark_refcount_dec, selinux_secmark_refcount_dec),
6864 LSM_HOOK_INIT(req_classify_flow, selinux_req_classify_flow),
6865 LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
6866 LSM_HOOK_INIT(tun_dev_free_security, selinux_tun_dev_free_security),
6867 LSM_HOOK_INIT(tun_dev_create, selinux_tun_dev_create),
6868 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
6869 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
6870 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006871#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006872 LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
Daniel Jurgensab861df2017-05-19 15:48:58 +03006873 LSM_HOOK_INIT(ib_endport_manage_subnet,
6874 selinux_ib_endport_manage_subnet),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006875 LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
6876 LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
6877#endif
Trent Jaegerd28d1e02005-12-13 23:12:40 -08006878#ifdef CONFIG_SECURITY_NETWORK_XFRM
Casey Schauflere20b0432015-05-02 15:11:36 -07006879 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
6880 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone),
6881 LSM_HOOK_INIT(xfrm_policy_free_security, selinux_xfrm_policy_free),
6882 LSM_HOOK_INIT(xfrm_policy_delete_security, selinux_xfrm_policy_delete),
6883 LSM_HOOK_INIT(xfrm_state_alloc, selinux_xfrm_state_alloc),
6884 LSM_HOOK_INIT(xfrm_state_alloc_acquire,
6885 selinux_xfrm_state_alloc_acquire),
6886 LSM_HOOK_INIT(xfrm_state_free_security, selinux_xfrm_state_free),
6887 LSM_HOOK_INIT(xfrm_state_delete_security, selinux_xfrm_state_delete),
6888 LSM_HOOK_INIT(xfrm_policy_lookup, selinux_xfrm_policy_lookup),
6889 LSM_HOOK_INIT(xfrm_state_pol_flow_match,
6890 selinux_xfrm_state_pol_flow_match),
6891 LSM_HOOK_INIT(xfrm_decode_session, selinux_xfrm_decode_session),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892#endif
Michael LeMayd7200242006-06-22 14:47:17 -07006893
6894#ifdef CONFIG_KEYS
Casey Schauflere20b0432015-05-02 15:11:36 -07006895 LSM_HOOK_INIT(key_alloc, selinux_key_alloc),
6896 LSM_HOOK_INIT(key_free, selinux_key_free),
6897 LSM_HOOK_INIT(key_permission, selinux_key_permission),
6898 LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity),
Michael LeMayd7200242006-06-22 14:47:17 -07006899#endif
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006900
6901#ifdef CONFIG_AUDIT
Casey Schauflere20b0432015-05-02 15:11:36 -07006902 LSM_HOOK_INIT(audit_rule_init, selinux_audit_rule_init),
6903 LSM_HOOK_INIT(audit_rule_known, selinux_audit_rule_known),
6904 LSM_HOOK_INIT(audit_rule_match, selinux_audit_rule_match),
6905 LSM_HOOK_INIT(audit_rule_free, selinux_audit_rule_free),
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006906#endif
Chenbo Fengec27c352017-10-18 13:00:25 -07006907
6908#ifdef CONFIG_BPF_SYSCALL
6909 LSM_HOOK_INIT(bpf, selinux_bpf),
6910 LSM_HOOK_INIT(bpf_map, selinux_bpf_map),
6911 LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog),
6912 LSM_HOOK_INIT(bpf_map_alloc_security, selinux_bpf_map_alloc),
6913 LSM_HOOK_INIT(bpf_prog_alloc_security, selinux_bpf_prog_alloc),
6914 LSM_HOOK_INIT(bpf_map_free_security, selinux_bpf_map_free),
6915 LSM_HOOK_INIT(bpf_prog_free_security, selinux_bpf_prog_free),
6916#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07006917};
6918
6919static __init int selinux_init(void)
6920{
peter enderborgc103a912018-06-12 10:09:03 +02006921 pr_info("SELinux: Initializing.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006922
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006923 memset(&selinux_state, 0, sizeof(selinux_state));
Paul Mooree5a5ca92018-03-01 17:38:30 -05006924 enforcing_set(&selinux_state, selinux_enforcing_boot);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006925 selinux_state.checkreqprot = selinux_checkreqprot_boot;
6926 selinux_ss_init(&selinux_state.ss);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006927 selinux_avc_init(&selinux_state.avc);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006928
Linus Torvalds1da177e2005-04-16 15:20:36 -07006929 /* Set the security state for the initial task. */
David Howellsd84f4f92008-11-14 10:39:23 +11006930 cred_init_security();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006931
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04006932 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
6933
James Morris7cae7e22006-03-22 00:09:22 -08006934 sel_inode_cache = kmem_cache_create("selinux_inode_security",
6935 sizeof(struct inode_security_struct),
Paul Mundt20c2df82007-07-20 10:11:58 +09006936 0, SLAB_PANIC, NULL);
Sangwoo63205652015-10-21 17:44:30 -04006937 file_security_cache = kmem_cache_create("selinux_file_security",
6938 sizeof(struct file_security_struct),
6939 0, SLAB_PANIC, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006940 avc_init();
6941
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006942 avtab_cache_init();
6943
6944 ebitmap_cache_init();
6945
6946 hashtab_cache_init();
6947
Casey Schauflerd69dece52017-01-18 17:09:05 -08006948 security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006949
Paul Moore615e51f2014-06-26 14:33:56 -04006950 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6951 panic("SELinux: Unable to register AVC netcache callback\n");
6952
Daniel Jurgens8f408ab2017-05-19 15:48:53 +03006953 if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
6954 panic("SELinux: Unable to register AVC LSM notifier callback\n");
6955
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006956 if (selinux_enforcing_boot)
peter enderborgc103a912018-06-12 10:09:03 +02006957 pr_debug("SELinux: Starting in enforcing mode\n");
Eric Paris828dfe12008-04-17 13:17:49 -04006958 else
peter enderborgc103a912018-06-12 10:09:03 +02006959 pr_debug("SELinux: Starting in permissive mode\n");
Michael LeMayd7200242006-06-22 14:47:17 -07006960
Linus Torvalds1da177e2005-04-16 15:20:36 -07006961 return 0;
6962}
6963
Al Viroe8c26252010-03-23 06:36:54 -04006964static void delayed_superblock_init(struct super_block *sb, void *unused)
6965{
Al Viro204cc0c2018-12-13 13:41:47 -05006966 selinux_set_mnt_opts(sb, NULL, 0, NULL);
Al Viroe8c26252010-03-23 06:36:54 -04006967}
6968
Linus Torvalds1da177e2005-04-16 15:20:36 -07006969void selinux_complete_init(void)
6970{
peter enderborgc103a912018-06-12 10:09:03 +02006971 pr_debug("SELinux: Completing initialization.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006972
6973 /* Set up any superblocks initialized prior to the policy load. */
peter enderborgc103a912018-06-12 10:09:03 +02006974 pr_debug("SELinux: Setting up existing superblocks.\n");
Al Viroe8c26252010-03-23 06:36:54 -04006975 iterate_supers(delayed_superblock_init, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006976}
6977
6978/* SELinux requires early initialization in order to label
6979 all processes and objects when they are created. */
Kees Cook3d6e5f62018-10-10 17:18:23 -07006980DEFINE_LSM(selinux) = {
Kees Cook07aed2f2018-10-10 17:18:24 -07006981 .name = "selinux",
Kees Cook14bd99c2018-09-19 19:57:06 -07006982 .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
Kees Cookc5459b82018-09-13 22:28:48 -07006983 .enabled = &selinux_enabled,
Kees Cook3d6e5f62018-10-10 17:18:23 -07006984 .init = selinux_init,
6985};
Linus Torvalds1da177e2005-04-16 15:20:36 -07006986
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006987#if defined(CONFIG_NETFILTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006988
Florian Westphal591bb2782017-07-26 11:40:52 +02006989static const struct nf_hook_ops selinux_nf_ops[] = {
Paul Mooreeffad8d2008-01-29 08:49:27 -05006990 {
6991 .hook = selinux_ipv4_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00006992 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006993 .hooknum = NF_INET_POST_ROUTING,
6994 .priority = NF_IP_PRI_SELINUX_LAST,
6995 },
6996 {
6997 .hook = selinux_ipv4_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00006998 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006999 .hooknum = NF_INET_FORWARD,
7000 .priority = NF_IP_PRI_SELINUX_FIRST,
Paul Moore948bf852008-10-10 10:16:32 -04007001 },
7002 {
7003 .hook = selinux_ipv4_output,
Alban Crequy2597a832012-05-14 03:56:39 +00007004 .pf = NFPROTO_IPV4,
Paul Moore948bf852008-10-10 10:16:32 -04007005 .hooknum = NF_INET_LOCAL_OUT,
7006 .priority = NF_IP_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02007007 },
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04007008#if IS_ENABLED(CONFIG_IPV6)
Paul Mooreeffad8d2008-01-29 08:49:27 -05007009 {
7010 .hook = selinux_ipv6_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00007011 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05007012 .hooknum = NF_INET_POST_ROUTING,
7013 .priority = NF_IP6_PRI_SELINUX_LAST,
7014 },
7015 {
7016 .hook = selinux_ipv6_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00007017 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05007018 .hooknum = NF_INET_FORWARD,
7019 .priority = NF_IP6_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02007020 },
Huw Davies2917f572016-06-27 15:06:15 -04007021 {
7022 .hook = selinux_ipv6_output,
7023 .pf = NFPROTO_IPV6,
7024 .hooknum = NF_INET_LOCAL_OUT,
7025 .priority = NF_IP6_PRI_SELINUX_FIRST,
7026 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07007027#endif /* IPV6 */
Jiri Pirko25db6be2014-09-03 17:42:13 +02007028};
Linus Torvalds1da177e2005-04-16 15:20:36 -07007029
Florian Westphal8e71bf72017-04-21 11:49:09 +02007030static int __net_init selinux_nf_register(struct net *net)
7031{
7032 return nf_register_net_hooks(net, selinux_nf_ops,
7033 ARRAY_SIZE(selinux_nf_ops));
7034}
7035
7036static void __net_exit selinux_nf_unregister(struct net *net)
7037{
7038 nf_unregister_net_hooks(net, selinux_nf_ops,
7039 ARRAY_SIZE(selinux_nf_ops));
7040}
7041
7042static struct pernet_operations selinux_net_ops = {
7043 .init = selinux_nf_register,
7044 .exit = selinux_nf_unregister,
7045};
7046
Linus Torvalds1da177e2005-04-16 15:20:36 -07007047static int __init selinux_nf_ip_init(void)
7048{
Jiri Pirko25db6be2014-09-03 17:42:13 +02007049 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007050
7051 if (!selinux_enabled)
Jiri Pirko25db6be2014-09-03 17:42:13 +02007052 return 0;
Eric Parisfadcdb42007-02-22 18:11:31 -05007053
peter enderborgc103a912018-06-12 10:09:03 +02007054 pr_debug("SELinux: Registering netfilter hooks\n");
Eric Parisfadcdb42007-02-22 18:11:31 -05007055
Florian Westphal8e71bf72017-04-21 11:49:09 +02007056 err = register_pernet_subsys(&selinux_net_ops);
Alexey Dobriyan6c5a9d22008-07-26 17:48:15 -07007057 if (err)
Florian Westphal8e71bf72017-04-21 11:49:09 +02007058 panic("SELinux: register_pernet_subsys: error %d\n", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007059
Jiri Pirko25db6be2014-09-03 17:42:13 +02007060 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007061}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007062__initcall(selinux_nf_ip_init);
7063
7064#ifdef CONFIG_SECURITY_SELINUX_DISABLE
7065static void selinux_nf_ip_exit(void)
7066{
peter enderborgc103a912018-06-12 10:09:03 +02007067 pr_debug("SELinux: Unregistering netfilter hooks\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007068
Florian Westphal8e71bf72017-04-21 11:49:09 +02007069 unregister_pernet_subsys(&selinux_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007070}
7071#endif
7072
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08007073#else /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007074
7075#ifdef CONFIG_SECURITY_SELINUX_DISABLE
7076#define selinux_nf_ip_exit()
7077#endif
7078
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08007079#endif /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007080
7081#ifdef CONFIG_SECURITY_SELINUX_DISABLE
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007082int selinux_disable(struct selinux_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007083{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007084 if (state->initialized) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007085 /* Not permitted after initial policy load. */
7086 return -EINVAL;
7087 }
7088
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007089 if (state->disabled) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007090 /* Only do this once. */
7091 return -EINVAL;
7092 }
7093
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007094 state->disabled = 1;
7095
peter enderborgc103a912018-06-12 10:09:03 +02007096 pr_info("SELinux: Disabled at runtime.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007097
Stephen Smalley30d55282006-05-03 10:52:36 -04007098 selinux_enabled = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007099
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07007100 security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007101
Eric Parisaf8ff042009-09-20 21:23:01 -04007102 /* Try to destroy the avc node cache */
7103 avc_disable();
7104
Linus Torvalds1da177e2005-04-16 15:20:36 -07007105 /* Unregister netfilter hooks. */
7106 selinux_nf_ip_exit();
7107
7108 /* Unregister selinuxfs. */
7109 exit_sel_fs();
7110
7111 return 0;
7112}
7113#endif