blob: 4b64ad31326f6451ea2298860a6af0eb152b2b5f [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
Paul Moored621d352008-01-29 08:43:36 -0500148/**
149 * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
150 *
151 * Description:
152 * This function checks the SECMARK reference counter to see if any SECMARK
153 * targets are currently configured, if the reference counter is greater than
154 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
Chris PeBenito2be4d742013-05-03 09:05:39 -0400155 * enabled, false (0) if SECMARK is disabled. If the always_check_network
156 * policy capability is enabled, SECMARK is always considered enabled.
Paul Moored621d352008-01-29 08:43:36 -0500157 *
158 */
159static int selinux_secmark_enabled(void)
160{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500161 return (selinux_policycap_alwaysnetwork() ||
162 atomic_read(&selinux_secmark_refcount));
Chris PeBenito2be4d742013-05-03 09:05:39 -0400163}
164
165/**
166 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
167 *
168 * Description:
169 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
170 * (1) if any are enabled or false (0) if neither are enabled. If the
171 * always_check_network policy capability is enabled, peer labeling
172 * is always considered enabled.
173 *
174 */
175static int selinux_peerlbl_enabled(void)
176{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500177 return (selinux_policycap_alwaysnetwork() ||
178 netlbl_enabled() || selinux_xfrm_enabled());
Paul Moored621d352008-01-29 08:43:36 -0500179}
180
Paul Moore615e51f2014-06-26 14:33:56 -0400181static int selinux_netcache_avc_callback(u32 event)
182{
183 if (event == AVC_CALLBACK_RESET) {
184 sel_netif_flush();
185 sel_netnode_flush();
186 sel_netport_flush();
187 synchronize_net();
188 }
189 return 0;
190}
191
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300192static int selinux_lsm_notifier_avc_callback(u32 event)
193{
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300194 if (event == AVC_CALLBACK_RESET) {
195 sel_ib_pkey_flush();
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300196 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
Daniel Jurgens409dcf32017-05-19 15:48:59 +0300197 }
Daniel Jurgens8f408ab2017-05-19 15:48:53 +0300198
199 return 0;
200}
201
David Howellsd84f4f92008-11-14 10:39:23 +1100202/*
203 * initialise the security for the init task
204 */
205static void cred_init_security(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206{
David Howells3b11a1d2008-11-14 10:39:26 +1100207 struct cred *cred = (struct cred *) current->real_cred;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 struct task_security_struct *tsec;
209
Casey Schauflerbbd36622018-11-12 09:30:56 -0800210 lsm_early_cred(cred);
211 tsec = selinux_cred(cred);
David Howellsd84f4f92008-11-14 10:39:23 +1100212 tsec->osid = tsec->sid = SECINITSID_KERNEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213}
214
David Howells275bb412008-11-14 10:39:19 +1100215/*
David Howells88e67f32008-11-14 10:39:21 +1100216 * get the security ID of a set of credentials
217 */
218static inline u32 cred_sid(const struct cred *cred)
219{
220 const struct task_security_struct *tsec;
221
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700222 tsec = selinux_cred(cred);
David Howells88e67f32008-11-14 10:39:21 +1100223 return tsec->sid;
224}
225
226/*
David Howells3b11a1d2008-11-14 10:39:26 +1100227 * get the objective security ID of a task
David Howells275bb412008-11-14 10:39:19 +1100228 */
229static inline u32 task_sid(const struct task_struct *task)
230{
David Howells275bb412008-11-14 10:39:19 +1100231 u32 sid;
232
233 rcu_read_lock();
David Howells88e67f32008-11-14 10:39:21 +1100234 sid = cred_sid(__task_cred(task));
David Howells275bb412008-11-14 10:39:19 +1100235 rcu_read_unlock();
236 return sid;
237}
238
David Howells88e67f32008-11-14 10:39:21 +1100239/* Allocate and free functions for each kind of security blob. */
240
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241static int inode_alloc_security(struct inode *inode)
242{
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700243 struct inode_security_struct *isec = selinux_inode(inode);
David Howells275bb412008-11-14 10:39:19 +1100244 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +0100246 spin_lock_init(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 INIT_LIST_HEAD(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 isec->inode = inode;
249 isec->sid = SECINITSID_UNLABELED;
250 isec->sclass = SECCLASS_FILE;
David Howells275bb412008-11-14 10:39:19 +1100251 isec->task_sid = sid;
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100252 isec->initialized = LABEL_INVALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253
254 return 0;
255}
256
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500257static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
258
259/*
260 * Try reloading inode security labels that have been marked as invalid. The
261 * @may_sleep parameter indicates when sleeping and thus reloading labels is
Andreas Gruenbacher42059112016-11-10 22:18:27 +0100262 * allowed; when set to false, returns -ECHILD when the label is
Al Viroe9193282018-04-24 21:31:02 -0400263 * invalid. The @dentry parameter should be set to a dentry of the inode.
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500264 */
265static int __inode_security_revalidate(struct inode *inode,
Al Viroe9193282018-04-24 21:31:02 -0400266 struct dentry *dentry,
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500267 bool may_sleep)
268{
Casey Schaufler80788c22018-09-21 17:19:11 -0700269 struct inode_security_struct *isec = selinux_inode(inode);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500270
271 might_sleep_if(may_sleep);
272
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500273 if (selinux_state.initialized &&
274 isec->initialized != LABEL_INITIALIZED) {
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500275 if (!may_sleep)
276 return -ECHILD;
277
278 /*
279 * Try reloading the inode security label. This will fail if
280 * @opt_dentry is NULL and no dentry for this inode can be
281 * found; in that case, continue using the old label.
282 */
Al Viroe9193282018-04-24 21:31:02 -0400283 inode_doinit_with_dentry(inode, dentry);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500284 }
285 return 0;
286}
287
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500288static struct inode_security_struct *inode_security_novalidate(struct inode *inode)
289{
Casey Schaufler80788c22018-09-21 17:19:11 -0700290 return selinux_inode(inode);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500291}
292
293static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu)
294{
295 int error;
296
297 error = __inode_security_revalidate(inode, NULL, !rcu);
298 if (error)
299 return ERR_PTR(error);
Casey Schaufler80788c22018-09-21 17:19:11 -0700300 return selinux_inode(inode);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500301}
302
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500303/*
304 * Get the security label of an inode.
305 */
306static struct inode_security_struct *inode_security(struct inode *inode)
307{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500308 __inode_security_revalidate(inode, NULL, true);
Casey Schaufler80788c22018-09-21 17:19:11 -0700309 return selinux_inode(inode);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500310}
311
Paul Moore2c971652016-04-19 16:36:28 -0400312static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry)
313{
314 struct inode *inode = d_backing_inode(dentry);
315
Casey Schaufler80788c22018-09-21 17:19:11 -0700316 return selinux_inode(inode);
Paul Moore2c971652016-04-19 16:36:28 -0400317}
318
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500319/*
320 * Get the security label of a dentry's backing inode.
321 */
322static struct inode_security_struct *backing_inode_security(struct dentry *dentry)
323{
324 struct inode *inode = d_backing_inode(dentry);
325
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -0500326 __inode_security_revalidate(inode, dentry, true);
Casey Schaufler80788c22018-09-21 17:19:11 -0700327 return selinux_inode(inode);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500328}
329
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330static void inode_free_security(struct inode *inode)
331{
Casey Schaufler80788c22018-09-21 17:19:11 -0700332 struct inode_security_struct *isec = selinux_inode(inode);
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700333 struct superblock_security_struct *sbsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
Casey Schauflerafb1cbe32018-09-21 17:19:29 -0700335 if (!isec)
336 return;
337 sbsec = inode->i_sb->s_security;
Waiman Long9629d042015-07-10 17:19:56 -0400338 /*
339 * As not all inode security structures are in a list, we check for
340 * empty list outside of the lock to make sure that we won't waste
341 * time taking a lock doing nothing.
342 *
343 * The list_del_init() function can be safely called more than once.
344 * It should not be possible for this function to be called with
345 * concurrent list_add(), but for better safety against future changes
346 * in the code, we use list_empty_careful() here.
347 */
348 if (!list_empty_careful(&isec->list)) {
349 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 list_del_init(&isec->list);
Waiman Long9629d042015-07-10 17:19:56 -0400351 spin_unlock(&sbsec->isec_lock);
352 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353}
354
355static int file_alloc_security(struct file *file)
356{
Casey Schaufler33bf60c2018-11-12 12:02:49 -0800357 struct file_security_struct *fsec = selinux_file(file);
David Howells275bb412008-11-14 10:39:19 +1100358 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
David Howells275bb412008-11-14 10:39:19 +1100360 fsec->sid = sid;
361 fsec->fown_sid = sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362
363 return 0;
364}
365
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366static int superblock_alloc_security(struct super_block *sb)
367{
368 struct superblock_security_struct *sbsec;
369
James Morris89d155e2005-10-30 14:59:21 -0800370 sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 if (!sbsec)
372 return -ENOMEM;
373
Eric Parisbc7e9822006-09-25 23:32:02 -0700374 mutex_init(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 INIT_LIST_HEAD(&sbsec->isec_head);
376 spin_lock_init(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 sbsec->sb = sb;
378 sbsec->sid = SECINITSID_UNLABELED;
379 sbsec->def_sid = SECINITSID_FILE;
Eric Parisc312feb2006-07-10 04:43:53 -0700380 sbsec->mntpoint_sid = SECINITSID_UNLABELED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 sb->s_security = sbsec;
382
383 return 0;
384}
385
386static void superblock_free_security(struct super_block *sb)
387{
388 struct superblock_security_struct *sbsec = sb->s_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 sb->s_security = NULL;
390 kfree(sbsec);
391}
392
Al Virobd323652018-12-13 15:04:59 -0500393struct selinux_mnt_opts {
394 const char *fscontext, *context, *rootcontext, *defcontext;
395};
396
Al Viro204cc0c2018-12-13 13:41:47 -0500397static void selinux_free_mnt_opts(void *mnt_opts)
398{
Al Virobd323652018-12-13 15:04:59 -0500399 struct selinux_mnt_opts *opts = mnt_opts;
400 kfree(opts->fscontext);
401 kfree(opts->context);
402 kfree(opts->rootcontext);
403 kfree(opts->defcontext);
Al Viro204cc0c2018-12-13 13:41:47 -0500404 kfree(opts);
405}
406
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407static inline int inode_doinit(struct inode *inode)
408{
409 return inode_doinit_with_dentry(inode, NULL);
410}
411
412enum {
Eric Paris31e87932007-09-19 17:19:12 -0400413 Opt_error = -1,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 Opt_context = 1,
415 Opt_fscontext = 2,
Eric Parisc9180a52007-11-30 13:00:35 -0500416 Opt_defcontext = 3,
417 Opt_rootcontext = 4,
Al Viroda3d76a2018-12-17 10:14:16 -0500418 Opt_seclabel = 5,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419};
420
Al Viroda3d76a2018-12-17 10:14:16 -0500421#define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg}
Al Viro169d68efb2018-12-14 22:44:50 -0500422static struct {
423 const char *name;
424 int len;
425 int opt;
426 bool has_arg;
427} tokens[] = {
Al Viroda3d76a2018-12-17 10:14:16 -0500428 A(context, true),
429 A(fscontext, true),
430 A(defcontext, true),
431 A(rootcontext, true),
432 A(seclabel, false),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433};
Al Viro169d68efb2018-12-14 22:44:50 -0500434#undef A
435
436static int match_opt_prefix(char *s, int l, char **arg)
437{
438 int i;
439
440 for (i = 0; i < ARRAY_SIZE(tokens); i++) {
441 size_t len = tokens[i].len;
442 if (len > l || memcmp(s, tokens[i].name, len))
443 continue;
444 if (tokens[i].has_arg) {
445 if (len == l || s[len] != '=')
446 continue;
447 *arg = s + len + 1;
448 } else if (len != l)
449 continue;
450 return tokens[i].opt;
451 }
452 return Opt_error;
453}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454
455#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
456
Eric Parisc312feb2006-07-10 04:43:53 -0700457static int may_context_mount_sb_relabel(u32 sid,
458 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100459 const struct cred *cred)
Eric Parisc312feb2006-07-10 04:43:53 -0700460{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700461 const struct task_security_struct *tsec = selinux_cred(cred);
Eric Parisc312feb2006-07-10 04:43:53 -0700462 int rc;
463
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500464 rc = avc_has_perm(&selinux_state,
465 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700466 FILESYSTEM__RELABELFROM, NULL);
467 if (rc)
468 return rc;
469
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500470 rc = avc_has_perm(&selinux_state,
471 tsec->sid, sid, SECCLASS_FILESYSTEM,
Eric Parisc312feb2006-07-10 04:43:53 -0700472 FILESYSTEM__RELABELTO, NULL);
473 return rc;
474}
475
Eric Paris08089252006-07-10 04:43:55 -0700476static int may_context_mount_inode_relabel(u32 sid,
477 struct superblock_security_struct *sbsec,
David Howells275bb412008-11-14 10:39:19 +1100478 const struct cred *cred)
Eric Paris08089252006-07-10 04:43:55 -0700479{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -0700480 const struct task_security_struct *tsec = selinux_cred(cred);
Eric Paris08089252006-07-10 04:43:55 -0700481 int rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500482 rc = avc_has_perm(&selinux_state,
483 tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700484 FILESYSTEM__RELABELFROM, NULL);
485 if (rc)
486 return rc;
487
Stephen Smalley6b6bc622018-03-05 11:47:56 -0500488 rc = avc_has_perm(&selinux_state,
489 sid, sbsec->sid, SECCLASS_FILESYSTEM,
Eric Paris08089252006-07-10 04:43:55 -0700490 FILESYSTEM__ASSOCIATE, NULL);
491 return rc;
492}
493
Eric Parisb43e7252012-10-10 14:27:35 -0400494static int selinux_is_sblabel_mnt(struct super_block *sb)
495{
496 struct superblock_security_struct *sbsec = sb->s_security;
497
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500498 return sbsec->behavior == SECURITY_FS_USE_XATTR ||
499 sbsec->behavior == SECURITY_FS_USE_TRANS ||
500 sbsec->behavior == SECURITY_FS_USE_TASK ||
J. Bruce Fields9fc2b4b2015-06-04 15:57:25 -0400501 sbsec->behavior == SECURITY_FS_USE_NATIVE ||
Mark Salyzynd5f3a5f2015-02-04 11:34:30 -0500502 /* Special handling. Genfs but also in-core setxattr handler */
503 !strcmp(sb->s_type->name, "sysfs") ||
504 !strcmp(sb->s_type->name, "pstore") ||
505 !strcmp(sb->s_type->name, "debugfs") ||
Yongqin Liua2c7c6f2017-01-09 10:07:30 -0500506 !strcmp(sb->s_type->name, "tracefs") ||
Stephen Smalley2651225b2017-02-28 10:35:56 -0500507 !strcmp(sb->s_type->name, "rootfs") ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500508 (selinux_policycap_cgroupseclabel() &&
Stephen Smalley2651225b2017-02-28 10:35:56 -0500509 (!strcmp(sb->s_type->name, "cgroup") ||
510 !strcmp(sb->s_type->name, "cgroup2")));
Eric Parisb43e7252012-10-10 14:27:35 -0400511}
512
Eric Parisc9180a52007-11-30 13:00:35 -0500513static int sb_finish_set_opts(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514{
515 struct superblock_security_struct *sbsec = sb->s_security;
516 struct dentry *root = sb->s_root;
David Howellsc6f493d2015-03-17 22:26:22 +0000517 struct inode *root_inode = d_backing_inode(root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 int rc = 0;
519
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
521 /* Make sure that the xattr handler exists and that no
522 error other than -ENODATA is returned by getxattr on
523 the root directory. -ENODATA is ok, as this may be
524 the first boot of the SELinux kernel before we have
525 assigned xattr values to the filesystem. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200526 if (!(root_inode->i_opflags & IOP_XATTR)) {
peter enderborgc103a912018-06-12 10:09:03 +0200527 pr_warn("SELinux: (dev %s, type %s) has no "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800528 "xattr support\n", sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 rc = -EOPNOTSUPP;
530 goto out;
531 }
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +0200532
533 rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 if (rc < 0 && rc != -ENODATA) {
535 if (rc == -EOPNOTSUPP)
peter enderborgc103a912018-06-12 10:09:03 +0200536 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800537 "%s) has no security xattr handler\n",
538 sb->s_id, sb->s_type->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 else
peter enderborgc103a912018-06-12 10:09:03 +0200540 pr_warn("SELinux: (dev %s, type "
Linus Torvalds29b1deb2013-12-15 11:17:45 -0800541 "%s) getxattr errno %d\n", sb->s_id,
542 sb->s_type->name, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 goto out;
544 }
545 }
546
Eric Pariseadcabc2012-08-24 15:59:14 -0400547 sbsec->flags |= SE_SBINITIALIZED;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400548
549 /*
550 * Explicitly set or clear SBLABEL_MNT. It's not sufficient to simply
551 * leave the flag untouched because sb_clone_mnt_opts might be handing
552 * us a superblock that needs the flag to be cleared.
553 */
Eric Parisb43e7252012-10-10 14:27:35 -0400554 if (selinux_is_sblabel_mnt(sb))
Eric Paris12f348b2012-10-09 10:56:25 -0400555 sbsec->flags |= SBLABEL_MNT;
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400556 else
557 sbsec->flags &= ~SBLABEL_MNT;
David P. Quigleyddd29ec2009-09-09 14:25:37 -0400558
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 /* Initialize the root inode. */
Eric Parisc9180a52007-11-30 13:00:35 -0500560 rc = inode_doinit_with_dentry(root_inode, root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
562 /* Initialize any other inodes associated with the superblock, e.g.
563 inodes created prior to initial policy load or inodes created
564 during get_sb by a pseudo filesystem that directly
565 populates itself. */
566 spin_lock(&sbsec->isec_lock);
Al Viro8d641242018-12-10 15:34:12 -0500567 while (!list_empty(&sbsec->isec_head)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 struct inode_security_struct *isec =
Al Viro8d641242018-12-10 15:34:12 -0500569 list_first_entry(&sbsec->isec_head,
Eric Parisc9180a52007-11-30 13:00:35 -0500570 struct inode_security_struct, list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 struct inode *inode = isec->inode;
Stephen Smalley923190d2014-10-06 16:32:52 -0400572 list_del_init(&isec->list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 spin_unlock(&sbsec->isec_lock);
574 inode = igrab(inode);
575 if (inode) {
Eric Parisc9180a52007-11-30 13:00:35 -0500576 if (!IS_PRIVATE(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 inode_doinit(inode);
578 iput(inode);
579 }
580 spin_lock(&sbsec->isec_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 }
582 spin_unlock(&sbsec->isec_lock);
583out:
Eric Parisc9180a52007-11-30 13:00:35 -0500584 return rc;
585}
586
Eric Parisc9180a52007-11-30 13:00:35 -0500587static int bad_option(struct superblock_security_struct *sbsec, char flag,
588 u32 old_sid, u32 new_sid)
589{
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500590 char mnt_flags = sbsec->flags & SE_MNTMASK;
591
Eric Parisc9180a52007-11-30 13:00:35 -0500592 /* check if the old mount command had the same options */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500593 if (sbsec->flags & SE_SBINITIALIZED)
Eric Parisc9180a52007-11-30 13:00:35 -0500594 if (!(sbsec->flags & flag) ||
595 (old_sid != new_sid))
596 return 1;
597
598 /* check if we were passed the same options twice,
599 * aka someone passed context=a,context=b
600 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500601 if (!(sbsec->flags & SE_SBINITIALIZED))
602 if (mnt_flags & flag)
Eric Parisc9180a52007-11-30 13:00:35 -0500603 return 1;
604 return 0;
605}
Eric Parise0007522008-03-05 10:31:54 -0500606
Al Virobd323652018-12-13 15:04:59 -0500607static int parse_sid(struct super_block *sb, const char *s, u32 *sid)
608{
609 int rc = security_context_str_to_sid(&selinux_state, s,
610 sid, GFP_KERNEL);
611 if (rc)
612 pr_warn("SELinux: security_context_str_to_sid"
613 "(%s) failed for (dev %s, type %s) errno=%d\n",
614 s, sb->s_id, sb->s_type->name, rc);
615 return rc;
616}
617
Eric Parisc9180a52007-11-30 13:00:35 -0500618/*
619 * Allow filesystems with binary mount data to explicitly set mount point
620 * labeling information.
621 */
Eric Parise0007522008-03-05 10:31:54 -0500622static int selinux_set_mnt_opts(struct super_block *sb,
Al Viro204cc0c2018-12-13 13:41:47 -0500623 void *mnt_opts,
David Quigley649f6e72013-05-22 12:50:36 -0400624 unsigned long kern_flags,
625 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500626{
David Howells275bb412008-11-14 10:39:19 +1100627 const struct cred *cred = current_cred();
Eric Parisc9180a52007-11-30 13:00:35 -0500628 struct superblock_security_struct *sbsec = sb->s_security;
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500629 struct dentry *root = sbsec->sb->s_root;
Al Virobd323652018-12-13 15:04:59 -0500630 struct selinux_mnt_opts *opts = mnt_opts;
Paul Moore2c971652016-04-19 16:36:28 -0400631 struct inode_security_struct *root_isec;
Eric Parisc9180a52007-11-30 13:00:35 -0500632 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
633 u32 defcontext_sid = 0;
Al Virobd323652018-12-13 15:04:59 -0500634 int rc = 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500635
636 mutex_lock(&sbsec->lock);
637
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500638 if (!selinux_state.initialized) {
Al Virobd323652018-12-13 15:04:59 -0500639 if (!opts) {
Eric Parisc9180a52007-11-30 13:00:35 -0500640 /* Defer initialization until selinux_complete_init,
641 after the initial policy is loaded and the security
642 server is ready to handle calls. */
Eric Parisc9180a52007-11-30 13:00:35 -0500643 goto out;
644 }
645 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200646 pr_warn("SELinux: Unable to set superblock options "
Eric Paris744ba352008-04-17 11:52:44 -0400647 "before the security server is initialized\n");
Eric Parisc9180a52007-11-30 13:00:35 -0500648 goto out;
649 }
David Quigley649f6e72013-05-22 12:50:36 -0400650 if (kern_flags && !set_kern_flags) {
651 /* Specifying internal flags without providing a place to
652 * place the results is not allowed */
653 rc = -EINVAL;
654 goto out;
655 }
Eric Parisc9180a52007-11-30 13:00:35 -0500656
657 /*
Eric Parise0007522008-03-05 10:31:54 -0500658 * Binary mount data FS will come through this function twice. Once
659 * from an explicit call and once from the generic calls from the vfs.
660 * Since the generic VFS calls will not contain any security mount data
661 * we need to skip the double mount verification.
662 *
663 * This does open a hole in which we will not notice if the first
664 * mount using this sb set explict options and a second mount using
665 * this sb does not set any security options. (The first options
666 * will be used for both mounts)
667 */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500668 if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
Al Virobd323652018-12-13 15:04:59 -0500669 && !opts)
Eric Parisf5269712008-05-14 11:27:45 -0400670 goto out;
Eric Parise0007522008-03-05 10:31:54 -0500671
Paul Moore2c971652016-04-19 16:36:28 -0400672 root_isec = backing_inode_security_novalidate(root);
673
Eric Parise0007522008-03-05 10:31:54 -0500674 /*
Eric Parisc9180a52007-11-30 13:00:35 -0500675 * parse the mount options, check if they are valid sids.
676 * also check if someone is trying to mount the same sb more
677 * than once with different security options.
678 */
Al Virobd323652018-12-13 15:04:59 -0500679 if (opts) {
680 if (opts->fscontext) {
681 rc = parse_sid(sb, opts->fscontext, &fscontext_sid);
682 if (rc)
683 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500684 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
685 fscontext_sid))
686 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500687 sbsec->flags |= FSCONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500688 }
689 if (opts->context) {
690 rc = parse_sid(sb, opts->context, &context_sid);
691 if (rc)
692 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500693 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
694 context_sid))
695 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500696 sbsec->flags |= CONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500697 }
698 if (opts->rootcontext) {
699 rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid);
700 if (rc)
701 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500702 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
703 rootcontext_sid))
704 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500705 sbsec->flags |= ROOTCONTEXT_MNT;
Al Virobd323652018-12-13 15:04:59 -0500706 }
707 if (opts->defcontext) {
708 rc = parse_sid(sb, opts->defcontext, &defcontext_sid);
709 if (rc)
710 goto out;
Eric Parisc9180a52007-11-30 13:00:35 -0500711 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
712 defcontext_sid))
713 goto out_double_mount;
Eric Parisc9180a52007-11-30 13:00:35 -0500714 sbsec->flags |= DEFCONTEXT_MNT;
Eric Parisc9180a52007-11-30 13:00:35 -0500715 }
716 }
717
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500718 if (sbsec->flags & SE_SBINITIALIZED) {
Eric Parisc9180a52007-11-30 13:00:35 -0500719 /* previously mounted with options, but not on this attempt? */
Al Virobd323652018-12-13 15:04:59 -0500720 if ((sbsec->flags & SE_MNTMASK) && !opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500721 goto out_double_mount;
722 rc = 0;
723 goto out;
724 }
725
James Morris089be432008-07-15 18:32:49 +1000726 if (strcmp(sb->s_type->name, "proc") == 0)
Stephen Smalley134509d2015-06-04 16:22:17 -0400727 sbsec->flags |= SE_SBPROC | SE_SBGENFS;
728
Stephen Smalley8e014722015-06-04 16:22:17 -0400729 if (!strcmp(sb->s_type->name, "debugfs") ||
Jeff Vander Stoep6a391182017-06-20 09:35:33 -0700730 !strcmp(sb->s_type->name, "tracefs") ||
Stephen Smalley8e014722015-06-04 16:22:17 -0400731 !strcmp(sb->s_type->name, "sysfs") ||
Antonio Murdaca901ef842017-02-09 17:02:42 +0100732 !strcmp(sb->s_type->name, "pstore") ||
733 !strcmp(sb->s_type->name, "cgroup") ||
734 !strcmp(sb->s_type->name, "cgroup2"))
Stephen Smalley134509d2015-06-04 16:22:17 -0400735 sbsec->flags |= SE_SBGENFS;
Eric Parisc9180a52007-11-30 13:00:35 -0500736
David Quigleyeb9ae682013-05-22 12:50:37 -0400737 if (!sbsec->behavior) {
738 /*
739 * Determine the labeling behavior to use for this
740 * filesystem type.
741 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500742 rc = security_fs_use(&selinux_state, sb);
David Quigleyeb9ae682013-05-22 12:50:37 -0400743 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +0200744 pr_warn("%s: security_fs_use(%s) returned %d\n",
David Quigleyeb9ae682013-05-22 12:50:37 -0400745 __func__, sb->s_type->name, rc);
746 goto out;
747 }
Eric Parisc9180a52007-11-30 13:00:35 -0500748 }
Seth Forsheeaad82892016-04-26 14:36:20 -0500749
750 /*
Stephen Smalley01593d32017-01-09 10:07:31 -0500751 * If this is a user namespace mount and the filesystem type is not
752 * explicitly whitelisted, then no contexts are allowed on the command
753 * line and security labels must be ignored.
Seth Forsheeaad82892016-04-26 14:36:20 -0500754 */
Stephen Smalley01593d32017-01-09 10:07:31 -0500755 if (sb->s_user_ns != &init_user_ns &&
756 strcmp(sb->s_type->name, "tmpfs") &&
757 strcmp(sb->s_type->name, "ramfs") &&
758 strcmp(sb->s_type->name, "devpts")) {
Seth Forsheeaad82892016-04-26 14:36:20 -0500759 if (context_sid || fscontext_sid || rootcontext_sid ||
760 defcontext_sid) {
761 rc = -EACCES;
762 goto out;
763 }
764 if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
765 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500766 rc = security_transition_sid(&selinux_state,
767 current_sid(),
768 current_sid(),
Seth Forsheeaad82892016-04-26 14:36:20 -0500769 SECCLASS_FILE, NULL,
770 &sbsec->mntpoint_sid);
771 if (rc)
772 goto out;
773 }
774 goto out_set_opts;
775 }
776
Eric Parisc9180a52007-11-30 13:00:35 -0500777 /* sets the context of the superblock for the fs being mounted. */
778 if (fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100779 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500780 if (rc)
781 goto out;
782
783 sbsec->sid = fscontext_sid;
784 }
785
786 /*
787 * Switch to using mount point labeling behavior.
788 * sets the label used on all file below the mountpoint, and will set
789 * the superblock context if not already set.
790 */
David Quigleyeb9ae682013-05-22 12:50:37 -0400791 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
792 sbsec->behavior = SECURITY_FS_USE_NATIVE;
793 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
794 }
795
Eric Parisc9180a52007-11-30 13:00:35 -0500796 if (context_sid) {
797 if (!fscontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100798 rc = may_context_mount_sb_relabel(context_sid, sbsec,
799 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500800 if (rc)
801 goto out;
802 sbsec->sid = context_sid;
803 } else {
David Howells275bb412008-11-14 10:39:19 +1100804 rc = may_context_mount_inode_relabel(context_sid, sbsec,
805 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500806 if (rc)
807 goto out;
808 }
809 if (!rootcontext_sid)
810 rootcontext_sid = context_sid;
811
812 sbsec->mntpoint_sid = context_sid;
813 sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
814 }
815
816 if (rootcontext_sid) {
David Howells275bb412008-11-14 10:39:19 +1100817 rc = may_context_mount_inode_relabel(rootcontext_sid, sbsec,
818 cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500819 if (rc)
820 goto out;
821
822 root_isec->sid = rootcontext_sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -0500823 root_isec->initialized = LABEL_INITIALIZED;
Eric Parisc9180a52007-11-30 13:00:35 -0500824 }
825
826 if (defcontext_sid) {
David Quigleyeb9ae682013-05-22 12:50:37 -0400827 if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
828 sbsec->behavior != SECURITY_FS_USE_NATIVE) {
Eric Parisc9180a52007-11-30 13:00:35 -0500829 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200830 pr_warn("SELinux: defcontext option is "
Eric Parisc9180a52007-11-30 13:00:35 -0500831 "invalid for this filesystem type\n");
832 goto out;
833 }
834
835 if (defcontext_sid != sbsec->def_sid) {
836 rc = may_context_mount_inode_relabel(defcontext_sid,
David Howells275bb412008-11-14 10:39:19 +1100837 sbsec, cred);
Eric Parisc9180a52007-11-30 13:00:35 -0500838 if (rc)
839 goto out;
840 }
841
842 sbsec->def_sid = defcontext_sid;
843 }
844
Seth Forsheeaad82892016-04-26 14:36:20 -0500845out_set_opts:
Eric Parisc9180a52007-11-30 13:00:35 -0500846 rc = sb_finish_set_opts(sb);
847out:
Eric Parisbc7e9822006-09-25 23:32:02 -0700848 mutex_unlock(&sbsec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -0500850out_double_mount:
851 rc = -EINVAL;
peter enderborgc103a912018-06-12 10:09:03 +0200852 pr_warn("SELinux: mount invalid. Same superblock, different "
Al Virobd323652018-12-13 15:04:59 -0500853 "security settings for (dev %s, type %s)\n", sb->s_id,
854 sb->s_type->name);
Eric Parisc9180a52007-11-30 13:00:35 -0500855 goto out;
856}
857
Jeff Layton094f7b62013-04-01 08:14:24 -0400858static int selinux_cmp_sb_context(const struct super_block *oldsb,
859 const struct super_block *newsb)
860{
861 struct superblock_security_struct *old = oldsb->s_security;
862 struct superblock_security_struct *new = newsb->s_security;
863 char oldflags = old->flags & SE_MNTMASK;
864 char newflags = new->flags & SE_MNTMASK;
865
866 if (oldflags != newflags)
867 goto mismatch;
868 if ((oldflags & FSCONTEXT_MNT) && old->sid != new->sid)
869 goto mismatch;
870 if ((oldflags & CONTEXT_MNT) && old->mntpoint_sid != new->mntpoint_sid)
871 goto mismatch;
872 if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid)
873 goto mismatch;
874 if (oldflags & ROOTCONTEXT_MNT) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500875 struct inode_security_struct *oldroot = backing_inode_security(oldsb->s_root);
876 struct inode_security_struct *newroot = backing_inode_security(newsb->s_root);
Jeff Layton094f7b62013-04-01 08:14:24 -0400877 if (oldroot->sid != newroot->sid)
878 goto mismatch;
879 }
880 return 0;
881mismatch:
peter enderborgc103a912018-06-12 10:09:03 +0200882 pr_warn("SELinux: mount invalid. Same superblock, "
Jeff Layton094f7b62013-04-01 08:14:24 -0400883 "different security settings for (dev %s, "
884 "type %s)\n", newsb->s_id, newsb->s_type->name);
885 return -EBUSY;
886}
887
888static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400889 struct super_block *newsb,
890 unsigned long kern_flags,
891 unsigned long *set_kern_flags)
Eric Parisc9180a52007-11-30 13:00:35 -0500892{
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400893 int rc = 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500894 const struct superblock_security_struct *oldsbsec = oldsb->s_security;
895 struct superblock_security_struct *newsbsec = newsb->s_security;
896
897 int set_fscontext = (oldsbsec->flags & FSCONTEXT_MNT);
898 int set_context = (oldsbsec->flags & CONTEXT_MNT);
899 int set_rootcontext = (oldsbsec->flags & ROOTCONTEXT_MNT);
900
Eric Paris0f5e6422008-04-21 16:24:11 -0400901 /*
902 * if the parent was able to be mounted it clearly had no special lsm
Al Viroe8c26252010-03-23 06:36:54 -0400903 * mount options. thus we can safely deal with this superblock later
Eric Paris0f5e6422008-04-21 16:24:11 -0400904 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500905 if (!selinux_state.initialized)
Jeff Layton094f7b62013-04-01 08:14:24 -0400906 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500907
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400908 /*
909 * Specifying internal flags without providing a place to
910 * place the results is not allowed.
911 */
912 if (kern_flags && !set_kern_flags)
913 return -EINVAL;
914
Eric Parisc9180a52007-11-30 13:00:35 -0500915 /* how can we clone if the old one wasn't set up?? */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500916 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
Eric Parisc9180a52007-11-30 13:00:35 -0500917
Jeff Layton094f7b62013-04-01 08:14:24 -0400918 /* if fs is reusing a sb, make sure that the contexts match */
David P. Quigley0d90a7e2009-01-16 09:22:02 -0500919 if (newsbsec->flags & SE_SBINITIALIZED)
Jeff Layton094f7b62013-04-01 08:14:24 -0400920 return selinux_cmp_sb_context(oldsb, newsb);
Eric Paris5a552612008-04-09 14:08:35 -0400921
Eric Parisc9180a52007-11-30 13:00:35 -0500922 mutex_lock(&newsbsec->lock);
923
924 newsbsec->flags = oldsbsec->flags;
925
926 newsbsec->sid = oldsbsec->sid;
927 newsbsec->def_sid = oldsbsec->def_sid;
928 newsbsec->behavior = oldsbsec->behavior;
929
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400930 if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
931 !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -0500932 rc = security_fs_use(&selinux_state, newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400933 if (rc)
934 goto out;
935 }
936
937 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !set_context) {
938 newsbsec->behavior = SECURITY_FS_USE_NATIVE;
939 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
940 }
941
Eric Parisc9180a52007-11-30 13:00:35 -0500942 if (set_context) {
943 u32 sid = oldsbsec->mntpoint_sid;
944
945 if (!set_fscontext)
946 newsbsec->sid = sid;
947 if (!set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500948 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -0500949 newisec->sid = sid;
950 }
951 newsbsec->mntpoint_sid = sid;
952 }
953 if (set_rootcontext) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -0500954 const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root);
955 struct inode_security_struct *newisec = backing_inode_security(newsb->s_root);
Eric Parisc9180a52007-11-30 13:00:35 -0500956
957 newisec->sid = oldisec->sid;
958 }
959
960 sb_finish_set_opts(newsb);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400961out:
Eric Parisc9180a52007-11-30 13:00:35 -0500962 mutex_unlock(&newsbsec->lock);
Scott Mayhew0b4d3452017-06-05 11:45:04 -0400963 return rc;
Eric Parisc9180a52007-11-30 13:00:35 -0500964}
965
Al Viroba641862018-12-14 20:28:15 -0500966static int selinux_add_opt(int token, const char *s, void **mnt_opts)
Eric Parisc9180a52007-11-30 13:00:35 -0500967{
Al Viroba641862018-12-14 20:28:15 -0500968 struct selinux_mnt_opts *opts = *mnt_opts;
Eric Parisc9180a52007-11-30 13:00:35 -0500969
Al Viroda3d76a2018-12-17 10:14:16 -0500970 if (token == Opt_seclabel) /* eaten and completely ignored */
Al Viro169d68efb2018-12-14 22:44:50 -0500971 return 0;
Eric Parisc9180a52007-11-30 13:00:35 -0500972
Al Viroba641862018-12-14 20:28:15 -0500973 if (!opts) {
974 opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL);
975 if (!opts)
976 return -ENOMEM;
977 *mnt_opts = opts;
978 }
979 if (!s)
980 return -ENOMEM;
981 switch (token) {
982 case Opt_context:
983 if (opts->context || opts->defcontext)
984 goto Einval;
985 opts->context = s;
986 break;
987 case Opt_fscontext:
988 if (opts->fscontext)
989 goto Einval;
990 opts->fscontext = s;
991 break;
992 case Opt_rootcontext:
993 if (opts->rootcontext)
994 goto Einval;
995 opts->rootcontext = s;
996 break;
997 case Opt_defcontext:
998 if (opts->context || opts->defcontext)
999 goto Einval;
1000 opts->defcontext = s;
1001 break;
1002 }
1003 return 0;
1004Einval:
1005 pr_warn(SEL_MOUNT_FAIL_MSG);
Al Viroba641862018-12-14 20:28:15 -05001006 return -EINVAL;
1007}
Eric Parisc9180a52007-11-30 13:00:35 -05001008
Al Viro757cbe52018-12-14 23:42:21 -05001009static int selinux_add_mnt_opt(const char *option, const char *val, int len,
1010 void **mnt_opts)
Eric Parisc9180a52007-11-30 13:00:35 -05001011{
Al Viro757cbe52018-12-14 23:42:21 -05001012 int token = Opt_error;
1013 int rc, i;
Eric Parisc9180a52007-11-30 13:00:35 -05001014
Al Viro757cbe52018-12-14 23:42:21 -05001015 for (i = 0; i < ARRAY_SIZE(tokens); i++) {
1016 if (strcmp(option, tokens[i].name) == 0) {
1017 token = tokens[i].opt;
Eric Parisc9180a52007-11-30 13:00:35 -05001018 break;
Eric Parisc9180a52007-11-30 13:00:35 -05001019 }
1020 }
1021
Al Viro757cbe52018-12-14 23:42:21 -05001022 if (token == Opt_error)
1023 return -EINVAL;
Eric Parise0007522008-03-05 10:31:54 -05001024
Al Viro757cbe52018-12-14 23:42:21 -05001025 if (token != Opt_seclabel)
1026 val = kmemdup_nul(val, len, GFP_KERNEL);
1027 rc = selinux_add_opt(token, val, mnt_opts);
1028 if (unlikely(rc)) {
1029 kfree(val);
1030 if (*mnt_opts) {
1031 selinux_free_mnt_opts(*mnt_opts);
1032 *mnt_opts = NULL;
1033 }
1034 }
1035 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
Al Viroe3489f82018-12-13 00:24:36 -05001038static int show_sid(struct seq_file *m, u32 sid)
Eric Paris2069f452008-07-04 09:47:13 +10001039{
Al Viroe3489f82018-12-13 00:24:36 -05001040 char *context = NULL;
1041 u32 len;
1042 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043
Al Viroe3489f82018-12-13 00:24:36 -05001044 rc = security_sid_to_context(&selinux_state, sid,
1045 &context, &len);
1046 if (!rc) {
1047 bool has_comma = context && strchr(context, ',');
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
Eric Paris2069f452008-07-04 09:47:13 +10001049 if (has_comma)
1050 seq_putc(m, '\"');
Al Viroe3489f82018-12-13 00:24:36 -05001051 seq_escape(m, context, "\"\n\\");
Eric Paris2069f452008-07-04 09:47:13 +10001052 if (has_comma)
1053 seq_putc(m, '\"');
1054 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 kfree(context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 return rc;
1057}
Eric Paris2069f452008-07-04 09:47:13 +10001058
1059static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
1060{
Al Viroe3489f82018-12-13 00:24:36 -05001061 struct superblock_security_struct *sbsec = sb->s_security;
Eric Paris2069f452008-07-04 09:47:13 +10001062 int rc;
1063
Al Viroe3489f82018-12-13 00:24:36 -05001064 if (!(sbsec->flags & SE_SBINITIALIZED))
1065 return 0;
1066
1067 if (!selinux_state.initialized)
1068 return 0;
1069
1070 if (sbsec->flags & FSCONTEXT_MNT) {
1071 seq_putc(m, ',');
1072 seq_puts(m, FSCONTEXT_STR);
1073 rc = show_sid(m, sbsec->sid);
1074 if (rc)
1075 return rc;
Eric Paris383795c2008-07-29 17:07:26 -04001076 }
Al Viroe3489f82018-12-13 00:24:36 -05001077 if (sbsec->flags & CONTEXT_MNT) {
1078 seq_putc(m, ',');
1079 seq_puts(m, CONTEXT_STR);
1080 rc = show_sid(m, sbsec->mntpoint_sid);
1081 if (rc)
1082 return rc;
1083 }
1084 if (sbsec->flags & DEFCONTEXT_MNT) {
1085 seq_putc(m, ',');
1086 seq_puts(m, DEFCONTEXT_STR);
1087 rc = show_sid(m, sbsec->def_sid);
1088 if (rc)
1089 return rc;
1090 }
1091 if (sbsec->flags & ROOTCONTEXT_MNT) {
1092 struct dentry *root = sbsec->sb->s_root;
1093 struct inode_security_struct *isec = backing_inode_security(root);
1094 seq_putc(m, ',');
1095 seq_puts(m, ROOTCONTEXT_STR);
1096 rc = show_sid(m, isec->sid);
1097 if (rc)
1098 return rc;
1099 }
1100 if (sbsec->flags & SBLABEL_MNT) {
1101 seq_putc(m, ',');
1102 seq_puts(m, LABELSUPP_STR);
1103 }
1104 return 0;
Eric Paris2069f452008-07-04 09:47:13 +10001105}
1106
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107static inline u16 inode_mode_to_security_class(umode_t mode)
1108{
1109 switch (mode & S_IFMT) {
1110 case S_IFSOCK:
1111 return SECCLASS_SOCK_FILE;
1112 case S_IFLNK:
1113 return SECCLASS_LNK_FILE;
1114 case S_IFREG:
1115 return SECCLASS_FILE;
1116 case S_IFBLK:
1117 return SECCLASS_BLK_FILE;
1118 case S_IFDIR:
1119 return SECCLASS_DIR;
1120 case S_IFCHR:
1121 return SECCLASS_CHR_FILE;
1122 case S_IFIFO:
1123 return SECCLASS_FIFO_FILE;
1124
1125 }
1126
1127 return SECCLASS_FILE;
1128}
1129
James Morris13402582005-09-30 14:24:34 -04001130static inline int default_protocol_stream(int protocol)
1131{
1132 return (protocol == IPPROTO_IP || protocol == IPPROTO_TCP);
1133}
1134
1135static inline int default_protocol_dgram(int protocol)
1136{
1137 return (protocol == IPPROTO_IP || protocol == IPPROTO_UDP);
1138}
1139
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140static inline u16 socket_type_to_security_class(int family, int type, int protocol)
1141{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001142 int extsockclass = selinux_policycap_extsockclass();
Stephen Smalleyda69a532017-01-09 10:07:30 -05001143
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 switch (family) {
1145 case PF_UNIX:
1146 switch (type) {
1147 case SOCK_STREAM:
1148 case SOCK_SEQPACKET:
1149 return SECCLASS_UNIX_STREAM_SOCKET;
1150 case SOCK_DGRAM:
Luis Ressel2a764b52017-07-25 15:13:41 -04001151 case SOCK_RAW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 return SECCLASS_UNIX_DGRAM_SOCKET;
1153 }
1154 break;
1155 case PF_INET:
1156 case PF_INET6:
1157 switch (type) {
1158 case SOCK_STREAM:
Stephen Smalleyda69a532017-01-09 10:07:30 -05001159 case SOCK_SEQPACKET:
James Morris13402582005-09-30 14:24:34 -04001160 if (default_protocol_stream(protocol))
1161 return SECCLASS_TCP_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001162 else if (extsockclass && protocol == IPPROTO_SCTP)
1163 return SECCLASS_SCTP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001164 else
1165 return SECCLASS_RAWIP_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 case SOCK_DGRAM:
James Morris13402582005-09-30 14:24:34 -04001167 if (default_protocol_dgram(protocol))
1168 return SECCLASS_UDP_SOCKET;
Stephen Smalleyef379792017-01-09 10:07:31 -05001169 else if (extsockclass && (protocol == IPPROTO_ICMP ||
1170 protocol == IPPROTO_ICMPV6))
Stephen Smalleyda69a532017-01-09 10:07:30 -05001171 return SECCLASS_ICMP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001172 else
1173 return SECCLASS_RAWIP_SOCKET;
James Morris2ee92d42006-11-13 16:09:01 -08001174 case SOCK_DCCP:
1175 return SECCLASS_DCCP_SOCKET;
James Morris13402582005-09-30 14:24:34 -04001176 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 return SECCLASS_RAWIP_SOCKET;
1178 }
1179 break;
1180 case PF_NETLINK:
1181 switch (protocol) {
1182 case NETLINK_ROUTE:
1183 return SECCLASS_NETLINK_ROUTE_SOCKET;
Pavel Emelyanov7f1fb602011-12-06 07:56:43 +00001184 case NETLINK_SOCK_DIAG:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185 return SECCLASS_NETLINK_TCPDIAG_SOCKET;
1186 case NETLINK_NFLOG:
1187 return SECCLASS_NETLINK_NFLOG_SOCKET;
1188 case NETLINK_XFRM:
1189 return SECCLASS_NETLINK_XFRM_SOCKET;
1190 case NETLINK_SELINUX:
1191 return SECCLASS_NETLINK_SELINUX_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001192 case NETLINK_ISCSI:
1193 return SECCLASS_NETLINK_ISCSI_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 case NETLINK_AUDIT:
1195 return SECCLASS_NETLINK_AUDIT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001196 case NETLINK_FIB_LOOKUP:
1197 return SECCLASS_NETLINK_FIB_LOOKUP_SOCKET;
1198 case NETLINK_CONNECTOR:
1199 return SECCLASS_NETLINK_CONNECTOR_SOCKET;
1200 case NETLINK_NETFILTER:
1201 return SECCLASS_NETLINK_NETFILTER_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 case NETLINK_DNRTMSG:
1203 return SECCLASS_NETLINK_DNRT_SOCKET;
James Morris0c9b7942005-04-16 15:24:13 -07001204 case NETLINK_KOBJECT_UEVENT:
1205 return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET;
Stephen Smalley6c6d2e92015-06-04 16:22:16 -04001206 case NETLINK_GENERIC:
1207 return SECCLASS_NETLINK_GENERIC_SOCKET;
1208 case NETLINK_SCSITRANSPORT:
1209 return SECCLASS_NETLINK_SCSITRANSPORT_SOCKET;
1210 case NETLINK_RDMA:
1211 return SECCLASS_NETLINK_RDMA_SOCKET;
1212 case NETLINK_CRYPTO:
1213 return SECCLASS_NETLINK_CRYPTO_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 default:
1215 return SECCLASS_NETLINK_SOCKET;
1216 }
1217 case PF_PACKET:
1218 return SECCLASS_PACKET_SOCKET;
1219 case PF_KEY:
1220 return SECCLASS_KEY_SOCKET;
Christopher J. PeBenito3e3ff152006-06-09 00:25:03 -07001221 case PF_APPLETALK:
1222 return SECCLASS_APPLETALK_SOCKET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 }
1224
Stephen Smalleyda69a532017-01-09 10:07:30 -05001225 if (extsockclass) {
1226 switch (family) {
1227 case PF_AX25:
1228 return SECCLASS_AX25_SOCKET;
1229 case PF_IPX:
1230 return SECCLASS_IPX_SOCKET;
1231 case PF_NETROM:
1232 return SECCLASS_NETROM_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001233 case PF_ATMPVC:
1234 return SECCLASS_ATMPVC_SOCKET;
1235 case PF_X25:
1236 return SECCLASS_X25_SOCKET;
1237 case PF_ROSE:
1238 return SECCLASS_ROSE_SOCKET;
1239 case PF_DECnet:
1240 return SECCLASS_DECNET_SOCKET;
1241 case PF_ATMSVC:
1242 return SECCLASS_ATMSVC_SOCKET;
1243 case PF_RDS:
1244 return SECCLASS_RDS_SOCKET;
1245 case PF_IRDA:
1246 return SECCLASS_IRDA_SOCKET;
1247 case PF_PPPOX:
1248 return SECCLASS_PPPOX_SOCKET;
1249 case PF_LLC:
1250 return SECCLASS_LLC_SOCKET;
Stephen Smalleyda69a532017-01-09 10:07:30 -05001251 case PF_CAN:
1252 return SECCLASS_CAN_SOCKET;
1253 case PF_TIPC:
1254 return SECCLASS_TIPC_SOCKET;
1255 case PF_BLUETOOTH:
1256 return SECCLASS_BLUETOOTH_SOCKET;
1257 case PF_IUCV:
1258 return SECCLASS_IUCV_SOCKET;
1259 case PF_RXRPC:
1260 return SECCLASS_RXRPC_SOCKET;
1261 case PF_ISDN:
1262 return SECCLASS_ISDN_SOCKET;
1263 case PF_PHONET:
1264 return SECCLASS_PHONET_SOCKET;
1265 case PF_IEEE802154:
1266 return SECCLASS_IEEE802154_SOCKET;
1267 case PF_CAIF:
1268 return SECCLASS_CAIF_SOCKET;
1269 case PF_ALG:
1270 return SECCLASS_ALG_SOCKET;
1271 case PF_NFC:
1272 return SECCLASS_NFC_SOCKET;
1273 case PF_VSOCK:
1274 return SECCLASS_VSOCK_SOCKET;
1275 case PF_KCM:
1276 return SECCLASS_KCM_SOCKET;
1277 case PF_QIPCRTR:
1278 return SECCLASS_QIPCRTR_SOCKET;
Linus Torvalds3051bf32017-02-22 10:15:09 -08001279 case PF_SMC:
1280 return SECCLASS_SMC_SOCKET;
Björn Töpel68e8b842018-05-02 13:01:22 +02001281 case PF_XDP:
1282 return SECCLASS_XDP_SOCKET;
1283#if PF_MAX > 45
Stephen Smalleyda69a532017-01-09 10:07:30 -05001284#error New address family defined, please update this function.
1285#endif
1286 }
1287 }
1288
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 return SECCLASS_SOCKET;
1290}
1291
Stephen Smalley134509d2015-06-04 16:22:17 -04001292static int selinux_genfs_get_sid(struct dentry *dentry,
1293 u16 tclass,
1294 u16 flags,
1295 u32 *sid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296{
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001297 int rc;
Al Virofc640052016-04-10 01:33:30 -04001298 struct super_block *sb = dentry->d_sb;
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001299 char *buffer, *path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300
Eric Paris828dfe12008-04-17 13:17:49 -04001301 buffer = (char *)__get_free_page(GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302 if (!buffer)
1303 return -ENOMEM;
1304
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001305 path = dentry_path_raw(dentry, buffer, PAGE_SIZE);
1306 if (IS_ERR(path))
1307 rc = PTR_ERR(path);
1308 else {
Stephen Smalley134509d2015-06-04 16:22:17 -04001309 if (flags & SE_SBPROC) {
1310 /* each process gets a /proc/PID/ entry. Strip off the
1311 * PID part to get a valid selinux labeling.
1312 * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
1313 while (path[1] >= '0' && path[1] <= '9') {
1314 path[1] = '/';
1315 path++;
1316 }
Lucian Adrian Grijincu8e6c9692011-02-01 18:42:22 +02001317 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001318 rc = security_genfs_sid(&selinux_state, sb->s_type->name,
1319 path, tclass, sid);
Stephen Smalley7bb185e2018-09-04 16:51:36 -04001320 if (rc == -ENOENT) {
1321 /* No match in policy, mark as unlabeled. */
1322 *sid = SECINITSID_UNLABELED;
1323 rc = 0;
1324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 free_page((unsigned long)buffer);
1327 return rc;
1328}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329
1330/* The inode's security attributes must be initialized before first use. */
1331static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
1332{
1333 struct superblock_security_struct *sbsec = NULL;
Casey Schaufler80788c22018-09-21 17:19:11 -07001334 struct inode_security_struct *isec = selinux_inode(inode);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001335 u32 task_sid, sid = 0;
1336 u16 sclass;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 struct dentry *dentry;
1338#define INITCONTEXTLEN 255
1339 char *context = NULL;
1340 unsigned len = 0;
1341 int rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001343 if (isec->initialized == LABEL_INITIALIZED)
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001344 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001346 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05001347 if (isec->initialized == LABEL_INITIALIZED)
Eric Paris23970742006-09-25 23:32:01 -07001348 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349
Andreas Gruenbacher13457d02016-11-10 22:18:29 +01001350 if (isec->sclass == SECCLASS_FILE)
1351 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1352
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 sbsec = inode->i_sb->s_security;
David P. Quigley0d90a7e2009-01-16 09:22:02 -05001354 if (!(sbsec->flags & SE_SBINITIALIZED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 /* Defer initialization until selinux_complete_init,
1356 after the initial policy is loaded and the security
1357 server is ready to handle calls. */
1358 spin_lock(&sbsec->isec_lock);
1359 if (list_empty(&isec->list))
1360 list_add(&isec->list, &sbsec->isec_head);
1361 spin_unlock(&sbsec->isec_lock);
Eric Paris23970742006-09-25 23:32:01 -07001362 goto out_unlock;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 }
1364
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001365 sclass = isec->sclass;
1366 task_sid = isec->task_sid;
1367 sid = isec->sid;
1368 isec->initialized = LABEL_PENDING;
1369 spin_unlock(&isec->lock);
1370
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371 switch (sbsec->behavior) {
David Quigleyeb9ae682013-05-22 12:50:37 -04001372 case SECURITY_FS_USE_NATIVE:
1373 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 case SECURITY_FS_USE_XATTR:
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001375 if (!(inode->i_opflags & IOP_XATTR)) {
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001376 sid = sbsec->def_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 break;
1378 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 /* Need a dentry, since the xattr API requires one.
1380 Life would be simpler if we could just pass the inode. */
1381 if (opt_dentry) {
1382 /* Called from d_instantiate or d_splice_alias. */
1383 dentry = dget(opt_dentry);
1384 } else {
Al Virob1271252018-04-25 10:28:38 -04001385 /*
1386 * Called from selinux_complete_init, try to find a dentry.
1387 * Some filesystems really want a connected one, so try
1388 * that first. We could split SECURITY_FS_USE_XATTR in
1389 * two, depending upon that...
1390 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001392 if (!dentry)
1393 dentry = d_find_any_alias(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 }
1395 if (!dentry) {
Eric Parisdf7f54c2009-03-09 14:35:58 -04001396 /*
1397 * this is can be hit on boot when a file is accessed
1398 * before the policy is loaded. When we load policy we
1399 * may find inodes that have no dentry on the
1400 * sbsec->isec_head list. No reason to complain as these
1401 * will get fixed up the next time we go through
1402 * inode_doinit with a dentry, before these inodes could
1403 * be used again by userspace.
1404 */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001405 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 }
1407
1408 len = INITCONTEXTLEN;
Eric Paris4cb912f2009-02-12 14:50:05 -05001409 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 if (!context) {
1411 rc = -ENOMEM;
1412 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001413 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001415 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001416 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417 if (rc == -ERANGE) {
James Morris314dabb2009-08-10 22:00:13 +10001418 kfree(context);
1419
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 /* Need a larger buffer. Query for the right size. */
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001421 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 if (rc < 0) {
1423 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001424 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 len = rc;
Eric Paris4cb912f2009-02-12 14:50:05 -05001427 context = kmalloc(len+1, GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 if (!context) {
1429 rc = -ENOMEM;
1430 dput(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001431 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 }
Eric Paris4cb912f2009-02-12 14:50:05 -05001433 context[len] = '\0';
Andreas Gruenbacher5d6c3192016-09-29 17:48:42 +02001434 rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 }
1436 dput(dentry);
1437 if (rc < 0) {
1438 if (rc != -ENODATA) {
peter enderborgc103a912018-06-12 10:09:03 +02001439 pr_warn("SELinux: %s: getxattr returned "
Harvey Harrisondd6f9532008-03-06 10:03:59 +11001440 "%d for dev=%s ino=%ld\n", __func__,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 -rc, inode->i_sb->s_id, inode->i_ino);
1442 kfree(context);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001443 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 }
1445 /* Map ENODATA to the default file SID */
1446 sid = sbsec->def_sid;
1447 rc = 0;
1448 } else {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001449 rc = security_context_to_sid_default(&selinux_state,
1450 context, rc, &sid,
Stephen Smalley869ab512008-04-04 08:46:05 -04001451 sbsec->def_sid,
1452 GFP_NOFS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 if (rc) {
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001454 char *dev = inode->i_sb->s_id;
1455 unsigned long ino = inode->i_ino;
1456
1457 if (rc == -EINVAL) {
1458 if (printk_ratelimit())
peter enderborgc103a912018-06-12 10:09:03 +02001459 pr_notice("SELinux: inode=%lu on dev=%s was found to have an invalid "
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001460 "context=%s. This indicates you may need to relabel the inode or the "
1461 "filesystem in question.\n", ino, dev, context);
1462 } else {
peter enderborgc103a912018-06-12 10:09:03 +02001463 pr_warn("SELinux: %s: context_to_sid(%s) "
Eric Paris4ba0a8a2009-02-12 15:01:10 -05001464 "returned %d for dev=%s ino=%ld\n",
1465 __func__, context, -rc, dev, ino);
1466 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 kfree(context);
1468 /* Leave with the unlabeled SID */
1469 rc = 0;
1470 break;
1471 }
1472 }
1473 kfree(context);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 break;
1475 case SECURITY_FS_USE_TASK:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001476 sid = task_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 break;
1478 case SECURITY_FS_USE_TRANS:
1479 /* Default to the fs SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001480 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481
1482 /* Try to obtain a transition SID. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001483 rc = security_transition_sid(&selinux_state, task_sid, sid,
1484 sclass, NULL, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001486 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 break;
Eric Parisc312feb2006-07-10 04:43:53 -07001488 case SECURITY_FS_USE_MNTPOINT:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001489 sid = sbsec->mntpoint_sid;
Eric Parisc312feb2006-07-10 04:43:53 -07001490 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 default:
Eric Parisc312feb2006-07-10 04:43:53 -07001492 /* Default to the fs superblock SID. */
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001493 sid = sbsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494
Stephen Smalley134509d2015-06-04 16:22:17 -04001495 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
Paul Mooref64410e2014-03-19 16:46:18 -04001496 /* We must have a dentry to determine the label on
1497 * procfs inodes */
Al Virob1271252018-04-25 10:28:38 -04001498 if (opt_dentry) {
Paul Mooref64410e2014-03-19 16:46:18 -04001499 /* Called from d_instantiate or
1500 * d_splice_alias. */
1501 dentry = dget(opt_dentry);
Al Virob1271252018-04-25 10:28:38 -04001502 } else {
Paul Mooref64410e2014-03-19 16:46:18 -04001503 /* Called from selinux_complete_init, try to
Al Virob1271252018-04-25 10:28:38 -04001504 * find a dentry. Some filesystems really want
1505 * a connected one, so try that first.
1506 */
Paul Mooref64410e2014-03-19 16:46:18 -04001507 dentry = d_find_alias(inode);
Al Virob1271252018-04-25 10:28:38 -04001508 if (!dentry)
1509 dentry = d_find_any_alias(inode);
1510 }
Paul Mooref64410e2014-03-19 16:46:18 -04001511 /*
1512 * This can be hit on boot when a file is accessed
1513 * before the policy is loaded. When we load policy we
1514 * may find inodes that have no dentry on the
1515 * sbsec->isec_head list. No reason to complain as
1516 * these will get fixed up the next time we go through
1517 * inode_doinit() with a dentry, before these inodes
1518 * could be used again by userspace.
1519 */
1520 if (!dentry)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001521 goto out;
1522 rc = selinux_genfs_get_sid(dentry, sclass,
Stephen Smalley134509d2015-06-04 16:22:17 -04001523 sbsec->flags, &sid);
Paul Mooref64410e2014-03-19 16:46:18 -04001524 dput(dentry);
1525 if (rc)
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001526 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 }
1528 break;
1529 }
1530
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001531out:
1532 spin_lock(&isec->lock);
1533 if (isec->initialized == LABEL_PENDING) {
1534 if (!sid || rc) {
1535 isec->initialized = LABEL_INVALID;
1536 goto out_unlock;
1537 }
1538
1539 isec->initialized = LABEL_INITIALIZED;
1540 isec->sid = sid;
1541 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542
Eric Paris23970742006-09-25 23:32:01 -07001543out_unlock:
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01001544 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 return rc;
1546}
1547
1548/* Convert a Linux signal to an access vector. */
1549static inline u32 signal_to_av(int sig)
1550{
1551 u32 perm = 0;
1552
1553 switch (sig) {
1554 case SIGCHLD:
1555 /* Commonly granted from child to parent. */
1556 perm = PROCESS__SIGCHLD;
1557 break;
1558 case SIGKILL:
1559 /* Cannot be caught or ignored */
1560 perm = PROCESS__SIGKILL;
1561 break;
1562 case SIGSTOP:
1563 /* Cannot be caught or ignored */
1564 perm = PROCESS__SIGSTOP;
1565 break;
1566 default:
1567 /* All other signals. */
1568 perm = PROCESS__SIGNAL;
1569 break;
1570 }
1571
1572 return perm;
1573}
1574
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001575#if CAP_LAST_CAP > 63
1576#error Fix SELinux to handle capabilities > 63.
1577#endif
1578
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579/* Check whether a task is allowed to use a capability. */
Eric Paris6a9de492012-01-03 12:25:14 -05001580static int cred_has_capability(const struct cred *cred,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001581 int cap, int audit, bool initns)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582{
Thomas Liu2bf49692009-07-14 12:14:09 -04001583 struct common_audit_data ad;
Eric Paris06112162008-11-11 22:02:50 +11001584 struct av_decision avd;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001585 u16 sclass;
David Howells3699c532009-01-06 22:27:01 +00001586 u32 sid = cred_sid(cred);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001587 u32 av = CAP_TO_MASK(cap);
Eric Paris06112162008-11-11 22:02:50 +11001588 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589
Eric Paris50c205f2012-04-04 15:01:43 -04001590 ad.type = LSM_AUDIT_DATA_CAP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 ad.u.cap = cap;
1592
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001593 switch (CAP_TO_INDEX(cap)) {
1594 case 0:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001595 sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001596 break;
1597 case 1:
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04001598 sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001599 break;
1600 default:
peter enderborgc103a912018-06-12 10:09:03 +02001601 pr_err("SELinux: out of range capability %d\n", cap);
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001602 BUG();
Eric Parisa35c6c832011-04-20 10:21:28 -04001603 return -EINVAL;
Stephen Smalleyb68e4182008-02-07 11:21:04 -05001604 }
Eric Paris06112162008-11-11 22:02:50 +11001605
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001606 rc = avc_has_perm_noaudit(&selinux_state,
1607 sid, sid, sclass, av, 0, &avd);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001608 if (audit == SECURITY_CAP_AUDIT) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001609 int rc2 = avc_audit(&selinux_state,
1610 sid, sid, sclass, av, &avd, rc, &ad, 0);
Eric Paris9ade0cf2011-04-25 16:26:29 -04001611 if (rc2)
1612 return rc2;
1613 }
Eric Paris06112162008-11-11 22:02:50 +11001614 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615}
1616
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617/* Check whether a task has a particular permission to an inode.
1618 The 'adp' parameter is optional and allows other audit
1619 data to be passed (e.g. the dentry). */
David Howells88e67f32008-11-14 10:39:21 +11001620static int inode_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 struct inode *inode,
1622 u32 perms,
Linus Torvalds19e49832013-10-04 12:54:11 -07001623 struct common_audit_data *adp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 struct inode_security_struct *isec;
David Howells275bb412008-11-14 10:39:19 +11001626 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627
David Howellse0e81732009-09-02 09:13:40 +01001628 validate_creds(cred);
1629
Eric Paris828dfe12008-04-17 13:17:49 -04001630 if (unlikely(IS_PRIVATE(inode)))
Stephen Smalleybbaca6c2007-02-14 00:34:16 -08001631 return 0;
1632
David Howells88e67f32008-11-14 10:39:21 +11001633 sid = cred_sid(cred);
Casey Schaufler80788c22018-09-21 17:19:11 -07001634 isec = selinux_inode(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001636 return avc_has_perm(&selinux_state,
1637 sid, isec->sid, isec->sclass, perms, adp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638}
1639
1640/* Same as inode_has_perm, but pass explicit audit data containing
1641 the dentry to help the auditing code to more easily generate the
1642 pathname if needed. */
David Howells88e67f32008-11-14 10:39:21 +11001643static inline int dentry_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 struct dentry *dentry,
1645 u32 av)
1646{
David Howellsc6f493d2015-03-17 22:26:22 +00001647 struct inode *inode = d_backing_inode(dentry);
Thomas Liu2bf49692009-07-14 12:14:09 -04001648 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001649
Eric Paris50c205f2012-04-04 15:01:43 -04001650 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Paris2875fa02011-04-28 16:04:24 -04001651 ad.u.dentry = dentry;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001652 __inode_security_revalidate(inode, dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001653 return inode_has_perm(cred, inode, av, &ad);
Eric Paris2875fa02011-04-28 16:04:24 -04001654}
1655
1656/* Same as inode_has_perm, but pass explicit audit data containing
1657 the path to help the auditing code to more easily generate the
1658 pathname if needed. */
1659static inline int path_has_perm(const struct cred *cred,
Al Viro3f7036a2015-03-08 19:28:30 -04001660 const struct path *path,
Eric Paris2875fa02011-04-28 16:04:24 -04001661 u32 av)
1662{
David Howellsc6f493d2015-03-17 22:26:22 +00001663 struct inode *inode = d_backing_inode(path->dentry);
Eric Paris2875fa02011-04-28 16:04:24 -04001664 struct common_audit_data ad;
1665
Eric Paris50c205f2012-04-04 15:01:43 -04001666 ad.type = LSM_AUDIT_DATA_PATH;
Eric Paris2875fa02011-04-28 16:04:24 -04001667 ad.u.path = *path;
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05001668 __inode_security_revalidate(inode, path->dentry, true);
Linus Torvalds19e49832013-10-04 12:54:11 -07001669 return inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670}
1671
David Howells13f8e982013-06-13 23:37:55 +01001672/* Same as path_has_perm, but uses the inode from the file struct. */
1673static inline int file_path_has_perm(const struct cred *cred,
1674 struct file *file,
1675 u32 av)
1676{
1677 struct common_audit_data ad;
1678
Vivek Goyal43af5de2016-09-09 11:37:49 -04001679 ad.type = LSM_AUDIT_DATA_FILE;
1680 ad.u.file = file;
Linus Torvalds19e49832013-10-04 12:54:11 -07001681 return inode_has_perm(cred, file_inode(file), av, &ad);
David Howells13f8e982013-06-13 23:37:55 +01001682}
1683
Chenbo Fengf66e4482017-10-18 13:00:26 -07001684#ifdef CONFIG_BPF_SYSCALL
1685static int bpf_fd_pass(struct file *file, u32 sid);
1686#endif
1687
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688/* Check whether a task can use an open file descriptor to
1689 access an inode in a given way. Check access to the
1690 descriptor itself, and then use dentry_has_perm to
1691 check a particular permission to the file.
1692 Access to the descriptor is implicitly granted if it
1693 has the same SID as the process. If av is zero, then
1694 access to the file is not checked, e.g. for cases
1695 where only the descriptor is affected like seek. */
David Howells88e67f32008-11-14 10:39:21 +11001696static int file_has_perm(const struct cred *cred,
1697 struct file *file,
1698 u32 av)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699{
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07001700 struct file_security_struct *fsec = selinux_file(file);
Al Viro496ad9a2013-01-23 17:07:38 -05001701 struct inode *inode = file_inode(file);
Thomas Liu2bf49692009-07-14 12:14:09 -04001702 struct common_audit_data ad;
David Howells88e67f32008-11-14 10:39:21 +11001703 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 int rc;
1705
Vivek Goyal43af5de2016-09-09 11:37:49 -04001706 ad.type = LSM_AUDIT_DATA_FILE;
1707 ad.u.file = file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708
David Howells275bb412008-11-14 10:39:19 +11001709 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001710 rc = avc_has_perm(&selinux_state,
1711 sid, fsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 SECCLASS_FD,
1713 FD__USE,
1714 &ad);
1715 if (rc)
David Howells88e67f32008-11-14 10:39:21 +11001716 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 }
1718
Chenbo Fengf66e4482017-10-18 13:00:26 -07001719#ifdef CONFIG_BPF_SYSCALL
1720 rc = bpf_fd_pass(file, cred_sid(cred));
1721 if (rc)
1722 return rc;
1723#endif
1724
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 /* av is zero if only checking access to the descriptor. */
David Howells88e67f32008-11-14 10:39:21 +11001726 rc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 if (av)
Linus Torvalds19e49832013-10-04 12:54:11 -07001728 rc = inode_has_perm(cred, inode, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729
David Howells88e67f32008-11-14 10:39:21 +11001730out:
1731 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732}
1733
David Howellsc3c188b2015-07-10 17:19:58 -04001734/*
1735 * Determine the label for an inode that might be unioned.
1736 */
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001737static int
1738selinux_determine_inode_label(const struct task_security_struct *tsec,
1739 struct inode *dir,
1740 const struct qstr *name, u16 tclass,
1741 u32 *_new_isid)
David Howellsc3c188b2015-07-10 17:19:58 -04001742{
1743 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
David Howellsc3c188b2015-07-10 17:19:58 -04001744
1745 if ((sbsec->flags & SE_SBINITIALIZED) &&
1746 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
1747 *_new_isid = sbsec->mntpoint_sid;
1748 } else if ((sbsec->flags & SBLABEL_MNT) &&
1749 tsec->create_sid) {
1750 *_new_isid = tsec->create_sid;
1751 } else {
Paul Moore20cdef82016-04-04 14:14:42 -04001752 const struct inode_security_struct *dsec = inode_security(dir);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001753 return security_transition_sid(&selinux_state, tsec->sid,
1754 dsec->sid, tclass,
David Howellsc3c188b2015-07-10 17:19:58 -04001755 name, _new_isid);
1756 }
1757
1758 return 0;
1759}
1760
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761/* Check whether a task can create a file. */
1762static int may_create(struct inode *dir,
1763 struct dentry *dentry,
1764 u16 tclass)
1765{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07001766 const struct task_security_struct *tsec = selinux_cred(current_cred());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 struct inode_security_struct *dsec;
1768 struct superblock_security_struct *sbsec;
David Howells275bb412008-11-14 10:39:19 +11001769 u32 sid, newsid;
Thomas Liu2bf49692009-07-14 12:14:09 -04001770 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 int rc;
1772
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001773 dsec = inode_security(dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 sbsec = dir->i_sb->s_security;
1775
David Howells275bb412008-11-14 10:39:19 +11001776 sid = tsec->sid;
David Howells275bb412008-11-14 10:39:19 +11001777
Eric Paris50c205f2012-04-04 15:01:43 -04001778 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001779 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001781 rc = avc_has_perm(&selinux_state,
1782 sid, dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 DIR__ADD_NAME | DIR__SEARCH,
1784 &ad);
1785 if (rc)
1786 return rc;
1787
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07001788 rc = selinux_determine_inode_label(selinux_cred(current_cred()), dir,
Vivek Goyalc957f6d2016-07-13 10:44:51 -04001789 &dentry->d_name, tclass, &newsid);
David Howellsc3c188b2015-07-10 17:19:58 -04001790 if (rc)
1791 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001793 rc = avc_has_perm(&selinux_state,
1794 sid, newsid, tclass, FILE__CREATE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 if (rc)
1796 return rc;
1797
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001798 return avc_has_perm(&selinux_state,
1799 newsid, sbsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 SECCLASS_FILESYSTEM,
1801 FILESYSTEM__ASSOCIATE, &ad);
1802}
1803
Eric Paris828dfe12008-04-17 13:17:49 -04001804#define MAY_LINK 0
1805#define MAY_UNLINK 1
1806#define MAY_RMDIR 2
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807
1808/* Check whether a task can link, unlink, or rmdir a file/directory. */
1809static int may_link(struct inode *dir,
1810 struct dentry *dentry,
1811 int kind)
1812
1813{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 struct inode_security_struct *dsec, *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04001815 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11001816 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 u32 av;
1818 int rc;
1819
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001820 dsec = inode_security(dir);
1821 isec = backing_inode_security(dentry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822
Eric Paris50c205f2012-04-04 15:01:43 -04001823 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04001824 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
1826 av = DIR__SEARCH;
1827 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001828 rc = avc_has_perm(&selinux_state,
1829 sid, dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 if (rc)
1831 return rc;
1832
1833 switch (kind) {
1834 case MAY_LINK:
1835 av = FILE__LINK;
1836 break;
1837 case MAY_UNLINK:
1838 av = FILE__UNLINK;
1839 break;
1840 case MAY_RMDIR:
1841 av = DIR__RMDIR;
1842 break;
1843 default:
peter enderborgc103a912018-06-12 10:09:03 +02001844 pr_warn("SELinux: %s: unrecognized kind %d\n",
Eric Paris744ba352008-04-17 11:52:44 -04001845 __func__, kind);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 return 0;
1847 }
1848
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001849 rc = avc_has_perm(&selinux_state,
1850 sid, isec->sid, isec->sclass, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 return rc;
1852}
1853
1854static inline int may_rename(struct inode *old_dir,
1855 struct dentry *old_dentry,
1856 struct inode *new_dir,
1857 struct dentry *new_dentry)
1858{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04001860 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11001861 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 u32 av;
1863 int old_is_dir, new_is_dir;
1864 int rc;
1865
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001866 old_dsec = inode_security(old_dir);
1867 old_isec = backing_inode_security(old_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00001868 old_is_dir = d_is_dir(old_dentry);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001869 new_dsec = inode_security(new_dir);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870
Eric Paris50c205f2012-04-04 15:01:43 -04001871 ad.type = LSM_AUDIT_DATA_DENTRY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872
Eric Parisa2694342011-04-25 13:10:27 -04001873 ad.u.dentry = old_dentry;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001874 rc = avc_has_perm(&selinux_state,
1875 sid, old_dsec->sid, SECCLASS_DIR,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1877 if (rc)
1878 return rc;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001879 rc = avc_has_perm(&selinux_state,
1880 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 old_isec->sclass, FILE__RENAME, &ad);
1882 if (rc)
1883 return rc;
1884 if (old_is_dir && new_dir != old_dir) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001885 rc = avc_has_perm(&selinux_state,
1886 sid, old_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 old_isec->sclass, DIR__REPARENT, &ad);
1888 if (rc)
1889 return rc;
1890 }
1891
Eric Parisa2694342011-04-25 13:10:27 -04001892 ad.u.dentry = new_dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 av = DIR__ADD_NAME | DIR__SEARCH;
David Howells2c616d42015-01-29 12:02:33 +00001894 if (d_is_positive(new_dentry))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 av |= DIR__REMOVE_NAME;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001896 rc = avc_has_perm(&selinux_state,
1897 sid, new_dsec->sid, SECCLASS_DIR, av, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 if (rc)
1899 return rc;
David Howells2c616d42015-01-29 12:02:33 +00001900 if (d_is_positive(new_dentry)) {
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05001901 new_isec = backing_inode_security(new_dentry);
David Howellse36cb0b2015-01-29 12:02:35 +00001902 new_is_dir = d_is_dir(new_dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001903 rc = avc_has_perm(&selinux_state,
1904 sid, new_isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 new_isec->sclass,
1906 (new_is_dir ? DIR__RMDIR : FILE__UNLINK), &ad);
1907 if (rc)
1908 return rc;
1909 }
1910
1911 return 0;
1912}
1913
1914/* Check whether a task can perform a filesystem operation. */
David Howells88e67f32008-11-14 10:39:21 +11001915static int superblock_has_perm(const struct cred *cred,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 struct super_block *sb,
1917 u32 perms,
Thomas Liu2bf49692009-07-14 12:14:09 -04001918 struct common_audit_data *ad)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 struct superblock_security_struct *sbsec;
David Howells88e67f32008-11-14 10:39:21 +11001921 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 sbsec = sb->s_security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05001924 return avc_has_perm(&selinux_state,
1925 sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926}
1927
1928/* Convert a Linux mode and permission mask to an access vector. */
1929static inline u32 file_mask_to_av(int mode, int mask)
1930{
1931 u32 av = 0;
1932
Al Virodba19c62011-07-25 20:49:29 -04001933 if (!S_ISDIR(mode)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 if (mask & MAY_EXEC)
1935 av |= FILE__EXECUTE;
1936 if (mask & MAY_READ)
1937 av |= FILE__READ;
1938
1939 if (mask & MAY_APPEND)
1940 av |= FILE__APPEND;
1941 else if (mask & MAY_WRITE)
1942 av |= FILE__WRITE;
1943
1944 } else {
1945 if (mask & MAY_EXEC)
1946 av |= DIR__SEARCH;
1947 if (mask & MAY_WRITE)
1948 av |= DIR__WRITE;
1949 if (mask & MAY_READ)
1950 av |= DIR__READ;
1951 }
1952
1953 return av;
1954}
1955
1956/* Convert a Linux file to an access vector. */
1957static inline u32 file_to_av(struct file *file)
1958{
1959 u32 av = 0;
1960
1961 if (file->f_mode & FMODE_READ)
1962 av |= FILE__READ;
1963 if (file->f_mode & FMODE_WRITE) {
1964 if (file->f_flags & O_APPEND)
1965 av |= FILE__APPEND;
1966 else
1967 av |= FILE__WRITE;
1968 }
Stephen Smalley0794c662008-03-17 08:55:18 -04001969 if (!av) {
1970 /*
1971 * Special file opened with flags 3 for ioctl-only use.
1972 */
1973 av = FILE__IOCTL;
1974 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
1976 return av;
1977}
1978
Eric Paris8b6a5a32008-10-29 17:06:46 -04001979/*
1980 * Convert a file to an access vector and include the correct open
1981 * open permission.
1982 */
1983static inline u32 open_file_to_av(struct file *file)
1984{
1985 u32 av = file_to_av(file);
Stephen Smalleyccb54472017-05-12 12:41:24 -04001986 struct inode *inode = file_inode(file);
Eric Paris8b6a5a32008-10-29 17:06:46 -04001987
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05001988 if (selinux_policycap_openperm() &&
1989 inode->i_sb->s_magic != SOCKFS_MAGIC)
Eric Paris49b7b8d2010-07-23 11:44:09 -04001990 av |= FILE__OPEN;
1991
Eric Paris8b6a5a32008-10-29 17:06:46 -04001992 return av;
1993}
1994
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995/* Hook functions begin here. */
1996
Stephen Smalley79af7302015-01-21 10:54:10 -05001997static int selinux_binder_set_context_mgr(struct task_struct *mgr)
1998{
1999 u32 mysid = current_sid();
2000 u32 mgrsid = task_sid(mgr);
2001
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002002 return avc_has_perm(&selinux_state,
2003 mysid, mgrsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002004 BINDER__SET_CONTEXT_MGR, NULL);
2005}
2006
2007static int selinux_binder_transaction(struct task_struct *from,
2008 struct task_struct *to)
2009{
2010 u32 mysid = current_sid();
2011 u32 fromsid = task_sid(from);
2012 u32 tosid = task_sid(to);
2013 int rc;
2014
2015 if (mysid != fromsid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002016 rc = avc_has_perm(&selinux_state,
2017 mysid, fromsid, SECCLASS_BINDER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002018 BINDER__IMPERSONATE, NULL);
2019 if (rc)
2020 return rc;
2021 }
2022
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002023 return avc_has_perm(&selinux_state,
2024 fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
Stephen Smalley79af7302015-01-21 10:54:10 -05002025 NULL);
2026}
2027
2028static int selinux_binder_transfer_binder(struct task_struct *from,
2029 struct task_struct *to)
2030{
2031 u32 fromsid = task_sid(from);
2032 u32 tosid = task_sid(to);
2033
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002034 return avc_has_perm(&selinux_state,
2035 fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
Stephen Smalley79af7302015-01-21 10:54:10 -05002036 NULL);
2037}
2038
2039static int selinux_binder_transfer_file(struct task_struct *from,
2040 struct task_struct *to,
2041 struct file *file)
2042{
2043 u32 sid = task_sid(to);
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07002044 struct file_security_struct *fsec = selinux_file(file);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002045 struct dentry *dentry = file->f_path.dentry;
Paul Moore20cdef82016-04-04 14:14:42 -04002046 struct inode_security_struct *isec;
Stephen Smalley79af7302015-01-21 10:54:10 -05002047 struct common_audit_data ad;
2048 int rc;
2049
2050 ad.type = LSM_AUDIT_DATA_PATH;
2051 ad.u.path = file->f_path;
2052
2053 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002054 rc = avc_has_perm(&selinux_state,
2055 sid, fsec->sid,
Stephen Smalley79af7302015-01-21 10:54:10 -05002056 SECCLASS_FD,
2057 FD__USE,
2058 &ad);
2059 if (rc)
2060 return rc;
2061 }
2062
Chenbo Fengf66e4482017-10-18 13:00:26 -07002063#ifdef CONFIG_BPF_SYSCALL
2064 rc = bpf_fd_pass(file, sid);
2065 if (rc)
2066 return rc;
2067#endif
2068
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002069 if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
Stephen Smalley79af7302015-01-21 10:54:10 -05002070 return 0;
2071
Paul Moore20cdef82016-04-04 14:14:42 -04002072 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002073 return avc_has_perm(&selinux_state,
2074 sid, isec->sid, isec->sclass, file_to_av(file),
Stephen Smalley79af7302015-01-21 10:54:10 -05002075 &ad);
2076}
2077
Ingo Molnar9e488582009-05-07 19:26:19 +10002078static int selinux_ptrace_access_check(struct task_struct *child,
David Howells5cd9c582008-08-14 11:37:28 +01002079 unsigned int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002081 u32 sid = current_sid();
2082 u32 csid = task_sid(child);
Stephen Smalley006ebb42008-05-19 08:32:49 -04002083
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002084 if (mode & PTRACE_MODE_READ)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002085 return avc_has_perm(&selinux_state,
2086 sid, csid, SECCLASS_FILE, FILE__READ, NULL);
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002087
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002088 return avc_has_perm(&selinux_state,
2089 sid, csid, SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
David Howells5cd9c582008-08-14 11:37:28 +01002090}
2091
2092static int selinux_ptrace_traceme(struct task_struct *parent)
2093{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002094 return avc_has_perm(&selinux_state,
2095 task_sid(parent), current_sid(), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002096 PROCESS__PTRACE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097}
2098
2099static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
Eric Paris828dfe12008-04-17 13:17:49 -04002100 kernel_cap_t *inheritable, kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002102 return avc_has_perm(&selinux_state,
2103 current_sid(), task_sid(target), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002104 PROCESS__GETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105}
2106
David Howellsd84f4f92008-11-14 10:39:23 +11002107static int selinux_capset(struct cred *new, const struct cred *old,
2108 const kernel_cap_t *effective,
2109 const kernel_cap_t *inheritable,
2110 const kernel_cap_t *permitted)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002112 return avc_has_perm(&selinux_state,
2113 cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002114 PROCESS__SETCAP, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115}
2116
James Morris5626d3e2009-01-30 10:05:06 +11002117/*
2118 * (This comment used to live with the selinux_task_setuid hook,
2119 * which was removed).
2120 *
2121 * Since setuid only affects the current process, and since the SELinux
2122 * controls are not based on the Linux identity attributes, SELinux does not
2123 * need to control this operation. However, SELinux does control the use of
2124 * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
2125 */
2126
Eric Paris6a9de492012-01-03 12:25:14 -05002127static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
2128 int cap, int audit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129{
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04002130 return cred_has_capability(cred, cap, audit, ns == &init_user_ns);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131}
2132
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
2134{
David Howells88e67f32008-11-14 10:39:21 +11002135 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136 int rc = 0;
2137
2138 if (!sb)
2139 return 0;
2140
2141 switch (cmds) {
Eric Paris828dfe12008-04-17 13:17:49 -04002142 case Q_SYNC:
2143 case Q_QUOTAON:
2144 case Q_QUOTAOFF:
2145 case Q_SETINFO:
2146 case Q_SETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002147 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAMOD, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002148 break;
2149 case Q_GETFMT:
2150 case Q_GETINFO:
2151 case Q_GETQUOTA:
David Howells88e67f32008-11-14 10:39:21 +11002152 rc = superblock_has_perm(cred, sb, FILESYSTEM__QUOTAGET, NULL);
Eric Paris828dfe12008-04-17 13:17:49 -04002153 break;
2154 default:
2155 rc = 0; /* let the kernel handle invalid cmds */
2156 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157 }
2158 return rc;
2159}
2160
2161static int selinux_quota_on(struct dentry *dentry)
2162{
David Howells88e67f32008-11-14 10:39:21 +11002163 const struct cred *cred = current_cred();
2164
Eric Paris2875fa02011-04-28 16:04:24 -04002165 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166}
2167
Eric Paris12b30522010-11-15 18:36:29 -05002168static int selinux_syslog(int type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170 switch (type) {
Kees Cookd78ca3c2010-02-03 15:37:13 -08002171 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
2172 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002173 return avc_has_perm(&selinux_state,
2174 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002175 SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, NULL);
Kees Cookd78ca3c2010-02-03 15:37:13 -08002176 case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
2177 case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
2178 /* Set level of messages printed to console */
2179 case SYSLOG_ACTION_CONSOLE_LEVEL:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002180 return avc_has_perm(&selinux_state,
2181 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002182 SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE,
2183 NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184 }
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002185 /* All other syslog types */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002186 return avc_has_perm(&selinux_state,
2187 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002188 SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189}
2190
2191/*
2192 * Check that a process has enough memory to allocate a new virtual
2193 * mapping. 0 means there is enough memory for the allocation to
2194 * succeed and -ENOMEM implies there is not.
2195 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 * Do not audit the selinux permission check, as this is applied to all
2197 * processes that allocate mappings.
2198 */
Alan Cox34b4e4a2007-08-22 14:01:28 -07002199static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200{
2201 int rc, cap_sys_admin = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002203 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04002204 SECURITY_CAP_NOAUDIT, true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205 if (rc == 0)
2206 cap_sys_admin = 1;
2207
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07002208 return cap_sys_admin;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209}
2210
2211/* binprm security operations */
2212
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002213static u32 ptrace_parent_sid(void)
Paul Moore0c6181c2016-03-30 21:41:21 -04002214{
2215 u32 sid = 0;
2216 struct task_struct *tracer;
2217
2218 rcu_read_lock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002219 tracer = ptrace_parent(current);
Paul Moore0c6181c2016-03-30 21:41:21 -04002220 if (tracer)
2221 sid = task_sid(tracer);
2222 rcu_read_unlock();
2223
2224 return sid;
2225}
2226
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002227static int check_nnp_nosuid(const struct linux_binprm *bprm,
2228 const struct task_security_struct *old_tsec,
2229 const struct task_security_struct *new_tsec)
2230{
2231 int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
Andy Lutomirski380cf5b2016-06-23 16:41:05 -05002232 int nosuid = !mnt_may_suid(bprm->file->f_path.mnt);
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002233 int rc;
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002234 u32 av;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002235
2236 if (!nnp && !nosuid)
2237 return 0; /* neither NNP nor nosuid */
2238
2239 if (new_tsec->sid == old_tsec->sid)
2240 return 0; /* No change in credentials */
2241
2242 /*
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002243 * If the policy enables the nnp_nosuid_transition policy capability,
2244 * then we permit transitions under NNP or nosuid if the
2245 * policy allows the corresponding permission between
2246 * the old and new contexts.
2247 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002248 if (selinux_policycap_nnp_nosuid_transition()) {
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002249 av = 0;
2250 if (nnp)
2251 av |= PROCESS2__NNP_TRANSITION;
2252 if (nosuid)
2253 av |= PROCESS2__NOSUID_TRANSITION;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002254 rc = avc_has_perm(&selinux_state,
2255 old_tsec->sid, new_tsec->sid,
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002256 SECCLASS_PROCESS2, av, NULL);
2257 if (!rc)
2258 return 0;
2259 }
2260
2261 /*
2262 * We also permit NNP or nosuid transitions to bounded SIDs,
2263 * i.e. SIDs that are guaranteed to only be allowed a subset
2264 * of the permissions of the current SID.
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002265 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002266 rc = security_bounded_transition(&selinux_state, old_tsec->sid,
2267 new_tsec->sid);
Stephen Smalleyaf63f412017-07-31 10:12:46 -04002268 if (!rc)
2269 return 0;
2270
2271 /*
2272 * On failure, preserve the errno values for NNP vs nosuid.
2273 * NNP: Operation not permitted for caller.
2274 * nosuid: Permission denied to file.
2275 */
2276 if (nnp)
2277 return -EPERM;
2278 return -EACCES;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002279}
2280
David Howellsa6f76f22008-11-14 10:39:24 +11002281static int selinux_bprm_set_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282{
David Howellsa6f76f22008-11-14 10:39:24 +11002283 const struct task_security_struct *old_tsec;
2284 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 struct inode_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04002286 struct common_audit_data ad;
Al Viro496ad9a2013-01-23 17:07:38 -05002287 struct inode *inode = file_inode(bprm->file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 int rc;
2289
David Howellsa6f76f22008-11-14 10:39:24 +11002290 /* SELinux context only depends on initial program or script and not
2291 * the script interpreter */
Kees Cookddb4a142017-07-18 15:25:23 -07002292 if (bprm->called_set_creds)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 return 0;
2294
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002295 old_tsec = selinux_cred(current_cred());
2296 new_tsec = selinux_cred(bprm->cred);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05002297 isec = inode_security(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298
2299 /* Default to the current task SID. */
David Howellsa6f76f22008-11-14 10:39:24 +11002300 new_tsec->sid = old_tsec->sid;
2301 new_tsec->osid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302
Michael LeMay28eba5b2006-06-27 02:53:42 -07002303 /* Reset fs, key, and sock SIDs on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002304 new_tsec->create_sid = 0;
2305 new_tsec->keycreate_sid = 0;
2306 new_tsec->sockcreate_sid = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
David Howellsa6f76f22008-11-14 10:39:24 +11002308 if (old_tsec->exec_sid) {
2309 new_tsec->sid = old_tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310 /* Reset exec SID on execve. */
David Howellsa6f76f22008-11-14 10:39:24 +11002311 new_tsec->exec_sid = 0;
Andy Lutomirski259e5e62012-04-12 16:47:50 -05002312
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002313 /* Fail on NNP or nosuid if not an allowed transition. */
2314 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2315 if (rc)
2316 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317 } else {
2318 /* Check for a default transition on this program. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002319 rc = security_transition_sid(&selinux_state, old_tsec->sid,
2320 isec->sid, SECCLASS_PROCESS, NULL,
Eric Paris652bb9b2011-02-01 11:05:40 -05002321 &new_tsec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 if (rc)
2323 return rc;
Stephen Smalley7b0d0b42014-08-04 13:36:49 -04002324
2325 /*
2326 * Fallback to old SID on NNP or nosuid if not an allowed
2327 * transition.
2328 */
2329 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2330 if (rc)
2331 new_tsec->sid = old_tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 }
2333
Vivek Goyal43af5de2016-09-09 11:37:49 -04002334 ad.type = LSM_AUDIT_DATA_FILE;
2335 ad.u.file = bprm->file;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336
David Howellsa6f76f22008-11-14 10:39:24 +11002337 if (new_tsec->sid == old_tsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002338 rc = avc_has_perm(&selinux_state,
2339 old_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
2341 if (rc)
2342 return rc;
2343 } else {
2344 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002345 rc = avc_has_perm(&selinux_state,
2346 old_tsec->sid, new_tsec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347 SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
2348 if (rc)
2349 return rc;
2350
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002351 rc = avc_has_perm(&selinux_state,
2352 new_tsec->sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353 SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
2354 if (rc)
2355 return rc;
2356
David Howellsa6f76f22008-11-14 10:39:24 +11002357 /* Check for shared state */
2358 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002359 rc = avc_has_perm(&selinux_state,
2360 old_tsec->sid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002361 SECCLASS_PROCESS, PROCESS__SHARE,
2362 NULL);
2363 if (rc)
2364 return -EPERM;
2365 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366
David Howellsa6f76f22008-11-14 10:39:24 +11002367 /* Make sure that anyone attempting to ptrace over a task that
2368 * changes its SID has the appropriate permit */
Eric W. Biederman9227dd22017-01-23 17:26:31 +13002369 if (bprm->unsafe & LSM_UNSAFE_PTRACE) {
Stephen Smalleybe0554c2017-01-09 10:07:31 -05002370 u32 ptsid = ptrace_parent_sid();
David Howellsa6f76f22008-11-14 10:39:24 +11002371 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002372 rc = avc_has_perm(&selinux_state,
2373 ptsid, new_tsec->sid,
David Howellsa6f76f22008-11-14 10:39:24 +11002374 SECCLASS_PROCESS,
2375 PROCESS__PTRACE, NULL);
2376 if (rc)
2377 return -EPERM;
2378 }
2379 }
2380
2381 /* Clear any possibly unsafe personality bits on exec: */
2382 bprm->per_clear |= PER_CLEAR_ON_SETID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384 /* Enable secure mode for SIDs transitions unless
2385 the noatsecure permission is granted between
2386 the two SIDs, i.e. ahp returns 0. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002387 rc = avc_has_perm(&selinux_state,
2388 old_tsec->sid, new_tsec->sid,
Kees Cook62874c32017-07-18 15:25:25 -07002389 SECCLASS_PROCESS, PROCESS__NOATSECURE,
2390 NULL);
2391 bprm->secureexec |= !!rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392 }
2393
Kees Cook62874c32017-07-18 15:25:25 -07002394 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395}
2396
Al Viroc3c073f2012-08-21 22:32:06 -04002397static int match_file(const void *p, struct file *file, unsigned fd)
2398{
2399 return file_has_perm(p, file, file_to_av(file)) ? fd + 1 : 0;
2400}
2401
Linus Torvalds1da177e2005-04-16 15:20:36 -07002402/* Derived from fs/exec.c:flush_old_files. */
David Howells745ca242008-11-14 10:39:22 +11002403static inline void flush_unauthorized_files(const struct cred *cred,
2404 struct files_struct *files)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 struct file *file, *devnull = NULL;
Stephen Smalleyb20c8122006-09-25 23:32:03 -07002407 struct tty_struct *tty;
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002408 int drop_tty = 0;
Al Viroc3c073f2012-08-21 22:32:06 -04002409 unsigned n;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002411 tty = get_current_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412 if (tty) {
Peter Hurley4a510962016-01-09 21:35:23 -08002413 spin_lock(&tty->files_lock);
Eric Paris37dd0bd2008-10-31 17:40:00 -04002414 if (!list_empty(&tty->tty_files)) {
Nick Piggind996b622010-08-18 04:37:36 +10002415 struct tty_file_private *file_priv;
Eric Paris37dd0bd2008-10-31 17:40:00 -04002416
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417 /* Revalidate access to controlling tty.
David Howells13f8e982013-06-13 23:37:55 +01002418 Use file_path_has_perm on the tty path directly
2419 rather than using file_has_perm, as this particular
2420 open file may belong to another process and we are
2421 only interested in the inode-based check here. */
Nick Piggind996b622010-08-18 04:37:36 +10002422 file_priv = list_first_entry(&tty->tty_files,
2423 struct tty_file_private, list);
2424 file = file_priv->file;
David Howells13f8e982013-06-13 23:37:55 +01002425 if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE))
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002426 drop_tty = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 }
Peter Hurley4a510962016-01-09 21:35:23 -08002428 spin_unlock(&tty->files_lock);
Alan Cox452a00d2008-10-13 10:39:13 +01002429 tty_kref_put(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430 }
Eric W. Biederman98a27ba2007-05-08 00:26:56 -07002431 /* Reset controlling tty. */
2432 if (drop_tty)
2433 no_tty();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434
2435 /* Revalidate access to inherited open files. */
Al Viroc3c073f2012-08-21 22:32:06 -04002436 n = iterate_fd(files, 0, match_file, cred);
2437 if (!n) /* none found? */
2438 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439
Al Viroc3c073f2012-08-21 22:32:06 -04002440 devnull = dentry_open(&selinux_null, O_RDWR, cred);
Al Viro45525b22012-10-16 13:30:07 -04002441 if (IS_ERR(devnull))
2442 devnull = NULL;
2443 /* replace all the matching ones with this */
2444 do {
2445 replace_fd(n - 1, devnull, 0);
2446 } while ((n = iterate_fd(files, n, match_file, cred)) != 0);
2447 if (devnull)
Al Viroc3c073f2012-08-21 22:32:06 -04002448 fput(devnull);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449}
2450
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451/*
David Howellsa6f76f22008-11-14 10:39:24 +11002452 * Prepare a process for imminent new credential changes due to exec
Linus Torvalds1da177e2005-04-16 15:20:36 -07002453 */
David Howellsa6f76f22008-11-14 10:39:24 +11002454static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455{
David Howellsa6f76f22008-11-14 10:39:24 +11002456 struct task_security_struct *new_tsec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457 struct rlimit *rlim, *initrlim;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458 int rc, i;
2459
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002460 new_tsec = selinux_cred(bprm->cred);
David Howellsa6f76f22008-11-14 10:39:24 +11002461 if (new_tsec->sid == new_tsec->osid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462 return;
2463
2464 /* Close files for which the new task SID is not authorized. */
David Howellsa6f76f22008-11-14 10:39:24 +11002465 flush_unauthorized_files(bprm->cred, current->files);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002466
David Howellsa6f76f22008-11-14 10:39:24 +11002467 /* Always clear parent death signal on SID transitions. */
2468 current->pdeath_signal = 0;
2469
2470 /* Check whether the new SID can inherit resource limits from the old
2471 * SID. If not, reset all soft limits to the lower of the current
2472 * task's hard limit and the init task's soft limit.
2473 *
2474 * Note that the setting of hard limits (even to lower them) can be
2475 * controlled by the setrlimit check. The inclusion of the init task's
2476 * soft limit into the computation is to avoid resetting soft limits
2477 * higher than the default soft limit for cases where the default is
2478 * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
2479 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002480 rc = avc_has_perm(&selinux_state,
2481 new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
David Howellsa6f76f22008-11-14 10:39:24 +11002482 PROCESS__RLIMITINH, NULL);
2483 if (rc) {
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002484 /* protect against do_prlimit() */
2485 task_lock(current);
David Howellsa6f76f22008-11-14 10:39:24 +11002486 for (i = 0; i < RLIM_NLIMITS; i++) {
2487 rlim = current->signal->rlim + i;
2488 initrlim = init_task.signal->rlim + i;
2489 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2490 }
Oleg Nesteroveb2d55a2010-06-23 22:43:32 +02002491 task_unlock(current);
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002492 if (IS_ENABLED(CONFIG_POSIX_TIMERS))
2493 update_rlimit_cpu(current, rlimit(RLIMIT_CPU));
David Howellsa6f76f22008-11-14 10:39:24 +11002494 }
2495}
2496
2497/*
2498 * Clean up the process immediately after the installation of new credentials
2499 * due to exec
2500 */
2501static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2502{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002503 const struct task_security_struct *tsec = selinux_cred(current_cred());
David Howellsa6f76f22008-11-14 10:39:24 +11002504 struct itimerval itimer;
David Howellsa6f76f22008-11-14 10:39:24 +11002505 u32 osid, sid;
2506 int rc, i;
David Howellsa6f76f22008-11-14 10:39:24 +11002507
David Howellsa6f76f22008-11-14 10:39:24 +11002508 osid = tsec->osid;
2509 sid = tsec->sid;
2510
2511 if (sid == osid)
2512 return;
2513
2514 /* Check whether the new SID can inherit signal state from the old SID.
2515 * If not, clear itimers to avoid subsequent signal generation and
2516 * flush and unblock signals.
2517 *
2518 * This must occur _after_ the task SID has been updated so that any
2519 * kill done after the flush will be checked against the new SID.
2520 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002521 rc = avc_has_perm(&selinux_state,
2522 osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523 if (rc) {
Nicolas Pitrebaa73d92016-11-11 00:10:10 -05002524 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) {
2525 memset(&itimer, 0, sizeof itimer);
2526 for (i = 0; i < 3; i++)
2527 do_setitimer(i, &itimer, NULL);
2528 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 spin_lock_irq(&current->sighand->siglock);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002530 if (!fatal_signal_pending(current)) {
2531 flush_sigqueue(&current->pending);
2532 flush_sigqueue(&current->signal->shared_pending);
David Howells3bcac022009-04-29 13:45:05 +01002533 flush_signal_handlers(current, 1);
2534 sigemptyset(&current->blocked);
Oleg Nesterov9e7c8f82015-06-04 16:22:16 -04002535 recalc_sigpending();
David Howells3bcac022009-04-29 13:45:05 +01002536 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537 spin_unlock_irq(&current->sighand->siglock);
2538 }
2539
David Howellsa6f76f22008-11-14 10:39:24 +11002540 /* Wake up the parent if it is waiting so that it can recheck
2541 * wait permission to the new task SID. */
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002542 read_lock(&tasklist_lock);
Oleg Nesterov0b7570e2009-09-23 15:56:46 -07002543 __wake_up_parent(current, current->real_parent);
Oleg Nesterovecd6de32009-04-29 16:02:24 +02002544 read_unlock(&tasklist_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545}
2546
2547/* superblock security operations */
2548
2549static int selinux_sb_alloc_security(struct super_block *sb)
2550{
2551 return superblock_alloc_security(sb);
2552}
2553
2554static void selinux_sb_free_security(struct super_block *sb)
2555{
2556 superblock_free_security(sb);
2557}
2558
Al Viro99dbbb52018-12-14 21:56:23 -05002559static inline int opt_len(const char *s)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560{
Al Viro99dbbb52018-12-14 21:56:23 -05002561 bool open_quote = false;
2562 int len;
2563 char c;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564
Al Viro99dbbb52018-12-14 21:56:23 -05002565 for (len = 0; (c = s[len]) != '\0'; len++) {
2566 if (c == '"')
Cory Olmo3528a952006-09-29 01:58:44 -07002567 open_quote = !open_quote;
Al Viro99dbbb52018-12-14 21:56:23 -05002568 if (c == ',' && !open_quote)
2569 break;
2570 }
2571 return len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572}
2573
Al Viro204cc0c2018-12-13 13:41:47 -05002574static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts)
Eric Paris026eb162011-03-03 16:09:14 -05002575{
Al Viro99dbbb52018-12-14 21:56:23 -05002576 char *from = options;
2577 char *to = options;
2578 bool first = true;
Al Viro5b400232018-12-12 20:13:29 -05002579
Al Viro99dbbb52018-12-14 21:56:23 -05002580 while (1) {
2581 int len = opt_len(from);
2582 int token, rc;
2583 char *arg = NULL;
2584
2585 token = match_opt_prefix(from, len, &arg);
2586
2587 if (token != Opt_error) {
2588 char *p, *q;
2589
2590 /* strip quotes */
2591 if (arg) {
2592 for (p = q = arg; p < from + len; p++) {
2593 char c = *p;
2594 if (c != '"')
2595 *q++ = c;
2596 }
2597 arg = kmemdup_nul(arg, q - arg, GFP_KERNEL);
2598 }
2599 rc = selinux_add_opt(token, arg, mnt_opts);
2600 if (unlikely(rc)) {
2601 kfree(arg);
2602 if (*mnt_opts) {
2603 selinux_free_mnt_opts(*mnt_opts);
2604 *mnt_opts = NULL;
2605 }
2606 return rc;
2607 }
2608 } else {
2609 if (!first) { // copy with preceding comma
2610 from--;
2611 len++;
2612 }
2613 if (to != from)
2614 memmove(to, from, len);
2615 to += len;
2616 first = false;
2617 }
2618 if (!from[len])
2619 break;
2620 from += len + 1;
2621 }
2622 *to = '\0';
2623 return 0;
Al Viro5b400232018-12-12 20:13:29 -05002624}
2625
Al Viro204cc0c2018-12-13 13:41:47 -05002626static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
Eric Paris026eb162011-03-03 16:09:14 -05002627{
Al Virobd323652018-12-13 15:04:59 -05002628 struct selinux_mnt_opts *opts = mnt_opts;
Eric Paris026eb162011-03-03 16:09:14 -05002629 struct superblock_security_struct *sbsec = sb->s_security;
Al Virobd323652018-12-13 15:04:59 -05002630 u32 sid;
2631 int rc;
Eric Paris026eb162011-03-03 16:09:14 -05002632
2633 if (!(sbsec->flags & SE_SBINITIALIZED))
2634 return 0;
2635
Al Viro204cc0c2018-12-13 13:41:47 -05002636 if (!opts)
Eric Paris026eb162011-03-03 16:09:14 -05002637 return 0;
2638
Al Virobd323652018-12-13 15:04:59 -05002639 if (opts->fscontext) {
2640 rc = parse_sid(sb, opts->fscontext, &sid);
2641 if (rc)
Al Viroc039bc32018-12-01 23:06:57 -05002642 return rc;
Al Virobd323652018-12-13 15:04:59 -05002643 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
2644 goto out_bad_option;
Eric Paris026eb162011-03-03 16:09:14 -05002645 }
Al Virobd323652018-12-13 15:04:59 -05002646 if (opts->context) {
2647 rc = parse_sid(sb, opts->context, &sid);
2648 if (rc)
2649 return rc;
2650 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
2651 goto out_bad_option;
2652 }
2653 if (opts->rootcontext) {
2654 struct inode_security_struct *root_isec;
2655 root_isec = backing_inode_security(sb->s_root);
2656 rc = parse_sid(sb, opts->rootcontext, &sid);
2657 if (rc)
2658 return rc;
2659 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
2660 goto out_bad_option;
2661 }
2662 if (opts->defcontext) {
2663 rc = parse_sid(sb, opts->defcontext, &sid);
2664 if (rc)
2665 return rc;
2666 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
2667 goto out_bad_option;
Eric Paris026eb162011-03-03 16:09:14 -05002668 }
Al Viroc039bc32018-12-01 23:06:57 -05002669 return 0;
Eric Paris026eb162011-03-03 16:09:14 -05002670
Eric Paris026eb162011-03-03 16:09:14 -05002671out_bad_option:
peter enderborgc103a912018-06-12 10:09:03 +02002672 pr_warn("SELinux: unable to change security options "
Linus Torvalds29b1deb2013-12-15 11:17:45 -08002673 "during remount (dev %s, type=%s)\n", sb->s_id,
2674 sb->s_type->name);
Al Viroc039bc32018-12-01 23:06:57 -05002675 return -EINVAL;
Eric Paris026eb162011-03-03 16:09:14 -05002676}
2677
Al Viroa10d7c22018-12-05 11:58:35 -05002678static int selinux_sb_kern_mount(struct super_block *sb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679{
David Howells88e67f32008-11-14 10:39:21 +11002680 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002681 struct common_audit_data ad;
James Morris74192242008-12-19 11:41:10 +11002682
Eric Paris50c205f2012-04-04 15:01:43 -04002683 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002684 ad.u.dentry = sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002685 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686}
2687
David Howells726c3342006-06-23 02:02:58 -07002688static int selinux_sb_statfs(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002689{
David Howells88e67f32008-11-14 10:39:21 +11002690 const struct cred *cred = current_cred();
Thomas Liu2bf49692009-07-14 12:14:09 -04002691 struct common_audit_data ad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692
Eric Paris50c205f2012-04-04 15:01:43 -04002693 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04002694 ad.u.dentry = dentry->d_sb->s_root;
David Howells88e67f32008-11-14 10:39:21 +11002695 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696}
2697
Al Viro808d4e32012-10-11 11:42:01 -04002698static int selinux_mount(const char *dev_name,
Al Viro8a04c432016-03-25 14:52:53 -04002699 const struct path *path,
Al Viro808d4e32012-10-11 11:42:01 -04002700 const char *type,
Eric Paris828dfe12008-04-17 13:17:49 -04002701 unsigned long flags,
2702 void *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703{
David Howells88e67f32008-11-14 10:39:21 +11002704 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705
2706 if (flags & MS_REMOUNT)
Al Virod8c95842011-12-07 18:16:57 -05002707 return superblock_has_perm(cred, path->dentry->d_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002708 FILESYSTEM__REMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709 else
Eric Paris2875fa02011-04-28 16:04:24 -04002710 return path_has_perm(cred, path, FILE__MOUNTON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711}
2712
2713static int selinux_umount(struct vfsmount *mnt, int flags)
2714{
David Howells88e67f32008-11-14 10:39:21 +11002715 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716
David Howells88e67f32008-11-14 10:39:21 +11002717 return superblock_has_perm(cred, mnt->mnt_sb,
Eric Paris828dfe12008-04-17 13:17:49 -04002718 FILESYSTEM__UNMOUNT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719}
2720
2721/* inode security operations */
2722
2723static int selinux_inode_alloc_security(struct inode *inode)
2724{
2725 return inode_alloc_security(inode);
2726}
2727
2728static void selinux_inode_free_security(struct inode *inode)
2729{
2730 inode_free_security(inode);
2731}
2732
David Quigleyd47be3d2013-05-22 12:50:34 -04002733static int selinux_dentry_init_security(struct dentry *dentry, int mode,
Al Viro4f3ccd72016-07-20 16:06:15 -04002734 const struct qstr *name, void **ctx,
David Quigleyd47be3d2013-05-22 12:50:34 -04002735 u32 *ctxlen)
2736{
David Quigleyd47be3d2013-05-22 12:50:34 -04002737 u32 newsid;
2738 int rc;
2739
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002740 rc = selinux_determine_inode_label(selinux_cred(current_cred()),
Vivek Goyalc957f6d2016-07-13 10:44:51 -04002741 d_inode(dentry->d_parent), name,
David Howellsc3c188b2015-07-10 17:19:58 -04002742 inode_mode_to_security_class(mode),
2743 &newsid);
2744 if (rc)
2745 return rc;
David Quigleyd47be3d2013-05-22 12:50:34 -04002746
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002747 return security_sid_to_context(&selinux_state, newsid, (char **)ctx,
2748 ctxlen);
David Quigleyd47be3d2013-05-22 12:50:34 -04002749}
2750
Vivek Goyala518b0a2016-07-13 10:44:53 -04002751static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
2752 struct qstr *name,
2753 const struct cred *old,
2754 struct cred *new)
2755{
2756 u32 newsid;
2757 int rc;
2758 struct task_security_struct *tsec;
2759
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002760 rc = selinux_determine_inode_label(selinux_cred(old),
Vivek Goyala518b0a2016-07-13 10:44:53 -04002761 d_inode(dentry->d_parent), name,
2762 inode_mode_to_security_class(mode),
2763 &newsid);
2764 if (rc)
2765 return rc;
2766
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002767 tsec = selinux_cred(new);
Vivek Goyala518b0a2016-07-13 10:44:53 -04002768 tsec->create_sid = newsid;
2769 return 0;
2770}
2771
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002772static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
Tetsuo Handa95489062013-07-25 05:44:02 +09002773 const struct qstr *qstr,
2774 const char **name,
Eric Paris2a7dba32011-02-01 11:05:39 -05002775 void **value, size_t *len)
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002776{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002777 const struct task_security_struct *tsec = selinux_cred(current_cred());
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002778 struct superblock_security_struct *sbsec;
Corentin LABBEc0d4f462017-10-04 20:32:17 +02002779 u32 newsid, clen;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002780 int rc;
Tetsuo Handa95489062013-07-25 05:44:02 +09002781 char *context;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002782
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002783 sbsec = dir->i_sb->s_security;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002784
David Howells275bb412008-11-14 10:39:19 +11002785 newsid = tsec->create_sid;
2786
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07002787 rc = selinux_determine_inode_label(selinux_cred(current_cred()),
David Howellsc3c188b2015-07-10 17:19:58 -04002788 dir, qstr,
2789 inode_mode_to_security_class(inode->i_mode),
2790 &newsid);
2791 if (rc)
2792 return rc;
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002793
Eric Paris296fddf2006-09-25 23:32:00 -07002794 /* Possibly defer initialization to selinux_complete_init. */
David P. Quigley0d90a7e2009-01-16 09:22:02 -05002795 if (sbsec->flags & SE_SBINITIALIZED) {
Casey Schaufler80788c22018-09-21 17:19:11 -07002796 struct inode_security_struct *isec = selinux_inode(inode);
Eric Paris296fddf2006-09-25 23:32:00 -07002797 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2798 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05002799 isec->initialized = LABEL_INITIALIZED;
Eric Paris296fddf2006-09-25 23:32:00 -07002800 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002801
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002802 if (!selinux_state.initialized || !(sbsec->flags & SBLABEL_MNT))
Stephen Smalley25a74f32005-11-08 21:34:33 -08002803 return -EOPNOTSUPP;
2804
Tetsuo Handa95489062013-07-25 05:44:02 +09002805 if (name)
2806 *name = XATTR_SELINUX_SUFFIX;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002807
2808 if (value && len) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002809 rc = security_sid_to_context_force(&selinux_state, newsid,
2810 &context, &clen);
Tetsuo Handa95489062013-07-25 05:44:02 +09002811 if (rc)
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002812 return rc;
Stephen Smalley570bc1c2005-09-09 13:01:43 -07002813 *value = context;
2814 *len = clen;
2815 }
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002816
Stephen Smalley5e41ff92005-09-09 13:01:35 -07002817 return 0;
2818}
2819
Al Viro4acdaf22011-07-26 01:42:34 -04002820static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821{
2822 return may_create(dir, dentry, SECCLASS_FILE);
2823}
2824
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
2826{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 return may_link(dir, old_dentry, MAY_LINK);
2828}
2829
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
2831{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 return may_link(dir, dentry, MAY_UNLINK);
2833}
2834
2835static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
2836{
2837 return may_create(dir, dentry, SECCLASS_LNK_FILE);
2838}
2839
Al Viro18bb1db2011-07-26 01:41:39 -04002840static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, umode_t mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841{
2842 return may_create(dir, dentry, SECCLASS_DIR);
2843}
2844
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
2846{
2847 return may_link(dir, dentry, MAY_RMDIR);
2848}
2849
Al Viro1a67aaf2011-07-26 01:52:52 -04002850static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852 return may_create(dir, dentry, inode_mode_to_security_class(mode));
2853}
2854
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
Eric Paris828dfe12008-04-17 13:17:49 -04002856 struct inode *new_inode, struct dentry *new_dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857{
2858 return may_rename(old_inode, old_dentry, new_inode, new_dentry);
2859}
2860
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861static int selinux_inode_readlink(struct dentry *dentry)
2862{
David Howells88e67f32008-11-14 10:39:21 +11002863 const struct cred *cred = current_cred();
2864
Eric Paris2875fa02011-04-28 16:04:24 -04002865 return dentry_has_perm(cred, dentry, FILE__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866}
2867
NeilBrownbda0be72015-03-23 13:37:39 +11002868static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
2869 bool rcu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870{
David Howells88e67f32008-11-14 10:39:21 +11002871 const struct cred *cred = current_cred();
NeilBrownbda0be72015-03-23 13:37:39 +11002872 struct common_audit_data ad;
2873 struct inode_security_struct *isec;
2874 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875
NeilBrownbda0be72015-03-23 13:37:39 +11002876 validate_creds(cred);
2877
2878 ad.type = LSM_AUDIT_DATA_DENTRY;
2879 ad.u.dentry = dentry;
2880 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05002881 isec = inode_security_rcu(inode, rcu);
2882 if (IS_ERR(isec))
2883 return PTR_ERR(isec);
NeilBrownbda0be72015-03-23 13:37:39 +11002884
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002885 return avc_has_perm_flags(&selinux_state,
2886 sid, isec->sid, isec->sclass, FILE__READ, &ad,
NeilBrownbda0be72015-03-23 13:37:39 +11002887 rcu ? MAY_NOT_BLOCK : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888}
2889
Eric Parisd4cf970d2012-04-04 15:01:42 -04002890static noinline int audit_inode_permission(struct inode *inode,
2891 u32 perms, u32 audited, u32 denied,
Stephen Smalley626b9742014-04-29 11:29:04 -07002892 int result,
Eric Parisd4cf970d2012-04-04 15:01:42 -04002893 unsigned flags)
2894{
2895 struct common_audit_data ad;
Casey Schaufler80788c22018-09-21 17:19:11 -07002896 struct inode_security_struct *isec = selinux_inode(inode);
Eric Parisd4cf970d2012-04-04 15:01:42 -04002897 int rc;
2898
Eric Paris50c205f2012-04-04 15:01:43 -04002899 ad.type = LSM_AUDIT_DATA_INODE;
Eric Parisd4cf970d2012-04-04 15:01:42 -04002900 ad.u.inode = inode;
2901
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002902 rc = slow_avc_audit(&selinux_state,
2903 current_sid(), isec->sid, isec->sclass, perms,
Stephen Smalley626b9742014-04-29 11:29:04 -07002904 audited, denied, result, &ad, flags);
Eric Parisd4cf970d2012-04-04 15:01:42 -04002905 if (rc)
2906 return rc;
2907 return 0;
2908}
2909
Al Viroe74f71e2011-06-20 19:38:15 -04002910static int selinux_inode_permission(struct inode *inode, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911{
David Howells88e67f32008-11-14 10:39:21 +11002912 const struct cred *cred = current_cred();
Eric Parisb782e0a2010-07-23 11:44:03 -04002913 u32 perms;
2914 bool from_access;
Al Virocf1dd1d2011-06-20 19:44:08 -04002915 unsigned flags = mask & MAY_NOT_BLOCK;
Eric Paris2e334052012-04-04 15:01:42 -04002916 struct inode_security_struct *isec;
2917 u32 sid;
2918 struct av_decision avd;
2919 int rc, rc2;
2920 u32 audited, denied;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921
Eric Parisb782e0a2010-07-23 11:44:03 -04002922 from_access = mask & MAY_ACCESS;
Eric Parisd09ca732010-07-23 11:43:57 -04002923 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
2924
Eric Parisb782e0a2010-07-23 11:44:03 -04002925 /* No permission to check. Existence test. */
2926 if (!mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928
Eric Paris2e334052012-04-04 15:01:42 -04002929 validate_creds(cred);
Eric Parisb782e0a2010-07-23 11:44:03 -04002930
Eric Paris2e334052012-04-04 15:01:42 -04002931 if (unlikely(IS_PRIVATE(inode)))
2932 return 0;
Eric Parisb782e0a2010-07-23 11:44:03 -04002933
2934 perms = file_mask_to_av(inode->i_mode, mask);
2935
Eric Paris2e334052012-04-04 15:01:42 -04002936 sid = cred_sid(cred);
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05002937 isec = inode_security_rcu(inode, flags & MAY_NOT_BLOCK);
2938 if (IS_ERR(isec))
2939 return PTR_ERR(isec);
Eric Paris2e334052012-04-04 15:01:42 -04002940
Stephen Smalley6b6bc622018-03-05 11:47:56 -05002941 rc = avc_has_perm_noaudit(&selinux_state,
2942 sid, isec->sid, isec->sclass, perms, 0, &avd);
Eric Paris2e334052012-04-04 15:01:42 -04002943 audited = avc_audit_required(perms, &avd, rc,
2944 from_access ? FILE__AUDIT_ACCESS : 0,
2945 &denied);
2946 if (likely(!audited))
2947 return rc;
2948
Stephen Smalley626b9742014-04-29 11:29:04 -07002949 rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags);
Eric Paris2e334052012-04-04 15:01:42 -04002950 if (rc2)
2951 return rc2;
2952 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953}
2954
2955static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2956{
David Howells88e67f32008-11-14 10:39:21 +11002957 const struct cred *cred = current_cred();
Stephen Smalleyccb54472017-05-12 12:41:24 -04002958 struct inode *inode = d_backing_inode(dentry);
Amerigo Wangbc6a6002009-08-20 19:29:02 -07002959 unsigned int ia_valid = iattr->ia_valid;
Eric Paris95dbf732012-04-04 13:45:34 -04002960 __u32 av = FILE__WRITE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961
Amerigo Wangbc6a6002009-08-20 19:29:02 -07002962 /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
2963 if (ia_valid & ATTR_FORCE) {
2964 ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE |
2965 ATTR_FORCE);
2966 if (!ia_valid)
2967 return 0;
2968 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969
Amerigo Wangbc6a6002009-08-20 19:29:02 -07002970 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2971 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
Eric Paris2875fa02011-04-28 16:04:24 -04002972 return dentry_has_perm(cred, dentry, FILE__SETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05002974 if (selinux_policycap_openperm() &&
Stephen Smalleyccb54472017-05-12 12:41:24 -04002975 inode->i_sb->s_magic != SOCKFS_MAGIC &&
2976 (ia_valid & ATTR_SIZE) &&
2977 !(ia_valid & ATTR_FILE))
Eric Paris95dbf732012-04-04 13:45:34 -04002978 av |= FILE__OPEN;
2979
2980 return dentry_has_perm(cred, dentry, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981}
2982
Al Viro3f7036a2015-03-08 19:28:30 -04002983static int selinux_inode_getattr(const struct path *path)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984{
Al Viro3f7036a2015-03-08 19:28:30 -04002985 return path_has_perm(current_cred(), path, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986}
2987
Stephen Smalleydb590002017-04-20 11:31:30 -04002988static bool has_cap_mac_admin(bool audit)
2989{
2990 const struct cred *cred = current_cred();
2991 int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT;
2992
2993 if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit))
2994 return false;
2995 if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true))
2996 return false;
2997 return true;
2998}
2999
David Howells8f0cfa52008-04-29 00:59:41 -07003000static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3001 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002{
David Howellsc6f493d2015-03-17 22:26:22 +00003003 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003004 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 struct superblock_security_struct *sbsec;
Thomas Liu2bf49692009-07-14 12:14:09 -04003006 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11003007 u32 newsid, sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008 int rc = 0;
3009
Eric W. Biederman6b240302017-10-02 09:38:20 -05003010 if (strcmp(name, XATTR_NAME_SELINUX)) {
3011 rc = cap_inode_setxattr(dentry, name, value, size, flags);
3012 if (rc)
3013 return rc;
3014
3015 /* Not an attribute we recognize, so just check the
3016 ordinary setattr permission. */
3017 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3018 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003019
3020 sbsec = inode->i_sb->s_security;
Eric Paris12f348b2012-10-09 10:56:25 -04003021 if (!(sbsec->flags & SBLABEL_MNT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003022 return -EOPNOTSUPP;
3023
Serge E. Hallyn2e149672011-03-23 16:43:26 -07003024 if (!inode_owner_or_capable(inode))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003025 return -EPERM;
3026
Eric Paris50c205f2012-04-04 15:01:43 -04003027 ad.type = LSM_AUDIT_DATA_DENTRY;
Eric Parisa2694342011-04-25 13:10:27 -04003028 ad.u.dentry = dentry;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029
Paul Moore20cdef82016-04-04 14:14:42 -04003030 isec = backing_inode_security(dentry);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003031 rc = avc_has_perm(&selinux_state,
3032 sid, isec->sid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 FILE__RELABELFROM, &ad);
3034 if (rc)
3035 return rc;
3036
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003037 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3038 GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003039 if (rc == -EINVAL) {
Stephen Smalleydb590002017-04-20 11:31:30 -04003040 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04003041 struct audit_buffer *ab;
3042 size_t audit_size;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003043
3044 /* We strip a nul only if it is at the end, otherwise the
3045 * context contains a nul and we should audit that */
Al Viroe3fea3f2012-06-09 08:15:16 +01003046 if (value) {
Colin Ian Kingadd24372017-10-14 13:46:55 +01003047 const char *str = value;
3048
Al Viroe3fea3f2012-06-09 08:15:16 +01003049 if (str[size - 1] == '\0')
3050 audit_size = size - 1;
3051 else
3052 audit_size = size;
3053 } else {
Al Viroe3fea3f2012-06-09 08:15:16 +01003054 audit_size = 0;
3055 }
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04003056 ab = audit_log_start(audit_context(),
3057 GFP_ATOMIC, AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04003058 audit_log_format(ab, "op=setxattr invalid_context=");
3059 audit_log_n_untrustedstring(ab, value, audit_size);
3060 audit_log_end(ab);
3061
Stephen Smalley12b29f32008-05-07 13:03:20 -04003062 return rc;
Eric Parisd6ea83e2012-04-04 13:45:49 -04003063 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003064 rc = security_context_to_sid_force(&selinux_state, value,
3065 size, &newsid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04003066 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067 if (rc)
3068 return rc;
3069
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003070 rc = avc_has_perm(&selinux_state,
3071 sid, newsid, isec->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 FILE__RELABELTO, &ad);
3073 if (rc)
3074 return rc;
3075
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003076 rc = security_validate_transition(&selinux_state, isec->sid, newsid,
3077 sid, isec->sclass);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078 if (rc)
3079 return rc;
3080
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003081 return avc_has_perm(&selinux_state,
3082 newsid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003083 sbsec->sid,
3084 SECCLASS_FILESYSTEM,
3085 FILESYSTEM__ASSOCIATE,
3086 &ad);
3087}
3088
David Howells8f0cfa52008-04-29 00:59:41 -07003089static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
Eric Parisf5269712008-05-14 11:27:45 -04003090 const void *value, size_t size,
David Howells8f0cfa52008-04-29 00:59:41 -07003091 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003092{
David Howellsc6f493d2015-03-17 22:26:22 +00003093 struct inode *inode = d_backing_inode(dentry);
Paul Moore20cdef82016-04-04 14:14:42 -04003094 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003095 u32 newsid;
3096 int rc;
3097
3098 if (strcmp(name, XATTR_NAME_SELINUX)) {
3099 /* Not an attribute we recognize, so nothing to do. */
3100 return;
3101 }
3102
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003103 rc = security_context_to_sid_force(&selinux_state, value, size,
3104 &newsid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105 if (rc) {
peter enderborgc103a912018-06-12 10:09:03 +02003106 pr_err("SELinux: unable to map context to SID"
Stephen Smalley12b29f32008-05-07 13:03:20 -04003107 "for (%s, %lu), rc=%d\n",
3108 inode->i_sb->s_id, inode->i_ino, -rc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109 return;
3110 }
3111
Paul Moore20cdef82016-04-04 14:14:42 -04003112 isec = backing_inode_security(dentry);
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003113 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003114 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003116 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003117 spin_unlock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003118
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 return;
3120}
3121
David Howells8f0cfa52008-04-29 00:59:41 -07003122static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123{
David Howells88e67f32008-11-14 10:39:21 +11003124 const struct cred *cred = current_cred();
3125
Eric Paris2875fa02011-04-28 16:04:24 -04003126 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127}
3128
Eric Paris828dfe12008-04-17 13:17:49 -04003129static int selinux_inode_listxattr(struct dentry *dentry)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130{
David Howells88e67f32008-11-14 10:39:21 +11003131 const struct cred *cred = current_cred();
3132
Eric Paris2875fa02011-04-28 16:04:24 -04003133 return dentry_has_perm(cred, dentry, FILE__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134}
3135
David Howells8f0cfa52008-04-29 00:59:41 -07003136static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003137{
Eric W. Biederman6b240302017-10-02 09:38:20 -05003138 if (strcmp(name, XATTR_NAME_SELINUX)) {
3139 int rc = cap_inode_removexattr(dentry, name);
3140 if (rc)
3141 return rc;
3142
3143 /* Not an attribute we recognize, so just check the
3144 ordinary setattr permission. */
3145 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3146 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147
3148 /* No one is allowed to remove a SELinux security label.
3149 You can change the label, but all data must be labeled. */
3150 return -EACCES;
3151}
3152
James Morrisd381d8a2005-10-30 14:59:22 -08003153/*
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003154 * Copy the inode security context value to the user.
James Morrisd381d8a2005-10-30 14:59:22 -08003155 *
3156 * Permission check is handled by selinux_inode_getxattr hook.
3157 */
Andreas Gruenbacherea861df2015-12-24 11:09:39 -05003158static int selinux_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003159{
David P. Quigley42492592008-02-04 22:29:39 -08003160 u32 size;
3161 int error;
3162 char *context = NULL;
Paul Moore20cdef82016-04-04 14:14:42 -04003163 struct inode_security_struct *isec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00003165 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3166 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003168 /*
3169 * If the caller has CAP_MAC_ADMIN, then get the raw context
3170 * value even if it is not defined by current policy; otherwise,
3171 * use the in-core value under current policy.
3172 * Use the non-auditing forms of the permission checks since
3173 * getxattr may be called by unprivileged processes commonly
3174 * and lack of permission just means that we fall back to the
3175 * in-core context value, not a denial.
3176 */
Paul Moore20cdef82016-04-04 14:14:42 -04003177 isec = inode_security(inode);
Stephen Smalleydb590002017-04-20 11:31:30 -04003178 if (has_cap_mac_admin(false))
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003179 error = security_sid_to_context_force(&selinux_state,
3180 isec->sid, &context,
Stephen Smalleyabc69bb2008-05-21 14:16:12 -04003181 &size);
3182 else
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003183 error = security_sid_to_context(&selinux_state, isec->sid,
3184 &context, &size);
David P. Quigley42492592008-02-04 22:29:39 -08003185 if (error)
3186 return error;
3187 error = size;
3188 if (alloc) {
3189 *buffer = context;
3190 goto out_nofree;
3191 }
3192 kfree(context);
3193out_nofree:
3194 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195}
3196
3197static int selinux_inode_setsecurity(struct inode *inode, const char *name,
Eric Paris828dfe12008-04-17 13:17:49 -04003198 const void *value, size_t size, int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003199{
Paul Moore2c971652016-04-19 16:36:28 -04003200 struct inode_security_struct *isec = inode_security_novalidate(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003201 u32 newsid;
3202 int rc;
3203
3204 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3205 return -EOPNOTSUPP;
3206
3207 if (!value || !size)
3208 return -EACCES;
3209
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003210 rc = security_context_to_sid(&selinux_state, value, size, &newsid,
3211 GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003212 if (rc)
3213 return rc;
3214
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003215 spin_lock(&isec->lock);
David Quigleyaa9c2662013-05-22 12:50:44 -04003216 isec->sclass = inode_mode_to_security_class(inode->i_mode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003217 isec->sid = newsid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003218 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003219 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003220 return 0;
3221}
3222
3223static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
3224{
3225 const int len = sizeof(XATTR_NAME_SELINUX);
3226 if (buffer && len <= buffer_size)
3227 memcpy(buffer, XATTR_NAME_SELINUX, len);
3228 return len;
3229}
3230
Andreas Gruenbacherd6335d72015-12-24 11:09:39 -05003231static void selinux_inode_getsecid(struct inode *inode, u32 *secid)
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003232{
Andreas Gruenbachere817c2f2016-02-18 12:04:08 +01003233 struct inode_security_struct *isec = inode_security_novalidate(inode);
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02003234 *secid = isec->sid;
3235}
3236
Vivek Goyal56909eb2016-07-13 10:44:48 -04003237static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
3238{
3239 u32 sid;
3240 struct task_security_struct *tsec;
3241 struct cred *new_creds = *new;
3242
3243 if (new_creds == NULL) {
3244 new_creds = prepare_creds();
3245 if (!new_creds)
3246 return -ENOMEM;
3247 }
3248
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003249 tsec = selinux_cred(new_creds);
Vivek Goyal56909eb2016-07-13 10:44:48 -04003250 /* Get label from overlay inode and set it in create_sid */
3251 selinux_inode_getsecid(d_inode(src), &sid);
3252 tsec->create_sid = sid;
3253 *new = new_creds;
3254 return 0;
3255}
3256
Vivek Goyal19472b62016-07-13 10:44:50 -04003257static int selinux_inode_copy_up_xattr(const char *name)
3258{
3259 /* The copy_up hook above sets the initial context on an inode, but we
3260 * don't then want to overwrite it by blindly copying all the lower
3261 * xattrs up. Instead, we have to filter out SELinux-related xattrs.
3262 */
3263 if (strcmp(name, XATTR_NAME_SELINUX) == 0)
3264 return 1; /* Discard */
3265 /*
3266 * Any other attribute apart from SELINUX is not claimed, supported
3267 * by selinux.
3268 */
3269 return -EOPNOTSUPP;
3270}
3271
Linus Torvalds1da177e2005-04-16 15:20:36 -07003272/* file security operations */
3273
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003274static int selinux_revalidate_file_permission(struct file *file, int mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275{
David Howells88e67f32008-11-14 10:39:21 +11003276 const struct cred *cred = current_cred();
Al Viro496ad9a2013-01-23 17:07:38 -05003277 struct inode *inode = file_inode(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003278
Linus Torvalds1da177e2005-04-16 15:20:36 -07003279 /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */
3280 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
3281 mask |= MAY_APPEND;
3282
Paul Moore389fb8002009-03-27 17:10:34 -04003283 return file_has_perm(cred, file,
3284 file_mask_to_av(inode->i_mode, mask));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003285}
3286
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003287static int selinux_file_permission(struct file *file, int mask)
3288{
Al Viro496ad9a2013-01-23 17:07:38 -05003289 struct inode *inode = file_inode(file);
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003290 struct file_security_struct *fsec = selinux_file(file);
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003291 struct inode_security_struct *isec;
Stephen Smalley20dda182009-06-22 14:54:53 -04003292 u32 sid = current_sid();
3293
Paul Moore389fb8002009-03-27 17:10:34 -04003294 if (!mask)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003295 /* No permission to check. Existence test. */
3296 return 0;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003297
Andreas Gruenbacherb1973672016-01-05 23:12:33 +01003298 isec = inode_security(inode);
Stephen Smalley20dda182009-06-22 14:54:53 -04003299 if (sid == fsec->sid && fsec->isid == isec->sid &&
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003300 fsec->pseqno == avc_policy_seqno(&selinux_state))
Eric Paris83d49852012-04-04 13:45:40 -04003301 /* No change since file_open check. */
Stephen Smalley20dda182009-06-22 14:54:53 -04003302 return 0;
3303
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003304 return selinux_revalidate_file_permission(file, mask);
3305}
3306
Linus Torvalds1da177e2005-04-16 15:20:36 -07003307static int selinux_file_alloc_security(struct file *file)
3308{
3309 return file_alloc_security(file);
3310}
3311
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003312/*
3313 * Check whether a task has the ioctl permission and cmd
3314 * operation to an inode.
3315 */
Geliang Tang1d2a1682015-10-21 17:44:27 -04003316static int ioctl_has_perm(const struct cred *cred, struct file *file,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003317 u32 requested, u16 cmd)
3318{
3319 struct common_audit_data ad;
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003320 struct file_security_struct *fsec = selinux_file(file);
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003321 struct inode *inode = file_inode(file);
Paul Moore20cdef82016-04-04 14:14:42 -04003322 struct inode_security_struct *isec;
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003323 struct lsm_ioctlop_audit ioctl;
3324 u32 ssid = cred_sid(cred);
3325 int rc;
3326 u8 driver = cmd >> 8;
3327 u8 xperm = cmd & 0xff;
3328
3329 ad.type = LSM_AUDIT_DATA_IOCTL_OP;
3330 ad.u.op = &ioctl;
3331 ad.u.op->cmd = cmd;
3332 ad.u.op->path = file->f_path;
3333
3334 if (ssid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003335 rc = avc_has_perm(&selinux_state,
3336 ssid, fsec->sid,
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003337 SECCLASS_FD,
3338 FD__USE,
3339 &ad);
3340 if (rc)
3341 goto out;
3342 }
3343
3344 if (unlikely(IS_PRIVATE(inode)))
3345 return 0;
3346
Paul Moore20cdef82016-04-04 14:14:42 -04003347 isec = inode_security(inode);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003348 rc = avc_has_extended_perms(&selinux_state,
3349 ssid, isec->sid, isec->sclass,
3350 requested, driver, xperm, &ad);
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003351out:
3352 return rc;
3353}
3354
Linus Torvalds1da177e2005-04-16 15:20:36 -07003355static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3356 unsigned long arg)
3357{
David Howells88e67f32008-11-14 10:39:21 +11003358 const struct cred *cred = current_cred();
Eric Paris0b24dcb2011-02-25 15:39:20 -05003359 int error = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003360
Eric Paris0b24dcb2011-02-25 15:39:20 -05003361 switch (cmd) {
3362 case FIONREAD:
3363 /* fall through */
3364 case FIBMAP:
3365 /* fall through */
3366 case FIGETBSZ:
3367 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003368 case FS_IOC_GETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003369 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003370 case FS_IOC_GETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003371 error = file_has_perm(cred, file, FILE__GETATTR);
3372 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373
Al Viro2f99c362012-03-23 16:04:05 -04003374 case FS_IOC_SETFLAGS:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003375 /* fall through */
Al Viro2f99c362012-03-23 16:04:05 -04003376 case FS_IOC_SETVERSION:
Eric Paris0b24dcb2011-02-25 15:39:20 -05003377 error = file_has_perm(cred, file, FILE__SETATTR);
3378 break;
3379
3380 /* sys_ioctl() checks */
3381 case FIONBIO:
3382 /* fall through */
3383 case FIOASYNC:
3384 error = file_has_perm(cred, file, 0);
3385 break;
3386
3387 case KDSKBENT:
3388 case KDSKBSENT:
Eric Paris6a9de492012-01-03 12:25:14 -05003389 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
Stephen Smalley8e4ff6f2016-04-08 13:52:00 -04003390 SECURITY_CAP_AUDIT, true);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003391 break;
3392
3393 /* default case assumes that the command will go
3394 * to the file's ioctl() function.
3395 */
3396 default:
Jeff Vander Stoepfa1aa142015-07-10 17:19:56 -04003397 error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
Eric Paris0b24dcb2011-02-25 15:39:20 -05003398 }
3399 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003400}
3401
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003402static int default_noexec;
3403
Linus Torvalds1da177e2005-04-16 15:20:36 -07003404static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
3405{
David Howells88e67f32008-11-14 10:39:21 +11003406 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003407 u32 sid = cred_sid(cred);
David Howellsd84f4f92008-11-14 10:39:23 +11003408 int rc = 0;
David Howells88e67f32008-11-14 10:39:21 +11003409
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003410 if (default_noexec &&
Stephen Smalley892e8ca2015-07-10 09:40:59 -04003411 (prot & PROT_EXEC) && (!file || IS_PRIVATE(file_inode(file)) ||
3412 (!shared && (prot & PROT_WRITE)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413 /*
3414 * We are making executable an anonymous mapping or a
3415 * private file mapping that will also be writable.
3416 * This has an additional check.
3417 */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003418 rc = avc_has_perm(&selinux_state,
3419 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003420 PROCESS__EXECMEM, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421 if (rc)
David Howellsd84f4f92008-11-14 10:39:23 +11003422 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003424
3425 if (file) {
3426 /* read access is always possible with a mapping */
3427 u32 av = FILE__READ;
3428
3429 /* write access only matters if the mapping is shared */
3430 if (shared && (prot & PROT_WRITE))
3431 av |= FILE__WRITE;
3432
3433 if (prot & PROT_EXEC)
3434 av |= FILE__EXECUTE;
3435
David Howells88e67f32008-11-14 10:39:21 +11003436 return file_has_perm(cred, file, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003437 }
David Howellsd84f4f92008-11-14 10:39:23 +11003438
3439error:
3440 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003441}
3442
Al Viroe5467852012-05-30 13:30:51 -04003443static int selinux_mmap_addr(unsigned long addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003444{
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07003445 int rc = 0;
Paul Moore98883bf2014-03-19 16:46:11 -04003446
3447 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
3448 u32 sid = current_sid();
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003449 rc = avc_has_perm(&selinux_state,
3450 sid, sid, SECCLASS_MEMPROTECT,
Paul Moore98883bf2014-03-19 16:46:11 -04003451 MEMPROTECT__MMAP_ZERO, NULL);
3452 }
3453
3454 return rc;
Al Viroe5467852012-05-30 13:30:51 -04003455}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003456
Al Viroe5467852012-05-30 13:30:51 -04003457static int selinux_mmap_file(struct file *file, unsigned long reqprot,
3458 unsigned long prot, unsigned long flags)
3459{
Stephen Smalley3ba4bf52017-05-05 09:14:48 -04003460 struct common_audit_data ad;
3461 int rc;
3462
3463 if (file) {
3464 ad.type = LSM_AUDIT_DATA_FILE;
3465 ad.u.file = file;
3466 rc = inode_has_perm(current_cred(), file_inode(file),
3467 FILE__MAP, &ad);
3468 if (rc)
3469 return rc;
3470 }
3471
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003472 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003473 prot = reqprot;
3474
3475 return file_map_prot_check(file, prot,
3476 (flags & MAP_TYPE) == MAP_SHARED);
3477}
3478
3479static int selinux_file_mprotect(struct vm_area_struct *vma,
3480 unsigned long reqprot,
3481 unsigned long prot)
3482{
David Howells88e67f32008-11-14 10:39:21 +11003483 const struct cred *cred = current_cred();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003484 u32 sid = cred_sid(cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003485
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05003486 if (selinux_state.checkreqprot)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003487 prot = reqprot;
3488
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04003489 if (default_noexec &&
3490 (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
James Morrisd541bbe2009-01-29 12:19:51 +11003491 int rc = 0;
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003492 if (vma->vm_start >= vma->vm_mm->start_brk &&
3493 vma->vm_end <= vma->vm_mm->brk) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003494 rc = avc_has_perm(&selinux_state,
3495 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003496 PROCESS__EXECHEAP, NULL);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003497 } else if (!vma->vm_file &&
Stephen Smalleyc2316db2016-04-08 13:55:03 -04003498 ((vma->vm_start <= vma->vm_mm->start_stack &&
3499 vma->vm_end >= vma->vm_mm->start_stack) ||
Andy Lutomirskid17af502016-09-30 10:58:58 -07003500 vma_is_stack_for_current(vma))) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003501 rc = avc_has_perm(&selinux_state,
3502 sid, sid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003503 PROCESS__EXECSTACK, NULL);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003504 } else if (vma->vm_file && vma->anon_vma) {
3505 /*
3506 * We are making executable a file mapping that has
3507 * had some COW done. Since pages might have been
3508 * written, check ability to execute the possibly
3509 * modified content. This typically should only
3510 * occur for text relocations.
3511 */
David Howellsd84f4f92008-11-14 10:39:23 +11003512 rc = file_has_perm(cred, vma->vm_file, FILE__EXECMOD);
Stephen Smalleydb4c9642006-02-01 03:05:54 -08003513 }
Lorenzo Hernandez García-Hierro6b992192005-06-25 14:54:34 -07003514 if (rc)
3515 return rc;
3516 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003517
3518 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
3519}
3520
3521static int selinux_file_lock(struct file *file, unsigned int cmd)
3522{
David Howells88e67f32008-11-14 10:39:21 +11003523 const struct cred *cred = current_cred();
3524
3525 return file_has_perm(cred, file, FILE__LOCK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003526}
3527
3528static int selinux_file_fcntl(struct file *file, unsigned int cmd,
3529 unsigned long arg)
3530{
David Howells88e67f32008-11-14 10:39:21 +11003531 const struct cred *cred = current_cred();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003532 int err = 0;
3533
3534 switch (cmd) {
Eric Paris828dfe12008-04-17 13:17:49 -04003535 case F_SETFL:
Eric Paris828dfe12008-04-17 13:17:49 -04003536 if ((file->f_flags & O_APPEND) && !(arg & O_APPEND)) {
David Howells88e67f32008-11-14 10:39:21 +11003537 err = file_has_perm(cred, file, FILE__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003538 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003539 }
3540 /* fall through */
3541 case F_SETOWN:
3542 case F_SETSIG:
3543 case F_GETFL:
3544 case F_GETOWN:
3545 case F_GETSIG:
Cyrill Gorcunov1d151c32012-07-30 14:43:00 -07003546 case F_GETOWNER_UIDS:
Eric Paris828dfe12008-04-17 13:17:49 -04003547 /* Just check FD__USE permission */
David Howells88e67f32008-11-14 10:39:21 +11003548 err = file_has_perm(cred, file, 0);
Eric Paris828dfe12008-04-17 13:17:49 -04003549 break;
3550 case F_GETLK:
3551 case F_SETLK:
3552 case F_SETLKW:
Jeff Layton0d3f7a22014-04-22 08:23:58 -04003553 case F_OFD_GETLK:
3554 case F_OFD_SETLK:
3555 case F_OFD_SETLKW:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003556#if BITS_PER_LONG == 32
Eric Paris828dfe12008-04-17 13:17:49 -04003557 case F_GETLK64:
3558 case F_SETLK64:
3559 case F_SETLKW64:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003560#endif
David Howells88e67f32008-11-14 10:39:21 +11003561 err = file_has_perm(cred, file, FILE__LOCK);
Eric Paris828dfe12008-04-17 13:17:49 -04003562 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003563 }
3564
3565 return err;
3566}
3567
Jeff Laytone0b93ed2014-08-22 11:27:32 -04003568static void selinux_file_set_fowner(struct file *file)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003570 struct file_security_struct *fsec;
3571
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003572 fsec = selinux_file(file);
David Howells275bb412008-11-14 10:39:19 +11003573 fsec->fown_sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003574}
3575
3576static int selinux_file_send_sigiotask(struct task_struct *tsk,
3577 struct fown_struct *fown, int signum)
3578{
Eric Paris828dfe12008-04-17 13:17:49 -04003579 struct file *file;
Stephen Smalley65c90bc2009-05-04 15:43:18 -04003580 u32 sid = task_sid(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003581 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582 struct file_security_struct *fsec;
3583
3584 /* struct fown_struct is never outside the context of a struct file */
Eric Paris828dfe12008-04-17 13:17:49 -04003585 file = container_of(fown, struct file, f_owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003587 fsec = selinux_file(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003588
3589 if (!signum)
3590 perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
3591 else
3592 perm = signal_to_av(signum);
3593
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003594 return avc_has_perm(&selinux_state,
3595 fsec->fown_sid, sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003596 SECCLASS_PROCESS, perm, NULL);
3597}
3598
3599static int selinux_file_receive(struct file *file)
3600{
David Howells88e67f32008-11-14 10:39:21 +11003601 const struct cred *cred = current_cred();
3602
3603 return file_has_perm(cred, file, file_to_av(file));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604}
3605
Al Viro94817692018-07-10 14:13:18 -04003606static int selinux_file_open(struct file *file)
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003607{
3608 struct file_security_struct *fsec;
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003609 struct inode_security_struct *isec;
David Howellsd84f4f92008-11-14 10:39:23 +11003610
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003611 fsec = selinux_file(file);
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003612 isec = inode_security(file_inode(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003613 /*
3614 * Save inode label and policy sequence number
3615 * at open-time so that selinux_file_permission
3616 * can determine whether revalidation is necessary.
3617 * Task label is already saved in the file security
3618 * struct as its SID.
3619 */
3620 fsec->isid = isec->sid;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003621 fsec->pseqno = avc_policy_seqno(&selinux_state);
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003622 /*
3623 * Since the inode label or policy seqno may have changed
3624 * between the selinux_inode_permission check and the saving
3625 * of state above, recheck that access is still permitted.
3626 * Otherwise, access might never be revalidated against the
3627 * new inode label or new policy.
3628 * This check is not redundant - do not remove.
3629 */
Al Viro94817692018-07-10 14:13:18 -04003630 return file_path_has_perm(file->f_cred, file, open_file_to_av(file));
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09003631}
3632
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633/* task security operations */
3634
Tetsuo Handaa79be232017-03-28 23:08:45 +09003635static int selinux_task_alloc(struct task_struct *task,
3636 unsigned long clone_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003638 u32 sid = current_sid();
3639
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003640 return avc_has_perm(&selinux_state,
3641 sid, sid, SECCLASS_PROCESS, PROCESS__FORK, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642}
3643
David Howellsf1752ee2008-11-14 10:39:17 +11003644/*
David Howellsd84f4f92008-11-14 10:39:23 +11003645 * prepare a new set of credentials for modification
3646 */
3647static int selinux_cred_prepare(struct cred *new, const struct cred *old,
3648 gfp_t gfp)
3649{
Casey Schauflerbbd36622018-11-12 09:30:56 -08003650 const struct task_security_struct *old_tsec = selinux_cred(old);
3651 struct task_security_struct *tsec = selinux_cred(new);
David Howellsd84f4f92008-11-14 10:39:23 +11003652
Casey Schauflerbbd36622018-11-12 09:30:56 -08003653 *tsec = *old_tsec;
David Howellsd84f4f92008-11-14 10:39:23 +11003654 return 0;
3655}
3656
3657/*
David Howellsee18d642009-09-02 09:14:21 +01003658 * transfer the SELinux data to a blank set of creds
3659 */
3660static void selinux_cred_transfer(struct cred *new, const struct cred *old)
3661{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003662 const struct task_security_struct *old_tsec = selinux_cred(old);
3663 struct task_security_struct *tsec = selinux_cred(new);
David Howellsee18d642009-09-02 09:14:21 +01003664
3665 *tsec = *old_tsec;
3666}
3667
Matthew Garrett3ec30112018-01-08 13:36:19 -08003668static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
3669{
3670 *secid = cred_sid(c);
3671}
3672
David Howellsee18d642009-09-02 09:14:21 +01003673/*
David Howells3a3b7ce2008-11-14 10:39:28 +11003674 * set the security data for a kernel service
3675 * - all the creation contexts are set to unlabelled
3676 */
3677static int selinux_kernel_act_as(struct cred *new, u32 secid)
3678{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003679 struct task_security_struct *tsec = selinux_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11003680 u32 sid = current_sid();
3681 int ret;
3682
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003683 ret = avc_has_perm(&selinux_state,
3684 sid, secid,
David Howells3a3b7ce2008-11-14 10:39:28 +11003685 SECCLASS_KERNEL_SERVICE,
3686 KERNEL_SERVICE__USE_AS_OVERRIDE,
3687 NULL);
3688 if (ret == 0) {
3689 tsec->sid = secid;
3690 tsec->create_sid = 0;
3691 tsec->keycreate_sid = 0;
3692 tsec->sockcreate_sid = 0;
3693 }
3694 return ret;
3695}
3696
3697/*
3698 * set the file creation context in a security record to the same as the
3699 * objective context of the specified inode
3700 */
3701static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3702{
Andreas Gruenbacher83da53c52015-12-24 11:09:39 -05003703 struct inode_security_struct *isec = inode_security(inode);
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07003704 struct task_security_struct *tsec = selinux_cred(new);
David Howells3a3b7ce2008-11-14 10:39:28 +11003705 u32 sid = current_sid();
3706 int ret;
3707
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003708 ret = avc_has_perm(&selinux_state,
3709 sid, isec->sid,
David Howells3a3b7ce2008-11-14 10:39:28 +11003710 SECCLASS_KERNEL_SERVICE,
3711 KERNEL_SERVICE__CREATE_FILES_AS,
3712 NULL);
3713
3714 if (ret == 0)
3715 tsec->create_sid = isec->sid;
David Howellsef574712010-02-26 01:56:16 +00003716 return ret;
David Howells3a3b7ce2008-11-14 10:39:28 +11003717}
3718
Eric Parisdd8dbf22009-11-03 16:35:32 +11003719static int selinux_kernel_module_request(char *kmod_name)
Eric Paris25354c42009-08-13 09:45:03 -04003720{
Eric Parisdd8dbf22009-11-03 16:35:32 +11003721 struct common_audit_data ad;
3722
Eric Paris50c205f2012-04-04 15:01:43 -04003723 ad.type = LSM_AUDIT_DATA_KMOD;
Eric Parisdd8dbf22009-11-03 16:35:32 +11003724 ad.u.kmod_name = kmod_name;
3725
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003726 return avc_has_perm(&selinux_state,
3727 current_sid(), SECINITSID_KERNEL, SECCLASS_SYSTEM,
Eric Parisdd8dbf22009-11-03 16:35:32 +11003728 SYSTEM__MODULE_REQUEST, &ad);
Eric Paris25354c42009-08-13 09:45:03 -04003729}
3730
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003731static int selinux_kernel_module_from_file(struct file *file)
3732{
3733 struct common_audit_data ad;
3734 struct inode_security_struct *isec;
3735 struct file_security_struct *fsec;
3736 u32 sid = current_sid();
3737 int rc;
3738
3739 /* init_module */
3740 if (file == NULL)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003741 return avc_has_perm(&selinux_state,
3742 sid, sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003743 SYSTEM__MODULE_LOAD, NULL);
3744
3745 /* finit_module */
Paul Moore20cdef82016-04-04 14:14:42 -04003746
Vivek Goyal43af5de2016-09-09 11:37:49 -04003747 ad.type = LSM_AUDIT_DATA_FILE;
3748 ad.u.file = file;
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003749
Casey Schauflerbb6c6b02018-09-21 17:22:32 -07003750 fsec = selinux_file(file);
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003751 if (sid != fsec->sid) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003752 rc = avc_has_perm(&selinux_state,
3753 sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003754 if (rc)
3755 return rc;
3756 }
3757
Paul Moore20cdef82016-04-04 14:14:42 -04003758 isec = inode_security(file_inode(file));
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003759 return avc_has_perm(&selinux_state,
3760 sid, isec->sid, SECCLASS_SYSTEM,
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07003761 SYSTEM__MODULE_LOAD, &ad);
3762}
3763
3764static int selinux_kernel_read_file(struct file *file,
3765 enum kernel_read_file_id id)
3766{
3767 int rc = 0;
3768
3769 switch (id) {
3770 case READING_MODULE:
3771 rc = selinux_kernel_module_from_file(file);
3772 break;
3773 default:
3774 break;
3775 }
3776
3777 return rc;
3778}
3779
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04003780static int selinux_kernel_load_data(enum kernel_load_data_id id)
3781{
3782 int rc = 0;
3783
3784 switch (id) {
3785 case LOADING_MODULE:
3786 rc = selinux_kernel_module_from_file(NULL);
3787 default:
3788 break;
3789 }
3790
3791 return rc;
3792}
3793
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3795{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003796 return avc_has_perm(&selinux_state,
3797 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003798 PROCESS__SETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003799}
3800
3801static int selinux_task_getpgid(struct task_struct *p)
3802{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003803 return avc_has_perm(&selinux_state,
3804 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003805 PROCESS__GETPGID, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003806}
3807
3808static int selinux_task_getsid(struct task_struct *p)
3809{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003810 return avc_has_perm(&selinux_state,
3811 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003812 PROCESS__GETSESSION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003813}
3814
David Quigleyf9008e4c2006-06-30 01:55:46 -07003815static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
3816{
David Howells275bb412008-11-14 10:39:19 +11003817 *secid = task_sid(p);
David Quigleyf9008e4c2006-06-30 01:55:46 -07003818}
3819
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820static int selinux_task_setnice(struct task_struct *p, int nice)
3821{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003822 return avc_has_perm(&selinux_state,
3823 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003824 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825}
3826
James Morris03e68062006-06-23 02:03:58 -07003827static int selinux_task_setioprio(struct task_struct *p, int ioprio)
3828{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003829 return avc_has_perm(&selinux_state,
3830 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003831 PROCESS__SETSCHED, NULL);
James Morris03e68062006-06-23 02:03:58 -07003832}
3833
David Quigleya1836a42006-06-30 01:55:49 -07003834static int selinux_task_getioprio(struct task_struct *p)
3835{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003836 return avc_has_perm(&selinux_state,
3837 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003838 PROCESS__GETSCHED, NULL);
David Quigleya1836a42006-06-30 01:55:49 -07003839}
3840
Corentin LABBE42985552017-10-04 20:32:18 +02003841static int selinux_task_prlimit(const struct cred *cred, const struct cred *tcred,
3842 unsigned int flags)
Stephen Smalley791ec492017-02-17 07:57:00 -05003843{
3844 u32 av = 0;
3845
Stephen Smalley84e68852017-02-28 09:35:08 -05003846 if (!flags)
3847 return 0;
Stephen Smalley791ec492017-02-17 07:57:00 -05003848 if (flags & LSM_PRLIMIT_WRITE)
3849 av |= PROCESS__SETRLIMIT;
3850 if (flags & LSM_PRLIMIT_READ)
3851 av |= PROCESS__GETRLIMIT;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003852 return avc_has_perm(&selinux_state,
3853 cred_sid(cred), cred_sid(tcred),
Stephen Smalley791ec492017-02-17 07:57:00 -05003854 SECCLASS_PROCESS, av, NULL);
3855}
3856
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003857static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
3858 struct rlimit *new_rlim)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003859{
Jiri Slaby8fd00b42009-08-26 18:41:16 +02003860 struct rlimit *old_rlim = p->signal->rlim + resource;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003861
3862 /* Control the ability to change the hard limit (whether
3863 lowering or raising it), so that the hard limit can
3864 later be used as a safe reset point for the soft limit
David Howellsd84f4f92008-11-14 10:39:23 +11003865 upon context transitions. See selinux_bprm_committing_creds. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866 if (old_rlim->rlim_max != new_rlim->rlim_max)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003867 return avc_has_perm(&selinux_state,
3868 current_sid(), task_sid(p),
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003869 SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003870
3871 return 0;
3872}
3873
KOSAKI Motohirob0ae1982010-10-15 04:21:18 +09003874static int selinux_task_setscheduler(struct task_struct *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003875{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003876 return avc_has_perm(&selinux_state,
3877 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003878 PROCESS__SETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879}
3880
3881static int selinux_task_getscheduler(struct task_struct *p)
3882{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003883 return avc_has_perm(&selinux_state,
3884 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003885 PROCESS__GETSCHED, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886}
3887
David Quigley35601542006-06-23 02:04:01 -07003888static int selinux_task_movememory(struct task_struct *p)
3889{
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003890 return avc_has_perm(&selinux_state,
3891 current_sid(), task_sid(p), SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003892 PROCESS__SETSCHED, NULL);
David Quigley35601542006-06-23 02:04:01 -07003893}
3894
Eric W. Biedermanae7795b2018-09-25 11:27:20 +02003895static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003896 int sig, const struct cred *cred)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897{
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003898 u32 secid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899 u32 perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900
Linus Torvalds1da177e2005-04-16 15:20:36 -07003901 if (!sig)
3902 perm = PROCESS__SIGNULL; /* null signal; existence test */
3903 else
3904 perm = signal_to_av(sig);
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003905 if (!cred)
Stephen Smalleybe0554c2017-01-09 10:07:31 -05003906 secid = current_sid();
Stephen Smalley6b4f3d02017-09-08 12:40:01 -04003907 else
3908 secid = cred_sid(cred);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05003909 return avc_has_perm(&selinux_state,
3910 secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911}
3912
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913static void selinux_task_to_inode(struct task_struct *p,
3914 struct inode *inode)
3915{
Casey Schaufler80788c22018-09-21 17:19:11 -07003916 struct inode_security_struct *isec = selinux_inode(inode);
David Howells275bb412008-11-14 10:39:19 +11003917 u32 sid = task_sid(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003919 spin_lock(&isec->lock);
Andreas Gruenbacherdb978da2016-11-10 22:18:28 +01003920 isec->sclass = inode_mode_to_security_class(inode->i_mode);
David Howells275bb412008-11-14 10:39:19 +11003921 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05003922 isec->initialized = LABEL_INITIALIZED;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01003923 spin_unlock(&isec->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003924}
3925
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06003927static int selinux_parse_skb_ipv4(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04003928 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929{
3930 int offset, ihlen, ret = -EINVAL;
3931 struct iphdr _iph, *ih;
3932
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03003933 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
3935 if (ih == NULL)
3936 goto out;
3937
3938 ihlen = ih->ihl * 4;
3939 if (ihlen < sizeof(_iph))
3940 goto out;
3941
Eric Paris48c62af2012-04-02 13:15:44 -04003942 ad->u.net->v4info.saddr = ih->saddr;
3943 ad->u.net->v4info.daddr = ih->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944 ret = 0;
3945
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06003946 if (proto)
3947 *proto = ih->protocol;
3948
Linus Torvalds1da177e2005-04-16 15:20:36 -07003949 switch (ih->protocol) {
Eric Paris828dfe12008-04-17 13:17:49 -04003950 case IPPROTO_TCP: {
3951 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003952
Eric Paris828dfe12008-04-17 13:17:49 -04003953 if (ntohs(ih->frag_off) & IP_OFFSET)
3954 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955
3956 offset += ihlen;
3957 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
3958 if (th == NULL)
3959 break;
3960
Eric Paris48c62af2012-04-02 13:15:44 -04003961 ad->u.net->sport = th->source;
3962 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003964 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965
Eric Paris828dfe12008-04-17 13:17:49 -04003966 case IPPROTO_UDP: {
3967 struct udphdr _udph, *uh;
3968
3969 if (ntohs(ih->frag_off) & IP_OFFSET)
3970 break;
3971
3972 offset += ihlen;
3973 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
3974 if (uh == NULL)
3975 break;
3976
Eric Paris48c62af2012-04-02 13:15:44 -04003977 ad->u.net->sport = uh->source;
3978 ad->u.net->dport = uh->dest;
Eric Paris828dfe12008-04-17 13:17:49 -04003979 break;
3980 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981
James Morris2ee92d42006-11-13 16:09:01 -08003982 case IPPROTO_DCCP: {
3983 struct dccp_hdr _dccph, *dh;
3984
3985 if (ntohs(ih->frag_off) & IP_OFFSET)
3986 break;
3987
3988 offset += ihlen;
3989 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
3990 if (dh == NULL)
3991 break;
3992
Eric Paris48c62af2012-04-02 13:15:44 -04003993 ad->u.net->sport = dh->dccph_sport;
3994 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08003995 break;
Eric Paris828dfe12008-04-17 13:17:49 -04003996 }
James Morris2ee92d42006-11-13 16:09:01 -08003997
Richard Hainesd4529302018-02-13 20:57:18 +00003998#if IS_ENABLED(CONFIG_IP_SCTP)
3999 case IPPROTO_SCTP: {
4000 struct sctphdr _sctph, *sh;
4001
4002 if (ntohs(ih->frag_off) & IP_OFFSET)
4003 break;
4004
4005 offset += ihlen;
4006 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4007 if (sh == NULL)
4008 break;
4009
4010 ad->u.net->sport = sh->source;
4011 ad->u.net->dport = sh->dest;
4012 break;
4013 }
4014#endif
Eric Paris828dfe12008-04-17 13:17:49 -04004015 default:
4016 break;
4017 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004018out:
4019 return ret;
4020}
4021
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004022#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004023
4024/* Returns error only if unable to parse addresses */
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004025static int selinux_parse_skb_ipv6(struct sk_buff *skb,
Thomas Liu2bf49692009-07-14 12:14:09 -04004026 struct common_audit_data *ad, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027{
4028 u8 nexthdr;
4029 int ret = -EINVAL, offset;
4030 struct ipv6hdr _ipv6h, *ip6;
Jesse Gross75f28112011-11-30 17:05:51 -08004031 __be16 frag_off;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004032
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03004033 offset = skb_network_offset(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004034 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
4035 if (ip6 == NULL)
4036 goto out;
4037
Eric Paris48c62af2012-04-02 13:15:44 -04004038 ad->u.net->v6info.saddr = ip6->saddr;
4039 ad->u.net->v6info.daddr = ip6->daddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004040 ret = 0;
4041
4042 nexthdr = ip6->nexthdr;
4043 offset += sizeof(_ipv6h);
Jesse Gross75f28112011-11-30 17:05:51 -08004044 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045 if (offset < 0)
4046 goto out;
4047
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004048 if (proto)
4049 *proto = nexthdr;
4050
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 switch (nexthdr) {
4052 case IPPROTO_TCP: {
Eric Paris828dfe12008-04-17 13:17:49 -04004053 struct tcphdr _tcph, *th;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004054
4055 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
4056 if (th == NULL)
4057 break;
4058
Eric Paris48c62af2012-04-02 13:15:44 -04004059 ad->u.net->sport = th->source;
4060 ad->u.net->dport = th->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061 break;
4062 }
4063
4064 case IPPROTO_UDP: {
4065 struct udphdr _udph, *uh;
4066
4067 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
4068 if (uh == NULL)
4069 break;
4070
Eric Paris48c62af2012-04-02 13:15:44 -04004071 ad->u.net->sport = uh->source;
4072 ad->u.net->dport = uh->dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004073 break;
4074 }
4075
James Morris2ee92d42006-11-13 16:09:01 -08004076 case IPPROTO_DCCP: {
4077 struct dccp_hdr _dccph, *dh;
4078
4079 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
4080 if (dh == NULL)
4081 break;
4082
Eric Paris48c62af2012-04-02 13:15:44 -04004083 ad->u.net->sport = dh->dccph_sport;
4084 ad->u.net->dport = dh->dccph_dport;
James Morris2ee92d42006-11-13 16:09:01 -08004085 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004086 }
James Morris2ee92d42006-11-13 16:09:01 -08004087
Richard Hainesd4529302018-02-13 20:57:18 +00004088#if IS_ENABLED(CONFIG_IP_SCTP)
4089 case IPPROTO_SCTP: {
4090 struct sctphdr _sctph, *sh;
4091
4092 sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
4093 if (sh == NULL)
4094 break;
4095
4096 ad->u.net->sport = sh->source;
4097 ad->u.net->dport = sh->dest;
4098 break;
4099 }
4100#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101 /* includes fragments */
4102 default:
4103 break;
4104 }
4105out:
4106 return ret;
4107}
4108
4109#endif /* IPV6 */
4110
Thomas Liu2bf49692009-07-14 12:14:09 -04004111static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
David Howellscf9481e2008-07-27 21:31:07 +10004112 char **_addrp, int src, u8 *proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004113{
David Howellscf9481e2008-07-27 21:31:07 +10004114 char *addrp;
4115 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116
Eric Paris48c62af2012-04-02 13:15:44 -04004117 switch (ad->u.net->family) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004118 case PF_INET:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004119 ret = selinux_parse_skb_ipv4(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004120 if (ret)
4121 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004122 addrp = (char *)(src ? &ad->u.net->v4info.saddr :
4123 &ad->u.net->v4info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004124 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004125
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04004126#if IS_ENABLED(CONFIG_IPV6)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127 case PF_INET6:
Venkat Yekkirala67f83cb2006-11-08 17:04:26 -06004128 ret = selinux_parse_skb_ipv6(skb, ad, proto);
David Howellscf9481e2008-07-27 21:31:07 +10004129 if (ret)
4130 goto parse_error;
Eric Paris48c62af2012-04-02 13:15:44 -04004131 addrp = (char *)(src ? &ad->u.net->v6info.saddr :
4132 &ad->u.net->v6info.daddr);
David Howellscf9481e2008-07-27 21:31:07 +10004133 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004134#endif /* IPV6 */
4135 default:
David Howellscf9481e2008-07-27 21:31:07 +10004136 addrp = NULL;
4137 goto okay;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004138 }
4139
David Howellscf9481e2008-07-27 21:31:07 +10004140parse_error:
peter enderborgc103a912018-06-12 10:09:03 +02004141 pr_warn(
David Howellscf9481e2008-07-27 21:31:07 +10004142 "SELinux: failure in selinux_parse_skb(),"
4143 " unable to parse packet\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07004144 return ret;
David Howellscf9481e2008-07-27 21:31:07 +10004145
4146okay:
4147 if (_addrp)
4148 *_addrp = addrp;
4149 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004150}
4151
Paul Moore4f6a9932007-03-01 14:35:22 -05004152/**
Paul Moore220deb92008-01-29 08:38:23 -05004153 * selinux_skb_peerlbl_sid - Determine the peer label of a packet
Paul Moore4f6a9932007-03-01 14:35:22 -05004154 * @skb: the packet
Paul Moore75e22912008-01-29 08:38:04 -05004155 * @family: protocol family
Paul Moore220deb92008-01-29 08:38:23 -05004156 * @sid: the packet's peer label SID
Paul Moore4f6a9932007-03-01 14:35:22 -05004157 *
4158 * Description:
Paul Moore220deb92008-01-29 08:38:23 -05004159 * Check the various different forms of network peer labeling and determine
4160 * the peer label/SID for the packet; most of the magic actually occurs in
4161 * the security server function security_net_peersid_cmp(). The function
4162 * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
4163 * or -EACCES if @sid is invalid due to inconsistencies with the different
4164 * peer labels.
Paul Moore4f6a9932007-03-01 14:35:22 -05004165 *
4166 */
Paul Moore220deb92008-01-29 08:38:23 -05004167static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
Paul Moore4f6a9932007-03-01 14:35:22 -05004168{
Paul Moore71f1cb02008-01-29 08:51:16 -05004169 int err;
Paul Moore4f6a9932007-03-01 14:35:22 -05004170 u32 xfrm_sid;
4171 u32 nlbl_sid;
Paul Moore220deb92008-01-29 08:38:23 -05004172 u32 nlbl_type;
Paul Moore4f6a9932007-03-01 14:35:22 -05004173
Paul Moore817eff72013-12-10 14:57:54 -05004174 err = selinux_xfrm_skb_sid(skb, &xfrm_sid);
Paul Moorebed4d7e2013-07-23 17:38:40 -04004175 if (unlikely(err))
4176 return -EACCES;
4177 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
4178 if (unlikely(err))
4179 return -EACCES;
Paul Moore220deb92008-01-29 08:38:23 -05004180
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004181 err = security_net_peersid_resolve(&selinux_state, nlbl_sid,
4182 nlbl_type, xfrm_sid, sid);
Paul Moore71f1cb02008-01-29 08:51:16 -05004183 if (unlikely(err)) {
peter enderborgc103a912018-06-12 10:09:03 +02004184 pr_warn(
Paul Moore71f1cb02008-01-29 08:51:16 -05004185 "SELinux: failure in selinux_skb_peerlbl_sid(),"
4186 " unable to determine packet's peer label\n");
Paul Moore220deb92008-01-29 08:38:23 -05004187 return -EACCES;
Paul Moore71f1cb02008-01-29 08:51:16 -05004188 }
Paul Moore220deb92008-01-29 08:38:23 -05004189
4190 return 0;
Paul Moore4f6a9932007-03-01 14:35:22 -05004191}
4192
Paul Moore446b8022013-12-04 16:10:51 -05004193/**
4194 * selinux_conn_sid - Determine the child socket label for a connection
4195 * @sk_sid: the parent socket's SID
4196 * @skb_sid: the packet's SID
4197 * @conn_sid: the resulting connection SID
4198 *
4199 * If @skb_sid is valid then the user:role:type information from @sk_sid is
4200 * combined with the MLS information from @skb_sid in order to create
4201 * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy
4202 * of @sk_sid. Returns zero on success, negative values on failure.
4203 *
4204 */
4205static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
4206{
4207 int err = 0;
4208
4209 if (skb_sid != SECSID_NULL)
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004210 err = security_sid_mls_copy(&selinux_state, sk_sid, skb_sid,
4211 conn_sid);
Paul Moore446b8022013-12-04 16:10:51 -05004212 else
4213 *conn_sid = sk_sid;
4214
4215 return err;
4216}
4217
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218/* socket security operations */
Paul Moored4f2d972010-04-22 14:46:18 -04004219
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004220static int socket_sockcreate_sid(const struct task_security_struct *tsec,
4221 u16 secclass, u32 *socksid)
Paul Moored4f2d972010-04-22 14:46:18 -04004222{
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004223 if (tsec->sockcreate_sid > SECSID_NULL) {
4224 *socksid = tsec->sockcreate_sid;
4225 return 0;
4226 }
4227
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004228 return security_transition_sid(&selinux_state, tsec->sid, tsec->sid,
4229 secclass, NULL, socksid);
Paul Moored4f2d972010-04-22 14:46:18 -04004230}
4231
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004232static int sock_has_perm(struct sock *sk, u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004233{
Paul Moore253bfae2010-04-22 14:46:19 -04004234 struct sk_security_struct *sksec = sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004235 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004236 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004237
Paul Moore253bfae2010-04-22 14:46:19 -04004238 if (sksec->sid == SECINITSID_KERNEL)
4239 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240
Eric Paris50c205f2012-04-04 15:01:43 -04004241 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004242 ad.u.net = &net;
4243 ad.u.net->sk = sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004245 return avc_has_perm(&selinux_state,
4246 current_sid(), sksec->sid, sksec->sclass, perms,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004247 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248}
4249
4250static int selinux_socket_create(int family, int type,
4251 int protocol, int kern)
4252{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07004253 const struct task_security_struct *tsec = selinux_cred(current_cred());
Paul Moored4f2d972010-04-22 14:46:18 -04004254 u32 newsid;
David Howells275bb412008-11-14 10:39:19 +11004255 u16 secclass;
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004256 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004257
4258 if (kern)
Paul Moored4f2d972010-04-22 14:46:18 -04004259 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260
David Howells275bb412008-11-14 10:39:19 +11004261 secclass = socket_type_to_security_class(family, type, protocol);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004262 rc = socket_sockcreate_sid(tsec, secclass, &newsid);
4263 if (rc)
4264 return rc;
4265
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004266 return avc_has_perm(&selinux_state,
4267 tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268}
4269
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004270static int selinux_socket_post_create(struct socket *sock, int family,
4271 int type, int protocol, int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004272{
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07004273 const struct task_security_struct *tsec = selinux_cred(current_cred());
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004274 struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock));
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004275 struct sk_security_struct *sksec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004276 u16 sclass = socket_type_to_security_class(family, type, protocol);
4277 u32 sid = SECINITSID_KERNEL;
David Howells275bb412008-11-14 10:39:19 +11004278 int err = 0;
4279
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004280 if (!kern) {
4281 err = socket_sockcreate_sid(tsec, sclass, &sid);
Harry Ciao2ad18bd2011-03-02 13:32:34 +08004282 if (err)
4283 return err;
4284 }
David Howells275bb412008-11-14 10:39:19 +11004285
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004286 isec->sclass = sclass;
4287 isec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004288 isec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004289
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004290 if (sock->sk) {
4291 sksec = sock->sk->sk_security;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004292 sksec->sclass = sclass;
4293 sksec->sid = sid;
Richard Hainesd4529302018-02-13 20:57:18 +00004294 /* Allows detection of the first association on this socket */
4295 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4296 sksec->sctp_assoc_state = SCTP_ASSOC_UNSET;
4297
Paul Moore389fb8002009-03-27 17:10:34 -04004298 err = selinux_netlbl_socket_post_create(sock->sk, family);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004299 }
4300
Venkat Yekkirala7420ed22006-08-04 23:17:57 -07004301 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302}
4303
David Herrmann0b811db2018-05-04 16:28:21 +02004304static int selinux_socket_socketpair(struct socket *socka,
4305 struct socket *sockb)
4306{
4307 struct sk_security_struct *sksec_a = socka->sk->sk_security;
4308 struct sk_security_struct *sksec_b = sockb->sk->sk_security;
4309
4310 sksec_a->peer_sid = sksec_b->sid;
4311 sksec_b->peer_sid = sksec_a->sid;
4312
4313 return 0;
4314}
4315
Linus Torvalds1da177e2005-04-16 15:20:36 -07004316/* Range of port numbers used to automatically bind.
4317 Need to determine whether we should perform a name_bind
4318 permission check between the socket and the port number. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319
4320static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
4321{
Paul Moore253bfae2010-04-22 14:46:19 -04004322 struct sock *sk = sock->sk;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004323 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324 u16 family;
4325 int err;
4326
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004327 err = sock_has_perm(sk, SOCKET__BIND);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004328 if (err)
4329 goto out;
4330
Richard Hainesd4529302018-02-13 20:57:18 +00004331 /* If PF_INET or PF_INET6, check name_bind permission for the port. */
Paul Moore253bfae2010-04-22 14:46:19 -04004332 family = sk->sk_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333 if (family == PF_INET || family == PF_INET6) {
4334 char *addrp;
Thomas Liu2bf49692009-07-14 12:14:09 -04004335 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004336 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337 struct sockaddr_in *addr4 = NULL;
4338 struct sockaddr_in6 *addr6 = NULL;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004339 u16 family_sa = address->sa_family;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340 unsigned short snum;
James Morrise399f982008-06-12 01:39:58 +10004341 u32 sid, node_perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342
Richard Hainesd4529302018-02-13 20:57:18 +00004343 /*
4344 * sctp_bindx(3) calls via selinux_sctp_bind_connect()
4345 * that validates multiple binding addresses. Because of this
4346 * need to check address->sa_family as it is possible to have
4347 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4348 */
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004349 switch (family_sa) {
4350 case AF_UNSPEC:
Richard Haines68741a8a2018-03-02 19:54:34 +00004351 case AF_INET:
4352 if (addrlen < sizeof(struct sockaddr_in))
4353 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004354 addr4 = (struct sockaddr_in *)address;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004355 if (family_sa == AF_UNSPEC) {
4356 /* see __inet_bind(), we only want to allow
4357 * AF_UNSPEC if the address is INADDR_ANY
4358 */
4359 if (addr4->sin_addr.s_addr != htonl(INADDR_ANY))
4360 goto err_af;
4361 family_sa = AF_INET;
4362 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004363 snum = ntohs(addr4->sin_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004364 addrp = (char *)&addr4->sin_addr.s_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004365 break;
4366 case AF_INET6:
4367 if (addrlen < SIN6_LEN_RFC2133)
4368 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369 addr6 = (struct sockaddr_in6 *)address;
4370 snum = ntohs(addr6->sin6_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371 addrp = (char *)&addr6->sin6_addr.s6_addr;
Richard Haines68741a8a2018-03-02 19:54:34 +00004372 break;
4373 default:
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004374 goto err_af;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004375 }
4376
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004377 ad.type = LSM_AUDIT_DATA_NET;
4378 ad.u.net = &net;
4379 ad.u.net->sport = htons(snum);
4380 ad.u.net->family = family_sa;
4381
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004382 if (snum) {
4383 int low, high;
4384
Eric W. Biederman0bbf87d2013-09-28 14:10:59 -07004385 inet_get_local_port_range(sock_net(sk), &low, &high);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004386
Krister Johansen4548b682017-01-20 17:49:11 -08004387 if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
4388 snum > high) {
Paul Moore3e1121722008-04-10 10:48:14 -04004389 err = sel_netport_sid(sk->sk_protocol,
4390 snum, &sid);
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004391 if (err)
4392 goto out;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004393 err = avc_has_perm(&selinux_state,
4394 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004395 sksec->sclass,
Stephen Hemminger227b60f2007-10-10 17:30:46 -07004396 SOCKET__NAME_BIND, &ad);
4397 if (err)
4398 goto out;
4399 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004400 }
Eric Paris828dfe12008-04-17 13:17:49 -04004401
Paul Moore253bfae2010-04-22 14:46:19 -04004402 switch (sksec->sclass) {
James Morris13402582005-09-30 14:24:34 -04004403 case SECCLASS_TCP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004404 node_perm = TCP_SOCKET__NODE_BIND;
4405 break;
Eric Paris828dfe12008-04-17 13:17:49 -04004406
James Morris13402582005-09-30 14:24:34 -04004407 case SECCLASS_UDP_SOCKET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408 node_perm = UDP_SOCKET__NODE_BIND;
4409 break;
James Morris2ee92d42006-11-13 16:09:01 -08004410
4411 case SECCLASS_DCCP_SOCKET:
4412 node_perm = DCCP_SOCKET__NODE_BIND;
4413 break;
4414
Richard Hainesd4529302018-02-13 20:57:18 +00004415 case SECCLASS_SCTP_SOCKET:
4416 node_perm = SCTP_SOCKET__NODE_BIND;
4417 break;
4418
Linus Torvalds1da177e2005-04-16 15:20:36 -07004419 default:
4420 node_perm = RAWIP_SOCKET__NODE_BIND;
4421 break;
4422 }
Eric Paris828dfe12008-04-17 13:17:49 -04004423
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004424 err = sel_netnode_sid(addrp, family_sa, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004425 if (err)
4426 goto out;
Eric Paris828dfe12008-04-17 13:17:49 -04004427
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004428 if (family_sa == AF_INET)
Eric Paris48c62af2012-04-02 13:15:44 -04004429 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004430 else
Eric Paris48c62af2012-04-02 13:15:44 -04004431 ad.u.net->v6info.saddr = addr6->sin6_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004433 err = avc_has_perm(&selinux_state,
4434 sksec->sid, sid,
Paul Moore253bfae2010-04-22 14:46:19 -04004435 sksec->sclass, node_perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436 if (err)
4437 goto out;
4438 }
4439out:
4440 return err;
Alexey Kodanev0f8db8c2018-05-11 20:15:11 +03004441err_af:
4442 /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */
4443 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4444 return -EINVAL;
4445 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004446}
4447
Richard Hainesd4529302018-02-13 20:57:18 +00004448/* This supports connect(2) and SCTP connect services such as sctp_connectx(3)
Mauro Carvalho Chehab5fb94e92018-05-08 15:14:57 -03004449 * and sctp_sendmsg(3) as described in Documentation/security/LSM-sctp.rst
Richard Hainesd4529302018-02-13 20:57:18 +00004450 */
4451static int selinux_socket_connect_helper(struct socket *sock,
4452 struct sockaddr *address, int addrlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004453{
Paul Moore014ab192008-10-10 10:16:33 -04004454 struct sock *sk = sock->sk;
Paul Moore253bfae2010-04-22 14:46:19 -04004455 struct sk_security_struct *sksec = sk->sk_security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004456 int err;
4457
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004458 err = sock_has_perm(sk, SOCKET__CONNECT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004459 if (err)
4460 return err;
4461
4462 /*
Richard Hainesd4529302018-02-13 20:57:18 +00004463 * If a TCP, DCCP or SCTP socket, check name_connect permission
4464 * for the port.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465 */
Paul Moore253bfae2010-04-22 14:46:19 -04004466 if (sksec->sclass == SECCLASS_TCP_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00004467 sksec->sclass == SECCLASS_DCCP_SOCKET ||
4468 sksec->sclass == SECCLASS_SCTP_SOCKET) {
Thomas Liu2bf49692009-07-14 12:14:09 -04004469 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004470 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004471 struct sockaddr_in *addr4 = NULL;
4472 struct sockaddr_in6 *addr6 = NULL;
4473 unsigned short snum;
James Morris2ee92d42006-11-13 16:09:01 -08004474 u32 sid, perm;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004475
Richard Hainesd4529302018-02-13 20:57:18 +00004476 /* sctp_connectx(3) calls via selinux_sctp_bind_connect()
4477 * that validates multiple connect addresses. Because of this
4478 * need to check address->sa_family as it is possible to have
4479 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4480 */
Richard Haines68741a8a2018-03-02 19:54:34 +00004481 switch (address->sa_family) {
4482 case AF_INET:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004483 addr4 = (struct sockaddr_in *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004484 if (addrlen < sizeof(struct sockaddr_in))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485 return -EINVAL;
4486 snum = ntohs(addr4->sin_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004487 break;
4488 case AF_INET6:
Linus Torvalds1da177e2005-04-16 15:20:36 -07004489 addr6 = (struct sockaddr_in6 *)address;
Stephen Smalley911656f2005-07-28 21:16:21 -07004490 if (addrlen < SIN6_LEN_RFC2133)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004491 return -EINVAL;
4492 snum = ntohs(addr6->sin6_port);
Richard Haines68741a8a2018-03-02 19:54:34 +00004493 break;
4494 default:
4495 /* Note that SCTP services expect -EINVAL, whereas
4496 * others expect -EAFNOSUPPORT.
4497 */
4498 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4499 return -EINVAL;
4500 else
4501 return -EAFNOSUPPORT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004502 }
4503
Paul Moore3e1121722008-04-10 10:48:14 -04004504 err = sel_netport_sid(sk->sk_protocol, snum, &sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004505 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004506 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004507
Richard Hainesd4529302018-02-13 20:57:18 +00004508 switch (sksec->sclass) {
4509 case SECCLASS_TCP_SOCKET:
4510 perm = TCP_SOCKET__NAME_CONNECT;
4511 break;
4512 case SECCLASS_DCCP_SOCKET:
4513 perm = DCCP_SOCKET__NAME_CONNECT;
4514 break;
4515 case SECCLASS_SCTP_SOCKET:
4516 perm = SCTP_SOCKET__NAME_CONNECT;
4517 break;
4518 }
James Morris2ee92d42006-11-13 16:09:01 -08004519
Eric Paris50c205f2012-04-04 15:01:43 -04004520 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004521 ad.u.net = &net;
4522 ad.u.net->dport = htons(snum);
Alexey Kodanev88b7d372018-05-11 20:15:12 +03004523 ad.u.net->family = address->sa_family;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004524 err = avc_has_perm(&selinux_state,
4525 sksec->sid, sid, sksec->sclass, perm, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004526 if (err)
Richard Hainesd4529302018-02-13 20:57:18 +00004527 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004528 }
4529
Richard Hainesd4529302018-02-13 20:57:18 +00004530 return 0;
4531}
Paul Moore014ab192008-10-10 10:16:33 -04004532
Richard Hainesd4529302018-02-13 20:57:18 +00004533/* Supports connect(2), see comments in selinux_socket_connect_helper() */
4534static int selinux_socket_connect(struct socket *sock,
4535 struct sockaddr *address, int addrlen)
4536{
4537 int err;
4538 struct sock *sk = sock->sk;
4539
4540 err = selinux_socket_connect_helper(sock, address, addrlen);
4541 if (err)
4542 return err;
4543
4544 return selinux_netlbl_socket_connect(sk, address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004545}
4546
4547static int selinux_socket_listen(struct socket *sock, int backlog)
4548{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004549 return sock_has_perm(sock->sk, SOCKET__LISTEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550}
4551
4552static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
4553{
4554 int err;
4555 struct inode_security_struct *isec;
4556 struct inode_security_struct *newisec;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004557 u16 sclass;
4558 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004559
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004560 err = sock_has_perm(sock->sk, SOCKET__ACCEPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004561 if (err)
4562 return err;
4563
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004564 isec = inode_security_novalidate(SOCK_INODE(sock));
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01004565 spin_lock(&isec->lock);
4566 sclass = isec->sclass;
4567 sid = isec->sid;
4568 spin_unlock(&isec->lock);
4569
4570 newisec = inode_security_novalidate(SOCK_INODE(newsock));
4571 newisec->sclass = sclass;
4572 newisec->sid = sid;
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05004573 newisec->initialized = LABEL_INITIALIZED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004574
4575 return 0;
4576}
4577
4578static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
Eric Paris828dfe12008-04-17 13:17:49 -04004579 int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004580{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004581 return sock_has_perm(sock->sk, SOCKET__WRITE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004582}
4583
4584static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
4585 int size, int flags)
4586{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004587 return sock_has_perm(sock->sk, SOCKET__READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588}
4589
4590static int selinux_socket_getsockname(struct socket *sock)
4591{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004592 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004593}
4594
4595static int selinux_socket_getpeername(struct socket *sock)
4596{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004597 return sock_has_perm(sock->sk, SOCKET__GETATTR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004598}
4599
Eric Paris828dfe12008-04-17 13:17:49 -04004600static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004601{
Paul Mooref8687af2006-10-30 15:22:15 -08004602 int err;
4603
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004604 err = sock_has_perm(sock->sk, SOCKET__SETOPT);
Paul Mooref8687af2006-10-30 15:22:15 -08004605 if (err)
4606 return err;
4607
4608 return selinux_netlbl_socket_setsockopt(sock, level, optname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004609}
4610
4611static int selinux_socket_getsockopt(struct socket *sock, int level,
4612 int optname)
4613{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004614 return sock_has_perm(sock->sk, SOCKET__GETOPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004615}
4616
4617static int selinux_socket_shutdown(struct socket *sock, int how)
4618{
Stephen Smalleybe0554c2017-01-09 10:07:31 -05004619 return sock_has_perm(sock->sk, SOCKET__SHUTDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004620}
4621
David S. Miller3610cda2011-01-05 15:38:53 -08004622static int selinux_socket_unix_stream_connect(struct sock *sock,
4623 struct sock *other,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004624 struct sock *newsk)
4625{
David S. Miller3610cda2011-01-05 15:38:53 -08004626 struct sk_security_struct *sksec_sock = sock->sk_security;
4627 struct sk_security_struct *sksec_other = other->sk_security;
Paul Moore4d1e2452010-04-22 14:46:18 -04004628 struct sk_security_struct *sksec_new = newsk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004629 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004630 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004631 int err;
4632
Eric Paris50c205f2012-04-04 15:01:43 -04004633 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004634 ad.u.net = &net;
4635 ad.u.net->sk = other;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004636
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004637 err = avc_has_perm(&selinux_state,
4638 sksec_sock->sid, sksec_other->sid,
Paul Moore4d1e2452010-04-22 14:46:18 -04004639 sksec_other->sclass,
Linus Torvalds1da177e2005-04-16 15:20:36 -07004640 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
4641 if (err)
4642 return err;
4643
Linus Torvalds1da177e2005-04-16 15:20:36 -07004644 /* server child socket */
Paul Moore4d1e2452010-04-22 14:46:18 -04004645 sksec_new->peer_sid = sksec_sock->sid;
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004646 err = security_sid_mls_copy(&selinux_state, sksec_other->sid,
4647 sksec_sock->sid, &sksec_new->sid);
Paul Moore4d1e2452010-04-22 14:46:18 -04004648 if (err)
4649 return err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004650
Paul Moore4d1e2452010-04-22 14:46:18 -04004651 /* connecting socket */
4652 sksec_sock->peer_sid = sksec_new->sid;
4653
4654 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004655}
4656
4657static int selinux_socket_unix_may_send(struct socket *sock,
4658 struct socket *other)
4659{
Paul Moore253bfae2010-04-22 14:46:19 -04004660 struct sk_security_struct *ssec = sock->sk->sk_security;
4661 struct sk_security_struct *osec = other->sk->sk_security;
Thomas Liu2bf49692009-07-14 12:14:09 -04004662 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004663 struct lsm_network_audit net = {0,};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004664
Eric Paris50c205f2012-04-04 15:01:43 -04004665 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004666 ad.u.net = &net;
4667 ad.u.net->sk = other->sk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004668
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004669 return avc_has_perm(&selinux_state,
4670 ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
Paul Moore253bfae2010-04-22 14:46:19 -04004671 &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004672}
4673
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004674static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
4675 char *addrp, u16 family, u32 peer_sid,
Thomas Liu2bf49692009-07-14 12:14:09 -04004676 struct common_audit_data *ad)
Paul Mooreeffad8d2008-01-29 08:49:27 -05004677{
4678 int err;
4679 u32 if_sid;
4680 u32 node_sid;
4681
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004682 err = sel_netif_sid(ns, ifindex, &if_sid);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004683 if (err)
4684 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004685 err = avc_has_perm(&selinux_state,
4686 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004687 SECCLASS_NETIF, NETIF__INGRESS, ad);
4688 if (err)
4689 return err;
4690
4691 err = sel_netnode_sid(addrp, family, &node_sid);
4692 if (err)
4693 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004694 return avc_has_perm(&selinux_state,
4695 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004696 SECCLASS_NODE, NODE__RECVFROM, ad);
4697}
4698
Paul Moore220deb92008-01-29 08:38:23 -05004699static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
Paul Moored8395c82008-10-10 10:16:30 -04004700 u16 family)
Paul Moore220deb92008-01-29 08:38:23 -05004701{
Paul Moore277d3422008-12-31 12:54:11 -05004702 int err = 0;
Paul Moore220deb92008-01-29 08:38:23 -05004703 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004704 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004705 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004706 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04004707 char *addrp;
4708
Eric Paris50c205f2012-04-04 15:01:43 -04004709 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004710 ad.u.net = &net;
4711 ad.u.net->netif = skb->skb_iif;
4712 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04004713 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
4714 if (err)
4715 return err;
Paul Moore220deb92008-01-29 08:38:23 -05004716
Paul Moore58bfbb52009-03-27 17:10:41 -04004717 if (selinux_secmark_enabled()) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004718 err = avc_has_perm(&selinux_state,
4719 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Moored8395c82008-10-10 10:16:30 -04004720 PACKET__RECV, &ad);
Paul Moore58bfbb52009-03-27 17:10:41 -04004721 if (err)
4722 return err;
4723 }
Paul Moore220deb92008-01-29 08:38:23 -05004724
Steffen Klassertb9679a72011-02-23 12:55:21 +01004725 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4726 if (err)
4727 return err;
4728 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004729
James Morris4e5ab4c2006-06-09 00:33:33 -07004730 return err;
4731}
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004732
James Morris4e5ab4c2006-06-09 00:33:33 -07004733static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4734{
Paul Moore220deb92008-01-29 08:38:23 -05004735 int err;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004736 struct sk_security_struct *sksec = sk->sk_security;
Paul Moore220deb92008-01-29 08:38:23 -05004737 u16 family = sk->sk_family;
4738 u32 sk_sid = sksec->sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04004739 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04004740 struct lsm_network_audit net = {0,};
Paul Moore220deb92008-01-29 08:38:23 -05004741 char *addrp;
Paul Moored8395c82008-10-10 10:16:30 -04004742 u8 secmark_active;
4743 u8 peerlbl_active;
James Morris4e5ab4c2006-06-09 00:33:33 -07004744
James Morris4e5ab4c2006-06-09 00:33:33 -07004745 if (family != PF_INET && family != PF_INET6)
Paul Moore220deb92008-01-29 08:38:23 -05004746 return 0;
James Morris4e5ab4c2006-06-09 00:33:33 -07004747
4748 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
Al Viro87fcd702006-12-04 22:00:55 +00004749 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
James Morris4e5ab4c2006-06-09 00:33:33 -07004750 family = PF_INET;
4751
Paul Moored8395c82008-10-10 10:16:30 -04004752 /* If any sort of compatibility mode is enabled then handoff processing
4753 * to the selinux_sock_rcv_skb_compat() function to deal with the
4754 * special handling. We do this in an attempt to keep this function
4755 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004756 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04004757 return selinux_sock_rcv_skb_compat(sk, skb, family);
4758
4759 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04004760 peerlbl_active = selinux_peerlbl_enabled();
Paul Moored8395c82008-10-10 10:16:30 -04004761 if (!secmark_active && !peerlbl_active)
4762 return 0;
4763
Eric Paris50c205f2012-04-04 15:01:43 -04004764 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04004765 ad.u.net = &net;
4766 ad.u.net->netif = skb->skb_iif;
4767 ad.u.net->family = family;
Paul Moore224dfbd2008-01-29 08:38:13 -05004768 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
James Morris4e5ab4c2006-06-09 00:33:33 -07004769 if (err)
Paul Moore220deb92008-01-29 08:38:23 -05004770 return err;
James Morris4e5ab4c2006-06-09 00:33:33 -07004771
Paul Moored8395c82008-10-10 10:16:30 -04004772 if (peerlbl_active) {
Paul Moored621d352008-01-29 08:43:36 -05004773 u32 peer_sid;
4774
4775 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
4776 if (err)
4777 return err;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04004778 err = selinux_inet_sys_rcv_skb(sock_net(sk), skb->skb_iif,
4779 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04004780 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004781 selinux_netlbl_err(skb, family, err, 0);
Paul Mooreeffad8d2008-01-29 08:49:27 -05004782 return err;
Paul Mooredfaebe92008-10-10 10:16:31 -04004783 }
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004784 err = avc_has_perm(&selinux_state,
4785 sk_sid, peer_sid, SECCLASS_PEER,
Paul Moored621d352008-01-29 08:43:36 -05004786 PEER__RECV, &ad);
Chad Hanson46d01d62013-12-23 17:45:01 -05004787 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04004788 selinux_netlbl_err(skb, family, err, 0);
Chad Hanson46d01d62013-12-23 17:45:01 -05004789 return err;
4790 }
Paul Moored621d352008-01-29 08:43:36 -05004791 }
4792
Paul Moored8395c82008-10-10 10:16:30 -04004793 if (secmark_active) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004794 err = avc_has_perm(&selinux_state,
4795 sk_sid, skb->secmark, SECCLASS_PACKET,
Paul Mooreeffad8d2008-01-29 08:49:27 -05004796 PACKET__RECV, &ad);
4797 if (err)
4798 return err;
4799 }
4800
Paul Moored621d352008-01-29 08:43:36 -05004801 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004802}
4803
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004804static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
4805 int __user *optlen, unsigned len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004806{
4807 int err = 0;
4808 char *scontext;
4809 u32 scontext_len;
Paul Moore253bfae2010-04-22 14:46:19 -04004810 struct sk_security_struct *sksec = sock->sk->sk_security;
Paul Moore3de4bab2006-11-17 17:38:54 -05004811 u32 peer_sid = SECSID_NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004812
Paul Moore253bfae2010-04-22 14:46:19 -04004813 if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
Richard Hainesd4529302018-02-13 20:57:18 +00004814 sksec->sclass == SECCLASS_TCP_SOCKET ||
4815 sksec->sclass == SECCLASS_SCTP_SOCKET)
Eric Parisdd3e7832010-04-07 15:08:46 -04004816 peer_sid = sksec->peer_sid;
Paul Moore253bfae2010-04-22 14:46:19 -04004817 if (peer_sid == SECSID_NULL)
4818 return -ENOPROTOOPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004819
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004820 err = security_sid_to_context(&selinux_state, peer_sid, &scontext,
4821 &scontext_len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004822 if (err)
Paul Moore253bfae2010-04-22 14:46:19 -04004823 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004824
4825 if (scontext_len > len) {
4826 err = -ERANGE;
4827 goto out_len;
4828 }
4829
4830 if (copy_to_user(optval, scontext, scontext_len))
4831 err = -EFAULT;
4832
4833out_len:
4834 if (put_user(scontext_len, optlen))
4835 err = -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004836 kfree(scontext);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004837 return err;
4838}
4839
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004840static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004841{
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004842 u32 peer_secid = SECSID_NULL;
Paul Moore75e22912008-01-29 08:38:04 -05004843 u16 family;
Paul Moore899134f2016-03-28 15:19:10 -04004844 struct inode_security_struct *isec;
Catherine Zhang877ce7c2006-06-29 12:27:47 -07004845
Paul Mooreaa862902008-10-10 10:16:29 -04004846 if (skb && skb->protocol == htons(ETH_P_IP))
4847 family = PF_INET;
4848 else if (skb && skb->protocol == htons(ETH_P_IPV6))
4849 family = PF_INET6;
4850 else if (sock)
Paul Moore75e22912008-01-29 08:38:04 -05004851 family = sock->sk->sk_family;
Paul Moore75e22912008-01-29 08:38:04 -05004852 else
4853 goto out;
4854
Paul Moore899134f2016-03-28 15:19:10 -04004855 if (sock && family == PF_UNIX) {
4856 isec = inode_security_novalidate(SOCK_INODE(sock));
4857 peer_secid = isec->sid;
4858 } else if (skb)
Paul Moore220deb92008-01-29 08:38:23 -05004859 selinux_skb_peerlbl_sid(skb, family, &peer_secid);
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004860
Paul Moore75e22912008-01-29 08:38:04 -05004861out:
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07004862 *secid = peer_secid;
Paul Moore75e22912008-01-29 08:38:04 -05004863 if (peer_secid == SECSID_NULL)
4864 return -EINVAL;
4865 return 0;
Catherine Zhang2c7946a2006-03-20 22:41:23 -08004866}
4867
Al Viro7d877f32005-10-21 03:20:43 -04004868static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004869{
Paul Moore84914b72010-04-22 14:46:18 -04004870 struct sk_security_struct *sksec;
4871
4872 sksec = kzalloc(sizeof(*sksec), priority);
4873 if (!sksec)
4874 return -ENOMEM;
4875
4876 sksec->peer_sid = SECINITSID_UNLABELED;
4877 sksec->sid = SECINITSID_UNLABELED;
Stephen Smalley5dee25d2015-07-10 17:19:57 -04004878 sksec->sclass = SECCLASS_SOCKET;
Paul Moore84914b72010-04-22 14:46:18 -04004879 selinux_netlbl_sk_security_reset(sksec);
4880 sk->sk_security = sksec;
4881
4882 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004883}
4884
4885static void selinux_sk_free_security(struct sock *sk)
4886{
Paul Moore84914b72010-04-22 14:46:18 -04004887 struct sk_security_struct *sksec = sk->sk_security;
4888
4889 sk->sk_security = NULL;
4890 selinux_netlbl_sk_security_free(sksec);
4891 kfree(sksec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004892}
4893
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004894static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
4895{
Eric Parisdd3e7832010-04-07 15:08:46 -04004896 struct sk_security_struct *sksec = sk->sk_security;
4897 struct sk_security_struct *newsksec = newsk->sk_security;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004898
Eric Parisdd3e7832010-04-07 15:08:46 -04004899 newsksec->sid = sksec->sid;
4900 newsksec->peer_sid = sksec->peer_sid;
4901 newsksec->sclass = sksec->sclass;
Paul Moore99f59ed2006-08-29 17:53:48 -07004902
Eric Parisdd3e7832010-04-07 15:08:46 -04004903 selinux_netlbl_sk_security_reset(newsksec);
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004904}
4905
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004906static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004907{
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004908 if (!sk)
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004909 *secid = SECINITSID_ANY_SOCKET;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004910 else {
4911 struct sk_security_struct *sksec = sk->sk_security;
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004912
Venkat Yekkiralabeb8d132006-08-04 23:12:42 -07004913 *secid = sksec->sid;
Venkat Yekkirala892c1412006-08-04 23:08:56 -07004914 }
Trent Jaegerd28d1e02005-12-13 23:12:40 -08004915}
4916
Eric Paris828dfe12008-04-17 13:17:49 -04004917static void selinux_sock_graft(struct sock *sk, struct socket *parent)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004918{
Andreas Gruenbacher5d226df2015-12-24 11:09:40 -05004919 struct inode_security_struct *isec =
4920 inode_security_novalidate(SOCK_INODE(parent));
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004921 struct sk_security_struct *sksec = sk->sk_security;
4922
Paul Moore2873ead2014-07-28 10:42:48 -04004923 if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||
4924 sk->sk_family == PF_UNIX)
David Woodhouse2148ccc2006-09-29 15:50:25 -07004925 isec->sid = sksec->sid;
Paul Moore220deb92008-01-29 08:38:23 -05004926 sksec->sclass = isec->sclass;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07004927}
4928
Richard Hainesd4529302018-02-13 20:57:18 +00004929/* Called whenever SCTP receives an INIT chunk. This happens when an incoming
4930 * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association
4931 * already present).
4932 */
4933static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
4934 struct sk_buff *skb)
4935{
4936 struct sk_security_struct *sksec = ep->base.sk->sk_security;
4937 struct common_audit_data ad;
4938 struct lsm_network_audit net = {0,};
4939 u8 peerlbl_active;
4940 u32 peer_sid = SECINITSID_UNLABELED;
4941 u32 conn_sid;
4942 int err = 0;
4943
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05004944 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00004945 return 0;
4946
4947 peerlbl_active = selinux_peerlbl_enabled();
4948
4949 if (peerlbl_active) {
4950 /* This will return peer_sid = SECSID_NULL if there are
4951 * no peer labels, see security_net_peersid_resolve().
4952 */
4953 err = selinux_skb_peerlbl_sid(skb, ep->base.sk->sk_family,
4954 &peer_sid);
4955 if (err)
4956 return err;
4957
4958 if (peer_sid == SECSID_NULL)
4959 peer_sid = SECINITSID_UNLABELED;
4960 }
4961
4962 if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) {
4963 sksec->sctp_assoc_state = SCTP_ASSOC_SET;
4964
4965 /* Here as first association on socket. As the peer SID
4966 * was allowed by peer recv (and the netif/node checks),
4967 * then it is approved by policy and used as the primary
4968 * peer SID for getpeercon(3).
4969 */
4970 sksec->peer_sid = peer_sid;
4971 } else if (sksec->peer_sid != peer_sid) {
4972 /* Other association peer SIDs are checked to enforce
4973 * consistency among the peer SIDs.
4974 */
4975 ad.type = LSM_AUDIT_DATA_NET;
4976 ad.u.net = &net;
4977 ad.u.net->sk = ep->base.sk;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05004978 err = avc_has_perm(&selinux_state,
4979 sksec->peer_sid, peer_sid, sksec->sclass,
Richard Hainesd4529302018-02-13 20:57:18 +00004980 SCTP_SOCKET__ASSOCIATION, &ad);
4981 if (err)
4982 return err;
4983 }
4984
4985 /* Compute the MLS component for the connection and store
4986 * the information in ep. This will be used by SCTP TCP type
4987 * sockets and peeled off connections as they cause a new
4988 * socket to be generated. selinux_sctp_sk_clone() will then
4989 * plug this into the new socket.
4990 */
4991 err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid);
4992 if (err)
4993 return err;
4994
4995 ep->secid = conn_sid;
4996 ep->peer_secid = peer_sid;
4997
4998 /* Set any NetLabel labels including CIPSO/CALIPSO options. */
4999 return selinux_netlbl_sctp_assoc_request(ep, skb);
5000}
5001
5002/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
5003 * based on their @optname.
5004 */
5005static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5006 struct sockaddr *address,
5007 int addrlen)
5008{
5009 int len, err = 0, walk_size = 0;
5010 void *addr_buf;
5011 struct sockaddr *addr;
5012 struct socket *sock;
5013
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005014 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005015 return 0;
5016
5017 /* Process one or more addresses that may be IPv4 or IPv6 */
5018 sock = sk->sk_socket;
5019 addr_buf = address;
5020
5021 while (walk_size < addrlen) {
Ondrej Mosnacekc1383252018-11-13 16:16:08 +01005022 if (walk_size + sizeof(sa_family_t) > addrlen)
5023 return -EINVAL;
5024
Richard Hainesd4529302018-02-13 20:57:18 +00005025 addr = addr_buf;
5026 switch (addr->sa_family) {
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005027 case AF_UNSPEC:
Richard Hainesd4529302018-02-13 20:57:18 +00005028 case AF_INET:
5029 len = sizeof(struct sockaddr_in);
5030 break;
5031 case AF_INET6:
5032 len = sizeof(struct sockaddr_in6);
5033 break;
5034 default:
Alexey Kodanev4152dc92018-05-11 20:15:13 +03005035 return -EINVAL;
Richard Hainesd4529302018-02-13 20:57:18 +00005036 }
5037
5038 err = -EINVAL;
5039 switch (optname) {
5040 /* Bind checks */
5041 case SCTP_PRIMARY_ADDR:
5042 case SCTP_SET_PEER_PRIMARY_ADDR:
5043 case SCTP_SOCKOPT_BINDX_ADD:
5044 err = selinux_socket_bind(sock, addr, len);
5045 break;
5046 /* Connect checks */
5047 case SCTP_SOCKOPT_CONNECTX:
5048 case SCTP_PARAM_SET_PRIMARY:
5049 case SCTP_PARAM_ADD_IP:
5050 case SCTP_SENDMSG_CONNECT:
5051 err = selinux_socket_connect_helper(sock, addr, len);
5052 if (err)
5053 return err;
5054
5055 /* As selinux_sctp_bind_connect() is called by the
5056 * SCTP protocol layer, the socket is already locked,
5057 * therefore selinux_netlbl_socket_connect_locked() is
5058 * is called here. The situations handled are:
5059 * sctp_connectx(3), sctp_sendmsg(3), sendmsg(2),
5060 * whenever a new IP address is added or when a new
5061 * primary address is selected.
5062 * Note that an SCTP connect(2) call happens before
5063 * the SCTP protocol layer and is handled via
5064 * selinux_socket_connect().
5065 */
5066 err = selinux_netlbl_socket_connect_locked(sk, addr);
5067 break;
5068 }
5069
5070 if (err)
5071 return err;
5072
5073 addr_buf += len;
5074 walk_size += len;
5075 }
5076
5077 return 0;
5078}
5079
5080/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */
5081static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
5082 struct sock *newsk)
5083{
5084 struct sk_security_struct *sksec = sk->sk_security;
5085 struct sk_security_struct *newsksec = newsk->sk_security;
5086
5087 /* If policy does not support SECCLASS_SCTP_SOCKET then call
5088 * the non-sctp clone version.
5089 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005090 if (!selinux_policycap_extsockclass())
Richard Hainesd4529302018-02-13 20:57:18 +00005091 return selinux_sk_clone_security(sk, newsk);
5092
5093 newsksec->sid = ep->secid;
5094 newsksec->peer_sid = ep->peer_secid;
5095 newsksec->sclass = sksec->sclass;
5096 selinux_netlbl_sctp_sk_clone(sk, newsk);
5097}
5098
Adrian Bunk9a673e52006-08-15 00:03:53 -07005099static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
5100 struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005101{
5102 struct sk_security_struct *sksec = sk->sk_security;
5103 int err;
Paul Moore0b1f24e2013-12-03 11:39:13 -05005104 u16 family = req->rsk_ops->family;
Paul Moore446b8022013-12-04 16:10:51 -05005105 u32 connsid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005106 u32 peersid;
5107
Paul Mooreaa862902008-10-10 10:16:29 -04005108 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
Paul Moore220deb92008-01-29 08:38:23 -05005109 if (err)
5110 return err;
Paul Moore446b8022013-12-04 16:10:51 -05005111 err = selinux_conn_sid(sksec->sid, peersid, &connsid);
5112 if (err)
5113 return err;
5114 req->secid = connsid;
5115 req->peer_secid = peersid;
Venkat Yekkiralaa51c64f2006-07-27 22:01:34 -07005116
Paul Moore389fb8002009-03-27 17:10:34 -04005117 return selinux_netlbl_inet_conn_request(req, family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005118}
5119
Adrian Bunk9a673e52006-08-15 00:03:53 -07005120static void selinux_inet_csk_clone(struct sock *newsk,
5121 const struct request_sock *req)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005122{
5123 struct sk_security_struct *newsksec = newsk->sk_security;
5124
5125 newsksec->sid = req->secid;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005126 newsksec->peer_sid = req->peer_secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005127 /* NOTE: Ideally, we should also get the isec->sid for the
5128 new socket in sync, but we don't have the isec available yet.
5129 So we will wait until sock_graft to do it, by which
5130 time it will have been created and available. */
Paul Moore99f59ed2006-08-29 17:53:48 -07005131
Paul Moore9f2ad662006-11-17 17:38:53 -05005132 /* We don't need to take any sort of lock here as we are the only
5133 * thread with access to newsksec */
Paul Moore389fb8002009-03-27 17:10:34 -04005134 selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005135}
5136
Paul Moore014ab192008-10-10 10:16:33 -04005137static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005138{
Paul Mooreaa862902008-10-10 10:16:29 -04005139 u16 family = sk->sk_family;
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005140 struct sk_security_struct *sksec = sk->sk_security;
5141
Paul Mooreaa862902008-10-10 10:16:29 -04005142 /* handle mapped IPv4 packets arriving via IPv6 sockets */
5143 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
5144 family = PF_INET;
5145
5146 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
Venkat Yekkirala6b877692006-11-08 17:04:09 -06005147}
5148
Eric Paris2606fd12010-10-13 16:24:41 -04005149static int selinux_secmark_relabel_packet(u32 sid)
5150{
5151 const struct task_security_struct *__tsec;
5152 u32 tsid;
5153
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07005154 __tsec = selinux_cred(current_cred());
Eric Paris2606fd12010-10-13 16:24:41 -04005155 tsid = __tsec->sid;
5156
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005157 return avc_has_perm(&selinux_state,
5158 tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
5159 NULL);
Eric Paris2606fd12010-10-13 16:24:41 -04005160}
5161
5162static void selinux_secmark_refcount_inc(void)
5163{
5164 atomic_inc(&selinux_secmark_refcount);
5165}
5166
5167static void selinux_secmark_refcount_dec(void)
5168{
5169 atomic_dec(&selinux_secmark_refcount);
5170}
5171
Adrian Bunk9a673e52006-08-15 00:03:53 -07005172static void selinux_req_classify_flow(const struct request_sock *req,
5173 struct flowi *fl)
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005174{
David S. Miller1d28f422011-03-12 00:29:39 -05005175 fl->flowi_secid = req->secid;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005176}
5177
Paul Moore5dbbaf22013-01-14 07:12:19 +00005178static int selinux_tun_dev_alloc_security(void **security)
5179{
5180 struct tun_security_struct *tunsec;
5181
5182 tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
5183 if (!tunsec)
5184 return -ENOMEM;
5185 tunsec->sid = current_sid();
5186
5187 *security = tunsec;
5188 return 0;
5189}
5190
5191static void selinux_tun_dev_free_security(void *security)
5192{
5193 kfree(security);
5194}
5195
Paul Mooreed6d76e2009-08-28 18:12:49 -04005196static int selinux_tun_dev_create(void)
5197{
5198 u32 sid = current_sid();
5199
5200 /* we aren't taking into account the "sockcreate" SID since the socket
5201 * that is being created here is not a socket in the traditional sense,
5202 * instead it is a private sock, accessible only to the kernel, and
5203 * representing a wide range of network traffic spanning multiple
5204 * connections unlike traditional sockets - check the TUN driver to
5205 * get a better understanding of why this socket is special */
5206
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005207 return avc_has_perm(&selinux_state,
5208 sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005209 NULL);
5210}
5211
Paul Moore5dbbaf22013-01-14 07:12:19 +00005212static int selinux_tun_dev_attach_queue(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005213{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005214 struct tun_security_struct *tunsec = security;
5215
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005216 return avc_has_perm(&selinux_state,
5217 current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Moore5dbbaf22013-01-14 07:12:19 +00005218 TUN_SOCKET__ATTACH_QUEUE, NULL);
5219}
5220
5221static int selinux_tun_dev_attach(struct sock *sk, void *security)
5222{
5223 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005224 struct sk_security_struct *sksec = sk->sk_security;
5225
5226 /* we don't currently perform any NetLabel based labeling here and it
5227 * isn't clear that we would want to do so anyway; while we could apply
5228 * labeling without the support of the TUN user the resulting labeled
5229 * traffic from the other end of the connection would almost certainly
5230 * cause confusion to the TUN user that had no idea network labeling
5231 * protocols were being used */
5232
Paul Moore5dbbaf22013-01-14 07:12:19 +00005233 sksec->sid = tunsec->sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005234 sksec->sclass = SECCLASS_TUN_SOCKET;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005235
5236 return 0;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005237}
5238
Paul Moore5dbbaf22013-01-14 07:12:19 +00005239static int selinux_tun_dev_open(void *security)
Paul Mooreed6d76e2009-08-28 18:12:49 -04005240{
Paul Moore5dbbaf22013-01-14 07:12:19 +00005241 struct tun_security_struct *tunsec = security;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005242 u32 sid = current_sid();
5243 int err;
5244
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005245 err = avc_has_perm(&selinux_state,
5246 sid, tunsec->sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005247 TUN_SOCKET__RELABELFROM, NULL);
5248 if (err)
5249 return err;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005250 err = avc_has_perm(&selinux_state,
5251 sid, sid, SECCLASS_TUN_SOCKET,
Paul Mooreed6d76e2009-08-28 18:12:49 -04005252 TUN_SOCKET__RELABELTO, NULL);
5253 if (err)
5254 return err;
Paul Moore5dbbaf22013-01-14 07:12:19 +00005255 tunsec->sid = sid;
Paul Mooreed6d76e2009-08-28 18:12:49 -04005256
5257 return 0;
5258}
5259
Linus Torvalds1da177e2005-04-16 15:20:36 -07005260static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
5261{
5262 int err = 0;
5263 u32 perm;
5264 struct nlmsghdr *nlh;
Paul Moore253bfae2010-04-22 14:46:19 -04005265 struct sk_security_struct *sksec = sk->sk_security;
Eric Paris828dfe12008-04-17 13:17:49 -04005266
Hong zhi guo77954982013-03-27 06:49:35 +00005267 if (skb->len < NLMSG_HDRLEN) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005268 err = -EINVAL;
5269 goto out;
5270 }
Arnaldo Carvalho de Melob529ccf2007-04-25 19:08:35 -07005271 nlh = nlmsg_hdr(skb);
Eric Paris828dfe12008-04-17 13:17:49 -04005272
Paul Moore253bfae2010-04-22 14:46:19 -04005273 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005274 if (err) {
5275 if (err == -EINVAL) {
Vladis Dronov76319942015-12-24 11:09:41 -05005276 pr_warn_ratelimited("SELinux: unrecognized netlink"
5277 " message: protocol=%hu nlmsg_type=%hu sclass=%s"
5278 " pig=%d comm=%s\n",
Marek Milkoviccded3ff2015-06-04 16:22:16 -04005279 sk->sk_protocol, nlh->nlmsg_type,
Vladis Dronov76319942015-12-24 11:09:41 -05005280 secclass_map[sksec->sclass - 1].name,
5281 task_pid_nr(current), current->comm);
Paul Mooree5a5ca92018-03-01 17:38:30 -05005282 if (!enforcing_enabled(&selinux_state) ||
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005283 security_get_allow_unknown(&selinux_state))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005284 err = 0;
5285 }
5286
5287 /* Ignore */
5288 if (err == -ENOENT)
5289 err = 0;
5290 goto out;
5291 }
5292
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005293 err = sock_has_perm(sk, perm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005294out:
5295 return err;
5296}
5297
5298#ifdef CONFIG_NETFILTER
5299
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005300static unsigned int selinux_ip_forward(struct sk_buff *skb,
5301 const struct net_device *indev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005302 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005303{
Paul Mooredfaebe92008-10-10 10:16:31 -04005304 int err;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005305 char *addrp;
5306 u32 peer_sid;
Thomas Liu2bf49692009-07-14 12:14:09 -04005307 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005308 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005309 u8 secmark_active;
Paul Moore948bf852008-10-10 10:16:32 -04005310 u8 netlbl_active;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005311 u8 peerlbl_active;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005312
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005313 if (!selinux_policycap_netpeer())
Paul Mooreeffad8d2008-01-29 08:49:27 -05005314 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005315
Paul Mooreeffad8d2008-01-29 08:49:27 -05005316 secmark_active = selinux_secmark_enabled();
Paul Moore948bf852008-10-10 10:16:32 -04005317 netlbl_active = netlbl_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005318 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005319 if (!secmark_active && !peerlbl_active)
5320 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005321
Paul Moored8395c82008-10-10 10:16:30 -04005322 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
5323 return NF_DROP;
5324
Eric Paris50c205f2012-04-04 15:01:43 -04005325 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005326 ad.u.net = &net;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005327 ad.u.net->netif = indev->ifindex;
Eric Paris48c62af2012-04-02 13:15:44 -04005328 ad.u.net->family = family;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005329 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
5330 return NF_DROP;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005331
Paul Mooredfaebe92008-10-10 10:16:31 -04005332 if (peerlbl_active) {
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005333 err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
5334 addrp, family, peer_sid, &ad);
Paul Mooredfaebe92008-10-10 10:16:31 -04005335 if (err) {
Huw Daviesa04e71f2016-06-27 15:06:16 -04005336 selinux_netlbl_err(skb, family, err, 1);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005337 return NF_DROP;
Paul Mooredfaebe92008-10-10 10:16:31 -04005338 }
5339 }
Paul Mooreeffad8d2008-01-29 08:49:27 -05005340
5341 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005342 if (avc_has_perm(&selinux_state,
5343 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005344 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
5345 return NF_DROP;
5346
Paul Moore948bf852008-10-10 10:16:32 -04005347 if (netlbl_active)
5348 /* we do this in the FORWARD path and not the POST_ROUTING
5349 * path because we want to make sure we apply the necessary
5350 * labeling before IPsec is applied so we can leverage AH
5351 * protection */
5352 if (selinux_netlbl_skbuff_setsid(skb, family, peer_sid) != 0)
5353 return NF_DROP;
5354
Paul Mooreeffad8d2008-01-29 08:49:27 -05005355 return NF_ACCEPT;
5356}
5357
Eric W. Biederman06198b32015-09-18 14:33:06 -05005358static unsigned int selinux_ipv4_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005359 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005360 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005361{
David S. Miller238e54c2015-04-03 20:32:56 -04005362 return selinux_ip_forward(skb, state->in, PF_INET);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005363}
5364
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005365#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005366static unsigned int selinux_ipv6_forward(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005367 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005368 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005369{
David S. Miller238e54c2015-04-03 20:32:56 -04005370 return selinux_ip_forward(skb, state->in, PF_INET6);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005371}
5372#endif /* IPV6 */
5373
Paul Moore948bf852008-10-10 10:16:32 -04005374static unsigned int selinux_ip_output(struct sk_buff *skb,
5375 u16 family)
5376{
Paul Moore47180062013-12-04 16:10:45 -05005377 struct sock *sk;
Paul Moore948bf852008-10-10 10:16:32 -04005378 u32 sid;
5379
5380 if (!netlbl_enabled())
5381 return NF_ACCEPT;
5382
5383 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
5384 * because we want to make sure we apply the necessary labeling
5385 * before IPsec is applied so we can leverage AH protection */
Paul Moore47180062013-12-04 16:10:45 -05005386 sk = skb->sk;
5387 if (sk) {
5388 struct sk_security_struct *sksec;
5389
Eric Dumazete446f9d2015-10-08 05:01:55 -07005390 if (sk_listener(sk))
Paul Moore47180062013-12-04 16:10:45 -05005391 /* if the socket is the listening state then this
5392 * packet is a SYN-ACK packet which means it needs to
5393 * be labeled based on the connection/request_sock and
5394 * not the parent socket. unfortunately, we can't
5395 * lookup the request_sock yet as it isn't queued on
5396 * the parent socket until after the SYN-ACK is sent.
5397 * the "solution" is to simply pass the packet as-is
5398 * as any IP option based labeling should be copied
5399 * from the initial connection request (in the IP
5400 * layer). it is far from ideal, but until we get a
5401 * security label in the packet itself this is the
5402 * best we can do. */
5403 return NF_ACCEPT;
5404
5405 /* standard practice, label using the parent socket */
5406 sksec = sk->sk_security;
Paul Moore948bf852008-10-10 10:16:32 -04005407 sid = sksec->sid;
5408 } else
5409 sid = SECINITSID_KERNEL;
5410 if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
5411 return NF_DROP;
5412
5413 return NF_ACCEPT;
5414}
5415
Eric W. Biederman06198b32015-09-18 14:33:06 -05005416static unsigned int selinux_ipv4_output(void *priv,
Paul Moore948bf852008-10-10 10:16:32 -04005417 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005418 const struct nf_hook_state *state)
Paul Moore948bf852008-10-10 10:16:32 -04005419{
5420 return selinux_ip_output(skb, PF_INET);
5421}
5422
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005423#if IS_ENABLED(CONFIG_IPV6)
Huw Davies2917f572016-06-27 15:06:15 -04005424static unsigned int selinux_ipv6_output(void *priv,
5425 struct sk_buff *skb,
5426 const struct nf_hook_state *state)
5427{
5428 return selinux_ip_output(skb, PF_INET6);
5429}
5430#endif /* IPV6 */
5431
Paul Mooreeffad8d2008-01-29 08:49:27 -05005432static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
5433 int ifindex,
Paul Moored8395c82008-10-10 10:16:30 -04005434 u16 family)
James Morris4e5ab4c2006-06-09 00:33:33 -07005435{
Eric Dumazet54abc682015-11-08 10:54:07 -08005436 struct sock *sk = skb_to_full_sk(skb);
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005437 struct sk_security_struct *sksec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005438 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005439 struct lsm_network_audit net = {0,};
Paul Moored8395c82008-10-10 10:16:30 -04005440 char *addrp;
5441 u8 proto;
James Morris4e5ab4c2006-06-09 00:33:33 -07005442
Paul Mooreeffad8d2008-01-29 08:49:27 -05005443 if (sk == NULL)
5444 return NF_ACCEPT;
Venkat Yekkirala4237c752006-07-24 23:32:50 -07005445 sksec = sk->sk_security;
James Morris4e5ab4c2006-06-09 00:33:33 -07005446
Eric Paris50c205f2012-04-04 15:01:43 -04005447 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005448 ad.u.net = &net;
5449 ad.u.net->netif = ifindex;
5450 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005451 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
5452 return NF_DROP;
5453
Paul Moore58bfbb52009-03-27 17:10:41 -04005454 if (selinux_secmark_enabled())
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005455 if (avc_has_perm(&selinux_state,
5456 sksec->sid, skb->secmark,
Paul Moored8395c82008-10-10 10:16:30 -04005457 SECCLASS_PACKET, PACKET__SEND, &ad))
Eric Paris2fe66ec2010-11-23 06:28:08 +00005458 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005459
Steffen Klassertb9679a72011-02-23 12:55:21 +01005460 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
5461 return NF_DROP_ERR(-ECONNREFUSED);
James Morris4e5ab4c2006-06-09 00:33:33 -07005462
Paul Mooreeffad8d2008-01-29 08:49:27 -05005463 return NF_ACCEPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005464}
5465
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005466static unsigned int selinux_ip_postroute(struct sk_buff *skb,
5467 const struct net_device *outdev,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005468 u16 family)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005469{
Paul Mooreeffad8d2008-01-29 08:49:27 -05005470 u32 secmark_perm;
5471 u32 peer_sid;
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005472 int ifindex = outdev->ifindex;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005473 struct sock *sk;
Thomas Liu2bf49692009-07-14 12:14:09 -04005474 struct common_audit_data ad;
Eric Paris48c62af2012-04-02 13:15:44 -04005475 struct lsm_network_audit net = {0,};
Paul Mooreeffad8d2008-01-29 08:49:27 -05005476 char *addrp;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005477 u8 secmark_active;
5478 u8 peerlbl_active;
5479
Paul Mooreeffad8d2008-01-29 08:49:27 -05005480 /* If any sort of compatibility mode is enabled then handoff processing
5481 * to the selinux_ip_postroute_compat() function to deal with the
5482 * special handling. We do this in an attempt to keep this function
5483 * as fast and as clean as possible. */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005484 if (!selinux_policycap_netpeer())
Paul Moored8395c82008-10-10 10:16:30 -04005485 return selinux_ip_postroute_compat(skb, ifindex, family);
Paul Moorec0828e52013-12-10 14:58:01 -05005486
Paul Mooreeffad8d2008-01-29 08:49:27 -05005487 secmark_active = selinux_secmark_enabled();
Chris PeBenito2be4d742013-05-03 09:05:39 -04005488 peerlbl_active = selinux_peerlbl_enabled();
Paul Mooreeffad8d2008-01-29 08:49:27 -05005489 if (!secmark_active && !peerlbl_active)
5490 return NF_ACCEPT;
5491
Eric Dumazet54abc682015-11-08 10:54:07 -08005492 sk = skb_to_full_sk(skb);
Paul Moorec0828e52013-12-10 14:58:01 -05005493
Paul Mooreeffad8d2008-01-29 08:49:27 -05005494#ifdef CONFIG_XFRM
5495 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
5496 * packet transformation so allow the packet to pass without any checks
5497 * since we'll have another chance to perform access control checks
5498 * when the packet is on it's final way out.
5499 * NOTE: there appear to be some IPv6 multicast cases where skb->dst
Paul Moorec0828e52013-12-10 14:58:01 -05005500 * is NULL, in this case go ahead and apply access control.
5501 * NOTE: if this is a local socket (skb->sk != NULL) that is in the
5502 * TCP listening state we cannot wait until the XFRM processing
5503 * is done as we will miss out on the SA label if we do;
5504 * unfortunately, this means more work, but it is only once per
5505 * connection. */
5506 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
Eric Dumazete446f9d2015-10-08 05:01:55 -07005507 !(sk && sk_listener(sk)))
Paul Mooreeffad8d2008-01-29 08:49:27 -05005508 return NF_ACCEPT;
5509#endif
Paul Mooreeffad8d2008-01-29 08:49:27 -05005510
Paul Moored8395c82008-10-10 10:16:30 -04005511 if (sk == NULL) {
Paul Moore446b8022013-12-04 16:10:51 -05005512 /* Without an associated socket the packet is either coming
5513 * from the kernel or it is being forwarded; check the packet
5514 * to determine which and if the packet is being forwarded
5515 * query the packet directly to determine the security label. */
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005516 if (skb->skb_iif) {
5517 secmark_perm = PACKET__FORWARD_OUT;
Paul Moored8395c82008-10-10 10:16:30 -04005518 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005519 return NF_DROP;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005520 } else {
5521 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005522 peer_sid = SECINITSID_KERNEL;
Steffen Klassert4a7ab3d2011-02-23 12:56:23 +01005523 }
Eric Dumazete446f9d2015-10-08 05:01:55 -07005524 } else if (sk_listener(sk)) {
Paul Moore446b8022013-12-04 16:10:51 -05005525 /* Locally generated packet but the associated socket is in the
5526 * listening state which means this is a SYN-ACK packet. In
5527 * this particular case the correct security label is assigned
5528 * to the connection/request_sock but unfortunately we can't
5529 * query the request_sock as it isn't queued on the parent
5530 * socket until after the SYN-ACK packet is sent; the only
5531 * viable choice is to regenerate the label like we do in
5532 * selinux_inet_conn_request(). See also selinux_ip_output()
5533 * for similar problems. */
5534 u32 skb_sid;
Eric Dumazete446f9d2015-10-08 05:01:55 -07005535 struct sk_security_struct *sksec;
5536
Eric Dumazete446f9d2015-10-08 05:01:55 -07005537 sksec = sk->sk_security;
Paul Moore446b8022013-12-04 16:10:51 -05005538 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
5539 return NF_DROP;
Paul Moorec0828e52013-12-10 14:58:01 -05005540 /* At this point, if the returned skb peerlbl is SECSID_NULL
5541 * and the packet has been through at least one XFRM
5542 * transformation then we must be dealing with the "final"
5543 * form of labeled IPsec packet; since we've already applied
5544 * all of our access controls on this packet we can safely
5545 * pass the packet. */
5546 if (skb_sid == SECSID_NULL) {
5547 switch (family) {
5548 case PF_INET:
5549 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
5550 return NF_ACCEPT;
5551 break;
5552 case PF_INET6:
5553 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
5554 return NF_ACCEPT;
Paul Moorea7a91a12014-09-03 10:51:59 -04005555 break;
Paul Moorec0828e52013-12-10 14:58:01 -05005556 default:
5557 return NF_DROP_ERR(-ECONNREFUSED);
5558 }
5559 }
Paul Moore446b8022013-12-04 16:10:51 -05005560 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
5561 return NF_DROP;
5562 secmark_perm = PACKET__SEND;
Paul Moored8395c82008-10-10 10:16:30 -04005563 } else {
Paul Moore446b8022013-12-04 16:10:51 -05005564 /* Locally generated packet, fetch the security label from the
5565 * associated socket. */
Paul Mooreeffad8d2008-01-29 08:49:27 -05005566 struct sk_security_struct *sksec = sk->sk_security;
5567 peer_sid = sksec->sid;
5568 secmark_perm = PACKET__SEND;
Paul Mooreeffad8d2008-01-29 08:49:27 -05005569 }
5570
Eric Paris50c205f2012-04-04 15:01:43 -04005571 ad.type = LSM_AUDIT_DATA_NET;
Eric Paris48c62af2012-04-02 13:15:44 -04005572 ad.u.net = &net;
5573 ad.u.net->netif = ifindex;
5574 ad.u.net->family = family;
Paul Moored8395c82008-10-10 10:16:30 -04005575 if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
Eric Paris04f6d702010-11-23 06:28:02 +00005576 return NF_DROP;
Paul Moored8395c82008-10-10 10:16:30 -04005577
Paul Mooreeffad8d2008-01-29 08:49:27 -05005578 if (secmark_active)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005579 if (avc_has_perm(&selinux_state,
5580 peer_sid, skb->secmark,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005581 SECCLASS_PACKET, secmark_perm, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005582 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005583
5584 if (peerlbl_active) {
5585 u32 if_sid;
5586 u32 node_sid;
5587
Paul Moorecbe0d6e2014-09-10 17:09:57 -04005588 if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005589 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005590 if (avc_has_perm(&selinux_state,
5591 peer_sid, if_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005592 SECCLASS_NETIF, NETIF__EGRESS, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005593 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005594
5595 if (sel_netnode_sid(addrp, family, &node_sid))
Eric Paris04f6d702010-11-23 06:28:02 +00005596 return NF_DROP;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005597 if (avc_has_perm(&selinux_state,
5598 peer_sid, node_sid,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005599 SECCLASS_NODE, NODE__SENDTO, &ad))
Eric Paris1f1aaf82010-11-16 11:52:57 +00005600 return NF_DROP_ERR(-ECONNREFUSED);
Paul Mooreeffad8d2008-01-29 08:49:27 -05005601 }
5602
5603 return NF_ACCEPT;
5604}
5605
Eric W. Biederman06198b32015-09-18 14:33:06 -05005606static unsigned int selinux_ipv4_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005607 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005608 const struct nf_hook_state *state)
Paul Mooreeffad8d2008-01-29 08:49:27 -05005609{
David S. Miller238e54c2015-04-03 20:32:56 -04005610 return selinux_ip_postroute(skb, state->out, PF_INET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005611}
5612
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04005613#if IS_ENABLED(CONFIG_IPV6)
Eric W. Biederman06198b32015-09-18 14:33:06 -05005614static unsigned int selinux_ipv6_postroute(void *priv,
Paul Mooreeffad8d2008-01-29 08:49:27 -05005615 struct sk_buff *skb,
David S. Miller238e54c2015-04-03 20:32:56 -04005616 const struct nf_hook_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005617{
David S. Miller238e54c2015-04-03 20:32:56 -04005618 return selinux_ip_postroute(skb, state->out, PF_INET6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005619}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005620#endif /* IPV6 */
5621
5622#endif /* CONFIG_NETFILTER */
5623
Linus Torvalds1da177e2005-04-16 15:20:36 -07005624static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
5625{
Stephen Smalley941fc5b2009-10-01 14:48:23 -04005626 return selinux_nlmsg_perm(sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005627}
5628
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005629static int ipc_alloc_security(struct kern_ipc_perm *perm,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005630 u16 sclass)
5631{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005632 struct ipc_security_struct *isec;
5633
James Morris89d155e2005-10-30 14:59:21 -08005634 isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005635 if (!isec)
5636 return -ENOMEM;
5637
Linus Torvalds1da177e2005-04-16 15:20:36 -07005638 isec->sclass = sclass;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005639 isec->sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005640 perm->security = isec;
5641
5642 return 0;
5643}
5644
5645static void ipc_free_security(struct kern_ipc_perm *perm)
5646{
5647 struct ipc_security_struct *isec = perm->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005648 perm->security = NULL;
5649 kfree(isec);
5650}
5651
5652static int msg_msg_alloc_security(struct msg_msg *msg)
5653{
5654 struct msg_security_struct *msec;
5655
James Morris89d155e2005-10-30 14:59:21 -08005656 msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005657 if (!msec)
5658 return -ENOMEM;
5659
Linus Torvalds1da177e2005-04-16 15:20:36 -07005660 msec->sid = SECINITSID_UNLABELED;
5661 msg->security = msec;
5662
5663 return 0;
5664}
5665
5666static void msg_msg_free_security(struct msg_msg *msg)
5667{
5668 struct msg_security_struct *msec = msg->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005669
5670 msg->security = NULL;
5671 kfree(msec);
5672}
5673
5674static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
Stephen Smalley6af963f2005-05-01 08:58:39 -07005675 u32 perms)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005676{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005677 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005678 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005679 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005680
Casey Schaufler7c653822018-09-21 17:19:45 -07005681 isec = selinux_ipc(ipc_perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005682
Eric Paris50c205f2012-04-04 15:01:43 -04005683 ad.type = LSM_AUDIT_DATA_IPC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005684 ad.u.ipc_id = ipc_perms->key;
5685
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005686 return avc_has_perm(&selinux_state,
5687 sid, isec->sid, isec->sclass, perms, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005688}
5689
5690static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
5691{
5692 return msg_msg_alloc_security(msg);
5693}
5694
5695static void selinux_msg_msg_free_security(struct msg_msg *msg)
5696{
5697 msg_msg_free_security(msg);
5698}
5699
5700/* message queue security operations */
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005701static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005702{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005703 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005704 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005705 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005706 int rc;
5707
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005708 rc = ipc_alloc_security(msq, SECCLASS_MSGQ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005709 if (rc)
5710 return rc;
5711
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005712 isec = msq->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005713
Eric Paris50c205f2012-04-04 15:01:43 -04005714 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005715 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005716
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005717 rc = avc_has_perm(&selinux_state,
5718 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005719 MSGQ__CREATE, &ad);
5720 if (rc) {
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005721 ipc_free_security(msq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005722 return rc;
5723 }
5724 return 0;
5725}
5726
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005727static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005728{
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005729 ipc_free_security(msq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005730}
5731
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005732static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005733{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005734 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005735 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005736 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005737
Casey Schaufler7c653822018-09-21 17:19:45 -07005738 isec = selinux_ipc(msq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005739
Eric Paris50c205f2012-04-04 15:01:43 -04005740 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005741 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005742
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005743 return avc_has_perm(&selinux_state,
5744 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005745 MSGQ__ASSOCIATE, &ad);
5746}
5747
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005748static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005749{
5750 int err;
5751 int perms;
5752
Eric Paris828dfe12008-04-17 13:17:49 -04005753 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005754 case IPC_INFO:
5755 case MSG_INFO:
5756 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005757 return avc_has_perm(&selinux_state,
5758 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005759 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005760 case IPC_STAT:
5761 case MSG_STAT:
Davidlohr Bueso23c8cec2018-04-10 16:35:30 -07005762 case MSG_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763 perms = MSGQ__GETATTR | MSGQ__ASSOCIATE;
5764 break;
5765 case IPC_SET:
5766 perms = MSGQ__SETATTR;
5767 break;
5768 case IPC_RMID:
5769 perms = MSGQ__DESTROY;
5770 break;
5771 default:
5772 return 0;
5773 }
5774
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005775 err = ipc_has_perm(msq, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005776 return err;
5777}
5778
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005779static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005780{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005781 struct ipc_security_struct *isec;
5782 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005783 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005784 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005785 int rc;
5786
Casey Schaufler7c653822018-09-21 17:19:45 -07005787 isec = selinux_ipc(msq);
5788 msec = selinux_msg_msg(msg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005789
5790 /*
5791 * First time through, need to assign label to the message
5792 */
5793 if (msec->sid == SECINITSID_UNLABELED) {
5794 /*
5795 * Compute new sid based on current process and
5796 * message queue this message will be stored in
5797 */
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05005798 rc = security_transition_sid(&selinux_state, sid, isec->sid,
5799 SECCLASS_MSG, NULL, &msec->sid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005800 if (rc)
5801 return rc;
5802 }
5803
Eric Paris50c205f2012-04-04 15:01:43 -04005804 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005805 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005806
5807 /* Can this process write to the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005808 rc = avc_has_perm(&selinux_state,
5809 sid, isec->sid, SECCLASS_MSGQ,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005810 MSGQ__WRITE, &ad);
5811 if (!rc)
5812 /* Can this process send the message */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005813 rc = avc_has_perm(&selinux_state,
5814 sid, msec->sid, SECCLASS_MSG,
David Howells275bb412008-11-14 10:39:19 +11005815 MSG__SEND, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005816 if (!rc)
5817 /* Can the message be put in the queue? */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005818 rc = avc_has_perm(&selinux_state,
5819 msec->sid, isec->sid, SECCLASS_MSGQ,
David Howells275bb412008-11-14 10:39:19 +11005820 MSGQ__ENQUEUE, &ad);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005821
5822 return rc;
5823}
5824
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005825static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005826 struct task_struct *target,
5827 long type, int mode)
5828{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005829 struct ipc_security_struct *isec;
5830 struct msg_security_struct *msec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005831 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005832 u32 sid = task_sid(target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005833 int rc;
5834
Casey Schaufler7c653822018-09-21 17:19:45 -07005835 isec = selinux_ipc(msq);
5836 msec = selinux_msg_msg(msg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005837
Eric Paris50c205f2012-04-04 15:01:43 -04005838 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermand8c6e852018-03-22 21:22:26 -05005839 ad.u.ipc_id = msq->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005840
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005841 rc = avc_has_perm(&selinux_state,
5842 sid, isec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005843 SECCLASS_MSGQ, MSGQ__READ, &ad);
5844 if (!rc)
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005845 rc = avc_has_perm(&selinux_state,
5846 sid, msec->sid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005847 SECCLASS_MSG, MSG__RECEIVE, &ad);
5848 return rc;
5849}
5850
5851/* Shared Memory security operations */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005852static int selinux_shm_alloc_security(struct kern_ipc_perm *shp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005853{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005854 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005855 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005856 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005857 int rc;
5858
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005859 rc = ipc_alloc_security(shp, SECCLASS_SHM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005860 if (rc)
5861 return rc;
5862
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005863 isec = shp->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005864
Eric Paris50c205f2012-04-04 15:01:43 -04005865 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005866 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005867
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005868 rc = avc_has_perm(&selinux_state,
5869 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005870 SHM__CREATE, &ad);
5871 if (rc) {
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005872 ipc_free_security(shp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005873 return rc;
5874 }
5875 return 0;
5876}
5877
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005878static void selinux_shm_free_security(struct kern_ipc_perm *shp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005879{
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005880 ipc_free_security(shp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005881}
5882
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005883static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005884{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005885 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005886 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005887 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005888
Casey Schaufler7c653822018-09-21 17:19:45 -07005889 isec = selinux_ipc(shp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005890
Eric Paris50c205f2012-04-04 15:01:43 -04005891 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005892 ad.u.ipc_id = shp->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005893
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005894 return avc_has_perm(&selinux_state,
5895 sid, isec->sid, SECCLASS_SHM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005896 SHM__ASSOCIATE, &ad);
5897}
5898
5899/* Note, at this point, shp is locked down */
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005900static int selinux_shm_shmctl(struct kern_ipc_perm *shp, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005901{
5902 int perms;
5903 int err;
5904
Eric Paris828dfe12008-04-17 13:17:49 -04005905 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005906 case IPC_INFO:
5907 case SHM_INFO:
5908 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005909 return avc_has_perm(&selinux_state,
5910 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05005911 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005912 case IPC_STAT:
5913 case SHM_STAT:
Davidlohr Buesoc21a6972018-04-10 16:35:23 -07005914 case SHM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07005915 perms = SHM__GETATTR | SHM__ASSOCIATE;
5916 break;
5917 case IPC_SET:
5918 perms = SHM__SETATTR;
5919 break;
5920 case SHM_LOCK:
5921 case SHM_UNLOCK:
5922 perms = SHM__LOCK;
5923 break;
5924 case IPC_RMID:
5925 perms = SHM__DESTROY;
5926 break;
5927 default:
5928 return 0;
5929 }
5930
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005931 err = ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005932 return err;
5933}
5934
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005935static int selinux_shm_shmat(struct kern_ipc_perm *shp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005936 char __user *shmaddr, int shmflg)
5937{
5938 u32 perms;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005939
5940 if (shmflg & SHM_RDONLY)
5941 perms = SHM__READ;
5942 else
5943 perms = SHM__READ | SHM__WRITE;
5944
Eric W. Biederman7191adf2018-03-22 21:08:27 -05005945 return ipc_has_perm(shp, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005946}
5947
5948/* Semaphore security operations */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005949static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005950{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005951 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005952 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005953 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005954 int rc;
5955
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005956 rc = ipc_alloc_security(sma, SECCLASS_SEM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005957 if (rc)
5958 return rc;
5959
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005960 isec = sma->security;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005961
Eric Paris50c205f2012-04-04 15:01:43 -04005962 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005963 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005964
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005965 rc = avc_has_perm(&selinux_state,
5966 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005967 SEM__CREATE, &ad);
5968 if (rc) {
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005969 ipc_free_security(sma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005970 return rc;
5971 }
5972 return 0;
5973}
5974
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005975static void selinux_sem_free_security(struct kern_ipc_perm *sma)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005976{
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005977 ipc_free_security(sma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005978}
5979
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005980static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005981{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005982 struct ipc_security_struct *isec;
Thomas Liu2bf49692009-07-14 12:14:09 -04005983 struct common_audit_data ad;
David Howells275bb412008-11-14 10:39:19 +11005984 u32 sid = current_sid();
Linus Torvalds1da177e2005-04-16 15:20:36 -07005985
Casey Schaufler7c653822018-09-21 17:19:45 -07005986 isec = selinux_ipc(sma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005987
Eric Paris50c205f2012-04-04 15:01:43 -04005988 ad.type = LSM_AUDIT_DATA_IPC;
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005989 ad.u.ipc_id = sma->key;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005990
Stephen Smalley6b6bc622018-03-05 11:47:56 -05005991 return avc_has_perm(&selinux_state,
5992 sid, isec->sid, SECCLASS_SEM,
Linus Torvalds1da177e2005-04-16 15:20:36 -07005993 SEM__ASSOCIATE, &ad);
5994}
5995
5996/* Note, at this point, sma is locked down */
Eric W. Biedermanaefad952018-03-22 20:52:43 -05005997static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005998{
5999 int err;
6000 u32 perms;
6001
Eric Paris828dfe12008-04-17 13:17:49 -04006002 switch (cmd) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006003 case IPC_INFO:
6004 case SEM_INFO:
6005 /* No specific object, just general system-wide information. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006006 return avc_has_perm(&selinux_state,
6007 current_sid(), SECINITSID_KERNEL,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006008 SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006009 case GETPID:
6010 case GETNCNT:
6011 case GETZCNT:
6012 perms = SEM__GETATTR;
6013 break;
6014 case GETVAL:
6015 case GETALL:
6016 perms = SEM__READ;
6017 break;
6018 case SETVAL:
6019 case SETALL:
6020 perms = SEM__WRITE;
6021 break;
6022 case IPC_RMID:
6023 perms = SEM__DESTROY;
6024 break;
6025 case IPC_SET:
6026 perms = SEM__SETATTR;
6027 break;
6028 case IPC_STAT:
6029 case SEM_STAT:
Davidlohr Buesoa280d6d2018-04-10 16:35:26 -07006030 case SEM_STAT_ANY:
Linus Torvalds1da177e2005-04-16 15:20:36 -07006031 perms = SEM__GETATTR | SEM__ASSOCIATE;
6032 break;
6033 default:
6034 return 0;
6035 }
6036
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006037 err = ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006038 return err;
6039}
6040
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006041static int selinux_sem_semop(struct kern_ipc_perm *sma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07006042 struct sembuf *sops, unsigned nsops, int alter)
6043{
6044 u32 perms;
6045
6046 if (alter)
6047 perms = SEM__READ | SEM__WRITE;
6048 else
6049 perms = SEM__READ;
6050
Eric W. Biedermanaefad952018-03-22 20:52:43 -05006051 return ipc_has_perm(sma, perms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006052}
6053
6054static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
6055{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006056 u32 av = 0;
6057
Linus Torvalds1da177e2005-04-16 15:20:36 -07006058 av = 0;
6059 if (flag & S_IRUGO)
6060 av |= IPC__UNIX_READ;
6061 if (flag & S_IWUGO)
6062 av |= IPC__UNIX_WRITE;
6063
6064 if (av == 0)
6065 return 0;
6066
Stephen Smalley6af963f2005-05-01 08:58:39 -07006067 return ipc_has_perm(ipcp, av);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006068}
6069
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02006070static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
6071{
Casey Schaufler7c653822018-09-21 17:19:45 -07006072 struct ipc_security_struct *isec = selinux_ipc(ipcp);
Ahmed S. Darwish713a04ae2008-03-01 21:52:30 +02006073 *secid = isec->sid;
6074}
6075
Eric Paris828dfe12008-04-17 13:17:49 -04006076static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006077{
6078 if (inode)
6079 inode_doinit_with_dentry(inode, dentry);
6080}
6081
6082static int selinux_getprocattr(struct task_struct *p,
Al Viro04ff9702007-03-12 16:17:58 +00006083 char *name, char **value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006084{
David Howells275bb412008-11-14 10:39:19 +11006085 const struct task_security_struct *__tsec;
Dustin Kirkland8c8570f2005-11-03 17:15:16 +00006086 u32 sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006087 int error;
Al Viro04ff9702007-03-12 16:17:58 +00006088 unsigned len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006089
David Howells275bb412008-11-14 10:39:19 +11006090 rcu_read_lock();
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006091 __tsec = selinux_cred(__task_cred(p));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006092
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006093 if (current != p) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006094 error = avc_has_perm(&selinux_state,
6095 current_sid(), __tsec->sid,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006096 SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
6097 if (error)
6098 goto bad;
6099 }
6100
Linus Torvalds1da177e2005-04-16 15:20:36 -07006101 if (!strcmp(name, "current"))
David Howells275bb412008-11-14 10:39:19 +11006102 sid = __tsec->sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006103 else if (!strcmp(name, "prev"))
David Howells275bb412008-11-14 10:39:19 +11006104 sid = __tsec->osid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006105 else if (!strcmp(name, "exec"))
David Howells275bb412008-11-14 10:39:19 +11006106 sid = __tsec->exec_sid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006107 else if (!strcmp(name, "fscreate"))
David Howells275bb412008-11-14 10:39:19 +11006108 sid = __tsec->create_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006109 else if (!strcmp(name, "keycreate"))
David Howells275bb412008-11-14 10:39:19 +11006110 sid = __tsec->keycreate_sid;
Eric Paris42c3e032006-06-26 00:26:03 -07006111 else if (!strcmp(name, "sockcreate"))
David Howells275bb412008-11-14 10:39:19 +11006112 sid = __tsec->sockcreate_sid;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006113 else {
6114 error = -EINVAL;
6115 goto bad;
6116 }
David Howells275bb412008-11-14 10:39:19 +11006117 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006118
6119 if (!sid)
6120 return 0;
6121
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006122 error = security_sid_to_context(&selinux_state, sid, value, &len);
Al Viro04ff9702007-03-12 16:17:58 +00006123 if (error)
6124 return error;
6125 return len;
David Howells275bb412008-11-14 10:39:19 +11006126
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006127bad:
David Howells275bb412008-11-14 10:39:19 +11006128 rcu_read_unlock();
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006129 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006130}
6131
Stephen Smalleyb21507e2017-01-09 10:07:31 -05006132static int selinux_setprocattr(const char *name, void *value, size_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006133{
6134 struct task_security_struct *tsec;
David Howellsd84f4f92008-11-14 10:39:23 +11006135 struct cred *new;
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006136 u32 mysid = current_sid(), sid = 0, ptsid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006137 int error;
6138 char *str = value;
6139
Linus Torvalds1da177e2005-04-16 15:20:36 -07006140 /*
6141 * Basic control over ability to set these attributes at all.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006142 */
6143 if (!strcmp(name, "exec"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006144 error = avc_has_perm(&selinux_state,
6145 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006146 PROCESS__SETEXEC, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006147 else if (!strcmp(name, "fscreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006148 error = avc_has_perm(&selinux_state,
6149 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006150 PROCESS__SETFSCREATE, NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006151 else if (!strcmp(name, "keycreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006152 error = avc_has_perm(&selinux_state,
6153 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006154 PROCESS__SETKEYCREATE, NULL);
Eric Paris42c3e032006-06-26 00:26:03 -07006155 else if (!strcmp(name, "sockcreate"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006156 error = avc_has_perm(&selinux_state,
6157 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006158 PROCESS__SETSOCKCREATE, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006159 else if (!strcmp(name, "current"))
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006160 error = avc_has_perm(&selinux_state,
6161 mysid, mysid, SECCLASS_PROCESS,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006162 PROCESS__SETCURRENT, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006163 else
6164 error = -EINVAL;
6165 if (error)
6166 return error;
6167
6168 /* Obtain a SID for the context, if one was specified. */
Stephen Smalleya050a572017-01-31 11:54:04 -05006169 if (size && str[0] && str[0] != '\n') {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006170 if (str[size-1] == '\n') {
6171 str[size-1] = 0;
6172 size--;
6173 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006174 error = security_context_to_sid(&selinux_state, value, size,
6175 &sid, GFP_KERNEL);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006176 if (error == -EINVAL && !strcmp(name, "fscreate")) {
Stephen Smalleydb590002017-04-20 11:31:30 -04006177 if (!has_cap_mac_admin(true)) {
Eric Parisd6ea83e2012-04-04 13:45:49 -04006178 struct audit_buffer *ab;
6179 size_t audit_size;
6180
6181 /* We strip a nul only if it is at the end, otherwise the
6182 * context contains a nul and we should audit that */
6183 if (str[size - 1] == '\0')
6184 audit_size = size - 1;
6185 else
6186 audit_size = size;
Richard Guy Briggscdfb6b32018-05-12 21:58:20 -04006187 ab = audit_log_start(audit_context(),
6188 GFP_ATOMIC,
6189 AUDIT_SELINUX_ERR);
Eric Parisd6ea83e2012-04-04 13:45:49 -04006190 audit_log_format(ab, "op=fscreate invalid_context=");
6191 audit_log_n_untrustedstring(ab, value, audit_size);
6192 audit_log_end(ab);
6193
Stephen Smalley12b29f32008-05-07 13:03:20 -04006194 return error;
Eric Parisd6ea83e2012-04-04 13:45:49 -04006195 }
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006196 error = security_context_to_sid_force(
6197 &selinux_state,
6198 value, size, &sid);
Stephen Smalley12b29f32008-05-07 13:03:20 -04006199 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006200 if (error)
6201 return error;
6202 }
6203
David Howellsd84f4f92008-11-14 10:39:23 +11006204 new = prepare_creds();
6205 if (!new)
6206 return -ENOMEM;
6207
Linus Torvalds1da177e2005-04-16 15:20:36 -07006208 /* Permission checking based on the specified context is
6209 performed during the actual operation (execve,
6210 open/mkdir/...), when we know the full context of the
David Howellsd84f4f92008-11-14 10:39:23 +11006211 operation. See selinux_bprm_set_creds for the execve
Linus Torvalds1da177e2005-04-16 15:20:36 -07006212 checks and may_create for the file creation checks. The
6213 operation will then fail if the context is not permitted. */
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006214 tsec = selinux_cred(new);
David Howellsd84f4f92008-11-14 10:39:23 +11006215 if (!strcmp(name, "exec")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006216 tsec->exec_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006217 } else if (!strcmp(name, "fscreate")) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006218 tsec->create_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006219 } else if (!strcmp(name, "keycreate")) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006220 error = avc_has_perm(&selinux_state,
6221 mysid, sid, SECCLASS_KEY, KEY__CREATE,
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006222 NULL);
Michael LeMay4eb582c2006-06-26 00:24:57 -07006223 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006224 goto abort_change;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006225 tsec->keycreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006226 } else if (!strcmp(name, "sockcreate")) {
Eric Paris42c3e032006-06-26 00:26:03 -07006227 tsec->sockcreate_sid = sid;
David Howellsd84f4f92008-11-14 10:39:23 +11006228 } else if (!strcmp(name, "current")) {
6229 error = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006230 if (sid == 0)
David Howellsd84f4f92008-11-14 10:39:23 +11006231 goto abort_change;
KaiGai Koheid9250de2008-08-28 16:35:57 +09006232
David Howellsd84f4f92008-11-14 10:39:23 +11006233 /* Only allow single threaded processes to change context */
6234 error = -EPERM;
Oleg Nesterov5bb459b2009-07-10 03:48:23 +02006235 if (!current_is_single_threaded()) {
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006236 error = security_bounded_transition(&selinux_state,
6237 tsec->sid, sid);
David Howellsd84f4f92008-11-14 10:39:23 +11006238 if (error)
6239 goto abort_change;
Eric Paris828dfe12008-04-17 13:17:49 -04006240 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07006241
6242 /* Check permissions for the transition. */
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006243 error = avc_has_perm(&selinux_state,
6244 tsec->sid, sid, SECCLASS_PROCESS,
Eric Paris828dfe12008-04-17 13:17:49 -04006245 PROCESS__DYNTRANSITION, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006246 if (error)
David Howellsd84f4f92008-11-14 10:39:23 +11006247 goto abort_change;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006248
6249 /* Check for ptracing, and update the task SID if ok.
6250 Otherwise, leave SID unchanged and fail. */
Stephen Smalleybe0554c2017-01-09 10:07:31 -05006251 ptsid = ptrace_parent_sid();
Paul Moore0c6181c2016-03-30 21:41:21 -04006252 if (ptsid != 0) {
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006253 error = avc_has_perm(&selinux_state,
6254 ptsid, sid, SECCLASS_PROCESS,
David Howellsd84f4f92008-11-14 10:39:23 +11006255 PROCESS__PTRACE, NULL);
6256 if (error)
6257 goto abort_change;
6258 }
6259
6260 tsec->sid = sid;
6261 } else {
6262 error = -EINVAL;
6263 goto abort_change;
6264 }
6265
6266 commit_creds(new);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006267 return size;
David Howellsd84f4f92008-11-14 10:39:23 +11006268
6269abort_change:
6270 abort_creds(new);
6271 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006272}
6273
David Quigley746df9b2013-05-22 12:50:35 -04006274static int selinux_ismaclabel(const char *name)
6275{
6276 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
6277}
6278
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006279static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
6280{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006281 return security_sid_to_context(&selinux_state, secid,
6282 secdata, seclen);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006283}
6284
David Howells7bf570d2008-04-29 20:52:51 +01006285static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
David Howells63cb3442008-01-15 23:47:35 +00006286{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006287 return security_context_to_sid(&selinux_state, secdata, seclen,
6288 secid, GFP_KERNEL);
David Howells63cb3442008-01-15 23:47:35 +00006289}
6290
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006291static void selinux_release_secctx(char *secdata, u32 seclen)
6292{
Paul Moore088999e2007-08-01 11:12:58 -04006293 kfree(secdata);
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006294}
6295
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006296static void selinux_inode_invalidate_secctx(struct inode *inode)
6297{
Casey Schaufler80788c22018-09-21 17:19:11 -07006298 struct inode_security_struct *isec = selinux_inode(inode);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006299
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006300 spin_lock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006301 isec->initialized = LABEL_INVALID;
Andreas Gruenbacher9287aed2016-11-15 11:06:40 +01006302 spin_unlock(&isec->lock);
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006303}
6304
David P. Quigley1ee65e32009-09-03 14:25:57 -04006305/*
6306 * called with inode->i_mutex locked
6307 */
6308static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
6309{
6310 return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
6311}
6312
6313/*
6314 * called with inode->i_mutex locked
6315 */
6316static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
6317{
6318 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
6319}
6320
6321static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
6322{
6323 int len = 0;
6324 len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
6325 ctx, true);
6326 if (len < 0)
6327 return len;
6328 *ctxlen = len;
6329 return 0;
6330}
Michael LeMayd7200242006-06-22 14:47:17 -07006331#ifdef CONFIG_KEYS
6332
David Howellsd84f4f92008-11-14 10:39:23 +11006333static int selinux_key_alloc(struct key *k, const struct cred *cred,
David Howells7e047ef2006-06-26 00:24:50 -07006334 unsigned long flags)
Michael LeMayd7200242006-06-22 14:47:17 -07006335{
David Howellsd84f4f92008-11-14 10:39:23 +11006336 const struct task_security_struct *tsec;
Michael LeMayd7200242006-06-22 14:47:17 -07006337 struct key_security_struct *ksec;
6338
6339 ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
6340 if (!ksec)
6341 return -ENOMEM;
6342
Casey Schaufler0c6cfa62018-09-21 17:17:16 -07006343 tsec = selinux_cred(cred);
David Howellsd84f4f92008-11-14 10:39:23 +11006344 if (tsec->keycreate_sid)
6345 ksec->sid = tsec->keycreate_sid;
Michael LeMay4eb582c2006-06-26 00:24:57 -07006346 else
David Howellsd84f4f92008-11-14 10:39:23 +11006347 ksec->sid = tsec->sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006348
David Howells275bb412008-11-14 10:39:19 +11006349 k->security = ksec;
Michael LeMayd7200242006-06-22 14:47:17 -07006350 return 0;
6351}
6352
6353static void selinux_key_free(struct key *k)
6354{
6355 struct key_security_struct *ksec = k->security;
6356
6357 k->security = NULL;
6358 kfree(ksec);
6359}
6360
6361static int selinux_key_permission(key_ref_t key_ref,
David Howellsd84f4f92008-11-14 10:39:23 +11006362 const struct cred *cred,
David Howellsf5895942014-03-14 17:44:49 +00006363 unsigned perm)
Michael LeMayd7200242006-06-22 14:47:17 -07006364{
6365 struct key *key;
Michael LeMayd7200242006-06-22 14:47:17 -07006366 struct key_security_struct *ksec;
David Howells275bb412008-11-14 10:39:19 +11006367 u32 sid;
Michael LeMayd7200242006-06-22 14:47:17 -07006368
6369 /* if no specific permissions are requested, we skip the
6370 permission check. No serious, additional covert channels
6371 appear to be created. */
6372 if (perm == 0)
6373 return 0;
6374
David Howellsd84f4f92008-11-14 10:39:23 +11006375 sid = cred_sid(cred);
David Howells275bb412008-11-14 10:39:19 +11006376
6377 key = key_ref_to_ptr(key_ref);
6378 ksec = key->security;
6379
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006380 return avc_has_perm(&selinux_state,
6381 sid, ksec->sid, SECCLASS_KEY, perm, NULL);
Michael LeMayd7200242006-06-22 14:47:17 -07006382}
6383
David Howells70a5bb72008-04-29 01:01:26 -07006384static int selinux_key_getsecurity(struct key *key, char **_buffer)
6385{
6386 struct key_security_struct *ksec = key->security;
6387 char *context = NULL;
6388 unsigned len;
6389 int rc;
6390
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006391 rc = security_sid_to_context(&selinux_state, ksec->sid,
6392 &context, &len);
David Howells70a5bb72008-04-29 01:01:26 -07006393 if (!rc)
6394 rc = len;
6395 *_buffer = context;
6396 return rc;
6397}
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006398#endif
David Howells70a5bb72008-04-29 01:01:26 -07006399
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006400#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006401static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
6402{
6403 struct common_audit_data ad;
6404 int err;
6405 u32 sid = 0;
6406 struct ib_security_struct *sec = ib_sec;
6407 struct lsm_ibpkey_audit ibpkey;
6408
Daniel Jurgens409dcf32017-05-19 15:48:59 +03006409 err = sel_ib_pkey_sid(subnet_prefix, pkey_val, &sid);
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006410 if (err)
6411 return err;
6412
6413 ad.type = LSM_AUDIT_DATA_IBPKEY;
6414 ibpkey.subnet_prefix = subnet_prefix;
6415 ibpkey.pkey = pkey_val;
6416 ad.u.ibpkey = &ibpkey;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006417 return avc_has_perm(&selinux_state,
6418 sec->sid, sid,
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006419 SECCLASS_INFINIBAND_PKEY,
6420 INFINIBAND_PKEY__ACCESS, &ad);
6421}
6422
Daniel Jurgensab861df2017-05-19 15:48:58 +03006423static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
6424 u8 port_num)
6425{
6426 struct common_audit_data ad;
6427 int err;
6428 u32 sid = 0;
6429 struct ib_security_struct *sec = ib_sec;
6430 struct lsm_ibendport_audit ibendport;
6431
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006432 err = security_ib_endport_sid(&selinux_state, dev_name, port_num,
6433 &sid);
Daniel Jurgensab861df2017-05-19 15:48:58 +03006434
6435 if (err)
6436 return err;
6437
6438 ad.type = LSM_AUDIT_DATA_IBENDPORT;
6439 strncpy(ibendport.dev_name, dev_name, sizeof(ibendport.dev_name));
6440 ibendport.port = port_num;
6441 ad.u.ibendport = &ibendport;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006442 return avc_has_perm(&selinux_state,
6443 sec->sid, sid,
Daniel Jurgensab861df2017-05-19 15:48:58 +03006444 SECCLASS_INFINIBAND_ENDPORT,
6445 INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
6446}
6447
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006448static int selinux_ib_alloc_security(void **ib_sec)
6449{
6450 struct ib_security_struct *sec;
6451
6452 sec = kzalloc(sizeof(*sec), GFP_KERNEL);
6453 if (!sec)
6454 return -ENOMEM;
6455 sec->sid = current_sid();
6456
6457 *ib_sec = sec;
6458 return 0;
6459}
6460
6461static void selinux_ib_free_security(void *ib_sec)
6462{
6463 kfree(ib_sec);
6464}
Michael LeMayd7200242006-06-22 14:47:17 -07006465#endif
6466
Chenbo Fengec27c352017-10-18 13:00:25 -07006467#ifdef CONFIG_BPF_SYSCALL
6468static int selinux_bpf(int cmd, union bpf_attr *attr,
6469 unsigned int size)
6470{
6471 u32 sid = current_sid();
6472 int ret;
6473
6474 switch (cmd) {
6475 case BPF_MAP_CREATE:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006476 ret = avc_has_perm(&selinux_state,
6477 sid, sid, SECCLASS_BPF, BPF__MAP_CREATE,
Chenbo Fengec27c352017-10-18 13:00:25 -07006478 NULL);
6479 break;
6480 case BPF_PROG_LOAD:
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006481 ret = avc_has_perm(&selinux_state,
6482 sid, sid, SECCLASS_BPF, BPF__PROG_LOAD,
Chenbo Fengec27c352017-10-18 13:00:25 -07006483 NULL);
6484 break;
6485 default:
6486 ret = 0;
6487 break;
6488 }
6489
6490 return ret;
6491}
6492
6493static u32 bpf_map_fmode_to_av(fmode_t fmode)
6494{
6495 u32 av = 0;
6496
6497 if (fmode & FMODE_READ)
6498 av |= BPF__MAP_READ;
6499 if (fmode & FMODE_WRITE)
6500 av |= BPF__MAP_WRITE;
6501 return av;
6502}
6503
Chenbo Fengf66e4482017-10-18 13:00:26 -07006504/* This function will check the file pass through unix socket or binder to see
6505 * if it is a bpf related object. And apply correspinding checks on the bpf
6506 * object based on the type. The bpf maps and programs, not like other files and
6507 * socket, are using a shared anonymous inode inside the kernel as their inode.
6508 * So checking that inode cannot identify if the process have privilege to
6509 * access the bpf object and that's why we have to add this additional check in
6510 * selinux_file_receive and selinux_binder_transfer_files.
6511 */
6512static int bpf_fd_pass(struct file *file, u32 sid)
6513{
6514 struct bpf_security_struct *bpfsec;
6515 struct bpf_prog *prog;
6516 struct bpf_map *map;
6517 int ret;
6518
6519 if (file->f_op == &bpf_map_fops) {
6520 map = file->private_data;
6521 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006522 ret = avc_has_perm(&selinux_state,
6523 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006524 bpf_map_fmode_to_av(file->f_mode), NULL);
6525 if (ret)
6526 return ret;
6527 } else if (file->f_op == &bpf_prog_fops) {
6528 prog = file->private_data;
6529 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006530 ret = avc_has_perm(&selinux_state,
6531 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengf66e4482017-10-18 13:00:26 -07006532 BPF__PROG_RUN, NULL);
6533 if (ret)
6534 return ret;
6535 }
6536 return 0;
6537}
6538
Chenbo Fengec27c352017-10-18 13:00:25 -07006539static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode)
6540{
6541 u32 sid = current_sid();
6542 struct bpf_security_struct *bpfsec;
6543
6544 bpfsec = map->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006545 return avc_has_perm(&selinux_state,
6546 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006547 bpf_map_fmode_to_av(fmode), NULL);
6548}
6549
6550static int selinux_bpf_prog(struct bpf_prog *prog)
6551{
6552 u32 sid = current_sid();
6553 struct bpf_security_struct *bpfsec;
6554
6555 bpfsec = prog->aux->security;
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006556 return avc_has_perm(&selinux_state,
6557 sid, bpfsec->sid, SECCLASS_BPF,
Chenbo Fengec27c352017-10-18 13:00:25 -07006558 BPF__PROG_RUN, NULL);
6559}
6560
6561static int selinux_bpf_map_alloc(struct bpf_map *map)
6562{
6563 struct bpf_security_struct *bpfsec;
6564
6565 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6566 if (!bpfsec)
6567 return -ENOMEM;
6568
6569 bpfsec->sid = current_sid();
6570 map->security = bpfsec;
6571
6572 return 0;
6573}
6574
6575static void selinux_bpf_map_free(struct bpf_map *map)
6576{
6577 struct bpf_security_struct *bpfsec = map->security;
6578
6579 map->security = NULL;
6580 kfree(bpfsec);
6581}
6582
6583static int selinux_bpf_prog_alloc(struct bpf_prog_aux *aux)
6584{
6585 struct bpf_security_struct *bpfsec;
6586
6587 bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
6588 if (!bpfsec)
6589 return -ENOMEM;
6590
6591 bpfsec->sid = current_sid();
6592 aux->security = bpfsec;
6593
6594 return 0;
6595}
6596
6597static void selinux_bpf_prog_free(struct bpf_prog_aux *aux)
6598{
6599 struct bpf_security_struct *bpfsec = aux->security;
6600
6601 aux->security = NULL;
6602 kfree(bpfsec);
6603}
6604#endif
6605
Casey Schauflerbbd36622018-11-12 09:30:56 -08006606struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = {
6607 .lbs_cred = sizeof(struct task_security_struct),
Casey Schaufler33bf60c2018-11-12 12:02:49 -08006608 .lbs_file = sizeof(struct file_security_struct),
Casey Schauflerafb1cbe32018-09-21 17:19:29 -07006609 .lbs_inode = sizeof(struct inode_security_struct),
Casey Schauflerbbd36622018-11-12 09:30:56 -08006610};
6611
James Morrisca97d932017-02-15 00:18:51 +11006612static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
Casey Schauflere20b0432015-05-02 15:11:36 -07006613 LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr),
6614 LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction),
6615 LSM_HOOK_INIT(binder_transfer_binder, selinux_binder_transfer_binder),
6616 LSM_HOOK_INIT(binder_transfer_file, selinux_binder_transfer_file),
Ahmed S. Darwish076c54c2008-03-06 18:09:10 +02006617
Casey Schauflere20b0432015-05-02 15:11:36 -07006618 LSM_HOOK_INIT(ptrace_access_check, selinux_ptrace_access_check),
6619 LSM_HOOK_INIT(ptrace_traceme, selinux_ptrace_traceme),
6620 LSM_HOOK_INIT(capget, selinux_capget),
6621 LSM_HOOK_INIT(capset, selinux_capset),
6622 LSM_HOOK_INIT(capable, selinux_capable),
6623 LSM_HOOK_INIT(quotactl, selinux_quotactl),
6624 LSM_HOOK_INIT(quota_on, selinux_quota_on),
6625 LSM_HOOK_INIT(syslog, selinux_syslog),
6626 LSM_HOOK_INIT(vm_enough_memory, selinux_vm_enough_memory),
Stephen Smalley79af7302015-01-21 10:54:10 -05006627
Casey Schauflere20b0432015-05-02 15:11:36 -07006628 LSM_HOOK_INIT(netlink_send, selinux_netlink_send),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006629
Casey Schauflere20b0432015-05-02 15:11:36 -07006630 LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds),
6631 LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds),
6632 LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006633
Casey Schauflere20b0432015-05-02 15:11:36 -07006634 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),
6635 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
Al Viro5b400232018-12-12 20:13:29 -05006636 LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts),
Al Viro204cc0c2018-12-13 13:41:47 -05006637 LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts),
Casey Schauflere20b0432015-05-02 15:11:36 -07006638 LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
6639 LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
6640 LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options),
6641 LSM_HOOK_INIT(sb_statfs, selinux_sb_statfs),
6642 LSM_HOOK_INIT(sb_mount, selinux_mount),
6643 LSM_HOOK_INIT(sb_umount, selinux_umount),
6644 LSM_HOOK_INIT(sb_set_mnt_opts, selinux_set_mnt_opts),
6645 LSM_HOOK_INIT(sb_clone_mnt_opts, selinux_sb_clone_mnt_opts),
Al Viro757cbe52018-12-14 23:42:21 -05006646 LSM_HOOK_INIT(sb_add_mnt_opt, selinux_add_mnt_opt),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006647
Casey Schauflere20b0432015-05-02 15:11:36 -07006648 LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
Vivek Goyala518b0a2016-07-13 10:44:53 -04006649 LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
Eric Parise0007522008-03-05 10:31:54 -05006650
Casey Schauflere20b0432015-05-02 15:11:36 -07006651 LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
6652 LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
6653 LSM_HOOK_INIT(inode_init_security, selinux_inode_init_security),
6654 LSM_HOOK_INIT(inode_create, selinux_inode_create),
6655 LSM_HOOK_INIT(inode_link, selinux_inode_link),
6656 LSM_HOOK_INIT(inode_unlink, selinux_inode_unlink),
6657 LSM_HOOK_INIT(inode_symlink, selinux_inode_symlink),
6658 LSM_HOOK_INIT(inode_mkdir, selinux_inode_mkdir),
6659 LSM_HOOK_INIT(inode_rmdir, selinux_inode_rmdir),
6660 LSM_HOOK_INIT(inode_mknod, selinux_inode_mknod),
6661 LSM_HOOK_INIT(inode_rename, selinux_inode_rename),
6662 LSM_HOOK_INIT(inode_readlink, selinux_inode_readlink),
6663 LSM_HOOK_INIT(inode_follow_link, selinux_inode_follow_link),
6664 LSM_HOOK_INIT(inode_permission, selinux_inode_permission),
6665 LSM_HOOK_INIT(inode_setattr, selinux_inode_setattr),
6666 LSM_HOOK_INIT(inode_getattr, selinux_inode_getattr),
6667 LSM_HOOK_INIT(inode_setxattr, selinux_inode_setxattr),
6668 LSM_HOOK_INIT(inode_post_setxattr, selinux_inode_post_setxattr),
6669 LSM_HOOK_INIT(inode_getxattr, selinux_inode_getxattr),
6670 LSM_HOOK_INIT(inode_listxattr, selinux_inode_listxattr),
6671 LSM_HOOK_INIT(inode_removexattr, selinux_inode_removexattr),
6672 LSM_HOOK_INIT(inode_getsecurity, selinux_inode_getsecurity),
6673 LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity),
6674 LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
6675 LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
Vivek Goyal56909eb2016-07-13 10:44:48 -04006676 LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
Vivek Goyal19472b62016-07-13 10:44:50 -04006677 LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006678
Casey Schauflere20b0432015-05-02 15:11:36 -07006679 LSM_HOOK_INIT(file_permission, selinux_file_permission),
6680 LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
Casey Schauflere20b0432015-05-02 15:11:36 -07006681 LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
6682 LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
6683 LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),
6684 LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
6685 LSM_HOOK_INIT(file_lock, selinux_file_lock),
6686 LSM_HOOK_INIT(file_fcntl, selinux_file_fcntl),
6687 LSM_HOOK_INIT(file_set_fowner, selinux_file_set_fowner),
6688 LSM_HOOK_INIT(file_send_sigiotask, selinux_file_send_sigiotask),
6689 LSM_HOOK_INIT(file_receive, selinux_file_receive),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690
Casey Schauflere20b0432015-05-02 15:11:36 -07006691 LSM_HOOK_INIT(file_open, selinux_file_open),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006692
Tetsuo Handaa79be232017-03-28 23:08:45 +09006693 LSM_HOOK_INIT(task_alloc, selinux_task_alloc),
Casey Schauflere20b0432015-05-02 15:11:36 -07006694 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
6695 LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
Matthew Garrett3ec30112018-01-08 13:36:19 -08006696 LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid),
Casey Schauflere20b0432015-05-02 15:11:36 -07006697 LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
6698 LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
6699 LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
Mimi Zoharc77b8cd2018-07-13 14:06:02 -04006700 LSM_HOOK_INIT(kernel_load_data, selinux_kernel_load_data),
Jeff Vander Stoep61d612ea2016-04-05 13:06:27 -07006701 LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file),
Casey Schauflere20b0432015-05-02 15:11:36 -07006702 LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
6703 LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
6704 LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
6705 LSM_HOOK_INIT(task_getsecid, selinux_task_getsecid),
6706 LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
6707 LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
6708 LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
Stephen Smalley791ec492017-02-17 07:57:00 -05006709 LSM_HOOK_INIT(task_prlimit, selinux_task_prlimit),
Casey Schauflere20b0432015-05-02 15:11:36 -07006710 LSM_HOOK_INIT(task_setrlimit, selinux_task_setrlimit),
6711 LSM_HOOK_INIT(task_setscheduler, selinux_task_setscheduler),
6712 LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler),
6713 LSM_HOOK_INIT(task_movememory, selinux_task_movememory),
6714 LSM_HOOK_INIT(task_kill, selinux_task_kill),
Casey Schauflere20b0432015-05-02 15:11:36 -07006715 LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode),
Yuichi Nakamura788e7dd2007-09-14 09:27:07 +09006716
Casey Schauflere20b0432015-05-02 15:11:36 -07006717 LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission),
6718 LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006719
Casey Schauflere20b0432015-05-02 15:11:36 -07006720 LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security),
6721 LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006722
Casey Schauflere20b0432015-05-02 15:11:36 -07006723 LSM_HOOK_INIT(msg_queue_alloc_security,
6724 selinux_msg_queue_alloc_security),
6725 LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security),
6726 LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate),
6727 LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl),
6728 LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd),
6729 LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006730
Casey Schauflere20b0432015-05-02 15:11:36 -07006731 LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security),
6732 LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security),
6733 LSM_HOOK_INIT(shm_associate, selinux_shm_associate),
6734 LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl),
6735 LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006736
Casey Schauflere20b0432015-05-02 15:11:36 -07006737 LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security),
6738 LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security),
6739 LSM_HOOK_INIT(sem_associate, selinux_sem_associate),
6740 LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl),
6741 LSM_HOOK_INIT(sem_semop, selinux_sem_semop),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006742
Casey Schauflere20b0432015-05-02 15:11:36 -07006743 LSM_HOOK_INIT(d_instantiate, selinux_d_instantiate),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744
Casey Schauflere20b0432015-05-02 15:11:36 -07006745 LSM_HOOK_INIT(getprocattr, selinux_getprocattr),
6746 LSM_HOOK_INIT(setprocattr, selinux_setprocattr),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006747
Casey Schauflere20b0432015-05-02 15:11:36 -07006748 LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel),
6749 LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx),
6750 LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid),
6751 LSM_HOOK_INIT(release_secctx, selinux_release_secctx),
Andreas Gruenbacher6f3be9f2015-12-24 11:09:40 -05006752 LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx),
Casey Schauflere20b0432015-05-02 15:11:36 -07006753 LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx),
6754 LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx),
6755 LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006756
Casey Schauflere20b0432015-05-02 15:11:36 -07006757 LSM_HOOK_INIT(unix_stream_connect, selinux_socket_unix_stream_connect),
6758 LSM_HOOK_INIT(unix_may_send, selinux_socket_unix_may_send),
Catherine Zhangdc49c1f2006-08-02 14:12:06 -07006759
Casey Schauflere20b0432015-05-02 15:11:36 -07006760 LSM_HOOK_INIT(socket_create, selinux_socket_create),
6761 LSM_HOOK_INIT(socket_post_create, selinux_socket_post_create),
David Herrmann0b811db2018-05-04 16:28:21 +02006762 LSM_HOOK_INIT(socket_socketpair, selinux_socket_socketpair),
Casey Schauflere20b0432015-05-02 15:11:36 -07006763 LSM_HOOK_INIT(socket_bind, selinux_socket_bind),
6764 LSM_HOOK_INIT(socket_connect, selinux_socket_connect),
6765 LSM_HOOK_INIT(socket_listen, selinux_socket_listen),
6766 LSM_HOOK_INIT(socket_accept, selinux_socket_accept),
6767 LSM_HOOK_INIT(socket_sendmsg, selinux_socket_sendmsg),
6768 LSM_HOOK_INIT(socket_recvmsg, selinux_socket_recvmsg),
6769 LSM_HOOK_INIT(socket_getsockname, selinux_socket_getsockname),
6770 LSM_HOOK_INIT(socket_getpeername, selinux_socket_getpeername),
6771 LSM_HOOK_INIT(socket_getsockopt, selinux_socket_getsockopt),
6772 LSM_HOOK_INIT(socket_setsockopt, selinux_socket_setsockopt),
6773 LSM_HOOK_INIT(socket_shutdown, selinux_socket_shutdown),
6774 LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
6775 LSM_HOOK_INIT(socket_getpeersec_stream,
6776 selinux_socket_getpeersec_stream),
6777 LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram),
6778 LSM_HOOK_INIT(sk_alloc_security, selinux_sk_alloc_security),
6779 LSM_HOOK_INIT(sk_free_security, selinux_sk_free_security),
6780 LSM_HOOK_INIT(sk_clone_security, selinux_sk_clone_security),
6781 LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid),
6782 LSM_HOOK_INIT(sock_graft, selinux_sock_graft),
Richard Hainesd4529302018-02-13 20:57:18 +00006783 LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request),
6784 LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone),
6785 LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect),
Casey Schauflere20b0432015-05-02 15:11:36 -07006786 LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request),
6787 LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone),
6788 LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),
6789 LSM_HOOK_INIT(secmark_relabel_packet, selinux_secmark_relabel_packet),
6790 LSM_HOOK_INIT(secmark_refcount_inc, selinux_secmark_refcount_inc),
6791 LSM_HOOK_INIT(secmark_refcount_dec, selinux_secmark_refcount_dec),
6792 LSM_HOOK_INIT(req_classify_flow, selinux_req_classify_flow),
6793 LSM_HOOK_INIT(tun_dev_alloc_security, selinux_tun_dev_alloc_security),
6794 LSM_HOOK_INIT(tun_dev_free_security, selinux_tun_dev_free_security),
6795 LSM_HOOK_INIT(tun_dev_create, selinux_tun_dev_create),
6796 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
6797 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
6798 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006799#ifdef CONFIG_SECURITY_INFINIBAND
Daniel Jurgenscfc4d882017-05-19 15:48:57 +03006800 LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
Daniel Jurgensab861df2017-05-19 15:48:58 +03006801 LSM_HOOK_INIT(ib_endport_manage_subnet,
6802 selinux_ib_endport_manage_subnet),
Daniel Jurgens3a976fa2017-05-19 15:48:56 +03006803 LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
6804 LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
6805#endif
Trent Jaegerd28d1e02005-12-13 23:12:40 -08006806#ifdef CONFIG_SECURITY_NETWORK_XFRM
Casey Schauflere20b0432015-05-02 15:11:36 -07006807 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
6808 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone),
6809 LSM_HOOK_INIT(xfrm_policy_free_security, selinux_xfrm_policy_free),
6810 LSM_HOOK_INIT(xfrm_policy_delete_security, selinux_xfrm_policy_delete),
6811 LSM_HOOK_INIT(xfrm_state_alloc, selinux_xfrm_state_alloc),
6812 LSM_HOOK_INIT(xfrm_state_alloc_acquire,
6813 selinux_xfrm_state_alloc_acquire),
6814 LSM_HOOK_INIT(xfrm_state_free_security, selinux_xfrm_state_free),
6815 LSM_HOOK_INIT(xfrm_state_delete_security, selinux_xfrm_state_delete),
6816 LSM_HOOK_INIT(xfrm_policy_lookup, selinux_xfrm_policy_lookup),
6817 LSM_HOOK_INIT(xfrm_state_pol_flow_match,
6818 selinux_xfrm_state_pol_flow_match),
6819 LSM_HOOK_INIT(xfrm_decode_session, selinux_xfrm_decode_session),
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820#endif
Michael LeMayd7200242006-06-22 14:47:17 -07006821
6822#ifdef CONFIG_KEYS
Casey Schauflere20b0432015-05-02 15:11:36 -07006823 LSM_HOOK_INIT(key_alloc, selinux_key_alloc),
6824 LSM_HOOK_INIT(key_free, selinux_key_free),
6825 LSM_HOOK_INIT(key_permission, selinux_key_permission),
6826 LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity),
Michael LeMayd7200242006-06-22 14:47:17 -07006827#endif
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006828
6829#ifdef CONFIG_AUDIT
Casey Schauflere20b0432015-05-02 15:11:36 -07006830 LSM_HOOK_INIT(audit_rule_init, selinux_audit_rule_init),
6831 LSM_HOOK_INIT(audit_rule_known, selinux_audit_rule_known),
6832 LSM_HOOK_INIT(audit_rule_match, selinux_audit_rule_match),
6833 LSM_HOOK_INIT(audit_rule_free, selinux_audit_rule_free),
Ahmed S. Darwish9d57a7f2008-03-01 22:03:14 +02006834#endif
Chenbo Fengec27c352017-10-18 13:00:25 -07006835
6836#ifdef CONFIG_BPF_SYSCALL
6837 LSM_HOOK_INIT(bpf, selinux_bpf),
6838 LSM_HOOK_INIT(bpf_map, selinux_bpf_map),
6839 LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog),
6840 LSM_HOOK_INIT(bpf_map_alloc_security, selinux_bpf_map_alloc),
6841 LSM_HOOK_INIT(bpf_prog_alloc_security, selinux_bpf_prog_alloc),
6842 LSM_HOOK_INIT(bpf_map_free_security, selinux_bpf_map_free),
6843 LSM_HOOK_INIT(bpf_prog_free_security, selinux_bpf_prog_free),
6844#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845};
6846
6847static __init int selinux_init(void)
6848{
peter enderborgc103a912018-06-12 10:09:03 +02006849 pr_info("SELinux: Initializing.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006850
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006851 memset(&selinux_state, 0, sizeof(selinux_state));
Paul Mooree5a5ca92018-03-01 17:38:30 -05006852 enforcing_set(&selinux_state, selinux_enforcing_boot);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006853 selinux_state.checkreqprot = selinux_checkreqprot_boot;
6854 selinux_ss_init(&selinux_state.ss);
Stephen Smalley6b6bc622018-03-05 11:47:56 -05006855 selinux_avc_init(&selinux_state.avc);
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006856
Linus Torvalds1da177e2005-04-16 15:20:36 -07006857 /* Set the security state for the initial task. */
David Howellsd84f4f92008-11-14 10:39:23 +11006858 cred_init_security();
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859
Stephen Smalleyfcaaade2010-04-28 15:57:57 -04006860 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
6861
Linus Torvalds1da177e2005-04-16 15:20:36 -07006862 avc_init();
6863
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006864 avtab_cache_init();
6865
6866 ebitmap_cache_init();
6867
6868 hashtab_cache_init();
6869
Casey Schauflerd69dece52017-01-18 17:09:05 -08006870 security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006871
Paul Moore615e51f2014-06-26 14:33:56 -04006872 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6873 panic("SELinux: Unable to register AVC netcache callback\n");
6874
Daniel Jurgens8f408ab2017-05-19 15:48:53 +03006875 if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
6876 panic("SELinux: Unable to register AVC LSM notifier callback\n");
6877
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05006878 if (selinux_enforcing_boot)
peter enderborgc103a912018-06-12 10:09:03 +02006879 pr_debug("SELinux: Starting in enforcing mode\n");
Eric Paris828dfe12008-04-17 13:17:49 -04006880 else
peter enderborgc103a912018-06-12 10:09:03 +02006881 pr_debug("SELinux: Starting in permissive mode\n");
Michael LeMayd7200242006-06-22 14:47:17 -07006882
Linus Torvalds1da177e2005-04-16 15:20:36 -07006883 return 0;
6884}
6885
Al Viroe8c26252010-03-23 06:36:54 -04006886static void delayed_superblock_init(struct super_block *sb, void *unused)
6887{
Al Viro204cc0c2018-12-13 13:41:47 -05006888 selinux_set_mnt_opts(sb, NULL, 0, NULL);
Al Viroe8c26252010-03-23 06:36:54 -04006889}
6890
Linus Torvalds1da177e2005-04-16 15:20:36 -07006891void selinux_complete_init(void)
6892{
peter enderborgc103a912018-06-12 10:09:03 +02006893 pr_debug("SELinux: Completing initialization.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006894
6895 /* Set up any superblocks initialized prior to the policy load. */
peter enderborgc103a912018-06-12 10:09:03 +02006896 pr_debug("SELinux: Setting up existing superblocks.\n");
Al Viroe8c26252010-03-23 06:36:54 -04006897 iterate_supers(delayed_superblock_init, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006898}
6899
6900/* SELinux requires early initialization in order to label
6901 all processes and objects when they are created. */
Kees Cook3d6e5f62018-10-10 17:18:23 -07006902DEFINE_LSM(selinux) = {
Kees Cook07aed2f2018-10-10 17:18:24 -07006903 .name = "selinux",
Kees Cook14bd99c2018-09-19 19:57:06 -07006904 .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
Kees Cookc5459b82018-09-13 22:28:48 -07006905 .enabled = &selinux_enabled,
Casey Schauflerbbd36622018-11-12 09:30:56 -08006906 .blobs = &selinux_blob_sizes,
Kees Cook3d6e5f62018-10-10 17:18:23 -07006907 .init = selinux_init,
6908};
Linus Torvalds1da177e2005-04-16 15:20:36 -07006909
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006910#if defined(CONFIG_NETFILTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006911
Florian Westphal591bb272017-07-26 11:40:52 +02006912static const struct nf_hook_ops selinux_nf_ops[] = {
Paul Mooreeffad8d2008-01-29 08:49:27 -05006913 {
6914 .hook = selinux_ipv4_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00006915 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006916 .hooknum = NF_INET_POST_ROUTING,
6917 .priority = NF_IP_PRI_SELINUX_LAST,
6918 },
6919 {
6920 .hook = selinux_ipv4_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00006921 .pf = NFPROTO_IPV4,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006922 .hooknum = NF_INET_FORWARD,
6923 .priority = NF_IP_PRI_SELINUX_FIRST,
Paul Moore948bf852008-10-10 10:16:32 -04006924 },
6925 {
6926 .hook = selinux_ipv4_output,
Alban Crequy2597a832012-05-14 03:56:39 +00006927 .pf = NFPROTO_IPV4,
Paul Moore948bf852008-10-10 10:16:32 -04006928 .hooknum = NF_INET_LOCAL_OUT,
6929 .priority = NF_IP_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02006930 },
Javier Martinez Canillas1a93a6e2016-08-08 13:08:25 -04006931#if IS_ENABLED(CONFIG_IPV6)
Paul Mooreeffad8d2008-01-29 08:49:27 -05006932 {
6933 .hook = selinux_ipv6_postroute,
Alban Crequy2597a832012-05-14 03:56:39 +00006934 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006935 .hooknum = NF_INET_POST_ROUTING,
6936 .priority = NF_IP6_PRI_SELINUX_LAST,
6937 },
6938 {
6939 .hook = selinux_ipv6_forward,
Alban Crequy2597a832012-05-14 03:56:39 +00006940 .pf = NFPROTO_IPV6,
Paul Mooreeffad8d2008-01-29 08:49:27 -05006941 .hooknum = NF_INET_FORWARD,
6942 .priority = NF_IP6_PRI_SELINUX_FIRST,
Jiri Pirko25db6be2014-09-03 17:42:13 +02006943 },
Huw Davies2917f572016-06-27 15:06:15 -04006944 {
6945 .hook = selinux_ipv6_output,
6946 .pf = NFPROTO_IPV6,
6947 .hooknum = NF_INET_LOCAL_OUT,
6948 .priority = NF_IP6_PRI_SELINUX_FIRST,
6949 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07006950#endif /* IPV6 */
Jiri Pirko25db6be2014-09-03 17:42:13 +02006951};
Linus Torvalds1da177e2005-04-16 15:20:36 -07006952
Florian Westphal8e71bf72017-04-21 11:49:09 +02006953static int __net_init selinux_nf_register(struct net *net)
6954{
6955 return nf_register_net_hooks(net, selinux_nf_ops,
6956 ARRAY_SIZE(selinux_nf_ops));
6957}
6958
6959static void __net_exit selinux_nf_unregister(struct net *net)
6960{
6961 nf_unregister_net_hooks(net, selinux_nf_ops,
6962 ARRAY_SIZE(selinux_nf_ops));
6963}
6964
6965static struct pernet_operations selinux_net_ops = {
6966 .init = selinux_nf_register,
6967 .exit = selinux_nf_unregister,
6968};
6969
Linus Torvalds1da177e2005-04-16 15:20:36 -07006970static int __init selinux_nf_ip_init(void)
6971{
Jiri Pirko25db6be2014-09-03 17:42:13 +02006972 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006973
6974 if (!selinux_enabled)
Jiri Pirko25db6be2014-09-03 17:42:13 +02006975 return 0;
Eric Parisfadcdb42007-02-22 18:11:31 -05006976
peter enderborgc103a912018-06-12 10:09:03 +02006977 pr_debug("SELinux: Registering netfilter hooks\n");
Eric Parisfadcdb42007-02-22 18:11:31 -05006978
Florian Westphal8e71bf72017-04-21 11:49:09 +02006979 err = register_pernet_subsys(&selinux_net_ops);
Alexey Dobriyan6c5a9d22008-07-26 17:48:15 -07006980 if (err)
Florian Westphal8e71bf72017-04-21 11:49:09 +02006981 panic("SELinux: register_pernet_subsys: error %d\n", err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006982
Jiri Pirko25db6be2014-09-03 17:42:13 +02006983 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006984}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006985__initcall(selinux_nf_ip_init);
6986
6987#ifdef CONFIG_SECURITY_SELINUX_DISABLE
6988static void selinux_nf_ip_exit(void)
6989{
peter enderborgc103a912018-06-12 10:09:03 +02006990 pr_debug("SELinux: Unregistering netfilter hooks\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07006991
Florian Westphal8e71bf72017-04-21 11:49:09 +02006992 unregister_pernet_subsys(&selinux_net_ops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006993}
6994#endif
6995
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08006996#else /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006997
6998#ifdef CONFIG_SECURITY_SELINUX_DISABLE
6999#define selinux_nf_ip_exit()
7000#endif
7001
Stephen Smalleyc2b507f2006-02-04 23:27:50 -08007002#endif /* CONFIG_NETFILTER */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007003
7004#ifdef CONFIG_SECURITY_SELINUX_DISABLE
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007005int selinux_disable(struct selinux_state *state)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007006{
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007007 if (state->initialized) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007008 /* Not permitted after initial policy load. */
7009 return -EINVAL;
7010 }
7011
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007012 if (state->disabled) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007013 /* Only do this once. */
7014 return -EINVAL;
7015 }
7016
Stephen Smalleyaa8e7122018-03-01 18:48:02 -05007017 state->disabled = 1;
7018
peter enderborgc103a912018-06-12 10:09:03 +02007019 pr_info("SELinux: Disabled at runtime.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07007020
Stephen Smalley30d55282006-05-03 10:52:36 -04007021 selinux_enabled = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007022
Casey Schauflerb1d9e6b2015-05-02 15:11:42 -07007023 security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007024
Eric Parisaf8ff042009-09-20 21:23:01 -04007025 /* Try to destroy the avc node cache */
7026 avc_disable();
7027
Linus Torvalds1da177e2005-04-16 15:20:36 -07007028 /* Unregister netfilter hooks. */
7029 selinux_nf_ip_exit();
7030
7031 /* Unregister selinuxfs. */
7032 exit_sel_fs();
7033
7034 return 0;
7035}
7036#endif