Commit 2b15fe63 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

LSM: Add all of the new security/* files for basic task control

This includes the security_* functions, and the default and capability
modules.
parent c59ccd5f
This diff is collapsed.
CONFIG_SECURITY_CAPABILITIES
This enables the "default" Linux capabilities functionality.
If you are unsure how to answer this question, answer Y.
#
# Security configuration
#
mainmenu_option next_comment
comment 'Security options'
tristate 'Capabilities Support' CONFIG_SECURITY_CAPABILITIES
endmenu
#
# Makefile for the kernel security code
#
# Objects that export symbols
export-objs := security.o
# Object file lists
obj-y := security.o dummy.o
obj-$(CONFIG_SECURITY_CAPABILITIES) += capability.o
include $(TOPDIR)/Rules.make
This diff is collapsed.
/*
* Stub functions for the default security function pointers in case no
* security model is loaded.
*
* Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com>
* Copyright (C) 2001 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/security.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
{
return 0;
}
static int dummy_capget (struct task_struct *target, kernel_cap_t * effective,
kernel_cap_t * inheritable, kernel_cap_t * permitted)
{
return 0;
}
static int dummy_capset_check (struct task_struct *target,
kernel_cap_t * effective,
kernel_cap_t * inheritable,
kernel_cap_t * permitted)
{
return 0;
}
static void dummy_capset_set (struct task_struct *target,
kernel_cap_t * effective,
kernel_cap_t * inheritable,
kernel_cap_t * permitted)
{
return;
}
static int dummy_capable (struct task_struct *tsk, int cap)
{
if (cap_is_fs_cap (cap) ? tsk->fsuid == 0 : tsk->euid == 0)
/* capability granted */
return 0;
/* capability denied */
return -EPERM;
}
static int dummy_sys_security (unsigned int id, unsigned int call,
unsigned long *args)
{
return -ENOSYS;
}
static int dummy_bprm_alloc_security (struct linux_binprm *bprm)
{
return 0;
}
static void dummy_bprm_free_security (struct linux_binprm *bprm)
{
return;
}
static void dummy_bprm_compute_creds (struct linux_binprm *bprm)
{
return;
}
static int dummy_bprm_set_security (struct linux_binprm *bprm)
{
return 0;
}
static int dummy_bprm_check_security (struct linux_binprm *bprm)
{
return 0;
}
static int dummy_task_create (unsigned long clone_flags)
{
return 0;
}
static int dummy_task_alloc_security (struct task_struct *p)
{
return 0;
}
static void dummy_task_free_security (struct task_struct *p)
{
return;
}
static int dummy_task_setuid (uid_t id0, uid_t id1, uid_t id2, int flags)
{
return 0;
}
static int dummy_task_post_setuid (uid_t id0, uid_t id1, uid_t id2, int flags)
{
return 0;
}
static int dummy_task_setgid (gid_t id0, gid_t id1, gid_t id2, int flags)
{
return 0;
}
static int dummy_task_setpgid (struct task_struct *p, pid_t pgid)
{
return 0;
}
static int dummy_task_getpgid (struct task_struct *p)
{
return 0;
}
static int dummy_task_getsid (struct task_struct *p)
{
return 0;
}
static int dummy_task_setgroups (int gidsetsize, gid_t * grouplist)
{
return 0;
}
static int dummy_task_setnice (struct task_struct *p, int nice)
{
return 0;
}
static int dummy_task_setrlimit (unsigned int resource, struct rlimit *new_rlim)
{
return 0;
}
static int dummy_task_setscheduler (struct task_struct *p, int policy,
struct sched_param *lp)
{
return 0;
}
static int dummy_task_getscheduler (struct task_struct *p)
{
return 0;
}
static int dummy_task_wait (struct task_struct *p)
{
return 0;
}
static int dummy_task_kill (struct task_struct *p, struct siginfo *info,
int sig)
{
return 0;
}
static int dummy_task_prctl (int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5)
{
return 0;
}
static void dummy_task_kmod_set_label (void)
{
return;
}
static void dummy_task_reparent_to_init (struct task_struct *p)
{
p->euid = p->fsuid = 0;
return;
}
static int dummy_register (const char *name, struct security_operations *ops)
{
return -EINVAL;
}
static int dummy_unregister (const char *name, struct security_operations *ops)
{
return -EINVAL;
}
struct security_operations dummy_security_ops = {
ptrace: dummy_ptrace,
capget: dummy_capget,
capset_check: dummy_capset_check,
capset_set: dummy_capset_set,
capable: dummy_capable,
sys_security: dummy_sys_security,
bprm_alloc_security: dummy_bprm_alloc_security,
bprm_free_security: dummy_bprm_free_security,
bprm_compute_creds: dummy_bprm_compute_creds,
bprm_set_security: dummy_bprm_set_security,
bprm_check_security: dummy_bprm_check_security,
task_create: dummy_task_create,
task_alloc_security: dummy_task_alloc_security,
task_free_security: dummy_task_free_security,
task_setuid: dummy_task_setuid,
task_post_setuid: dummy_task_post_setuid,
task_setgid: dummy_task_setgid,
task_setpgid: dummy_task_setpgid,
task_getpgid: dummy_task_getpgid,
task_getsid: dummy_task_getsid,
task_setgroups: dummy_task_setgroups,
task_setnice: dummy_task_setnice,
task_setrlimit: dummy_task_setrlimit,
task_setscheduler: dummy_task_setscheduler,
task_getscheduler: dummy_task_getscheduler,
task_wait: dummy_task_wait,
task_kill: dummy_task_kill,
task_prctl: dummy_task_prctl,
task_kmod_set_label: dummy_task_kmod_set_label,
task_reparent_to_init: dummy_task_reparent_to_init,
register_security: dummy_register,
unregister_security: dummy_unregister,
};
/*
* Security plug functions
*
* Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com>
* Copyright (C) 2001 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/security.h>
#define SECURITY_SCAFFOLD_VERSION "1.0.0"
extern struct security_operations dummy_security_ops; /* lives in dummy.c */
struct security_operations *security_ops; /* Initialized to NULL */
/* This macro checks that all pointers in a struct are non-NULL. It
* can be fooled by struct padding for object tile alignment and when
* pointers to data and pointers to functions aren't the same size.
* Yes it's ugly, we'll replace it if it becomes a problem.
*/
#define VERIFY_STRUCT(struct_type, s, e) \
do { \
unsigned long * __start = (unsigned long *)(s); \
unsigned long * __end = __start + \
sizeof(struct_type)/sizeof(unsigned long *); \
while (__start != __end) { \
if (!*__start) { \
printk(KERN_INFO "%s is missing something\n",\
#struct_type); \
e++; \
break; \
} \
__start++; \
} \
} while (0)
static int inline verify (struct security_operations *ops)
{
int err;
/* verify the security_operations structure exists */
if (!ops) {
printk (KERN_INFO "Passed a NULL security_operations "
"pointer, " __FUNCTION__ " failed.\n");
return -EINVAL;
}
/* Perform a little sanity checking on our inputs */
err = 0;
/* This first check scans the whole security_ops struct for
* missing structs or functions.
*
* (There is no further check now, but will leave as is until
* the lazy registration stuff is done -- JM).
*/
VERIFY_STRUCT(struct security_operations, ops, err);
if (err) {
printk (KERN_INFO "Not enough functions specified in the "
"security_operation structure, " __FUNCTION__
" failed.\n");
return -EINVAL;
}
return 0;
}
/**
* security_scaffolding_startup - initialzes the security scaffolding framework
*
* This should be called early in the kernel initialization sequence.
*/
int security_scaffolding_startup (void)
{
printk (KERN_INFO "Security Scaffold v" SECURITY_SCAFFOLD_VERSION
" initialized\n");
security_ops = &dummy_security_ops;
return 0;
}
/**
* register_security - registers a security framework with the kernel
* @ops: a pointer to the struct security_options that is to be registered
*
* This function is to allow a security module to register itself with the
* kernel security subsystem. Some rudimentary checking is done on the @ops
* value passed to this function. A call to unregister_security() should be
* done to remove this security_options structure from the kernel.
*
* If the @ops structure does not contain function pointers for all hooks in
* the structure, or there is already a security module registered with the
* kernel, an error will be returned. Otherwise 0 is returned on success.
*/
int register_security (struct security_operations *ops)
{
if (verify (ops)) {
printk (KERN_INFO __FUNCTION__ " could not verify "
"security_operations structure.\n");
return -EINVAL;
}
if (security_ops != &dummy_security_ops) {
printk (KERN_INFO "There is already a security "
"framework initialized, " __FUNCTION__ " failed.\n");
return -EINVAL;
}
security_ops = ops;
return 0;
}
/**
* unregister_security - unregisters a security framework with the kernel
* @ops: a pointer to the struct security_options that is to be registered
*
* This function removes a struct security_operations variable that had
* previously been registered with a successful call to register_security().
*
* If @ops does not match the valued previously passed to register_security()
* an error is returned. Otherwise the default security options is set to the
* the dummy_security_ops structure, and 0 is returned.
*/
int unregister_security (struct security_operations *ops)
{
if (ops != security_ops) {
printk (KERN_INFO __FUNCTION__ ": trying to unregister "
"a security_opts structure that is not "
"registered, failing.\n");
return -EINVAL;
}
security_ops = &dummy_security_ops;
return 0;
}
/**
* mod_reg_security - allows security modules to be "stacked"
* @name: a pointer to a string with the name of the security_options to be registered
* @ops: a pointer to the struct security_options that is to be registered
*
* This function allows security modules to be stacked if the currently loaded
* security module allows this to happen. It passes the @name and @ops to the
* register_security function of the currently loaded security module.
*
* The return value depends on the currently loaded security module, with 0 as
* success.
*/
int mod_reg_security (const char *name, struct security_operations *ops)
{
if (verify (ops)) {
printk (KERN_INFO __FUNCTION__ " could not verify "
"security operations.\n");
return -EINVAL;
}
if (ops == security_ops) {
printk (KERN_INFO __FUNCTION__ " security operations "
"already registered.\n");
return -EINVAL;
}
return security_ops->register_security (name, ops);
}
/**
* mod_unreg_security - allows a security module registered with mod_reg_security() to be unloaded
* @name: a pointer to a string with the name of the security_options to be removed
* @ops: a pointer to the struct security_options that is to be removed
*
* This function allows security modules that have been successfully registered
* with a call to mod_reg_security() to be unloaded from the system.
* This calls the currently loaded security module's unregister_security() call
* with the @name and @ops variables.
*
* The return value depends on the currently loaded security module, with 0 as
* success.
*/
int mod_unreg_security (const char *name, struct security_operations *ops)
{
if (ops == security_ops) {
printk (KERN_INFO __FUNCTION__ " invalid attempt to unregister "
" primary security ops.\n");
return -EINVAL;
}
return security_ops->unregister_security (name, ops);
}
/**
* capable - calls the currently loaded security module's capable() function with the specified capability
* @cap: the requested capability level.
*
* This function calls the currently loaded security module's cabable()
* function with a pointer to the current task and the specified @cap value.
*
* This allows the security module to implement the capable function call
* however it chooses to.
*/
int capable (int cap)
{
if (security_ops->capable (current, cap)) {
/* capability denied */
return 0;
}
/* capability granted */
current->flags |= PF_SUPERPRIV;
return 1;
}
/**
* sys_security - security syscall multiplexor.
* @id: module id
* @call: call identifier
* @args: arg list for call
*
* Similar to sys_socketcall. Can use id to help identify which module user
* app is talking to. The recommended convention for creating the
* hexadecimal id value is:
* 'echo "Name_of_module" | md5sum | cut -c -8'.
* By following this convention, there's no need for a central registry.
*/
asmlinkage long sys_security (unsigned int id, unsigned int call,
unsigned long *args)
{
return security_ops->sys_security (id, call, args);
}
EXPORT_SYMBOL (register_security);
EXPORT_SYMBOL (unregister_security);
EXPORT_SYMBOL (mod_reg_security);
EXPORT_SYMBOL (mod_unreg_security);
EXPORT_SYMBOL (capable);
EXPORT_SYMBOL (security_ops);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment