FB The frame buffer device is enabled.
HW Appropriate hardware is enabled.
IA-64 IA-64 architecture is enabled.
+ IMA Integrity measurement architecture is enabled.
IOSCHED More than one I/O scheduler is enabled.
IP_PNP IP DHCP, BOOTP, or RARP is enabled.
ISAPNP ISA PnP code is enabled.
Parameters denoted with BOOT are actually interpreted by the boot
loader, and have no meaning to the kernel directly.
Do not modify the syntax of boot loader parameters without extreme
- need or coordination with <Documentation/x86/i386/boot.txt>.
+ need or coordination with <Documentation/x86/boot.txt>.
There are also arch-specific kernel-parameters not documented here.
See for example <Documentation/x86/x86_64/boot-options.txt>.
acpi= [HW,ACPI,X86-64,i386]
Advanced Configuration and Power Interface
- Format: { force | off | ht | strict | noirq }
+ Format: { force | off | ht | strict | noirq | rsdt }
force -- enable ACPI if default was off
off -- disable ACPI if default was on
noirq -- do not use ACPI for IRQ routing
icn= [HW,ISDN]
Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]
- ide= [HW] (E)IDE subsystem
- Format: ide=nodma or ide=doubler
+ ide-core.nodma= [HW] (E)IDE subsystem
+ Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc
+ .vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom
+ .chs .ignore_cable are additional options
See Documentation/ide/ide.txt.
idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
ihash_entries= [KNL]
Set number of hash buckets for inode cache.
+ ima_audit= [IMA]
+ Format: { "0" | "1" }
+ 0 -- integrity auditing messages. (Default)
+ 1 -- enable informational integrity auditing messages.
+
+ ima_hash= [IMA]
+ Formt: { "sha1" | "md5" }
+ default: "sha1"
+
in2000= [HW,SCSI]
See header of drivers/scsi/in2000.c.
intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option
+ on
+ Enable intel iommu driver.
off
Disable intel iommu driver.
igfx_off [Default Off]
See Documentation/fb/modedb.txt.
vga= [BOOT,X86-32] Select a particular video mode
- See Documentation/x86/i386/boot.txt and
+ See Documentation/x86/boot.txt and
Documentation/svga.txt.
Use vga=ask for menu.
This is actually a boot loader parameter; the value is
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
+ ARM/NUVOTON W90X900 ARM ARCHITECTURE
+ P: Wan ZongShun
+ M: mcuos.com@gmail.com
+ L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+ W: http://www.mcuos.com
+ S: Maintained
+
ARPD SUPPORT
P: Jonathan Layes
L: netdev@vger.kernel.org
W: http://bu3sch.de/btgpio.php
S: Maintained
+ BTRFS FILE SYSTEM
+ P: Chris Mason
+ M: chris.mason@oracle.com
+ L: linux-btrfs@vger.kernel.org
+ W: http://btrfs.wiki.kernel.org/
+ T: git kernel.org:/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
+ S: Maintained
+
BTTV VIDEO4LINUX DRIVER
P: Mauro Carvalho Chehab
M: mchehab@infradead.org
CONTROL GROUPS (CGROUPS)
P: Paul Menage
M: menage@google.com
+ P: Li Zefan
+ M: lizf@cn.fujitsu.com
L: containers@lists.linux-foundation.org
S: Maintained
S: Supported
DOCUMENTATION (/Documentation directory)
- P: Michael Kerrisk
- M: mtk.manpages@gmail.com
P: Randy Dunlap
M: rdunlap@xenotime.net
L: linux-doc@vger.kernel.org
S: Maintained
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
- P: Robert Love
- M: rlove@rlove.org
- M: linux-kernel@vger.kernel.org
- W: http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/
+ P: Frank Seidel
+ M: frank@f-seidel.de
+ L: lm-sensors@lm-sensors.org
+ W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
S: Maintained
GSPCA FINEPIX SUBDRIVER
HIBERNATION (aka Software Suspend, aka swsusp)
P: Pavel Machek
- M: pavel@suse.cz
+ M: pavel@ucw.cz
P: Rafael J. Wysocki
M: rjw@sisk.pl
L: linux-pm@lists.linux-foundation.org
L: linux1394-devel@lists.sourceforge.net
S: Maintained
+INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
+P: Mimi Zohar
+M: zohar@us.ibm.com
+S: Supported
+
IMS TWINTURBO FRAMEBUFFER DRIVER
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Orphan
ISDN SUBSYSTEM
P: Karsten Keil
- M: kkeil@suse.de
+ M: isdn@linux-pingi.de
L: isdn4linux@listserv.isdn4linux.de (subscribers-only)
W: http://www.isdn4linux.de
T: git kernel.org:/pub/scm/linux/kernel/kkeil/isdn-2.6.git
M: mtk.manpages@gmail.com
W: http://www.kernel.org/doc/man-pages
L: linux-man@vger.kernel.org
- S: Supported
+ S: Maintained
MARVELL LIBERTAS WIRELESS DRIVER
P: Dan Williams
M: jeremy@xensource.com
P: Chris Wright
M: chrisw@sous-sol.org
- P: Zachary Amsden
- M: zach@vmware.com
+ P: Alok Kataria
+ M: akataria@vmware.com
P: Rusty Russell
M: rusty@rustcorp.com.au
L: virtualization@lists.osdl.org
PARISC ARCHITECTURE
P: Kyle McMartin
M: kyle@mcmartin.ca
- P: Matthew Wilcox
- M: matthew@wil.cx
- P: Grant Grundler
- M: grundler@parisc-linux.org
+ P: Helge Deller
+ M: deller@gmx.de
L: linux-parisc@vger.kernel.org
W: http://www.parisc-linux.org/
T: git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
PXA MMCI DRIVER
S: Orphan
+ PXA RTC DRIVER
+ P: Robert Jarzmik
+ M: robert.jarzmik@free.fr
+ L: rtc-linux@googlegroups.com
+ S: Maintained
+
QLOGIC QLA2XXX FC-SCSI DRIVER
P: Andrew Vasquez
M: linux-driver@qlogic.com
L: linux-kernel@vger.kernel.org
L: linux-security-module@vger.kernel.org (suggested Cc:)
T: git kernel.org:pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
+W: http://security.wiki.kernel.org/
S: Supported
SECURITY CONTACT
T: git kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
S: Supported
+ SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
+ P: Sathya Perla
+ M: sathyap@serverengines.com
+ P: Subbu Seetharaman
+ M: subbus@serverengines.com
+ L: netdev@vger.kernel.org
+ W: http://www.serverengines.com
+ S: Supported
+
SFC NETWORK DRIVER
P: Steve Hodgson
P: Ben Hutchings
P: Len Brown
M: len.brown@intel.com
P: Pavel Machek
- M: pavel@suse.cz
+ M: pavel@ucw.cz
P: Rafael J. Wysocki
M: rjw@sisk.pl
L: linux-pm@lists.linux-foundation.org
W: http://sourceforge.net/projects/tlan/
S: Maintained
+TOMOYO SECURITY MODULE
+P: Kentaro Takeda
+M: takedakn@nttdata.co.jp
+P: Tetsuo Handa
+M: penguin-kernel@I-love.SAKURA.ne.jp
+L: linux-kernel@vger.kernel.org (kernel issues)
+L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English)
+L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese)
+L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese)
+W: http://tomoyo.sourceforge.jp/
+T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches/
+S: Maintained
+
TOSHIBA ACPI EXTRAS DRIVER
P: John Belmonte
M: toshiba_acpi@memebeam.org
M: srajiv@linux.vnet.ibm.com
W: http://tpmdd.sourceforge.net
P: Marcel Selhorst
- M: tpm@selhorst.net
- W: http://www.prosec.rub.de/tpm/
+ M: m.selhorst@sirrix.com
+ W: http://www.sirrix.com
L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
S: Maintained
ZR36067 VIDEO FOR LINUX DRIVER
- P: Ronald Bultje
- M: rbultje@ronald.bitfreak.net
L: mjpeg-users@lists.sourceforge.net
+ L: linux-media@vger.kernel.org
W: http://mjpeg.sourceforge.net/driver-zoran/
- S: Maintained
+ T: Mercurial http://linuxtv.org/hg/v4l-dvb
+ S: Odd Fixes
ZS DECSTATION Z85C30 SERIAL DRIVER
P: Maciej W. Rozycki
retval = mutex_lock_interruptible(¤t->cred_exec_mutex);
if (retval < 0)
goto out_free;
+ current->in_execve = 1;
retval = -ENOMEM;
bprm->cred = prepare_exec_creds();
if (!bprm->cred)
goto out_unlock;
- check_unsafe_exec(bprm);
+ check_unsafe_exec(bprm, current->files);
file = open_exec(filename);
retval = PTR_ERR(file);
goto out;
/* execve succeeded */
+ current->in_execve = 0;
mutex_unlock(¤t->cred_exec_mutex);
acct_update_integrals(current);
free_bprm(bprm);
}
out_unlock:
+ current->in_execve = 0;
mutex_unlock(¤t->cred_exec_mutex);
out_free:
#include <linux/proc_fs.h>
#include <linux/mount.h>
#include <linux/security.h>
+#include <linux/ima.h>
#include <linux/syscalls.h>
#include <linux/tsacct_kern.h>
#include <linux/cn_proc.h>
MAY_READ | MAY_EXEC | MAY_OPEN);
if (error)
goto exit;
+ error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN);
+ if (error)
+ goto exit;
file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
error = PTR_ERR(file);
goto out_path_put;
err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
+ if (err)
+ goto out_path_put;
+ err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN);
if (err)
goto out_path_put;
* - the caller must hold current->cred_exec_mutex to protect against
* PTRACE_ATTACH
*/
- void check_unsafe_exec(struct linux_binprm *bprm)
+ void check_unsafe_exec(struct linux_binprm *bprm, struct files_struct *files)
{
- struct task_struct *p = current;
+ struct task_struct *p = current, *t;
+ unsigned long flags;
+ unsigned n_fs, n_files, n_sighand;
bprm->unsafe = tracehook_unsafe_exec(p);
- if (atomic_read(&p->fs->count) > 1 ||
- atomic_read(&p->files->count) > 1 ||
- atomic_read(&p->sighand->count) > 1)
+ n_fs = 1;
+ n_files = 1;
+ n_sighand = 1;
+ lock_task_sighand(p, &flags);
+ for (t = next_thread(p); t != p; t = next_thread(t)) {
+ if (t->fs == p->fs)
+ n_fs++;
+ if (t->files == files)
+ n_files++;
+ n_sighand++;
+ }
+
+ if (atomic_read(&p->fs->count) > n_fs ||
+ atomic_read(&p->files->count) > n_files ||
+ atomic_read(&p->sighand->count) > n_sighand)
bprm->unsafe |= LSM_UNSAFE_SHARE;
+
+ unlock_task_sighand(p, &flags);
}
/*
struct linux_binfmt *fmt;
retval = security_bprm_check(bprm);
+ if (retval)
+ return retval;
+ retval = ima_bprm_check(bprm);
if (retval)
return retval;
retval = mutex_lock_interruptible(¤t->cred_exec_mutex);
if (retval < 0)
goto out_free;
+ current->in_execve = 1;
retval = -ENOMEM;
bprm->cred = prepare_exec_creds();
if (!bprm->cred)
goto out_unlock;
- check_unsafe_exec(bprm);
+ check_unsafe_exec(bprm, displaced);
file = open_exec(filename);
retval = PTR_ERR(file);
goto out;
/* execve succeeded */
+ current->in_execve = 0;
mutex_unlock(¤t->cred_exec_mutex);
acct_update_integrals(current);
free_bprm(bprm);
}
out_unlock:
+ current->in_execve = 0;
mutex_unlock(¤t->cred_exec_mutex);
out_free:
#include <linux/hash.h>
#include <linux/swap.h>
#include <linux/security.h>
+#include <linux/ima.h>
#include <linux/pagemap.h>
#include <linux/cdev.h>
#include <linux/bootmem.h>
inode->i_cdev = NULL;
inode->i_rdev = 0;
inode->dirtied_when = 0;
- if (security_inode_alloc(inode)) {
- if (inode->i_sb->s_op->destroy_inode)
- inode->i_sb->s_op->destroy_inode(inode);
- else
- kmem_cache_free(inode_cachep, (inode));
- return NULL;
- }
+
+ if (security_inode_alloc(inode))
+ goto out_free_inode;
+
+ /* allocate and initialize an i_integrity */
+ if (ima_inode_alloc(inode))
+ goto out_free_security;
spin_lock_init(&inode->i_lock);
lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
inode->i_mapping = mapping;
return inode;
+
+out_free_security:
+ security_inode_free(inode);
+out_free_inode:
+ if (inode->i_sb->s_op->destroy_inode)
+ inode->i_sb->s_op->destroy_inode(inode);
+ else
+ kmem_cache_free(inode_cachep, (inode));
+ return NULL;
}
EXPORT_SYMBOL(inode_init_always);
invalidate_inode_buffers(inode);
if (!atomic_read(&inode->i_count)) {
list_move(&inode->i_list, dispose);
+ WARN_ON(inode->i_state & I_NEW);
inode->i_state |= I_FREEING;
count++;
continue;
continue;
}
list_move(&inode->i_list, &freeable);
+ WARN_ON(inode->i_state & I_NEW);
inode->i_state |= I_FREEING;
nr_pruned++;
}
* just created it (so there can be no old holders
* that haven't tested I_LOCK).
*/
+ WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW));
inode->i_state &= ~(I_LOCK|I_NEW);
wake_up_inode(inode);
}
list_del_init(&inode->i_list);
list_del_init(&inode->i_sb_list);
+ WARN_ON(inode->i_state & I_NEW);
inode->i_state |= I_FREEING;
inodes_stat.nr_inodes--;
spin_unlock(&inode_lock);
spin_unlock(&inode_lock);
return;
}
+ WARN_ON(inode->i_state & I_NEW);
inode->i_state |= I_WILL_FREE;
spin_unlock(&inode_lock);
write_inode_now(inode, 1);
spin_lock(&inode_lock);
+ WARN_ON(inode->i_state & I_NEW);
inode->i_state &= ~I_WILL_FREE;
inodes_stat.nr_unused--;
hlist_del_init(&inode->i_hash);
}
list_del_init(&inode->i_list);
list_del_init(&inode->i_sb_list);
+ WARN_ON(inode->i_state & I_NEW);
inode->i_state |= I_FREEING;
inodes_stat.nr_inodes--;
spin_unlock(&inode_lock);
* @utime: time spent in user mode, in &cputime_t units
* @stime: time spent in kernel mode, in &cputime_t units
* @sum_exec_runtime: total time spent on the CPU, in nanoseconds
- * @lock: lock for fields in this struct
*
* This structure groups together three kinds of CPU time that are
* tracked for threads and thread groups. Most things considering
cputime_t utime;
cputime_t stime;
unsigned long long sum_exec_runtime;
- spinlock_t lock;
};
/* Alternate field names when used to cache expirations. */
#define prof_exp stime
#define virt_exp utime
#define sched_exp sum_exec_runtime
+ #define INIT_CPUTIME \
+ (struct task_cputime) { \
+ .utime = cputime_zero, \
+ .stime = cputime_zero, \
+ .sum_exec_runtime = 0, \
+ }
+
/**
- * struct thread_group_cputime - thread group interval timer counts
- * @totals: thread group interval timers; substructure for
- * uniprocessor kernel, per-cpu for SMP kernel.
+ * struct thread_group_cputimer - thread group interval timer counts
+ * @cputime: thread group interval timers.
+ * @running: non-zero when there are timers running and
+ * @cputime receives updates.
+ * @lock: lock for fields in this struct.
*
* This structure contains the version of task_cputime, above, that is
- * used for thread group CPU clock calculations.
+ * used for thread group CPU timer calculations.
*/
- struct thread_group_cputime {
- struct task_cputime totals;
+ struct thread_group_cputimer {
+ struct task_cputime cputime;
+ int running;
+ spinlock_t lock;
};
/*
cputime_t it_prof_incr, it_virt_incr;
/*
- * Thread group totals for process CPU clocks.
- * See thread_group_cputime(), et al, for details.
+ * Thread group totals for process CPU timers.
+ * See thread_group_cputimer(), et al, for details.
*/
- struct thread_group_cputime cputime;
+ struct thread_group_cputimer cputimer;
/* Earliest-expiration cache. */
struct task_cputime cputime_expires;
* Live threads maintain their own counters and add to these
* in __exit_signal, except for the group leader.
*/
- cputime_t cutime, cstime;
+ cputime_t utime, stime, cutime, cstime;
cputime_t gtime;
cputime_t cgtime;
unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
unsigned long inblock, oublock, cinblock, coublock;
struct task_io_accounting ioac;
+ /*
+ * Cumulative ns of schedule CPU time fo dead threads in the
+ * group, not including a zombie group leader, (This only differs
+ * from jiffies_to_ns(utime + stime) if sched_clock uses something
+ * other than jiffies.)
+ */
+ unsigned long long sum_sched_runtime;
+
/*
* We don't bother to synchronize most readers of this at all,
* because there is no reader checking a limit that actually needs
/* ??? */
unsigned int personality;
unsigned did_exec:1;
+ unsigned in_execve:1; /* Tell the LSMs that the process is doing an
+ * execve */
pid_t pid;
pid_t tgid;
#endif
};
+ /* Future-safe accessor for struct task_struct's cpus_allowed. */
+ #define tsk_cpumask(tsk) (&(tsk)->cpus_allowed)
+
/*
* Priority of a process goes from 0..MAX_PRIO-1, valid RT
* priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
/*
* Thread group CPU time accounting.
*/
-
- static inline
- void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
- {
- struct task_cputime *totals = &tsk->signal->cputime.totals;
- unsigned long flags;
-
- spin_lock_irqsave(&totals->lock, flags);
- *times = *totals;
- spin_unlock_irqrestore(&totals->lock, flags);
- }
+ void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times);
+ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times);
static inline void thread_group_cputime_init(struct signal_struct *sig)
{
- sig->cputime.totals = (struct task_cputime){
- .utime = cputime_zero,
- .stime = cputime_zero,
- .sum_exec_runtime = 0,
- };
-
- spin_lock_init(&sig->cputime.totals.lock);
+ sig->cputimer.cputime = INIT_CPUTIME;
+ spin_lock_init(&sig->cputimer.lock);
+ sig->cputimer.running = 0;
}
static inline void thread_group_cputime_free(struct signal_struct *sig)
extern int sched_group_set_rt_period(struct task_group *tg,
long rt_period_us);
extern long sched_group_rt_period(struct task_group *tg);
+ extern int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk);
#endif
#endif
+ extern int task_can_switch_user(struct user_struct *up,
+ struct task_struct *tsk);
+
#ifdef CONFIG_TASK_XACCT
static inline void add_rchar(struct task_struct *tsk, ssize_t amt)
{
#include <linux/nsproxy.h>
#include <linux/mount.h>
#include <linux/ipc_namespace.h>
+#include <linux/ima.h>
#include <asm/uaccess.h>
struct file * file;
char name[13];
int id;
+ int acctflag = 0;
if (size < SHMMIN || size > ns->shm_ctlmax)
return -EINVAL;
sprintf (name, "SYSV%08x", key);
if (shmflg & SHM_HUGETLB) {
- /* hugetlb_file_setup takes care of mlock user accounting */
- file = hugetlb_file_setup(name, size);
+ /* hugetlb_file_setup applies strict accounting */
+ if (shmflg & SHM_NORESERVE)
+ acctflag = VM_NORESERVE;
+ file = hugetlb_file_setup(name, size, acctflag);
shp->mlock_user = current_user();
} else {
- int acctflag = 0;
/*
* Do not allow no accounting for OVERCOMMIT_NEVER, even
* if it's asked for.
error = PTR_ERR(file);
if (IS_ERR(file))
goto no_file;
+ ima_shm_check(file);
id = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
if (id < 0) {
file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
if (!file)
goto out_free;
+ ima_shm_check(file);
file->private_data = sfd;
file->f_mapping = shp->shm_file->f_mapping;
struct user_namespace init_user_ns = {
.kref = {
- .refcount = ATOMIC_INIT(1),
+ .refcount = ATOMIC_INIT(2),
},
.creator = &root_user,
};
static void uid_hash_remove(struct user_struct *up)
{
hlist_del_init(&up->uidhash_node);
+ put_user_ns(up->user_ns);
}
static struct user_struct *uid_hash_find(uid_t uid, struct hlist_head *hashent)
/* work function to remove sysfs directory for a user and free up
* corresponding structures.
*/
- static void remove_user_sysfs_dir(struct work_struct *w)
+ static void cleanup_user_struct(struct work_struct *w)
{
struct user_struct *up = container_of(w, struct user_struct, work);
unsigned long flags;
int remove_user = 0;
- if (up->user_ns != &init_user_ns)
- return;
/* Make uid_hash_remove() + sysfs_remove_file() + kobject_del()
* atomic.
*/
if (!remove_user)
goto done;
- kobject_uevent(&up->kobj, KOBJ_REMOVE);
- kobject_del(&up->kobj);
- kobject_put(&up->kobj);
+ if (up->user_ns == &init_user_ns) {
+ kobject_uevent(&up->kobj, KOBJ_REMOVE);
+ kobject_del(&up->kobj);
+ kobject_put(&up->kobj);
+ }
sched_destroy_user(up);
key_put(up->uid_keyring);
atomic_inc(&up->__count);
spin_unlock_irqrestore(&uidhash_lock, flags);
- put_user_ns(up->user_ns);
- INIT_WORK(&up->work, remove_user_sysfs_dir);
+ INIT_WORK(&up->work, cleanup_user_struct);
schedule_work(&up->work);
}
sched_destroy_user(up);
key_put(up->uid_keyring);
key_put(up->session_keyring);
- put_user_ns(up->user_ns);
kmem_cache_free(uid_cachep, up);
}
#endif
+ #if defined(CONFIG_RT_GROUP_SCHED) && defined(CONFIG_USER_SCHED)
+ /*
+ * We need to check if a setuid can take place. This function should be called
+ * before successfully completing the setuid.
+ */
+ int task_can_switch_user(struct user_struct *up, struct task_struct *tsk)
+ {
+
+ return sched_rt_can_attach(up->tg, tsk);
+
+ }
+ #else
+ int task_can_switch_user(struct user_struct *up, struct task_struct *tsk)
+ {
+ return 1;
+ }
+ #endif
+
/*
* Locate the user_struct for the passed UID. If found, take a ref on it. The
* caller must undo that ref with free_uid().
#include <linux/fs.h>
#include <linux/personality.h>
#include <linux/security.h>
+#include <linux/ima.h>
#include <linux/hugetlb.h>
#include <linux/profile.h>
#include <linux/module.h>
struct inode *inode;
unsigned int vm_flags;
int error;
- int accountable = 1;
unsigned long reqprot = prot;
/*
return -EPERM;
vm_flags &= ~VM_MAYEXEC;
}
- if (is_file_hugepages(file))
- accountable = 0;
if (!file->f_op || !file->f_op->mmap)
return -ENODEV;
}
error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
+ if (error)
+ return error;
+ error = ima_file_mmap(file, prot);
if (error)
return error;
- return mmap_region(file, addr, len, flags, vm_flags, pgoff,
- accountable);
+ return mmap_region(file, addr, len, flags, vm_flags, pgoff);
}
EXPORT_SYMBOL(do_mmap_pgoff);
/*
* We account for memory if it's a private writeable mapping,
- * and VM_NORESERVE wasn't set.
+ * not hugepages and VM_NORESERVE wasn't set.
*/
- static inline int accountable_mapping(unsigned int vm_flags)
+ static inline int accountable_mapping(struct file *file, unsigned int vm_flags)
{
+ /*
+ * hugetlb has its own accounting separate from the core VM
+ * VM_HUGETLB may not be set yet so we cannot check for that flag.
+ */
+ if (file && is_file_hugepages(file))
+ return 0;
+
return (vm_flags & (VM_NORESERVE | VM_SHARED | VM_WRITE)) == VM_WRITE;
}
unsigned long mmap_region(struct file *file, unsigned long addr,
unsigned long len, unsigned long flags,
- unsigned int vm_flags, unsigned long pgoff,
- int accountable)
+ unsigned int vm_flags, unsigned long pgoff)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma, *prev;
/*
* Set 'VM_NORESERVE' if we should not account for the
- * memory use of this mapping. We only honor MAP_NORESERVE
- * if we're allowed to overcommit memory.
+ * memory use of this mapping.
*/
- if ((flags & MAP_NORESERVE) && sysctl_overcommit_memory != OVERCOMMIT_NEVER)
- vm_flags |= VM_NORESERVE;
- if (!accountable)
- vm_flags |= VM_NORESERVE;
+ if ((flags & MAP_NORESERVE)) {
+ /* We honor MAP_NORESERVE if allowed to overcommit */
+ if (sysctl_overcommit_memory != OVERCOMMIT_NEVER)
+ vm_flags |= VM_NORESERVE;
+
+ /* hugetlb applies strict overcommit unless MAP_NORESERVE */
+ if (file && is_file_hugepages(file))
+ vm_flags |= VM_NORESERVE;
+ }
/*
* Private writable mapping: check memory availability
*/
- if (accountable_mapping(vm_flags)) {
+ if (accountable_mapping(file, vm_flags)) {
charged = len >> PAGE_SHIFT;
if (security_vm_enough_memory(charged))
return -ENOMEM;
unsigned long end;
/* mm's last user has gone, and its about to be pulled down */
- arch_exit_mmap(mm);
mmu_notifier_release(mm);
- if (!mm->mmap) /* Can happen if dup_mmap() received an OOM */
- return;
-
if (mm->locked_vm) {
vma = mm->mmap;
while (vma) {
vma = vma->vm_next;
}
}
+
+ arch_exit_mmap(mm);
+
vma = mm->mmap;
+ if (!vma) /* Can happen if dup_mmap() received an OOM */
+ return;
+
lru_add_drain();
flush_cache_mm(mm);
tlb = tlb_gather_mmu(mm, 1);
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/swap.h>
+#include <linux/ima.h>
static struct vfsmount *shm_mnt;
*/
static inline int shmem_acct_size(unsigned long flags, loff_t size)
{
- return (flags & VM_ACCOUNT) ?
- security_vm_enough_memory_kern(VM_ACCT(size)) : 0;
+ return (flags & VM_NORESERVE) ?
+ 0 : security_vm_enough_memory_kern(VM_ACCT(size));
}
static inline void shmem_unacct_size(unsigned long flags, loff_t size)
{
- if (flags & VM_ACCOUNT)
+ if (!(flags & VM_NORESERVE))
vm_unacct_memory(VM_ACCT(size));
}
*/
static inline int shmem_acct_block(unsigned long flags)
{
- return (flags & VM_ACCOUNT) ?
- 0 : security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE));
+ return (flags & VM_NORESERVE) ?
+ security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)) : 0;
}
static inline void shmem_unacct_blocks(unsigned long flags, long pages)
{
- if (!(flags & VM_ACCOUNT))
+ if (flags & VM_NORESERVE)
vm_unacct_memory(pages * VM_ACCT(PAGE_CACHE_SIZE));
}
return 0;
}
- static struct inode *
- shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
+ static struct inode *shmem_get_inode(struct super_block *sb, int mode,
+ dev_t dev, unsigned long flags)
{
struct inode *inode;
struct shmem_inode_info *info;
info = SHMEM_I(inode);
memset(info, 0, (char *)inode - (char *)info);
spin_lock_init(&info->lock);
+ info->flags = flags & VM_NORESERVE;
INIT_LIST_HEAD(&info->swaplist);
switch (mode & S_IFMT) {
static int
shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
{
- struct inode *inode = shmem_get_inode(dir->i_sb, mode, dev);
+ struct inode *inode;
int error = -ENOSPC;
+ inode = shmem_get_inode(dir->i_sb, mode, dev, VM_NORESERVE);
if (inode) {
error = security_inode_init_security(inode, dir, NULL, NULL,
NULL);
if (len > PAGE_CACHE_SIZE)
return -ENAMETOOLONG;
- inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
+ inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0, VM_NORESERVE);
if (!inode)
return -ENOSPC;
sb->s_flags |= MS_POSIXACL;
#endif
- inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0);
+ inode = shmem_get_inode(sb, S_IFDIR | sbinfo->mode, 0, VM_NORESERVE);
if (!inode)
goto failed;
inode->i_uid = sbinfo->uid;
return 0;
}
- #define shmem_file_operations ramfs_file_operations
- #define shmem_vm_ops generic_file_vm_ops
- #define shmem_get_inode ramfs_get_inode
- #define shmem_acct_size(a, b) 0
- #define shmem_unacct_size(a, b) do {} while (0)
- #define SHMEM_MAX_BYTES LLONG_MAX
+ #define shmem_vm_ops generic_file_vm_ops
+ #define shmem_file_operations ramfs_file_operations
+ #define shmem_get_inode(sb, mode, dev, flags) ramfs_get_inode(sb, mode, dev)
+ #define shmem_acct_size(flags, size) 0
+ #define shmem_unacct_size(flags, size) do {} while (0)
+ #define SHMEM_MAX_BYTES LLONG_MAX
#endif /* CONFIG_SHMEM */
* shmem_file_setup - get an unlinked file living in tmpfs
* @name: name for dentry (to be seen in /proc/<pid>/maps
* @size: size to be set for the file
- * @flags: vm_flags
+ * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size
*/
struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
{
goto put_dentry;
error = -ENOSPC;
- inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
+ inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, flags);
if (!inode)
goto close_file;
- #ifdef CONFIG_SHMEM
- SHMEM_I(inode)->flags = (flags & VM_NORESERVE) ? 0 : VM_ACCOUNT;
- #endif
d_instantiate(dentry, inode);
inode->i_size = size;
inode->i_nlink = 0; /* It is unlinked */
if (IS_ERR(file))
return PTR_ERR(file);
+ ima_shm_check(file);
if (vma->vm_file)
fput(vma->vm_file);
vma->vm_file = file;
/**
* smack_ptrace_may_access - Smack approval on PTRACE_ATTACH
* @ctp: child task pointer
+ * @mode: ptrace attachment mode
*
* Returns 0 if access is OK, an error code otherwise
*
/**
* smack_sb_copy_data - copy mount options data for processing
- * @type: file system type
* @orig: where to start
- * @smackopts
+ * @smackopts: mount options string
*
* Returns 0 on success or -ENOMEM on error.
*
/**
* smack_sb_mount - Smack check for mounting
* @dev_name: unused
- * @nd: mount point
+ * @path: mount point
* @type: unused
* @flags: unused
* @data: unused
/**
* smack_inode_alloc_security - allocate an inode blob
- * @inode - the inode in need of a blob
+ * @inode: the inode in need of a blob
*
* Returns 0 if it gets a blob, -ENOMEM otherwise
*/
/**
* smack_inode_free_security - free an inode blob
- * @inode - the inode with a blob
+ * @inode: the inode with a blob
*
* Clears the blob pointer in inode
*/
* smack_inode_permission - Smack version of permission()
* @inode: the inode in question
* @mask: the access requested
- * @nd: unused
*
* This is the important Smack hook.
*
* @inode: the object
* @name: attribute name
* @buffer: where to put the result
- * @size: size of the buffer
- * @err: unused
+ * @alloc: unused
*
* Returns the size of the attribute or an error code
*/
/**
* smack_file_lock - Smack check on file locking
* @file: the object
- * @cmd unused
+ * @cmd: unused
*
* Returns 0 if current has write access, error code otherwise
*/
return 0;
}
-/*
- * commit new credentials
+/**
+ * smack_cred_commit - commit new credentials
* @new: the new credentials
* @old: the original credentials
*/
/**
* smack_kernel_act_as - Set the subjective context in a set of credentials
- * @new points to the set of credentials to be modified.
- * @secid specifies the security ID to be set
+ * @new: points to the set of credentials to be modified.
+ * @secid: specifies the security ID to be set
*
* Set the security data for a kernel service.
*/
/**
* smack_kernel_create_files_as - Set the file creation label in a set of creds
- * @new points to the set of credentials to be modified
- * @inode points to the inode to use as a reference
+ * @new: points to the set of credentials to be modified
+ * @inode: points to the inode to use as a reference
*
* Set the file creation context in a set of credentials to the same
* as the objective context of the specified inode
/**
* smack_task_to_inode - copy task smack into the inode blob
* @p: task to copy from
- * inode: inode to copy to
+ * @inode: inode to copy to
*
* Sets the smack pointer in the inode security blob
*/
* smack_sk_alloc_security - Allocate a socket blob
* @sk: the socket
* @family: unused
- * @priority: memory allocation priority
+ * @gfp_flags: memory allocation flags
*
* Assign Smack pointers to current
*
* looks for host based access restrictions
*
* This version will only be appropriate for really small
- * sets of single label hosts. Because of the masking
- * it cannot shortcut out on the first match. There are
- * numerious ways to address the problem, but none of them
- * have been applied here.
+ * sets of single label hosts.
*
* Returns the label of the far end or NULL if it's not special.
*/
static char *smack_host_label(struct sockaddr_in *sip)
{
struct smk_netlbladdr *snp;
- char *bestlabel = NULL;
struct in_addr *siap = &sip->sin_addr;
- struct in_addr *liap;
- struct in_addr *miap;
- struct in_addr bestmask;
if (siap->s_addr == 0)
return NULL;
- bestmask.s_addr = 0;
-
for (snp = smack_netlbladdrs; snp != NULL; snp = snp->smk_next) {
- liap = &snp->smk_host.sin_addr;
- miap = &snp->smk_mask;
- /*
- * If the addresses match after applying the list entry mask
- * the entry matches the address. If it doesn't move along to
- * the next entry.
- */
- if ((liap->s_addr & miap->s_addr) !=
- (siap->s_addr & miap->s_addr))
- continue;
/*
- * If the list entry mask identifies a single address
- * it can't get any more specific.
+ * we break after finding the first match because
+ * the list is sorted from longest to shortest mask
+ * so we have found the most specific match
*/
- if (miap->s_addr == 0xffffffff)
+ if ((&snp->smk_host.sin_addr)->s_addr ==
+ (siap->s_addr & (&snp->smk_mask)->s_addr)) {
return snp->smk_label;
- /*
- * If the list entry mask is less specific than the best
- * already found this entry is uninteresting.
- */
- if ((miap->s_addr | bestmask.s_addr) == bestmask.s_addr)
- continue;
- /*
- * This is better than any entry found so far.
- */
- bestmask.s_addr = miap->s_addr;
- bestlabel = snp->smk_label;
+ }
}
- return bestlabel;
+ return NULL;
}
/**
/**
* smack_ipc_getsecid - Extract smack security id
- * @ipcp: the object permissions
+ * @ipp: the object permissions
* @secid: where result will be saved
*/
static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid)
/**
* smack_socket_sendmsg - Smack check based on destination host
* @sock: the socket
- * @msghdr: the message
+ * @msg: the message
* @size: the size of the message
*
* Return 0 if the current subject can write to the destination
/**
- * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat
- * pair to smack
+ * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
* @sap: netlabel secattr
* @sip: where to put the result
*
* @sock: the socket
* @optval: user's destination
* @optlen: size thereof
- * @len: max thereoe
+ * @len: max thereof
*
* returns zero on success, an error code otherwise
*/
#endif /* CONFIG_AUDIT */
-/*
+/**
* smack_secid_to_secctx - return the smack label for a secid
* @secid: incoming integer
* @secdata: destination
return 0;
}
-/*
+/**
* smack_secctx_to_secid - return the secid for a smack label
* @secdata: smack label
* @seclen: how long result is
return 0;
}
-/*
+/**
* smack_release_secctx - don't do anything.
- * @key_ref: unused
- * @context: unused
- * @perm: unused
+ * @secdata: unused
+ * @seclen: unused
*
* Exists to make sure nothing gets done, and properly
*/