mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-02-01 07:42:18 +00:00
Auto exploit mitigation feature
* 0day explit mitigation * Memory corruption prevention * Privilege escalation prevention * Buffer over flow prevention * File System corruption defense * Thread escape prevention This may very well be the most intensive inclusion to BrooklynR. This will not be part of an x86 suite nor it will be released as tool kit. The security core toolkit will remain part of kernel base.
This commit is contained in:
parent
1e6726821d
commit
2a709f28fa
1206
grsecurity/Kconfig
Normal file
1206
grsecurity/Kconfig
Normal file
File diff suppressed because it is too large
Load Diff
54
grsecurity/Makefile
Normal file
54
grsecurity/Makefile
Normal file
@ -0,0 +1,54 @@
|
||||
# grsecurity - access control and security hardening for Linux
|
||||
# All code in this directory and various hooks located throughout the Linux kernel are
|
||||
# Copyright (C) 2001-2014 Bradley Spengler, Open Source Security, Inc.
|
||||
# http://www.grsecurity.net spender@grsecurity.net
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 2
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
KBUILD_CFLAGS += -Werror
|
||||
|
||||
obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
|
||||
grsec_mount.o grsec_sig.o grsec_sysctl.o \
|
||||
grsec_time.o grsec_tpe.o grsec_link.o grsec_pax.o grsec_ptrace.o \
|
||||
grsec_usb.o grsec_ipc.o grsec_proc.o grsec_tty.o
|
||||
|
||||
obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_segv.o \
|
||||
gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
|
||||
gracl_learn.o grsec_log.o gracl_policy.o
|
||||
ifdef CONFIG_COMPAT
|
||||
obj-$(CONFIG_GRKERNSEC) += gracl_compat.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
|
||||
|
||||
ifdef CONFIG_NET
|
||||
obj-y += grsec_sock.o
|
||||
obj-$(CONFIG_GRKERNSEC) += gracl_ip.o
|
||||
endif
|
||||
|
||||
ifndef CONFIG_GRKERNSEC
|
||||
obj-y += grsec_disabled.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_GRKERNSEC_HIDESYM
|
||||
extra-y := grsec_hidesym.o
|
||||
$(obj)/grsec_hidesym.o:
|
||||
@-chmod -f 500 /boot
|
||||
@-chmod -f 500 /lib/modules
|
||||
@-chmod -f 500 /lib64/modules
|
||||
@-chmod -f 500 /lib32/modules
|
||||
@-chmod -f 700 .
|
||||
@-chmod -f 700 $(objtree)
|
||||
@echo ' grsec: protected kernel image paths'
|
||||
endif
|
2773
grsecurity/gracl.c
Normal file
2773
grsecurity/gracl.c
Normal file
File diff suppressed because it is too large
Load Diff
105
grsecurity/gracl_alloc.c
Normal file
105
grsecurity/gracl_alloc.c
Normal file
@ -0,0 +1,105 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/gracl.h>
|
||||
#include <linux/grsecurity.h>
|
||||
|
||||
static struct gr_alloc_state __current_alloc_state = { 1, 1, NULL };
|
||||
struct gr_alloc_state *current_alloc_state = &__current_alloc_state;
|
||||
|
||||
static int
|
||||
alloc_pop(void)
|
||||
{
|
||||
if (current_alloc_state->alloc_stack_next == 1)
|
||||
return 0;
|
||||
|
||||
kfree(current_alloc_state->alloc_stack[current_alloc_state->alloc_stack_next - 2]);
|
||||
|
||||
current_alloc_state->alloc_stack_next--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
alloc_push(void *buf)
|
||||
{
|
||||
if (current_alloc_state->alloc_stack_next >= current_alloc_state->alloc_stack_size)
|
||||
return 1;
|
||||
|
||||
current_alloc_state->alloc_stack[current_alloc_state->alloc_stack_next - 1] = buf;
|
||||
|
||||
current_alloc_state->alloc_stack_next++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
acl_alloc(unsigned long len)
|
||||
{
|
||||
void *ret = NULL;
|
||||
|
||||
if (!len || len > PAGE_SIZE)
|
||||
goto out;
|
||||
|
||||
ret = kmalloc(len, GFP_KERNEL);
|
||||
|
||||
if (ret) {
|
||||
if (alloc_push(ret)) {
|
||||
kfree(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
acl_alloc_num(unsigned long num, unsigned long len)
|
||||
{
|
||||
if (!len || (num > (PAGE_SIZE / len)))
|
||||
return NULL;
|
||||
|
||||
return acl_alloc(num * len);
|
||||
}
|
||||
|
||||
void
|
||||
acl_free_all(void)
|
||||
{
|
||||
if (!current_alloc_state->alloc_stack)
|
||||
return;
|
||||
|
||||
while (alloc_pop()) ;
|
||||
|
||||
if (current_alloc_state->alloc_stack) {
|
||||
if ((current_alloc_state->alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
|
||||
kfree(current_alloc_state->alloc_stack);
|
||||
else
|
||||
vfree(current_alloc_state->alloc_stack);
|
||||
}
|
||||
|
||||
current_alloc_state->alloc_stack = NULL;
|
||||
current_alloc_state->alloc_stack_size = 1;
|
||||
current_alloc_state->alloc_stack_next = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
acl_alloc_stack_init(unsigned long size)
|
||||
{
|
||||
if ((size * sizeof (void *)) <= PAGE_SIZE)
|
||||
current_alloc_state->alloc_stack =
|
||||
(void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
|
||||
else
|
||||
current_alloc_state->alloc_stack = (void **) vmalloc(size * sizeof (void *));
|
||||
|
||||
current_alloc_state->alloc_stack_size = size;
|
||||
current_alloc_state->alloc_stack_next = 1;
|
||||
|
||||
if (!current_alloc_state->alloc_stack)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
96
grsecurity/gracl_cap.c
Normal file
96
grsecurity/gracl_cap.c
Normal file
@ -0,0 +1,96 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/gracl.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
extern const char *captab_log[];
|
||||
extern int captab_log_entries;
|
||||
|
||||
int gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap, bool log)
|
||||
{
|
||||
struct acl_subject_label *curracl;
|
||||
|
||||
if (!gr_acl_is_enabled())
|
||||
return 1;
|
||||
|
||||
curracl = task->acl;
|
||||
|
||||
if (curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
|
||||
if (log)
|
||||
security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
|
||||
task->role->roletype, GR_GLOBAL_UID(cred->uid),
|
||||
GR_GLOBAL_GID(cred->gid), task->exec_file ?
|
||||
gr_to_filename(task->exec_file->f_path.dentry,
|
||||
task->exec_file->f_path.mnt) : curracl->filename,
|
||||
curracl->filename, 0UL,
|
||||
0UL, "", (unsigned long) cap, &task->signal->saved_ip);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gr_task_acl_is_capable(const struct task_struct *task, const struct cred *cred, const int cap, bool log)
|
||||
{
|
||||
struct acl_subject_label *curracl;
|
||||
kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
|
||||
kernel_cap_t cap_audit = __cap_empty_set;
|
||||
|
||||
if (!gr_acl_is_enabled())
|
||||
return 1;
|
||||
|
||||
curracl = task->acl;
|
||||
|
||||
cap_drop = curracl->cap_lower;
|
||||
cap_mask = curracl->cap_mask;
|
||||
cap_audit = curracl->cap_invert_audit;
|
||||
|
||||
while ((curracl = curracl->parent_subject)) {
|
||||
/* if the cap isn't specified in the current computed mask but is specified in the
|
||||
current level subject, and is lowered in the current level subject, then add
|
||||
it to the set of dropped capabilities
|
||||
otherwise, add the current level subject's mask to the current computed mask
|
||||
*/
|
||||
if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
|
||||
cap_raise(cap_mask, cap);
|
||||
if (cap_raised(curracl->cap_lower, cap))
|
||||
cap_raise(cap_drop, cap);
|
||||
if (cap_raised(curracl->cap_invert_audit, cap))
|
||||
cap_raise(cap_audit, cap);
|
||||
}
|
||||
}
|
||||
|
||||
if (!cap_raised(cap_drop, cap)) {
|
||||
if (log && cap_raised(cap_audit, cap))
|
||||
gr_log_cap(GR_DO_AUDIT, GR_CAP_ACL_MSG2, task, captab_log[cap]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* only learn the capability use if the process has the capability in the
|
||||
general case, the two uses in sys.c of gr_learn_cap are an exception
|
||||
to this rule to ensure any role transition involves what the full-learned
|
||||
policy believes in a privileged process
|
||||
*/
|
||||
if (cap_raised(cred->cap_effective, cap) && gr_learn_cap(task, cred, cap, log))
|
||||
return 1;
|
||||
|
||||
if (log && (cap >= 0) && (cap < captab_log_entries) && cap_raised(cred->cap_effective, cap) && !cap_raised(cap_audit, cap))
|
||||
gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_acl_is_capable(const int cap)
|
||||
{
|
||||
return gr_task_acl_is_capable(current, current_cred(), cap, true);
|
||||
}
|
||||
|
||||
int
|
||||
gr_acl_is_capable_nolog(const int cap)
|
||||
{
|
||||
return gr_task_acl_is_capable(current, current_cred(), cap, false);
|
||||
}
|
||||
|
269
grsecurity/gracl_compat.c
Normal file
269
grsecurity/gracl_compat.c
Normal file
@ -0,0 +1,269 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/gracl.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/gracl_compat.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
int copy_gr_arg_wrapper_compat(const char *buf, struct gr_arg_wrapper *uwrap)
|
||||
{
|
||||
struct gr_arg_wrapper_compat uwrapcompat;
|
||||
|
||||
if (copy_from_user(&uwrapcompat, buf, sizeof(uwrapcompat)))
|
||||
return -EFAULT;
|
||||
|
||||
if ((uwrapcompat.version != GRSECURITY_VERSION) ||
|
||||
(uwrapcompat.size != sizeof(struct gr_arg_compat)))
|
||||
return -EINVAL;
|
||||
|
||||
uwrap->arg = compat_ptr(uwrapcompat.arg);
|
||||
uwrap->version = uwrapcompat.version;
|
||||
uwrap->size = sizeof(struct gr_arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_gr_arg_compat(const struct gr_arg __user *buf, struct gr_arg *arg)
|
||||
{
|
||||
struct gr_arg_compat argcompat;
|
||||
|
||||
if (copy_from_user(&argcompat, buf, sizeof(argcompat)))
|
||||
return -EFAULT;
|
||||
|
||||
arg->role_db.r_table = compat_ptr(argcompat.role_db.r_table);
|
||||
arg->role_db.num_pointers = argcompat.role_db.num_pointers;
|
||||
arg->role_db.num_roles = argcompat.role_db.num_roles;
|
||||
arg->role_db.num_domain_children = argcompat.role_db.num_domain_children;
|
||||
arg->role_db.num_subjects = argcompat.role_db.num_subjects;
|
||||
arg->role_db.num_objects = argcompat.role_db.num_objects;
|
||||
|
||||
memcpy(&arg->pw, &argcompat.pw, sizeof(arg->pw));
|
||||
memcpy(&arg->salt, &argcompat.salt, sizeof(arg->salt));
|
||||
memcpy(&arg->sum, &argcompat.sum, sizeof(arg->sum));
|
||||
memcpy(&arg->sp_role, &argcompat.sp_role, sizeof(arg->sp_role));
|
||||
arg->sprole_pws = compat_ptr(argcompat.sprole_pws);
|
||||
arg->segv_device = argcompat.segv_device;
|
||||
arg->segv_inode = argcompat.segv_inode;
|
||||
arg->segv_uid = argcompat.segv_uid;
|
||||
arg->num_sprole_pws = argcompat.num_sprole_pws;
|
||||
arg->mode = argcompat.mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_acl_object_label_compat(struct acl_object_label *obj, const struct acl_object_label *userp)
|
||||
{
|
||||
struct acl_object_label_compat objcompat;
|
||||
|
||||
if (copy_from_user(&objcompat, userp, sizeof(objcompat)))
|
||||
return -EFAULT;
|
||||
|
||||
obj->filename = compat_ptr(objcompat.filename);
|
||||
obj->inode = objcompat.inode;
|
||||
obj->device = objcompat.device;
|
||||
obj->mode = objcompat.mode;
|
||||
|
||||
obj->nested = compat_ptr(objcompat.nested);
|
||||
obj->globbed = compat_ptr(objcompat.globbed);
|
||||
|
||||
obj->prev = compat_ptr(objcompat.prev);
|
||||
obj->next = compat_ptr(objcompat.next);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_acl_subject_label_compat(struct acl_subject_label *subj, const struct acl_subject_label *userp)
|
||||
{
|
||||
unsigned int i;
|
||||
struct acl_subject_label_compat subjcompat;
|
||||
|
||||
if (copy_from_user(&subjcompat, userp, sizeof(subjcompat)))
|
||||
return -EFAULT;
|
||||
|
||||
subj->filename = compat_ptr(subjcompat.filename);
|
||||
subj->inode = subjcompat.inode;
|
||||
subj->device = subjcompat.device;
|
||||
subj->mode = subjcompat.mode;
|
||||
subj->cap_mask = subjcompat.cap_mask;
|
||||
subj->cap_lower = subjcompat.cap_lower;
|
||||
subj->cap_invert_audit = subjcompat.cap_invert_audit;
|
||||
|
||||
for (i = 0; i < GR_NLIMITS; i++) {
|
||||
if (subjcompat.res[i].rlim_cur == COMPAT_RLIM_INFINITY)
|
||||
subj->res[i].rlim_cur = RLIM_INFINITY;
|
||||
else
|
||||
subj->res[i].rlim_cur = subjcompat.res[i].rlim_cur;
|
||||
if (subjcompat.res[i].rlim_max == COMPAT_RLIM_INFINITY)
|
||||
subj->res[i].rlim_max = RLIM_INFINITY;
|
||||
else
|
||||
subj->res[i].rlim_max = subjcompat.res[i].rlim_max;
|
||||
}
|
||||
subj->resmask = subjcompat.resmask;
|
||||
|
||||
subj->user_trans_type = subjcompat.user_trans_type;
|
||||
subj->group_trans_type = subjcompat.group_trans_type;
|
||||
subj->user_transitions = compat_ptr(subjcompat.user_transitions);
|
||||
subj->group_transitions = compat_ptr(subjcompat.group_transitions);
|
||||
subj->user_trans_num = subjcompat.user_trans_num;
|
||||
subj->group_trans_num = subjcompat.group_trans_num;
|
||||
|
||||
memcpy(&subj->sock_families, &subjcompat.sock_families, sizeof(subj->sock_families));
|
||||
memcpy(&subj->ip_proto, &subjcompat.ip_proto, sizeof(subj->ip_proto));
|
||||
subj->ip_type = subjcompat.ip_type;
|
||||
subj->ips = compat_ptr(subjcompat.ips);
|
||||
subj->ip_num = subjcompat.ip_num;
|
||||
subj->inaddr_any_override = subjcompat.inaddr_any_override;
|
||||
|
||||
subj->crashes = subjcompat.crashes;
|
||||
subj->expires = subjcompat.expires;
|
||||
|
||||
subj->parent_subject = compat_ptr(subjcompat.parent_subject);
|
||||
subj->hash = compat_ptr(subjcompat.hash);
|
||||
subj->prev = compat_ptr(subjcompat.prev);
|
||||
subj->next = compat_ptr(subjcompat.next);
|
||||
|
||||
subj->obj_hash = compat_ptr(subjcompat.obj_hash);
|
||||
subj->obj_hash_size = subjcompat.obj_hash_size;
|
||||
subj->pax_flags = subjcompat.pax_flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_acl_role_label_compat(struct acl_role_label *role, const struct acl_role_label *userp)
|
||||
{
|
||||
struct acl_role_label_compat rolecompat;
|
||||
|
||||
if (copy_from_user(&rolecompat, userp, sizeof(rolecompat)))
|
||||
return -EFAULT;
|
||||
|
||||
role->rolename = compat_ptr(rolecompat.rolename);
|
||||
role->uidgid = rolecompat.uidgid;
|
||||
role->roletype = rolecompat.roletype;
|
||||
|
||||
role->auth_attempts = rolecompat.auth_attempts;
|
||||
role->expires = rolecompat.expires;
|
||||
|
||||
role->root_label = compat_ptr(rolecompat.root_label);
|
||||
role->hash = compat_ptr(rolecompat.hash);
|
||||
|
||||
role->prev = compat_ptr(rolecompat.prev);
|
||||
role->next = compat_ptr(rolecompat.next);
|
||||
|
||||
role->transitions = compat_ptr(rolecompat.transitions);
|
||||
role->allowed_ips = compat_ptr(rolecompat.allowed_ips);
|
||||
role->domain_children = compat_ptr(rolecompat.domain_children);
|
||||
role->domain_child_num = rolecompat.domain_child_num;
|
||||
|
||||
role->umask = rolecompat.umask;
|
||||
|
||||
role->subj_hash = compat_ptr(rolecompat.subj_hash);
|
||||
role->subj_hash_size = rolecompat.subj_hash_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_role_allowed_ip_compat(struct role_allowed_ip *roleip, const struct role_allowed_ip *userp)
|
||||
{
|
||||
struct role_allowed_ip_compat roleip_compat;
|
||||
|
||||
if (copy_from_user(&roleip_compat, userp, sizeof(roleip_compat)))
|
||||
return -EFAULT;
|
||||
|
||||
roleip->addr = roleip_compat.addr;
|
||||
roleip->netmask = roleip_compat.netmask;
|
||||
|
||||
roleip->prev = compat_ptr(roleip_compat.prev);
|
||||
roleip->next = compat_ptr(roleip_compat.next);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_role_transition_compat(struct role_transition *trans, const struct role_transition *userp)
|
||||
{
|
||||
struct role_transition_compat trans_compat;
|
||||
|
||||
if (copy_from_user(&trans_compat, userp, sizeof(trans_compat)))
|
||||
return -EFAULT;
|
||||
|
||||
trans->rolename = compat_ptr(trans_compat.rolename);
|
||||
|
||||
trans->prev = compat_ptr(trans_compat.prev);
|
||||
trans->next = compat_ptr(trans_compat.next);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int copy_gr_hash_struct_compat(struct gr_hash_struct *hash, const struct gr_hash_struct *userp)
|
||||
{
|
||||
struct gr_hash_struct_compat hash_compat;
|
||||
|
||||
if (copy_from_user(&hash_compat, userp, sizeof(hash_compat)))
|
||||
return -EFAULT;
|
||||
|
||||
hash->table = compat_ptr(hash_compat.table);
|
||||
hash->nametable = compat_ptr(hash_compat.nametable);
|
||||
hash->first = compat_ptr(hash_compat.first);
|
||||
|
||||
hash->table_size = hash_compat.table_size;
|
||||
hash->used_size = hash_compat.used_size;
|
||||
|
||||
hash->type = hash_compat.type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_pointer_from_array_compat(void *ptr, unsigned long idx, const void *userp)
|
||||
{
|
||||
compat_uptr_t ptrcompat;
|
||||
|
||||
if (copy_from_user(&ptrcompat, userp + (idx * sizeof(ptrcompat)), sizeof(ptrcompat)))
|
||||
return -EFAULT;
|
||||
|
||||
*(void **)ptr = compat_ptr(ptrcompat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_acl_ip_label_compat(struct acl_ip_label *ip, const struct acl_ip_label *userp)
|
||||
{
|
||||
struct acl_ip_label_compat ip_compat;
|
||||
|
||||
if (copy_from_user(&ip_compat, userp, sizeof(ip_compat)))
|
||||
return -EFAULT;
|
||||
|
||||
ip->iface = compat_ptr(ip_compat.iface);
|
||||
ip->addr = ip_compat.addr;
|
||||
ip->netmask = ip_compat.netmask;
|
||||
ip->low = ip_compat.low;
|
||||
ip->high = ip_compat.high;
|
||||
ip->mode = ip_compat.mode;
|
||||
ip->type = ip_compat.type;
|
||||
|
||||
memcpy(&ip->proto, &ip_compat.proto, sizeof(ip->proto));
|
||||
|
||||
ip->prev = compat_ptr(ip_compat.prev);
|
||||
ip->next = compat_ptr(ip_compat.next);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_sprole_pw_compat(struct sprole_pw *pw, unsigned long idx, const struct sprole_pw *userp)
|
||||
{
|
||||
struct sprole_pw_compat pw_compat;
|
||||
|
||||
if (copy_from_user(&pw_compat, (const void *)userp + (sizeof(pw_compat) * idx), sizeof(pw_compat)))
|
||||
return -EFAULT;
|
||||
|
||||
pw->rolename = compat_ptr(pw_compat.rolename);
|
||||
memcpy(&pw->salt, pw_compat.salt, sizeof(pw->salt));
|
||||
memcpy(&pw->sum, pw_compat.sum, sizeof(pw->sum));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t get_gr_arg_wrapper_size_compat(void)
|
||||
{
|
||||
return sizeof(struct gr_arg_wrapper_compat);
|
||||
}
|
||||
|
448
grsecurity/gracl_fs.c
Normal file
448
grsecurity/gracl_fs.c
Normal file
@ -0,0 +1,448 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/gracl.h>
|
||||
|
||||
umode_t
|
||||
gr_acl_umask(void)
|
||||
{
|
||||
if (unlikely(!gr_acl_is_enabled()))
|
||||
return 0;
|
||||
|
||||
return current->role->umask;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_hidden_file(const struct dentry * dentry,
|
||||
const struct vfsmount * mnt)
|
||||
{
|
||||
__u32 mode;
|
||||
|
||||
if (unlikely(d_is_negative(dentry)))
|
||||
return GR_FIND;
|
||||
|
||||
mode =
|
||||
gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
|
||||
|
||||
if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
|
||||
gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
|
||||
return mode;
|
||||
} else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
|
||||
gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
|
||||
return 0;
|
||||
} else if (unlikely(!(mode & GR_FIND)))
|
||||
return 0;
|
||||
|
||||
return GR_FIND;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
|
||||
int acc_mode)
|
||||
{
|
||||
__u32 reqmode = GR_FIND;
|
||||
__u32 mode;
|
||||
|
||||
if (unlikely(d_is_negative(dentry)))
|
||||
return reqmode;
|
||||
|
||||
if (acc_mode & MAY_APPEND)
|
||||
reqmode |= GR_APPEND;
|
||||
else if (acc_mode & MAY_WRITE)
|
||||
reqmode |= GR_WRITE;
|
||||
if ((acc_mode & MAY_READ) && !d_is_dir(dentry))
|
||||
reqmode |= GR_READ;
|
||||
|
||||
mode =
|
||||
gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
|
||||
mnt);
|
||||
|
||||
if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
|
||||
gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
|
||||
reqmode & GR_READ ? " reading" : "",
|
||||
reqmode & GR_WRITE ? " writing" : reqmode &
|
||||
GR_APPEND ? " appending" : "");
|
||||
return reqmode;
|
||||
} else
|
||||
if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
|
||||
{
|
||||
gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
|
||||
reqmode & GR_READ ? " reading" : "",
|
||||
reqmode & GR_WRITE ? " writing" : reqmode &
|
||||
GR_APPEND ? " appending" : "");
|
||||
return 0;
|
||||
} else if (unlikely((mode & reqmode) != reqmode))
|
||||
return 0;
|
||||
|
||||
return reqmode;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_creat(const struct dentry * dentry,
|
||||
const struct dentry * p_dentry,
|
||||
const struct vfsmount * p_mnt, int open_flags, int acc_mode,
|
||||
const int imode)
|
||||
{
|
||||
__u32 reqmode = GR_WRITE | GR_CREATE;
|
||||
__u32 mode;
|
||||
|
||||
if (acc_mode & MAY_APPEND)
|
||||
reqmode |= GR_APPEND;
|
||||
// if a directory was required or the directory already exists, then
|
||||
// don't count this open as a read
|
||||
if ((acc_mode & MAY_READ) &&
|
||||
!((open_flags & O_DIRECTORY) || d_is_dir(dentry)))
|
||||
reqmode |= GR_READ;
|
||||
if ((open_flags & O_CREAT) &&
|
||||
((imode & S_ISUID) || ((imode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))))
|
||||
reqmode |= GR_SETID;
|
||||
|
||||
mode =
|
||||
gr_check_create(dentry, p_dentry, p_mnt,
|
||||
reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
|
||||
|
||||
if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
|
||||
gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
|
||||
reqmode & GR_READ ? " reading" : "",
|
||||
reqmode & GR_WRITE ? " writing" : reqmode &
|
||||
GR_APPEND ? " appending" : "");
|
||||
return reqmode;
|
||||
} else
|
||||
if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
|
||||
{
|
||||
gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
|
||||
reqmode & GR_READ ? " reading" : "",
|
||||
reqmode & GR_WRITE ? " writing" : reqmode &
|
||||
GR_APPEND ? " appending" : "");
|
||||
return 0;
|
||||
} else if (unlikely((mode & reqmode) != reqmode))
|
||||
return 0;
|
||||
|
||||
return reqmode;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
|
||||
const int fmode)
|
||||
{
|
||||
__u32 mode, reqmode = GR_FIND;
|
||||
|
||||
if ((fmode & S_IXOTH) && !d_is_dir(dentry))
|
||||
reqmode |= GR_EXEC;
|
||||
if (fmode & S_IWOTH)
|
||||
reqmode |= GR_WRITE;
|
||||
if (fmode & S_IROTH)
|
||||
reqmode |= GR_READ;
|
||||
|
||||
mode =
|
||||
gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
|
||||
mnt);
|
||||
|
||||
if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
|
||||
gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
|
||||
reqmode & GR_READ ? " reading" : "",
|
||||
reqmode & GR_WRITE ? " writing" : "",
|
||||
reqmode & GR_EXEC ? " executing" : "");
|
||||
return reqmode;
|
||||
} else
|
||||
if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
|
||||
{
|
||||
gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
|
||||
reqmode & GR_READ ? " reading" : "",
|
||||
reqmode & GR_WRITE ? " writing" : "",
|
||||
reqmode & GR_EXEC ? " executing" : "");
|
||||
return 0;
|
||||
} else if (unlikely((mode & reqmode) != reqmode))
|
||||
return 0;
|
||||
|
||||
return reqmode;
|
||||
}
|
||||
|
||||
static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
|
||||
{
|
||||
__u32 mode;
|
||||
|
||||
mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
|
||||
|
||||
if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
|
||||
gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
|
||||
return mode;
|
||||
} else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
|
||||
gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
|
||||
return 0;
|
||||
} else if (unlikely((mode & (reqmode)) != (reqmode)))
|
||||
return 0;
|
||||
|
||||
return (reqmode);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
|
||||
{
|
||||
return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
|
||||
umode_t *modeptr)
|
||||
{
|
||||
umode_t mode;
|
||||
struct inode *inode = d_backing_inode(dentry);
|
||||
|
||||
*modeptr &= ~gr_acl_umask();
|
||||
mode = *modeptr;
|
||||
|
||||
if (unlikely(inode && S_ISSOCK(inode->i_mode)))
|
||||
return 1;
|
||||
|
||||
if (unlikely(!d_is_dir(dentry) &&
|
||||
((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))))) {
|
||||
return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
|
||||
GR_CHMOD_ACL_MSG);
|
||||
} else {
|
||||
return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
|
||||
}
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_setxattr(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
return generic_fs_handler(dentry, mnt, GR_WRITE, GR_SETXATTR_ACL_MSG);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_removexattr(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
return generic_fs_handler(dentry, mnt, GR_WRITE, GR_REMOVEXATTR_ACL_MSG);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
|
||||
GR_UNIXCONNECT_ACL_MSG);
|
||||
}
|
||||
|
||||
/* hardlinks require at minimum create and link permission,
|
||||
any additional privilege required is based on the
|
||||
privilege of the file being linked to
|
||||
*/
|
||||
__u32
|
||||
gr_acl_handle_link(const struct dentry * new_dentry,
|
||||
const struct dentry * parent_dentry,
|
||||
const struct vfsmount * parent_mnt,
|
||||
const struct dentry * old_dentry,
|
||||
const struct vfsmount * old_mnt, const struct filename *to)
|
||||
{
|
||||
__u32 mode;
|
||||
__u32 needmode = GR_CREATE | GR_LINK;
|
||||
__u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
|
||||
|
||||
mode =
|
||||
gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
|
||||
old_mnt);
|
||||
|
||||
if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
|
||||
gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to->name);
|
||||
return mode;
|
||||
} else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
|
||||
gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to->name);
|
||||
return 0;
|
||||
} else if (unlikely((mode & needmode) != needmode))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_symlink(const struct dentry * new_dentry,
|
||||
const struct dentry * parent_dentry,
|
||||
const struct vfsmount * parent_mnt, const struct filename *from)
|
||||
{
|
||||
__u32 needmode = GR_WRITE | GR_CREATE;
|
||||
__u32 mode;
|
||||
|
||||
mode =
|
||||
gr_check_create(new_dentry, parent_dentry, parent_mnt,
|
||||
GR_CREATE | GR_AUDIT_CREATE |
|
||||
GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
|
||||
|
||||
if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
|
||||
gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from->name, new_dentry, parent_mnt);
|
||||
return mode;
|
||||
} else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
|
||||
gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from->name, new_dentry, parent_mnt);
|
||||
return 0;
|
||||
} else if (unlikely((mode & needmode) != needmode))
|
||||
return 0;
|
||||
|
||||
return (GR_WRITE | GR_CREATE);
|
||||
}
|
||||
|
||||
static __u32 generic_fs_create_handler(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, __u32 reqmode, const char *fmt)
|
||||
{
|
||||
__u32 mode;
|
||||
|
||||
mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
|
||||
|
||||
if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
|
||||
gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
|
||||
return mode;
|
||||
} else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
|
||||
gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
|
||||
return 0;
|
||||
} else if (unlikely((mode & (reqmode)) != (reqmode)))
|
||||
return 0;
|
||||
|
||||
return (reqmode);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_mknod(const struct dentry * new_dentry,
|
||||
const struct dentry * parent_dentry,
|
||||
const struct vfsmount * parent_mnt,
|
||||
const int mode)
|
||||
{
|
||||
__u32 reqmode = GR_WRITE | GR_CREATE;
|
||||
if (unlikely((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))))
|
||||
reqmode |= GR_SETID;
|
||||
|
||||
return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
|
||||
reqmode, GR_MKNOD_ACL_MSG);
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_mkdir(const struct dentry *new_dentry,
|
||||
const struct dentry *parent_dentry,
|
||||
const struct vfsmount *parent_mnt)
|
||||
{
|
||||
return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
|
||||
GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
|
||||
}
|
||||
|
||||
#define RENAME_CHECK_SUCCESS(old, new) \
|
||||
(((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
|
||||
((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
|
||||
|
||||
int
|
||||
gr_acl_handle_rename(struct dentry *new_dentry,
|
||||
struct dentry *parent_dentry,
|
||||
const struct vfsmount *parent_mnt,
|
||||
struct dentry *old_dentry,
|
||||
struct inode *old_parent_inode,
|
||||
struct vfsmount *old_mnt, const struct filename *newname, unsigned int flags)
|
||||
{
|
||||
__u32 comp1, comp2;
|
||||
int error = 0;
|
||||
|
||||
if (unlikely(!gr_acl_is_enabled()))
|
||||
return 0;
|
||||
|
||||
if (flags & RENAME_EXCHANGE) {
|
||||
comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
|
||||
GR_AUDIT_READ | GR_AUDIT_WRITE |
|
||||
GR_SUPPRESS, parent_mnt);
|
||||
comp2 =
|
||||
gr_search_file(old_dentry,
|
||||
GR_READ | GR_WRITE | GR_AUDIT_READ |
|
||||
GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
|
||||
} else if (d_is_negative(new_dentry)) {
|
||||
comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
|
||||
GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
|
||||
GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
|
||||
comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
|
||||
GR_DELETE | GR_AUDIT_DELETE |
|
||||
GR_AUDIT_READ | GR_AUDIT_WRITE |
|
||||
GR_SUPPRESS, old_mnt);
|
||||
} else {
|
||||
comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
|
||||
GR_CREATE | GR_DELETE |
|
||||
GR_AUDIT_CREATE | GR_AUDIT_DELETE |
|
||||
GR_AUDIT_READ | GR_AUDIT_WRITE |
|
||||
GR_SUPPRESS, parent_mnt);
|
||||
comp2 =
|
||||
gr_search_file(old_dentry,
|
||||
GR_READ | GR_WRITE | GR_AUDIT_READ |
|
||||
GR_DELETE | GR_AUDIT_DELETE |
|
||||
GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
|
||||
}
|
||||
|
||||
if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
|
||||
((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
|
||||
gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname->name);
|
||||
else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
|
||||
&& !(comp2 & GR_SUPPRESS)) {
|
||||
gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname->name);
|
||||
error = -EACCES;
|
||||
} else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
|
||||
error = -EACCES;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
gr_acl_handle_exit(void)
|
||||
{
|
||||
u16 id;
|
||||
char *rolename;
|
||||
|
||||
if (unlikely(current->acl_sp_role && gr_acl_is_enabled() &&
|
||||
!(current->role->roletype & GR_ROLE_PERSIST))) {
|
||||
id = current->acl_role_id;
|
||||
rolename = current->role->rolename;
|
||||
gr_set_acls(1);
|
||||
gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
|
||||
}
|
||||
|
||||
gr_put_exec_file(current);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_acl_handle_procpidmem(const struct task_struct *task)
|
||||
{
|
||||
if (unlikely(!gr_acl_is_enabled()))
|
||||
return 0;
|
||||
|
||||
if (task != current && (task->acl->mode & GR_PROTPROCFD) &&
|
||||
!(current->acl->mode & GR_POVERRIDE) &&
|
||||
!(current->role->roletype & GR_ROLE_GOD))
|
||||
return -EACCES;
|
||||
|
||||
return 0;
|
||||
}
|
387
grsecurity/gracl_ip.c
Normal file
387
grsecurity/gracl_ip.c
Normal file
@ -0,0 +1,387 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/errno.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/inetdevice.h>
|
||||
#include <linux/gracl.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
#define GR_BIND 0x01
|
||||
#define GR_CONNECT 0x02
|
||||
#define GR_INVERT 0x04
|
||||
#define GR_BINDOVERRIDE 0x08
|
||||
#define GR_CONNECTOVERRIDE 0x10
|
||||
#define GR_SOCK_FAMILY 0x20
|
||||
|
||||
static const char * gr_protocols[IPPROTO_MAX] = {
|
||||
"ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
|
||||
"egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
|
||||
"chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
|
||||
"trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
|
||||
"merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
|
||||
"il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
|
||||
"mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
|
||||
"tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
|
||||
"sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
|
||||
"cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
|
||||
"iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
|
||||
"eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
|
||||
"scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
|
||||
"aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
|
||||
"vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
|
||||
"uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
|
||||
"sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
|
||||
"unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
|
||||
"unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
|
||||
"unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
|
||||
"unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
|
||||
"unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
|
||||
"unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
|
||||
"unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
|
||||
"unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
|
||||
"unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
|
||||
"unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
|
||||
"unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
|
||||
"unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
|
||||
"unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
|
||||
"unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
|
||||
"unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
|
||||
};
|
||||
|
||||
static const char * gr_socktypes[SOCK_MAX] = {
|
||||
"unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
|
||||
"unknown:7", "unknown:8", "unknown:9", "packet"
|
||||
};
|
||||
|
||||
static const char * gr_sockfamilies[AF_MAX] = {
|
||||
"unspec", "unix", "inet", "ax25", "ipx", "appletalk", "netrom", "bridge", "atmpvc", "x25",
|
||||
"inet6", "rose", "decnet", "netbeui", "security", "key", "netlink", "packet", "ash",
|
||||
"econet", "atmsvc", "rds", "sna", "irda", "ppox", "wanpipe", "llc", "ib", "mpls", "can",
|
||||
"tipc", "bluetooth", "iucv", "rxrpc", "isdn", "phonet", "ieee802154", "ciaf", "alg",
|
||||
"nfc", "vsock", "kcm", "qipcrtr"
|
||||
};
|
||||
|
||||
const char *
|
||||
gr_proto_to_name(unsigned char proto)
|
||||
{
|
||||
return gr_protocols[proto];
|
||||
}
|
||||
|
||||
const char *
|
||||
gr_socktype_to_name(unsigned char type)
|
||||
{
|
||||
return gr_socktypes[type];
|
||||
}
|
||||
|
||||
const char *
|
||||
gr_sockfamily_to_name(unsigned char family)
|
||||
{
|
||||
return gr_sockfamilies[family];
|
||||
}
|
||||
|
||||
extern const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
|
||||
|
||||
int
|
||||
gr_search_socket(const int domain, const int type, const int protocol)
|
||||
{
|
||||
struct acl_subject_label *curr;
|
||||
const struct cred *cred = current_cred();
|
||||
|
||||
if (unlikely(!gr_acl_is_enabled()))
|
||||
goto exit;
|
||||
|
||||
if ((domain < 0) || (type < 0) || (protocol < 0) ||
|
||||
(domain >= AF_MAX) || (type >= SOCK_MAX) || (protocol >= IPPROTO_MAX))
|
||||
goto exit; // let the kernel handle it
|
||||
|
||||
curr = current->acl;
|
||||
|
||||
if (curr->sock_families[domain / 32] & (1U << (domain % 32))) {
|
||||
/* the family is allowed, if this is PF_INET allow it only if
|
||||
the extra sock type/protocol checks pass */
|
||||
if (domain == PF_INET)
|
||||
goto inet_check;
|
||||
goto exit;
|
||||
} else {
|
||||
if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
|
||||
__u32 fakeip = 0;
|
||||
security_learn(GR_IP_LEARN_MSG, current->role->rolename,
|
||||
current->role->roletype, GR_GLOBAL_UID(cred->uid),
|
||||
GR_GLOBAL_GID(cred->gid), current->exec_file ?
|
||||
gr_to_filename(current->exec_file->f_path.dentry,
|
||||
current->exec_file->f_path.mnt) :
|
||||
curr->filename, curr->filename,
|
||||
&fakeip, domain, 0, 0, GR_SOCK_FAMILY,
|
||||
¤t->signal->saved_ip);
|
||||
goto exit;
|
||||
}
|
||||
goto exit_fail;
|
||||
}
|
||||
|
||||
inet_check:
|
||||
/* the rest of this checking is for IPv4 only */
|
||||
if (!curr->ips)
|
||||
goto exit;
|
||||
|
||||
if ((curr->ip_type & (1U << type)) &&
|
||||
(curr->ip_proto[protocol / 32] & (1U << (protocol % 32))))
|
||||
goto exit;
|
||||
|
||||
if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
|
||||
/* we don't place acls on raw sockets , and sometimes
|
||||
dgram/ip sockets are opened for ioctl and not
|
||||
bind/connect, so we'll fake a bind learn log */
|
||||
if (type == SOCK_RAW || type == SOCK_PACKET) {
|
||||
__u32 fakeip = 0;
|
||||
security_learn(GR_IP_LEARN_MSG, current->role->rolename,
|
||||
current->role->roletype, GR_GLOBAL_UID(cred->uid),
|
||||
GR_GLOBAL_GID(cred->gid), current->exec_file ?
|
||||
gr_to_filename(current->exec_file->f_path.dentry,
|
||||
current->exec_file->f_path.mnt) :
|
||||
curr->filename, curr->filename,
|
||||
&fakeip, 0, type,
|
||||
protocol, GR_CONNECT, ¤t->signal->saved_ip);
|
||||
} else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
|
||||
__u32 fakeip = 0;
|
||||
security_learn(GR_IP_LEARN_MSG, current->role->rolename,
|
||||
current->role->roletype, GR_GLOBAL_UID(cred->uid),
|
||||
GR_GLOBAL_GID(cred->gid), current->exec_file ?
|
||||
gr_to_filename(current->exec_file->f_path.dentry,
|
||||
current->exec_file->f_path.mnt) :
|
||||
curr->filename, curr->filename,
|
||||
&fakeip, 0, type,
|
||||
protocol, GR_BIND, ¤t->signal->saved_ip);
|
||||
}
|
||||
/* we'll log when they use connect or bind */
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit_fail:
|
||||
if (domain == PF_INET)
|
||||
gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, gr_sockfamily_to_name(domain),
|
||||
gr_socktype_to_name(type), gr_proto_to_name(protocol));
|
||||
else if (rcu_access_pointer(net_families[domain]) != NULL)
|
||||
gr_log_str2_int(GR_DONT_AUDIT, GR_SOCK_NOINET_MSG, gr_sockfamily_to_name(domain),
|
||||
gr_socktype_to_name(type), protocol);
|
||||
|
||||
return 0;
|
||||
exit:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int check_ip_policy(struct acl_ip_label *ip, __u32 ip_addr, __u16 ip_port, __u8 protocol, const int mode, const int type, __u32 our_addr, __u32 our_netmask)
|
||||
{
|
||||
if ((ip->mode & mode) &&
|
||||
(ip_port >= ip->low) &&
|
||||
(ip_port <= ip->high) &&
|
||||
((ntohl(ip_addr) & our_netmask) ==
|
||||
(ntohl(our_addr) & our_netmask))
|
||||
&& (ip->proto[protocol / 32] & (1U << (protocol % 32)))
|
||||
&& (ip->type & (1U << type))) {
|
||||
if (ip->mode & GR_INVERT)
|
||||
return 2; // specifically denied
|
||||
else
|
||||
return 1; // allowed
|
||||
}
|
||||
|
||||
return 0; // not specifically allowed, may continue parsing
|
||||
}
|
||||
|
||||
static int
|
||||
gr_search_connectbind(const int full_mode, struct sock *sk,
|
||||
struct sockaddr_in *addr, const int type)
|
||||
{
|
||||
char iface[IFNAMSIZ] = {0};
|
||||
struct acl_subject_label *curr;
|
||||
struct acl_ip_label *ip;
|
||||
struct inet_sock *isk;
|
||||
struct net_device *dev;
|
||||
struct in_device *idev;
|
||||
unsigned long i;
|
||||
int ret;
|
||||
int mode = full_mode & (GR_BIND | GR_CONNECT);
|
||||
__u32 ip_addr = 0;
|
||||
__u32 our_addr;
|
||||
__u32 our_netmask;
|
||||
char *p;
|
||||
__u16 ip_port = 0;
|
||||
const struct cred *cred = current_cred();
|
||||
|
||||
if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
|
||||
return 0;
|
||||
|
||||
curr = current->acl;
|
||||
isk = inet_sk(sk);
|
||||
|
||||
/* INADDR_ANY overriding for binds, inaddr_any_override is already in network order */
|
||||
if ((full_mode & GR_BINDOVERRIDE) && addr->sin_addr.s_addr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0)
|
||||
addr->sin_addr.s_addr = curr->inaddr_any_override;
|
||||
if ((full_mode & GR_CONNECT) && isk->inet_saddr == htonl(INADDR_ANY) && curr->inaddr_any_override != 0) {
|
||||
struct sockaddr_in saddr;
|
||||
int err;
|
||||
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_addr.s_addr = curr->inaddr_any_override;
|
||||
saddr.sin_port = isk->inet_sport;
|
||||
|
||||
err = security_socket_bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = sk->sk_socket->ops->bind(sk->sk_socket, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!curr->ips)
|
||||
return 0;
|
||||
|
||||
ip_addr = addr->sin_addr.s_addr;
|
||||
ip_port = ntohs(addr->sin_port);
|
||||
|
||||
if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
|
||||
security_learn(GR_IP_LEARN_MSG, current->role->rolename,
|
||||
current->role->roletype, GR_GLOBAL_UID(cred->uid),
|
||||
GR_GLOBAL_GID(cred->gid), current->exec_file ?
|
||||
gr_to_filename(current->exec_file->f_path.dentry,
|
||||
current->exec_file->f_path.mnt) :
|
||||
curr->filename, curr->filename,
|
||||
&ip_addr, ip_port, type,
|
||||
sk->sk_protocol, mode, ¤t->signal->saved_ip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < curr->ip_num; i++) {
|
||||
ip = *(curr->ips + i);
|
||||
if (ip->iface != NULL) {
|
||||
strncpy(iface, ip->iface, IFNAMSIZ - 1);
|
||||
p = strchr(iface, ':');
|
||||
if (p != NULL)
|
||||
*p = '\0';
|
||||
dev = dev_get_by_name(sock_net(sk), iface);
|
||||
if (dev == NULL)
|
||||
continue;
|
||||
idev = in_dev_get(dev);
|
||||
if (idev == NULL) {
|
||||
dev_put(dev);
|
||||
continue;
|
||||
}
|
||||
rcu_read_lock();
|
||||
for_ifa(idev) {
|
||||
if (!strcmp(ip->iface, ifa->ifa_label)) {
|
||||
our_addr = ifa->ifa_address;
|
||||
our_netmask = 0xffffffff;
|
||||
ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
|
||||
if (ret == 1) {
|
||||
rcu_read_unlock();
|
||||
in_dev_put(idev);
|
||||
dev_put(dev);
|
||||
return 0;
|
||||
} else if (ret == 2) {
|
||||
rcu_read_unlock();
|
||||
in_dev_put(idev);
|
||||
dev_put(dev);
|
||||
goto denied;
|
||||
}
|
||||
}
|
||||
} endfor_ifa(idev);
|
||||
rcu_read_unlock();
|
||||
in_dev_put(idev);
|
||||
dev_put(dev);
|
||||
} else {
|
||||
our_addr = ip->addr;
|
||||
our_netmask = ip->netmask;
|
||||
ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
|
||||
if (ret == 1)
|
||||
return 0;
|
||||
else if (ret == 2)
|
||||
goto denied;
|
||||
}
|
||||
}
|
||||
|
||||
denied:
|
||||
if (mode == GR_BIND)
|
||||
gr_log_int5_str2(GR_DONT_AUDIT, GR_BIND_ACL_MSG, &ip_addr, ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
|
||||
else if (mode == GR_CONNECT)
|
||||
gr_log_int5_str2(GR_DONT_AUDIT, GR_CONNECT_ACL_MSG, &ip_addr, ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
|
||||
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_connect(struct socket *sock, struct sockaddr_in *addr)
|
||||
{
|
||||
/* always allow disconnection of dgram sockets with connect */
|
||||
if (addr->sin_family == AF_UNSPEC)
|
||||
return 0;
|
||||
return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sock->sk, addr, sock->type);
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_bind(struct socket *sock, struct sockaddr_in *addr)
|
||||
{
|
||||
return gr_search_connectbind(GR_BIND | GR_BINDOVERRIDE, sock->sk, addr, sock->type);
|
||||
}
|
||||
|
||||
int gr_search_listen(struct socket *sock)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
addr.sin_addr.s_addr = inet_sk(sk)->inet_saddr;
|
||||
addr.sin_port = inet_sk(sk)->inet_sport;
|
||||
|
||||
return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
|
||||
}
|
||||
|
||||
int gr_search_accept(struct socket *sock)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
addr.sin_addr.s_addr = inet_sk(sk)->inet_saddr;
|
||||
addr.sin_port = inet_sk(sk)->inet_sport;
|
||||
|
||||
return gr_search_connectbind(GR_BIND | GR_CONNECTOVERRIDE, sock->sk, &addr, sock->type);
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr)
|
||||
{
|
||||
if (addr)
|
||||
return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
|
||||
else {
|
||||
struct sockaddr_in sin;
|
||||
const struct inet_sock *inet = inet_sk(sk);
|
||||
|
||||
sin.sin_addr.s_addr = inet->inet_daddr;
|
||||
sin.sin_port = inet->inet_dport;
|
||||
|
||||
return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
if (unlikely(skb->len < sizeof (struct udphdr)))
|
||||
return 0; // skip this packet
|
||||
|
||||
sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
|
||||
sin.sin_port = udp_hdr(skb)->source;
|
||||
|
||||
return gr_search_connectbind(GR_CONNECT | GR_CONNECTOVERRIDE, sk, &sin, SOCK_DGRAM);
|
||||
}
|
209
grsecurity/gracl_learn.c
Normal file
209
grsecurity/gracl_learn.c
Normal file
@ -0,0 +1,209 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
|
||||
size_t count, loff_t *ppos);
|
||||
extern int gr_acl_is_enabled(void);
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
|
||||
static int gr_learn_attached;
|
||||
|
||||
/* use a 512k buffer */
|
||||
#define LEARN_BUFFER_SIZE (512 * 1024)
|
||||
|
||||
static DEFINE_SPINLOCK(gr_learn_lock);
|
||||
static DEFINE_MUTEX(gr_learn_user_mutex);
|
||||
|
||||
/* we need to maintain two buffers, so that the kernel context of grlearn
|
||||
uses a semaphore around the userspace copying, and the other kernel contexts
|
||||
use a spinlock when copying into the buffer, since they cannot sleep
|
||||
*/
|
||||
static char *learn_buffer;
|
||||
static char *learn_buffer_user;
|
||||
static int learn_buffer_len;
|
||||
static int learn_buffer_user_len;
|
||||
|
||||
static ssize_t
|
||||
read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
|
||||
{
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
ssize_t retval = 0;
|
||||
|
||||
add_wait_queue(&learn_wait, &wait);
|
||||
do {
|
||||
mutex_lock(&gr_learn_user_mutex);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
spin_lock(&gr_learn_lock);
|
||||
if (learn_buffer_len) {
|
||||
set_current_state(TASK_RUNNING);
|
||||
break;
|
||||
}
|
||||
spin_unlock(&gr_learn_lock);
|
||||
mutex_unlock(&gr_learn_user_mutex);
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
retval = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
if (signal_pending(current)) {
|
||||
retval = -ERESTARTSYS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
schedule();
|
||||
} while (1);
|
||||
|
||||
memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
|
||||
learn_buffer_user_len = learn_buffer_len;
|
||||
retval = learn_buffer_len;
|
||||
learn_buffer_len = 0;
|
||||
|
||||
spin_unlock(&gr_learn_lock);
|
||||
|
||||
if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
|
||||
retval = -EFAULT;
|
||||
|
||||
mutex_unlock(&gr_learn_user_mutex);
|
||||
out:
|
||||
set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&learn_wait, &wait);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
poll_learn(struct file * file, poll_table * wait)
|
||||
{
|
||||
poll_wait(file, &learn_wait, wait);
|
||||
|
||||
if (learn_buffer_len)
|
||||
return (POLLIN | POLLRDNORM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_clear_learn_entries(void)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
mutex_lock(&gr_learn_user_mutex);
|
||||
spin_lock(&gr_learn_lock);
|
||||
tmp = learn_buffer;
|
||||
learn_buffer = NULL;
|
||||
spin_unlock(&gr_learn_lock);
|
||||
if (tmp)
|
||||
vfree(tmp);
|
||||
if (learn_buffer_user != NULL) {
|
||||
vfree(learn_buffer_user);
|
||||
learn_buffer_user = NULL;
|
||||
}
|
||||
learn_buffer_len = 0;
|
||||
mutex_unlock(&gr_learn_user_mutex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_add_learn_entry(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
unsigned int len;
|
||||
|
||||
if (!gr_learn_attached)
|
||||
return;
|
||||
|
||||
spin_lock(&gr_learn_lock);
|
||||
|
||||
/* leave a gap at the end so we know when it's "full" but don't have to
|
||||
compute the exact length of the string we're trying to append
|
||||
*/
|
||||
if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
|
||||
spin_unlock(&gr_learn_lock);
|
||||
wake_up_interruptible(&learn_wait);
|
||||
return;
|
||||
}
|
||||
if (learn_buffer == NULL) {
|
||||
spin_unlock(&gr_learn_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(args, fmt);
|
||||
len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
learn_buffer_len += len + 1;
|
||||
|
||||
spin_unlock(&gr_learn_lock);
|
||||
wake_up_interruptible(&learn_wait);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
open_learn(struct inode *inode, struct file *file)
|
||||
{
|
||||
if (file->f_mode & FMODE_READ && gr_learn_attached)
|
||||
return -EBUSY;
|
||||
if (file->f_mode & FMODE_READ) {
|
||||
int retval = 0;
|
||||
mutex_lock(&gr_learn_user_mutex);
|
||||
if (learn_buffer == NULL)
|
||||
learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
|
||||
if (learn_buffer_user == NULL)
|
||||
learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
|
||||
if (learn_buffer == NULL) {
|
||||
retval = -ENOMEM;
|
||||
goto out_error;
|
||||
}
|
||||
if (learn_buffer_user == NULL) {
|
||||
retval = -ENOMEM;
|
||||
goto out_error;
|
||||
}
|
||||
learn_buffer_len = 0;
|
||||
learn_buffer_user_len = 0;
|
||||
gr_learn_attached = 1;
|
||||
out_error:
|
||||
mutex_unlock(&gr_learn_user_mutex);
|
||||
return retval;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
close_learn(struct inode *inode, struct file *file)
|
||||
{
|
||||
if (file->f_mode & FMODE_READ) {
|
||||
char *tmp = NULL;
|
||||
mutex_lock(&gr_learn_user_mutex);
|
||||
spin_lock(&gr_learn_lock);
|
||||
tmp = learn_buffer;
|
||||
learn_buffer = NULL;
|
||||
spin_unlock(&gr_learn_lock);
|
||||
if (tmp)
|
||||
vfree(tmp);
|
||||
if (learn_buffer_user != NULL) {
|
||||
vfree(learn_buffer_user);
|
||||
learn_buffer_user = NULL;
|
||||
}
|
||||
learn_buffer_len = 0;
|
||||
learn_buffer_user_len = 0;
|
||||
gr_learn_attached = 0;
|
||||
mutex_unlock(&gr_learn_user_mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct file_operations grsec_fops = {
|
||||
.read = read_learn,
|
||||
.write = write_grsec_handler,
|
||||
.open = open_learn,
|
||||
.release = close_learn,
|
||||
.poll = poll_learn,
|
||||
};
|
1782
grsecurity/gracl_policy.c
Normal file
1782
grsecurity/gracl_policy.c
Normal file
File diff suppressed because it is too large
Load Diff
74
grsecurity/gracl_res.c
Normal file
74
grsecurity/gracl_res.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/gracl.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
static const char *restab_log[] = {
|
||||
[RLIMIT_CPU] = "RLIMIT_CPU",
|
||||
[RLIMIT_FSIZE] = "RLIMIT_FSIZE",
|
||||
[RLIMIT_DATA] = "RLIMIT_DATA",
|
||||
[RLIMIT_STACK] = "RLIMIT_STACK",
|
||||
[RLIMIT_CORE] = "RLIMIT_CORE",
|
||||
[RLIMIT_RSS] = "RLIMIT_RSS",
|
||||
[RLIMIT_NPROC] = "RLIMIT_NPROC",
|
||||
[RLIMIT_NOFILE] = "RLIMIT_NOFILE",
|
||||
[RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
|
||||
[RLIMIT_AS] = "RLIMIT_AS",
|
||||
[RLIMIT_LOCKS] = "RLIMIT_LOCKS",
|
||||
[RLIMIT_SIGPENDING] = "RLIMIT_SIGPENDING",
|
||||
[RLIMIT_MSGQUEUE] = "RLIMIT_MSGQUEUE",
|
||||
[RLIMIT_NICE] = "RLIMIT_NICE",
|
||||
[RLIMIT_RTPRIO] = "RLIMIT_RTPRIO",
|
||||
[RLIMIT_RTTIME] = "RLIMIT_RTTIME",
|
||||
[GR_CRASH_RES] = "RLIMIT_CRASH"
|
||||
};
|
||||
|
||||
void
|
||||
gr_log_resource(const struct task_struct *task,
|
||||
const int res, const unsigned long wanted, const int gt)
|
||||
{
|
||||
const struct cred *cred;
|
||||
unsigned long rlim;
|
||||
|
||||
if (!gr_acl_is_enabled() && !grsec_resource_logging)
|
||||
return;
|
||||
|
||||
// not yet supported resource
|
||||
if (unlikely(!restab_log[res]))
|
||||
return;
|
||||
|
||||
/*
|
||||
* not really security relevant, too much userland code shared
|
||||
* from pulseaudio that blindly attempts to violate limits in a loop,
|
||||
* resulting in log spam
|
||||
*/
|
||||
if (res == RLIMIT_NICE)
|
||||
return;
|
||||
|
||||
if (res == RLIMIT_CPU || res == RLIMIT_RTTIME)
|
||||
rlim = task_rlimit_max(task, res);
|
||||
else
|
||||
rlim = task_rlimit(task, res);
|
||||
|
||||
if (likely((rlim == RLIM_INFINITY) || (gt && wanted <= rlim) || (!gt && wanted < rlim)))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
cred = __task_cred(task);
|
||||
|
||||
if (res == RLIMIT_NPROC &&
|
||||
(cap_raised(cred->cap_effective, CAP_SYS_ADMIN) ||
|
||||
cap_raised(cred->cap_effective, CAP_SYS_RESOURCE)))
|
||||
goto out_rcu_unlock;
|
||||
else if (res == RLIMIT_MEMLOCK &&
|
||||
cap_raised(cred->cap_effective, CAP_IPC_LOCK))
|
||||
goto out_rcu_unlock;
|
||||
rcu_read_unlock();
|
||||
|
||||
gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], rlim);
|
||||
|
||||
return;
|
||||
out_rcu_unlock:
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
306
grsecurity/gracl_segv.c
Normal file
306
grsecurity/gracl_segv.c
Normal file
@ -0,0 +1,306 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/mman.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/gracl.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE)
|
||||
#include <linux/magic.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include "../fs/btrfs/async-thread.h"
|
||||
#include "../fs/btrfs/ctree.h"
|
||||
#include "../fs/btrfs/btrfs_inode.h"
|
||||
#endif
|
||||
|
||||
static struct crash_uid *uid_set;
|
||||
static unsigned short uid_used;
|
||||
static DEFINE_SPINLOCK(gr_uid_lock);
|
||||
extern rwlock_t gr_inode_lock;
|
||||
extern struct acl_subject_label *
|
||||
lookup_acl_subj_label(const u64 inode, const dev_t dev,
|
||||
const struct acl_role_label *role);
|
||||
|
||||
int
|
||||
gr_init_uidset(void)
|
||||
{
|
||||
uid_set =
|
||||
kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
|
||||
uid_used = 0;
|
||||
|
||||
return uid_set ? 1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_free_uidset(void)
|
||||
{
|
||||
if (uid_set) {
|
||||
struct crash_uid *tmpset;
|
||||
spin_lock(&gr_uid_lock);
|
||||
tmpset = uid_set;
|
||||
uid_set = NULL;
|
||||
uid_used = 0;
|
||||
spin_unlock(&gr_uid_lock);
|
||||
if (tmpset)
|
||||
kfree(tmpset);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_find_uid(const uid_t uid)
|
||||
{
|
||||
struct crash_uid *tmp = uid_set;
|
||||
uid_t buid;
|
||||
int low = 0, high = uid_used - 1, mid;
|
||||
|
||||
while (high >= low) {
|
||||
mid = (low + high) >> 1;
|
||||
buid = tmp[mid].uid;
|
||||
if (buid == uid)
|
||||
return mid;
|
||||
if (buid > uid)
|
||||
high = mid - 1;
|
||||
if (buid < uid)
|
||||
low = mid + 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
gr_insertsort(void)
|
||||
{
|
||||
unsigned short i, j;
|
||||
struct crash_uid index;
|
||||
|
||||
for (i = 1; i < uid_used; i++) {
|
||||
index = uid_set[i];
|
||||
j = i;
|
||||
while ((j > 0) && uid_set[j - 1].uid > index.uid) {
|
||||
uid_set[j] = uid_set[j - 1];
|
||||
j--;
|
||||
}
|
||||
uid_set[j] = index;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
gr_insert_uid(const kuid_t kuid, const unsigned long expires)
|
||||
{
|
||||
int loc;
|
||||
uid_t uid = GR_GLOBAL_UID(kuid);
|
||||
|
||||
if (uid_used == GR_UIDTABLE_MAX)
|
||||
return;
|
||||
|
||||
loc = gr_find_uid(uid);
|
||||
|
||||
if (loc >= 0) {
|
||||
uid_set[loc].expires = expires;
|
||||
return;
|
||||
}
|
||||
|
||||
uid_set[uid_used].uid = uid;
|
||||
uid_set[uid_used].expires = expires;
|
||||
uid_used++;
|
||||
|
||||
gr_insertsort();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_remove_uid(const unsigned short loc)
|
||||
{
|
||||
unsigned short i;
|
||||
|
||||
for (i = loc + 1; i < uid_used; i++)
|
||||
uid_set[i - 1] = uid_set[i];
|
||||
|
||||
uid_used--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int gr_find_and_remove_uid(uid_t uid)
|
||||
{
|
||||
int loc;
|
||||
|
||||
spin_lock(&gr_uid_lock);
|
||||
loc = gr_find_uid(uid);
|
||||
if (loc >= 0)
|
||||
gr_remove_uid(loc);
|
||||
spin_unlock(&gr_uid_lock);
|
||||
|
||||
return loc >= 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_check_crash_uid(const kuid_t kuid)
|
||||
{
|
||||
int loc;
|
||||
int ret = 0;
|
||||
uid_t uid;
|
||||
|
||||
if (unlikely(!gr_acl_is_enabled()))
|
||||
return 0;
|
||||
|
||||
uid = GR_GLOBAL_UID(kuid);
|
||||
|
||||
spin_lock(&gr_uid_lock);
|
||||
loc = gr_find_uid(uid);
|
||||
|
||||
if (loc < 0)
|
||||
goto out_unlock;
|
||||
|
||||
if (time_before_eq(uid_set[loc].expires, get_seconds()))
|
||||
gr_remove_uid(loc);
|
||||
else
|
||||
ret = 1;
|
||||
|
||||
out_unlock:
|
||||
spin_unlock(&gr_uid_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern int gr_fake_force_sig(int sig, struct task_struct *t);
|
||||
|
||||
void
|
||||
gr_handle_crash(struct task_struct *task, const int sig)
|
||||
{
|
||||
struct acl_subject_label *curr;
|
||||
struct task_struct *tsk, *tsk2;
|
||||
const struct cred *cred;
|
||||
const struct cred *cred2;
|
||||
|
||||
if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
|
||||
return;
|
||||
|
||||
if (unlikely(!gr_acl_is_enabled()))
|
||||
return;
|
||||
|
||||
curr = task->acl;
|
||||
|
||||
if (!(curr->resmask & (1U << GR_CRASH_RES)))
|
||||
return;
|
||||
|
||||
if (time_before_eq(curr->expires, get_seconds())) {
|
||||
curr->expires = 0;
|
||||
curr->crashes = 0;
|
||||
}
|
||||
|
||||
curr->crashes++;
|
||||
|
||||
if (!curr->expires)
|
||||
curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
|
||||
|
||||
if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
|
||||
time_after(curr->expires, get_seconds())) {
|
||||
int is_priv = is_privileged_binary(task->mm->exe_file->f_path.dentry);
|
||||
|
||||
rcu_read_lock();
|
||||
cred = __task_cred(task);
|
||||
if (gr_is_global_nonroot(cred->uid) && is_priv) {
|
||||
gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
|
||||
spin_lock(&gr_uid_lock);
|
||||
gr_insert_uid(cred->uid, curr->expires);
|
||||
spin_unlock(&gr_uid_lock);
|
||||
curr->expires = 0;
|
||||
curr->crashes = 0;
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_thread(tsk2, tsk) {
|
||||
cred2 = __task_cred(tsk);
|
||||
if (tsk != task && uid_eq(cred2->uid, cred->uid))
|
||||
gr_fake_force_sig(SIGKILL, tsk);
|
||||
} while_each_thread(tsk2, tsk);
|
||||
read_unlock(&tasklist_lock);
|
||||
} else {
|
||||
gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
|
||||
read_lock(&tasklist_lock);
|
||||
read_lock(&grsec_exec_file_lock);
|
||||
do_each_thread(tsk2, tsk) {
|
||||
if (likely(tsk != task)) {
|
||||
// if this thread has the same subject as the one that triggered
|
||||
// RES_CRASH and it's the same binary, kill it
|
||||
if (tsk->acl == task->acl && gr_is_same_file(tsk->exec_file, task->exec_file))
|
||||
gr_fake_force_sig(SIGKILL, tsk);
|
||||
}
|
||||
} while_each_thread(tsk2, tsk);
|
||||
read_unlock(&grsec_exec_file_lock);
|
||||
read_unlock(&tasklist_lock);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_check_crash_exec(const struct file *filp)
|
||||
{
|
||||
struct acl_subject_label *curr;
|
||||
struct dentry *dentry;
|
||||
|
||||
if (unlikely(!gr_acl_is_enabled()))
|
||||
return 0;
|
||||
|
||||
read_lock(&gr_inode_lock);
|
||||
dentry = filp->f_path.dentry;
|
||||
curr = lookup_acl_subj_label(gr_get_ino_from_dentry(dentry), gr_get_dev_from_dentry(dentry),
|
||||
current->role);
|
||||
read_unlock(&gr_inode_lock);
|
||||
|
||||
if (!curr || !(curr->resmask & (1U << GR_CRASH_RES)) ||
|
||||
(!curr->crashes && !curr->expires))
|
||||
return 0;
|
||||
|
||||
if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
|
||||
time_after(curr->expires, get_seconds()))
|
||||
return 1;
|
||||
else if (time_before_eq(curr->expires, get_seconds())) {
|
||||
curr->crashes = 0;
|
||||
curr->expires = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_alertkill(struct task_struct *task)
|
||||
{
|
||||
struct acl_subject_label *curracl;
|
||||
__u32 curr_ip;
|
||||
struct task_struct *p, *p2;
|
||||
|
||||
if (unlikely(!gr_acl_is_enabled()))
|
||||
return;
|
||||
|
||||
curracl = task->acl;
|
||||
curr_ip = task->signal->curr_ip;
|
||||
|
||||
if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_thread(p2, p) {
|
||||
if (p->signal->curr_ip == curr_ip)
|
||||
gr_fake_force_sig(SIGKILL, p);
|
||||
} while_each_thread(p2, p);
|
||||
read_unlock(&tasklist_lock);
|
||||
} else if (curracl->mode & GR_KILLPROC)
|
||||
gr_fake_force_sig(SIGKILL, task);
|
||||
|
||||
return;
|
||||
}
|
40
grsecurity/gracl_shm.c
Normal file
40
grsecurity/gracl_shm.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/ipc.h>
|
||||
#include <linux/gracl.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
int
|
||||
gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
|
||||
const u64 shm_createtime, const kuid_t cuid, const int shmid)
|
||||
{
|
||||
struct task_struct *task;
|
||||
|
||||
if (!gr_acl_is_enabled())
|
||||
return 1;
|
||||
|
||||
rcu_read_lock();
|
||||
read_lock(&tasklist_lock);
|
||||
|
||||
task = find_task_by_vpid(shm_cprid);
|
||||
|
||||
if (unlikely(!task))
|
||||
task = find_task_by_vpid(shm_lapid);
|
||||
|
||||
if (unlikely(task && (time_before_eq64(task->start_time, shm_createtime) ||
|
||||
(task_pid_nr(task) == shm_lapid)) &&
|
||||
(task->acl->mode & GR_PROTSHM) &&
|
||||
(task->acl != current->acl))) {
|
||||
read_unlock(&tasklist_lock);
|
||||
rcu_read_unlock();
|
||||
gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, GR_GLOBAL_UID(cuid), shm_cprid, shmid);
|
||||
return 0;
|
||||
}
|
||||
read_unlock(&tasklist_lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
return 1;
|
||||
}
|
19
grsecurity/grsec_chdir.c
Normal file
19
grsecurity/grsec_chdir.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
void
|
||||
gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
|
||||
if ((grsec_enable_chdir && grsec_enable_group &&
|
||||
in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
|
||||
!grsec_enable_group)) {
|
||||
gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
506
grsecurity/grsec_chroot.c
Normal file
506
grsecurity/grsec_chroot.c
Normal file
@ -0,0 +1,506 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/namei.h>
|
||||
#include "../fs/mount.h"
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_INITRD
|
||||
int gr_init_ran;
|
||||
#endif
|
||||
|
||||
void gr_inc_chroot_refcnts(struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME
|
||||
struct dentry *tmpd = dentry;
|
||||
|
||||
read_seqlock_excl(&mount_lock);
|
||||
write_seqlock(&rename_lock);
|
||||
|
||||
while (tmpd != mnt->mnt_root) {
|
||||
atomic_inc(&tmpd->chroot_refcnt);
|
||||
tmpd = tmpd->d_parent;
|
||||
}
|
||||
atomic_inc(&tmpd->chroot_refcnt);
|
||||
|
||||
write_sequnlock(&rename_lock);
|
||||
read_sequnlock_excl(&mount_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void gr_dec_chroot_refcnts(struct dentry *dentry, struct vfsmount *mnt)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME
|
||||
struct dentry *tmpd = dentry;
|
||||
|
||||
read_seqlock_excl(&mount_lock);
|
||||
write_seqlock(&rename_lock);
|
||||
|
||||
while (tmpd != mnt->mnt_root) {
|
||||
atomic_dec(&tmpd->chroot_refcnt);
|
||||
tmpd = tmpd->d_parent;
|
||||
}
|
||||
atomic_dec(&tmpd->chroot_refcnt);
|
||||
|
||||
write_sequnlock(&rename_lock);
|
||||
read_sequnlock_excl(&mount_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME
|
||||
static struct dentry *get_closest_chroot(struct dentry *dentry)
|
||||
{
|
||||
write_seqlock(&rename_lock);
|
||||
do {
|
||||
if (atomic_read(&dentry->chroot_refcnt)) {
|
||||
write_sequnlock(&rename_lock);
|
||||
return dentry;
|
||||
}
|
||||
dentry = dentry->d_parent;
|
||||
} while (!IS_ROOT(dentry));
|
||||
write_sequnlock(&rename_lock);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int gr_bad_chroot_rename(struct dentry *olddentry, struct vfsmount *oldmnt,
|
||||
struct dentry *newdentry, struct vfsmount *newmnt)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME
|
||||
struct dentry *chroot;
|
||||
|
||||
if (unlikely(!grsec_enable_chroot_rename))
|
||||
return 0;
|
||||
|
||||
if (likely(!proc_is_chrooted(current) && gr_is_global_root(current_uid())))
|
||||
return 0;
|
||||
|
||||
chroot = get_closest_chroot(olddentry);
|
||||
|
||||
if (chroot == NULL)
|
||||
return 0;
|
||||
|
||||
if (is_subdir(newdentry, chroot))
|
||||
return 0;
|
||||
|
||||
gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_RENAME_MSG, olddentry, oldmnt);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void gr_set_chroot_entries(struct task_struct *task, const struct path *path)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
if (task_pid_nr(task) > 1 && path->dentry != init_task.fs->root.dentry &&
|
||||
path->dentry != task->nsproxy->mnt_ns->root->mnt.mnt_root
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_INITRD
|
||||
&& gr_init_ran
|
||||
#endif
|
||||
)
|
||||
task->gr_is_chrooted = 1;
|
||||
else {
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_INITRD
|
||||
if (task_pid_nr(task) == 1 && !gr_init_ran)
|
||||
gr_init_ran = 1;
|
||||
#endif
|
||||
task->gr_is_chrooted = 0;
|
||||
}
|
||||
|
||||
task->gr_chroot_dentry = path->dentry;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void gr_clear_chroot_entries(struct task_struct *task)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
task->gr_is_chrooted = 0;
|
||||
task->gr_chroot_dentry = NULL;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_unix(const pid_t pid)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
|
||||
struct task_struct *p;
|
||||
|
||||
if (unlikely(!grsec_enable_chroot_unix))
|
||||
return 1;
|
||||
|
||||
if (likely(!proc_is_chrooted(current)))
|
||||
return 1;
|
||||
|
||||
rcu_read_lock();
|
||||
read_lock(&tasklist_lock);
|
||||
p = find_task_by_vpid_unrestricted(pid);
|
||||
if (unlikely(p && !have_same_root(current, p))) {
|
||||
read_unlock(&tasklist_lock);
|
||||
rcu_read_unlock();
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
|
||||
return 0;
|
||||
}
|
||||
read_unlock(&tasklist_lock);
|
||||
rcu_read_unlock();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_nice(void)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
|
||||
if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
|
||||
if (grsec_enable_chroot_nice && (niceval < task_nice(p))
|
||||
&& proc_is_chrooted(current)) {
|
||||
gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, task_pid_nr(p));
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_fowner(struct pid *pid, enum pid_type type)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
|
||||
struct task_struct *p;
|
||||
int ret = 0;
|
||||
if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !pid)
|
||||
return ret;
|
||||
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_pid_task(pid, type, p) {
|
||||
if (!have_same_root(current, p)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
} while_each_pid_task(pid, type, p);
|
||||
out:
|
||||
read_unlock(&tasklist_lock);
|
||||
return ret;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_pid_is_chrooted(struct task_struct *p)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
|
||||
if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
|
||||
return 0;
|
||||
|
||||
if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
|
||||
!have_same_root(current, p)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(gr_pid_is_chrooted);
|
||||
|
||||
#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
|
||||
int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
|
||||
{
|
||||
struct path path, currentroot;
|
||||
int ret = 0;
|
||||
|
||||
path.dentry = (struct dentry *)u_dentry;
|
||||
path.mnt = (struct vfsmount *)u_mnt;
|
||||
get_fs_root(current->fs, ¤troot);
|
||||
if (path_is_under(&path, ¤troot))
|
||||
ret = 1;
|
||||
path_put(¤troot);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
|
||||
if (!grsec_enable_chroot_fchdir)
|
||||
return 1;
|
||||
|
||||
if (!proc_is_chrooted(current))
|
||||
return 1;
|
||||
else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
|
||||
gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_chroot_pathat(int dfd, struct dentry *u_dentry, struct vfsmount *u_mnt, unsigned flags)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
|
||||
struct fd f;
|
||||
struct path fd_path;
|
||||
struct path file_path;
|
||||
|
||||
if (!grsec_enable_chroot_fchdir)
|
||||
return 0;
|
||||
|
||||
if (!proc_is_chrooted(current) || dfd == -1 || dfd == AT_FDCWD)
|
||||
return 0;
|
||||
|
||||
if (flags & LOOKUP_RCU)
|
||||
return -ECHILD;
|
||||
|
||||
f = fdget_raw(dfd);
|
||||
if (!f.file)
|
||||
return 0;
|
||||
|
||||
fd_path = f.file->f_path;
|
||||
path_get(&fd_path);
|
||||
fdput(f);
|
||||
|
||||
file_path.dentry = u_dentry;
|
||||
file_path.mnt = u_mnt;
|
||||
|
||||
if (!gr_is_outside_chroot(u_dentry, u_mnt) && !path_is_under(&file_path, &fd_path)) {
|
||||
path_put(&fd_path);
|
||||
gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_PATHAT_MSG, u_dentry, u_mnt);
|
||||
return -ENOENT;
|
||||
}
|
||||
path_put(&fd_path);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_chroot_fhandle(void)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
|
||||
if (!grsec_enable_chroot_fchdir)
|
||||
return 1;
|
||||
|
||||
if (!proc_is_chrooted(current))
|
||||
return 1;
|
||||
else {
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_CHROOT_FHANDLE_MSG);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
|
||||
const u64 shm_createtime)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
|
||||
struct task_struct *p;
|
||||
|
||||
if (unlikely(!grsec_enable_chroot_shmat))
|
||||
return 1;
|
||||
|
||||
if (likely(!proc_is_chrooted(current)))
|
||||
return 1;
|
||||
|
||||
rcu_read_lock();
|
||||
read_lock(&tasklist_lock);
|
||||
|
||||
if ((p = find_task_by_vpid_unrestricted(shm_cprid))) {
|
||||
if (time_before_eq64(p->start_time, shm_createtime)) {
|
||||
if (have_same_root(current, p)) {
|
||||
goto allow;
|
||||
} else {
|
||||
read_unlock(&tasklist_lock);
|
||||
rcu_read_unlock();
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* creator exited, pid reuse, fall through to next check */
|
||||
}
|
||||
if ((p = find_task_by_vpid_unrestricted(shm_lapid))) {
|
||||
if (unlikely(!have_same_root(current, p))) {
|
||||
read_unlock(&tasklist_lock);
|
||||
rcu_read_unlock();
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
allow:
|
||||
read_unlock(&tasklist_lock);
|
||||
rcu_read_unlock();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
|
||||
if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
|
||||
gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_mknod(const struct dentry *dentry,
|
||||
const struct vfsmount *mnt, const int mode)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
|
||||
if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
|
||||
proc_is_chrooted(current)) {
|
||||
gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_mount(const struct dentry *dentry,
|
||||
const struct vfsmount *mnt, const char *dev_name)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
|
||||
if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
|
||||
gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name ? dev_name : "none", dentry, mnt);
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_pivot(void)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
|
||||
if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
|
||||
if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
|
||||
!gr_is_outside_chroot(dentry, mnt)) {
|
||||
gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern const char *captab_log[];
|
||||
extern int captab_log_entries;
|
||||
|
||||
int
|
||||
gr_task_chroot_is_capable(const struct task_struct *task, const struct cred *cred, const int cap)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
|
||||
if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
|
||||
kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
|
||||
if (cap_raised(chroot_caps, cap)) {
|
||||
if (cap_raised(cred->cap_effective, cap) && cap < captab_log_entries) {
|
||||
gr_log_cap(GR_DONT_AUDIT, GR_CAP_CHROOT_MSG, task, captab_log[cap]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_chroot_is_capable(const int cap)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
|
||||
return gr_task_chroot_is_capable(current, current_cred(), cap);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_task_chroot_is_capable_nolog(const struct task_struct *task, const int cap)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
|
||||
if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
|
||||
kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
|
||||
if (cap_raised(chroot_caps, cap)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_chroot_is_capable_nolog(const int cap)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
|
||||
return gr_task_chroot_is_capable_nolog(current, cap);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_sysctl(const int op)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
|
||||
if (grsec_enable_chroot_sysctl && (op & MAY_WRITE) &&
|
||||
proc_is_chrooted(current))
|
||||
return -EACCES;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_chroot_chdir(const struct path *path)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
|
||||
if (grsec_enable_chroot_chdir)
|
||||
set_fs_pwd(current->fs, path);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_chroot_chmod(const struct dentry *dentry,
|
||||
const struct vfsmount *mnt, const int mode)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
|
||||
/* allow chmod +s on directories, but not files */
|
||||
if (grsec_enable_chroot_chmod && !d_is_dir(dentry) &&
|
||||
((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
|
||||
proc_is_chrooted(current)) {
|
||||
gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
445
grsecurity/grsec_disabled.c
Normal file
445
grsecurity/grsec_disabled.c
Normal file
@ -0,0 +1,445 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/sysctl.h>
|
||||
|
||||
#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
|
||||
void
|
||||
pax_set_initial_flags(struct linux_binprm *bprm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
__u32
|
||||
gr_handle_sysctl(const struct ctl_table * table, const int op)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TASKSTATS
|
||||
int gr_is_taskstats_denied(int pid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
gr_acl_is_enabled(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_learn_cap(const struct task_struct *task, const struct cred *cred, const int cap, bool log)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_proc_create(const struct dentry *dentry, const struct inode *inode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_rawio(const struct inode *inode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_acl_handle_psacct(struct task_struct *task, const long code)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_ptrace(struct task_struct *task, const long request)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_proc_ptrace(struct task_struct *task)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_set_acls(const int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_check_hidden_task(const struct task_struct *tsk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_check_protected_task(const struct task_struct *task)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_check_protected_task_fowner(struct pid *pid, enum pid_type type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_copy_label(struct task_struct *tsk)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_set_pax_flags(struct task_struct *task)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt,
|
||||
const int unsafe_share)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_delete(const u64 ino, const dev_t dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_crash(struct task_struct *task, const int sig)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_check_crash_exec(const struct file *filp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_check_crash_uid(const kuid_t uid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
|
||||
struct dentry *old_dentry,
|
||||
struct dentry *new_dentry,
|
||||
struct vfsmount *mnt, const __u8 replace, unsigned int flags)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_socket(const int family, const int type, const int protocol)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_connectbind(const int mode, const struct socket *sock,
|
||||
const struct sockaddr_in *addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_alertkill(struct task_struct *task)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_hidden_file(const struct dentry * dentry,
|
||||
const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
|
||||
int acc_mode)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
|
||||
unsigned int *vm_flags)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_truncate(const struct dentry * dentry,
|
||||
const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_access(const struct dentry * dentry,
|
||||
const struct vfsmount * mnt, const int fmode)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
|
||||
umode_t *mode)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_setxattr(const struct dentry * dentry, const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_removexattr(const struct dentry * dentry, const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
grsecurity_init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
umode_t gr_acl_umask(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_mknod(const struct dentry * new_dentry,
|
||||
const struct dentry * parent_dentry,
|
||||
const struct vfsmount * parent_mnt,
|
||||
const int mode)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_mkdir(const struct dentry * new_dentry,
|
||||
const struct dentry * parent_dentry,
|
||||
const struct vfsmount * parent_mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_symlink(const struct dentry * new_dentry,
|
||||
const struct dentry * parent_dentry,
|
||||
const struct vfsmount * parent_mnt, const struct filename *from)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_link(const struct dentry * new_dentry,
|
||||
const struct dentry * parent_dentry,
|
||||
const struct vfsmount * parent_mnt,
|
||||
const struct dentry * old_dentry,
|
||||
const struct vfsmount * old_mnt, const struct filename *to)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_acl_handle_rename(const struct dentry *new_dentry,
|
||||
const struct dentry *parent_dentry,
|
||||
const struct vfsmount *parent_mnt,
|
||||
const struct dentry *old_dentry,
|
||||
const struct inode *old_parent_inode,
|
||||
const struct vfsmount *old_mnt, const struct filename *newname,
|
||||
unsigned int flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_acl_handle_filldir(const struct file *file, const char *name,
|
||||
const int namelen, const u64 ino)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
|
||||
const u64 shm_createtime, const kuid_t cuid, const int shmid)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_accept(const struct socket *sock)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_listen(const struct socket *sock)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__u32
|
||||
gr_acl_handle_creat(const struct dentry * dentry,
|
||||
const struct dentry * p_dentry,
|
||||
const struct vfsmount * p_mnt, int open_flags, int acc_mode,
|
||||
const int imode)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
gr_acl_handle_exit(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
gr_set_role_label(const kuid_t uid, const kgid_t gid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_acl_handle_procpidmem(const struct task_struct *task)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_check_user_change(kuid_t real, kuid_t effective, kuid_t fs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_check_group_change(kgid_t real, kgid_t effective, kgid_t fs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gr_acl_enable_at_secure(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_t gr_get_dev_from_dentry(struct dentry *dentry)
|
||||
{
|
||||
return d_backing_inode(dentry)->i_sb->s_dev;
|
||||
}
|
||||
|
||||
u64 gr_get_ino_from_dentry(struct dentry *dentry)
|
||||
{
|
||||
return d_backing_inode(dentry)->i_ino;
|
||||
}
|
||||
|
||||
void gr_put_exec_file(struct task_struct *task)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURITY
|
||||
EXPORT_SYMBOL_GPL(gr_check_user_change);
|
||||
EXPORT_SYMBOL_GPL(gr_check_group_change);
|
||||
#endif
|
188
grsecurity/grsec_exec.c
Normal file
188
grsecurity/grsec_exec.c
Normal file
@ -0,0 +1,188 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/grdefs.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/compat.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC_EXECLOG
|
||||
static char gr_exec_arg_buf[132];
|
||||
static DEFINE_MUTEX(gr_exec_arg_mutex);
|
||||
#endif
|
||||
|
||||
struct user_arg_ptr {
|
||||
#ifdef CONFIG_COMPAT
|
||||
bool is_compat;
|
||||
#endif
|
||||
union {
|
||||
const char __user *const __user *native;
|
||||
#ifdef CONFIG_COMPAT
|
||||
const compat_uptr_t __user *compat;
|
||||
#endif
|
||||
} ptr;
|
||||
};
|
||||
|
||||
extern const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr);
|
||||
|
||||
void
|
||||
gr_handle_exec_args(struct linux_binprm *bprm, struct user_arg_ptr argv)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_EXECLOG
|
||||
char *grarg = gr_exec_arg_buf;
|
||||
unsigned int i, x, execlen = 0;
|
||||
char c;
|
||||
|
||||
if (!((grsec_enable_execlog && grsec_enable_group &&
|
||||
in_group_p(grsec_audit_gid))
|
||||
|| (grsec_enable_execlog && !grsec_enable_group)))
|
||||
return;
|
||||
|
||||
mutex_lock(&gr_exec_arg_mutex);
|
||||
memset(grarg, 0, sizeof(gr_exec_arg_buf));
|
||||
|
||||
for (i = 0; i < bprm->argc && execlen < 128; i++) {
|
||||
const char __user *p;
|
||||
unsigned int len;
|
||||
|
||||
p = get_user_arg_ptr(argv, i);
|
||||
if (IS_ERR(p))
|
||||
goto log;
|
||||
|
||||
len = strnlen_user(p, 128 - execlen);
|
||||
if (len > 128 - execlen)
|
||||
len = 128 - execlen;
|
||||
else if (len > 0)
|
||||
len--;
|
||||
if (copy_from_user(grarg + execlen, p, len))
|
||||
goto log;
|
||||
|
||||
/* rewrite unprintable characters */
|
||||
for (x = 0; x < len; x++) {
|
||||
c = *(grarg + execlen + x);
|
||||
if (c < 32 || c > 126)
|
||||
*(grarg + execlen + x) = ' ';
|
||||
}
|
||||
|
||||
execlen += len;
|
||||
*(grarg + execlen) = ' ';
|
||||
*(grarg + execlen + 1) = '\0';
|
||||
execlen++;
|
||||
}
|
||||
|
||||
log:
|
||||
gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
|
||||
bprm->file->f_path.mnt, grarg);
|
||||
mutex_unlock(&gr_exec_arg_mutex);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
extern int gr_acl_is_capable(const int cap);
|
||||
extern int gr_acl_is_capable_nolog(const int cap);
|
||||
extern int gr_task_acl_is_capable(const struct task_struct *task, const struct cred *cred, const int cap, bool log);
|
||||
extern int gr_chroot_is_capable(const int cap);
|
||||
extern int gr_chroot_is_capable_nolog(const int cap);
|
||||
extern int gr_task_chroot_is_capable(const struct task_struct *task, const struct cred *cred, const int cap);
|
||||
extern int gr_task_chroot_is_capable_nolog(const struct task_struct *task, const int cap);
|
||||
#endif
|
||||
|
||||
const char *captab_log[] = {
|
||||
"CAP_CHOWN",
|
||||
"CAP_DAC_OVERRIDE",
|
||||
"CAP_DAC_READ_SEARCH",
|
||||
"CAP_FOWNER",
|
||||
"CAP_FSETID",
|
||||
"CAP_KILL",
|
||||
"CAP_SETGID",
|
||||
"CAP_SETUID",
|
||||
"CAP_SETPCAP",
|
||||
"CAP_LINUX_IMMUTABLE",
|
||||
"CAP_NET_BIND_SERVICE",
|
||||
"CAP_NET_BROADCAST",
|
||||
"CAP_NET_ADMIN",
|
||||
"CAP_NET_RAW",
|
||||
"CAP_IPC_LOCK",
|
||||
"CAP_IPC_OWNER",
|
||||
"CAP_SYS_MODULE",
|
||||
"CAP_SYS_RAWIO",
|
||||
"CAP_SYS_CHROOT",
|
||||
"CAP_SYS_PTRACE",
|
||||
"CAP_SYS_PACCT",
|
||||
"CAP_SYS_ADMIN",
|
||||
"CAP_SYS_BOOT",
|
||||
"CAP_SYS_NICE",
|
||||
"CAP_SYS_RESOURCE",
|
||||
"CAP_SYS_TIME",
|
||||
"CAP_SYS_TTY_CONFIG",
|
||||
"CAP_MKNOD",
|
||||
"CAP_LEASE",
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_AUDIT_CONTROL",
|
||||
"CAP_SETFCAP",
|
||||
"CAP_MAC_OVERRIDE",
|
||||
"CAP_MAC_ADMIN",
|
||||
"CAP_SYSLOG",
|
||||
"CAP_WAKE_ALARM",
|
||||
"CAP_BLOCK_SUSPEND",
|
||||
"CAP_AUDIT_READ"
|
||||
};
|
||||
|
||||
int captab_log_entries = sizeof(captab_log)/sizeof(captab_log[0]);
|
||||
|
||||
int gr_is_capable(const int cap)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
if (gr_acl_is_capable(cap) && gr_chroot_is_capable(cap))
|
||||
return 1;
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int gr_task_is_capable(const struct task_struct *task, const struct cred *cred, const int cap)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
if (gr_task_acl_is_capable(task, cred, cap, true) && gr_task_chroot_is_capable(task, cred, cap))
|
||||
return 1;
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int gr_is_capable_nolog(const int cap)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
if (gr_acl_is_capable_nolog(cap) && gr_chroot_is_capable_nolog(cap))
|
||||
return 1;
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int gr_task_is_capable_nolog(const struct task_struct *task, const struct cred *cred, const int cap)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
if (gr_task_acl_is_capable(task, cred, cap, false) && gr_task_chroot_is_capable_nolog(task, cap))
|
||||
return 1;
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(gr_is_capable);
|
||||
EXPORT_SYMBOL_GPL(gr_is_capable_nolog);
|
||||
EXPORT_SYMBOL_GPL(gr_task_is_capable);
|
||||
EXPORT_SYMBOL_GPL(gr_task_is_capable_nolog);
|
26
grsecurity/grsec_fifo.c
Normal file
26
grsecurity/grsec_fifo.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
int
|
||||
gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
|
||||
const struct dentry *dir, const int flag, const int acc_mode)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_FIFO
|
||||
const struct cred *cred = current_cred();
|
||||
struct inode *inode = d_backing_inode(dentry);
|
||||
struct inode *dir_inode = d_backing_inode(dir);
|
||||
|
||||
if (grsec_enable_fifo && S_ISFIFO(inode->i_mode) &&
|
||||
!(flag & O_EXCL) && (dir_inode->i_mode & S_ISVTX) &&
|
||||
!uid_eq(inode->i_uid, dir_inode->i_uid) &&
|
||||
!uid_eq(cred->fsuid, inode->i_uid)) {
|
||||
if (!inode_permission(inode, acc_mode))
|
||||
gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, GR_GLOBAL_UID(inode->i_uid), GR_GLOBAL_GID(inode->i_gid));
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
23
grsecurity/grsec_fork.c
Normal file
23
grsecurity/grsec_fork.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
void
|
||||
gr_log_forkfail(const int retval)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_FORKFAIL
|
||||
if (grsec_enable_forkfail && (retval == -EAGAIN || retval == -ENOMEM)) {
|
||||
switch (retval) {
|
||||
case -EAGAIN:
|
||||
gr_log_str(GR_DONT_AUDIT, GR_FAILFORK_MSG, "EAGAIN");
|
||||
break;
|
||||
case -ENOMEM:
|
||||
gr_log_str(GR_DONT_AUDIT, GR_FAILFORK_MSG, "ENOMEM");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
294
grsecurity/grsec_init.c
Normal file
294
grsecurity/grsec_init.c
Normal file
@ -0,0 +1,294 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/gracl.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
int grsec_enable_ptrace_readexec __read_only;
|
||||
int grsec_enable_setxid __read_only;
|
||||
int grsec_enable_symlinkown __read_only;
|
||||
kgid_t grsec_symlinkown_gid __read_only;
|
||||
int grsec_enable_brute __read_only;
|
||||
int grsec_enable_link __read_only;
|
||||
int grsec_enable_dmesg __read_only;
|
||||
int grsec_enable_harden_ptrace __read_only;
|
||||
int grsec_enable_harden_ipc __read_only;
|
||||
int grsec_enable_fifo __read_only;
|
||||
int grsec_enable_execlog __read_only;
|
||||
int grsec_enable_signal __read_only;
|
||||
int grsec_enable_forkfail __read_only;
|
||||
int grsec_enable_audit_ptrace __read_only;
|
||||
int grsec_enable_time __read_only;
|
||||
int grsec_enable_group __read_only;
|
||||
kgid_t grsec_audit_gid __read_only;
|
||||
int grsec_enable_chdir __read_only;
|
||||
int grsec_enable_mount __read_only;
|
||||
int grsec_enable_rofs __read_only;
|
||||
int grsec_deny_new_usb __read_only;
|
||||
int grsec_enable_chroot_findtask __read_only;
|
||||
int grsec_enable_chroot_mount __read_only;
|
||||
int grsec_enable_chroot_shmat __read_only;
|
||||
int grsec_enable_chroot_fchdir __read_only;
|
||||
int grsec_enable_chroot_double __read_only;
|
||||
int grsec_enable_chroot_pivot __read_only;
|
||||
int grsec_enable_chroot_chdir __read_only;
|
||||
int grsec_enable_chroot_chmod __read_only;
|
||||
int grsec_enable_chroot_mknod __read_only;
|
||||
int grsec_enable_chroot_nice __read_only;
|
||||
int grsec_enable_chroot_execlog __read_only;
|
||||
int grsec_enable_chroot_caps __read_only;
|
||||
int grsec_enable_chroot_rename __read_only;
|
||||
int grsec_enable_chroot_sysctl __read_only;
|
||||
int grsec_enable_chroot_unix __read_only;
|
||||
int grsec_enable_tpe __read_only;
|
||||
kgid_t grsec_tpe_gid __read_only;
|
||||
int grsec_enable_blackhole __read_only;
|
||||
#ifdef CONFIG_IPV6_MODULE
|
||||
EXPORT_SYMBOL_GPL(grsec_enable_blackhole);
|
||||
#endif
|
||||
int grsec_lastack_retries __read_only;
|
||||
int grsec_enable_tpe_all __read_only;
|
||||
int grsec_enable_tpe_invert __read_only;
|
||||
int grsec_enable_socket_all __read_only;
|
||||
kgid_t grsec_socket_all_gid __read_only;
|
||||
int grsec_enable_socket_client __read_only;
|
||||
kgid_t grsec_socket_client_gid __read_only;
|
||||
int grsec_enable_socket_server __read_only;
|
||||
kgid_t grsec_socket_server_gid __read_only;
|
||||
int grsec_resource_logging __read_only;
|
||||
int grsec_disable_privio __read_only;
|
||||
int grsec_enable_log_rwxmaps __read_only;
|
||||
int grsec_enable_harden_tty __read_only;
|
||||
int grsec_lock __read_only;
|
||||
|
||||
DEFINE_SPINLOCK(grsec_alert_lock);
|
||||
unsigned long grsec_alert_wtime = 0;
|
||||
unsigned long grsec_alert_fyet = 0;
|
||||
|
||||
DEFINE_SPINLOCK(grsec_audit_lock);
|
||||
|
||||
DEFINE_RWLOCK(grsec_exec_file_lock);
|
||||
|
||||
char *gr_shared_page[4];
|
||||
|
||||
char *gr_alert_log_fmt;
|
||||
char *gr_audit_log_fmt;
|
||||
char *gr_alert_log_buf;
|
||||
char *gr_audit_log_buf;
|
||||
|
||||
extern struct gr_arg *gr_usermode;
|
||||
extern unsigned char *gr_system_salt;
|
||||
extern unsigned char *gr_system_sum;
|
||||
|
||||
void __init
|
||||
grsecurity_init(void)
|
||||
{
|
||||
int j;
|
||||
/* create the per-cpu shared pages */
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
|
||||
#endif
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE, __alignof__(unsigned long long));
|
||||
if (gr_shared_page[j] == NULL) {
|
||||
panic("Unable to allocate grsecurity shared page");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate log buffers */
|
||||
gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
|
||||
if (!gr_alert_log_fmt) {
|
||||
panic("Unable to allocate grsecurity alert log format buffer");
|
||||
return;
|
||||
}
|
||||
gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
|
||||
if (!gr_audit_log_fmt) {
|
||||
panic("Unable to allocate grsecurity audit log format buffer");
|
||||
return;
|
||||
}
|
||||
gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
|
||||
if (!gr_alert_log_buf) {
|
||||
panic("Unable to allocate grsecurity alert log buffer");
|
||||
return;
|
||||
}
|
||||
gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
|
||||
if (!gr_audit_log_buf) {
|
||||
panic("Unable to allocate grsecurity audit log buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate memory for authentication structure */
|
||||
gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
|
||||
gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
|
||||
gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
|
||||
|
||||
if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
|
||||
panic("Unable to allocate grsecurity authentication structure");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC_IO
|
||||
#if !defined(CONFIG_GRKERNSEC_SYSCTL_DISTRO)
|
||||
grsec_disable_privio = 1;
|
||||
#elif defined(CONFIG_GRKERNSEC_SYSCTL_ON)
|
||||
grsec_disable_privio = 1;
|
||||
#else
|
||||
grsec_disable_privio = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC_TPE_INVERT
|
||||
/* for backward compatibility, tpe_invert always defaults to on if
|
||||
enabled in the kernel
|
||||
*/
|
||||
grsec_enable_tpe_invert = 1;
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
|
||||
#ifndef CONFIG_GRKERNSEC_SYSCTL
|
||||
grsec_lock = 1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
|
||||
grsec_enable_log_rwxmaps = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
|
||||
grsec_enable_group = 1;
|
||||
grsec_audit_gid = KGIDT_INIT(CONFIG_GRKERNSEC_AUDIT_GID);
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_PTRACE_READEXEC
|
||||
grsec_enable_ptrace_readexec = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
|
||||
grsec_enable_chdir = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
|
||||
grsec_enable_harden_ptrace = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_HARDEN_IPC
|
||||
grsec_enable_harden_ipc = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_HARDEN_TTY
|
||||
grsec_enable_harden_tty = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
|
||||
grsec_enable_mount = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_LINK
|
||||
grsec_enable_link = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_BRUTE
|
||||
grsec_enable_brute = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_DMESG
|
||||
grsec_enable_dmesg = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_BLACKHOLE
|
||||
grsec_enable_blackhole = 1;
|
||||
grsec_lastack_retries = 4;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_FIFO
|
||||
grsec_enable_fifo = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_EXECLOG
|
||||
grsec_enable_execlog = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SETXID
|
||||
grsec_enable_setxid = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SIGNAL
|
||||
grsec_enable_signal = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_FORKFAIL
|
||||
grsec_enable_forkfail = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_TIME
|
||||
grsec_enable_time = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_RESLOG
|
||||
grsec_resource_logging = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
|
||||
grsec_enable_chroot_findtask = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
|
||||
grsec_enable_chroot_unix = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
|
||||
grsec_enable_chroot_mount = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
|
||||
grsec_enable_chroot_fchdir = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
|
||||
grsec_enable_chroot_shmat = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE
|
||||
grsec_enable_audit_ptrace = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
|
||||
grsec_enable_chroot_double = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
|
||||
grsec_enable_chroot_pivot = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
|
||||
grsec_enable_chroot_chdir = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
|
||||
grsec_enable_chroot_chmod = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
|
||||
grsec_enable_chroot_mknod = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
|
||||
grsec_enable_chroot_nice = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
|
||||
grsec_enable_chroot_execlog = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
|
||||
grsec_enable_chroot_caps = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME
|
||||
grsec_enable_chroot_rename = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
|
||||
grsec_enable_chroot_sysctl = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SYMLINKOWN
|
||||
grsec_enable_symlinkown = 1;
|
||||
grsec_symlinkown_gid = KGIDT_INIT(CONFIG_GRKERNSEC_SYMLINKOWN_GID);
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_TPE
|
||||
grsec_enable_tpe = 1;
|
||||
grsec_tpe_gid = KGIDT_INIT(CONFIG_GRKERNSEC_TPE_GID);
|
||||
#ifdef CONFIG_GRKERNSEC_TPE_ALL
|
||||
grsec_enable_tpe_all = 1;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
|
||||
grsec_enable_socket_all = 1;
|
||||
grsec_socket_all_gid = KGIDT_INIT(CONFIG_GRKERNSEC_SOCKET_ALL_GID);
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
|
||||
grsec_enable_socket_client = 1;
|
||||
grsec_socket_client_gid = KGIDT_INIT(CONFIG_GRKERNSEC_SOCKET_CLIENT_GID);
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
|
||||
grsec_enable_socket_server = 1;
|
||||
grsec_socket_server_gid = KGIDT_INIT(CONFIG_GRKERNSEC_SOCKET_SERVER_GID);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_DENYUSB_FORCE
|
||||
grsec_deny_new_usb = 1;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
48
grsecurity/grsec_ipc.c
Normal file
48
grsecurity/grsec_ipc.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/ipc.h>
|
||||
#include <linux/ipc_namespace.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
int
|
||||
gr_ipc_permitted(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, int requested_mode, int granted_mode)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_HARDEN_IPC
|
||||
int write;
|
||||
int orig_granted_mode;
|
||||
kuid_t euid;
|
||||
kgid_t egid;
|
||||
|
||||
if (!grsec_enable_harden_ipc)
|
||||
return 1;
|
||||
|
||||
euid = current_euid();
|
||||
egid = current_egid();
|
||||
|
||||
write = requested_mode & 00002;
|
||||
orig_granted_mode = ipcp->mode;
|
||||
|
||||
if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid))
|
||||
orig_granted_mode >>= 6;
|
||||
else {
|
||||
/* if likely wrong permissions, lock to user */
|
||||
if (orig_granted_mode & 0007)
|
||||
orig_granted_mode = 0;
|
||||
/* otherwise do a egid-only check */
|
||||
else if (gid_eq(egid, ipcp->cgid) || gid_eq(egid, ipcp->gid))
|
||||
orig_granted_mode >>= 3;
|
||||
/* otherwise, no access */
|
||||
else
|
||||
orig_granted_mode = 0;
|
||||
}
|
||||
if (!(requested_mode & ~granted_mode & 0007) && (requested_mode & ~orig_granted_mode & 0007) &&
|
||||
!ns_capable_noaudit(ns->user_ns, CAP_IPC_OWNER)) {
|
||||
gr_log_str_int(GR_DONT_AUDIT, GR_IPC_DENIED_MSG, write ? "write" : "read", GR_GLOBAL_UID(ipcp->cuid));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
65
grsecurity/grsec_link.c
Normal file
65
grsecurity/grsec_link.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
int gr_get_symlinkown_enabled(void)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_SYMLINKOWN
|
||||
if (grsec_enable_symlinkown && in_group_p(grsec_symlinkown_gid))
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gr_handle_symlink_owner(const struct path *link, const struct inode *target)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_SYMLINKOWN
|
||||
const struct inode *link_inode = d_backing_inode(link->dentry);
|
||||
|
||||
if (target && !uid_eq(link_inode->i_uid, target->i_uid)) {
|
||||
gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINKOWNER_MSG, link->dentry, link->mnt, GR_GLOBAL_UID(link_inode->i_uid), GR_GLOBAL_UID(target->i_uid));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_follow_link(const struct dentry *dentry, const struct vfsmount *mnt)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_LINK
|
||||
struct inode *inode = d_backing_inode(dentry);
|
||||
struct inode *parent = d_backing_inode(dentry->d_parent);
|
||||
const struct cred *cred = current_cred();
|
||||
|
||||
if (grsec_enable_link && d_is_symlink(dentry) &&
|
||||
(parent->i_mode & S_ISVTX) && !uid_eq(parent->i_uid, inode->i_uid) &&
|
||||
(parent->i_mode & S_IWOTH) && !uid_eq(cred->fsuid, inode->i_uid)) {
|
||||
gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, GR_GLOBAL_UID(inode->i_uid), GR_GLOBAL_GID(inode->i_gid));
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_hardlink(const struct dentry *dentry,
|
||||
const struct vfsmount *mnt,
|
||||
const struct filename *to)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_LINK
|
||||
struct inode *inode = d_backing_inode(dentry);
|
||||
const struct cred *cred = current_cred();
|
||||
|
||||
if (grsec_enable_link && !uid_eq(cred->fsuid, inode->i_uid) &&
|
||||
(!d_is_reg(dentry) || is_privileged_binary(dentry) ||
|
||||
(inode_permission(inode, MAY_READ | MAY_WRITE))) &&
|
||||
!capable(CAP_FOWNER) && gr_is_global_nonroot(cred->uid)) {
|
||||
gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, GR_GLOBAL_UID(inode->i_uid), GR_GLOBAL_GID(inode->i_gid), to->name);
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
340
grsecurity/grsec_log.c
Normal file
340
grsecurity/grsec_log.c
Normal file
@ -0,0 +1,340 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
#ifdef CONFIG_TREE_PREEMPT_RCU
|
||||
#define DISABLE_PREEMPT() preempt_disable()
|
||||
#define ENABLE_PREEMPT() preempt_enable()
|
||||
#else
|
||||
#define DISABLE_PREEMPT()
|
||||
#define ENABLE_PREEMPT()
|
||||
#endif
|
||||
|
||||
#define BEGIN_LOCKS(x) \
|
||||
DISABLE_PREEMPT(); \
|
||||
rcu_read_lock(); \
|
||||
read_lock(&tasklist_lock); \
|
||||
read_lock(&grsec_exec_file_lock); \
|
||||
if (x != GR_DO_AUDIT) \
|
||||
spin_lock(&grsec_alert_lock); \
|
||||
else \
|
||||
spin_lock(&grsec_audit_lock)
|
||||
|
||||
#define END_LOCKS(x) \
|
||||
if (x != GR_DO_AUDIT) \
|
||||
spin_unlock(&grsec_alert_lock); \
|
||||
else \
|
||||
spin_unlock(&grsec_audit_lock); \
|
||||
read_unlock(&grsec_exec_file_lock); \
|
||||
read_unlock(&tasklist_lock); \
|
||||
rcu_read_unlock(); \
|
||||
ENABLE_PREEMPT(); \
|
||||
if (x == GR_DONT_AUDIT) \
|
||||
gr_handle_alertkill(current)
|
||||
|
||||
enum {
|
||||
FLOODING,
|
||||
NO_FLOODING
|
||||
};
|
||||
|
||||
extern char *gr_alert_log_fmt;
|
||||
extern char *gr_audit_log_fmt;
|
||||
extern char *gr_alert_log_buf;
|
||||
extern char *gr_audit_log_buf;
|
||||
|
||||
static int gr_log_start(int audit)
|
||||
{
|
||||
char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
|
||||
char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
|
||||
char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
|
||||
#if (CONFIG_GRKERNSEC_FLOODTIME > 0 && CONFIG_GRKERNSEC_FLOODBURST > 0)
|
||||
unsigned long curr_secs = get_seconds();
|
||||
|
||||
if (audit == GR_DO_AUDIT)
|
||||
goto set_fmt;
|
||||
|
||||
if (!grsec_alert_wtime || time_after(curr_secs, grsec_alert_wtime + CONFIG_GRKERNSEC_FLOODTIME)) {
|
||||
grsec_alert_wtime = curr_secs;
|
||||
grsec_alert_fyet = 0;
|
||||
} else if (time_before_eq(curr_secs, grsec_alert_wtime + CONFIG_GRKERNSEC_FLOODTIME)
|
||||
&& (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
|
||||
grsec_alert_fyet++;
|
||||
} else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
|
||||
grsec_alert_wtime = curr_secs;
|
||||
grsec_alert_fyet++;
|
||||
printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
|
||||
return FLOODING;
|
||||
}
|
||||
else return FLOODING;
|
||||
|
||||
set_fmt:
|
||||
#endif
|
||||
memset(buf, 0, PAGE_SIZE);
|
||||
if (current->signal->curr_ip && gr_acl_is_enabled()) {
|
||||
sprintf(fmt, "%s%s", loglevel, "grsec: From %pI4: (%.64s:%c:%.950s) ");
|
||||
snprintf(buf, PAGE_SIZE - 1, fmt, ¤t->signal->curr_ip, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
|
||||
} else if (current->signal->curr_ip) {
|
||||
sprintf(fmt, "%s%s", loglevel, "grsec: From %pI4: ");
|
||||
snprintf(buf, PAGE_SIZE - 1, fmt, ¤t->signal->curr_ip);
|
||||
} else if (gr_acl_is_enabled()) {
|
||||
sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
|
||||
snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
|
||||
} else {
|
||||
sprintf(fmt, "%s%s", loglevel, "grsec: ");
|
||||
strcpy(buf, fmt);
|
||||
}
|
||||
|
||||
return NO_FLOODING;
|
||||
}
|
||||
|
||||
static void gr_log_middle(int audit, const char *msg, va_list ap)
|
||||
__attribute__ ((format (printf, 2, 0)));
|
||||
|
||||
static void gr_log_middle(int audit, const char *msg, va_list ap)
|
||||
{
|
||||
char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
|
||||
unsigned int len = strlen(buf);
|
||||
|
||||
vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void gr_log_middle_varargs(int audit, const char *msg, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
static void gr_log_middle_varargs(int audit, const char *msg, ...)
|
||||
{
|
||||
char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
|
||||
unsigned int len = strlen(buf);
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msg);
|
||||
vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
|
||||
va_end(ap);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void gr_log_end(int audit, int append_default)
|
||||
{
|
||||
char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
|
||||
if (append_default) {
|
||||
struct task_struct *task = current;
|
||||
struct task_struct *parent = task->real_parent;
|
||||
const struct cred *cred = __task_cred(task);
|
||||
const struct cred *pcred = __task_cred(parent);
|
||||
unsigned int len = strlen(buf);
|
||||
|
||||
snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, gr_task_fullpath(task), task->comm, task_pid_nr(task), GR_GLOBAL_UID(cred->uid), GR_GLOBAL_UID(cred->euid), GR_GLOBAL_GID(cred->gid), GR_GLOBAL_GID(cred->egid), gr_parent_task_fullpath(task), parent->comm, task_pid_nr(task->real_parent), GR_GLOBAL_UID(pcred->uid), GR_GLOBAL_UID(pcred->euid), GR_GLOBAL_GID(pcred->gid), GR_GLOBAL_GID(pcred->egid));
|
||||
}
|
||||
|
||||
printk("%s\n", buf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
|
||||
{
|
||||
int logtype;
|
||||
char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
|
||||
char *str1 = NULL, *str2 = NULL, *str3 = NULL;
|
||||
void *voidptr = NULL;
|
||||
int num1 = 0, num2 = 0;
|
||||
unsigned long ulong1 = 0, ulong2 = 0;
|
||||
struct dentry *dentry = NULL;
|
||||
struct vfsmount *mnt = NULL;
|
||||
struct file *file = NULL;
|
||||
struct task_struct *task = NULL;
|
||||
struct vm_area_struct *vma = NULL;
|
||||
const struct cred *cred, *pcred;
|
||||
va_list ap;
|
||||
|
||||
BEGIN_LOCKS(audit);
|
||||
logtype = gr_log_start(audit);
|
||||
if (logtype == FLOODING) {
|
||||
END_LOCKS(audit);
|
||||
return;
|
||||
}
|
||||
va_start(ap, argtypes);
|
||||
switch (argtypes) {
|
||||
case GR_TTYSNIFF:
|
||||
task = va_arg(ap, struct task_struct *);
|
||||
gr_log_middle_varargs(audit, msg, &task->signal->curr_ip, gr_task_fullpath0(task), task->comm, task_pid_nr(task), gr_parent_task_fullpath0(task), task->real_parent->comm, task_pid_nr(task->real_parent));
|
||||
break;
|
||||
case GR_SYSCTL_HIDDEN:
|
||||
str1 = va_arg(ap, char *);
|
||||
gr_log_middle_varargs(audit, msg, result, str1);
|
||||
break;
|
||||
case GR_RBAC:
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
|
||||
break;
|
||||
case GR_RBAC_STR:
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
str1 = va_arg(ap, char *);
|
||||
gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
|
||||
break;
|
||||
case GR_STR_RBAC:
|
||||
str1 = va_arg(ap, char *);
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
|
||||
break;
|
||||
case GR_RBAC_MODE2:
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
str1 = va_arg(ap, char *);
|
||||
str2 = va_arg(ap, char *);
|
||||
gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
|
||||
break;
|
||||
case GR_RBAC_MODE3:
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
str1 = va_arg(ap, char *);
|
||||
str2 = va_arg(ap, char *);
|
||||
str3 = va_arg(ap, char *);
|
||||
gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
|
||||
break;
|
||||
case GR_FILENAME:
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
|
||||
break;
|
||||
case GR_STR_FILENAME:
|
||||
str1 = va_arg(ap, char *);
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
|
||||
break;
|
||||
case GR_FILENAME_STR:
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
str1 = va_arg(ap, char *);
|
||||
gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
|
||||
break;
|
||||
case GR_FILENAME_TWO_INT:
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
num1 = va_arg(ap, int);
|
||||
num2 = va_arg(ap, int);
|
||||
gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
|
||||
break;
|
||||
case GR_FILENAME_TWO_INT_STR:
|
||||
dentry = va_arg(ap, struct dentry *);
|
||||
mnt = va_arg(ap, struct vfsmount *);
|
||||
num1 = va_arg(ap, int);
|
||||
num2 = va_arg(ap, int);
|
||||
str1 = va_arg(ap, char *);
|
||||
gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
|
||||
break;
|
||||
case GR_TEXTREL:
|
||||
str1 = va_arg(ap, char *);
|
||||
file = va_arg(ap, struct file *);
|
||||
ulong1 = va_arg(ap, unsigned long);
|
||||
ulong2 = va_arg(ap, unsigned long);
|
||||
gr_log_middle_varargs(audit, msg, str1, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
|
||||
break;
|
||||
case GR_PTRACE:
|
||||
task = va_arg(ap, struct task_struct *);
|
||||
gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_path.dentry, task->exec_file->f_path.mnt) : "(none)", task->comm, task_pid_nr(task));
|
||||
break;
|
||||
case GR_RESOURCE:
|
||||
task = va_arg(ap, struct task_struct *);
|
||||
cred = __task_cred(task);
|
||||
pcred = __task_cred(task->real_parent);
|
||||
ulong1 = va_arg(ap, unsigned long);
|
||||
str1 = va_arg(ap, char *);
|
||||
ulong2 = va_arg(ap, unsigned long);
|
||||
gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task_pid_nr(task), GR_GLOBAL_UID(cred->uid), GR_GLOBAL_UID(cred->euid), GR_GLOBAL_GID(cred->gid), GR_GLOBAL_GID(cred->egid), gr_parent_task_fullpath(task), task->real_parent->comm, task_pid_nr(task->real_parent), GR_GLOBAL_UID(pcred->uid), GR_GLOBAL_UID(pcred->euid), GR_GLOBAL_GID(pcred->gid), GR_GLOBAL_GID(pcred->egid));
|
||||
break;
|
||||
case GR_CAP:
|
||||
task = va_arg(ap, struct task_struct *);
|
||||
cred = __task_cred(task);
|
||||
pcred = __task_cred(task->real_parent);
|
||||
str1 = va_arg(ap, char *);
|
||||
gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task_pid_nr(task), GR_GLOBAL_UID(cred->uid), GR_GLOBAL_UID(cred->euid), GR_GLOBAL_GID(cred->gid), GR_GLOBAL_GID(cred->egid), gr_parent_task_fullpath(task), task->real_parent->comm, task_pid_nr(task->real_parent), GR_GLOBAL_UID(pcred->uid), GR_GLOBAL_UID(pcred->euid), GR_GLOBAL_GID(pcred->gid), GR_GLOBAL_GID(pcred->egid));
|
||||
break;
|
||||
case GR_SIG:
|
||||
str1 = va_arg(ap, char *);
|
||||
voidptr = va_arg(ap, void *);
|
||||
gr_log_middle_varargs(audit, msg, str1, voidptr);
|
||||
break;
|
||||
case GR_SIG2:
|
||||
task = va_arg(ap, struct task_struct *);
|
||||
cred = __task_cred(task);
|
||||
pcred = __task_cred(task->real_parent);
|
||||
num1 = va_arg(ap, int);
|
||||
gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task_pid_nr(task), GR_GLOBAL_UID(cred->uid), GR_GLOBAL_UID(cred->euid), GR_GLOBAL_GID(cred->gid), GR_GLOBAL_GID(cred->egid), gr_parent_task_fullpath0(task), task->real_parent->comm, task_pid_nr(task->real_parent), GR_GLOBAL_UID(pcred->uid), GR_GLOBAL_UID(pcred->euid), GR_GLOBAL_GID(pcred->gid), GR_GLOBAL_GID(pcred->egid));
|
||||
break;
|
||||
case GR_CRASH1:
|
||||
task = va_arg(ap, struct task_struct *);
|
||||
cred = __task_cred(task);
|
||||
pcred = __task_cred(task->real_parent);
|
||||
ulong1 = va_arg(ap, unsigned long);
|
||||
gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task_pid_nr(task), GR_GLOBAL_UID(cred->uid), GR_GLOBAL_UID(cred->euid), GR_GLOBAL_GID(cred->gid), GR_GLOBAL_GID(cred->egid), gr_parent_task_fullpath(task), task->real_parent->comm, task_pid_nr(task->real_parent), GR_GLOBAL_UID(pcred->uid), GR_GLOBAL_UID(pcred->euid), GR_GLOBAL_GID(pcred->gid), GR_GLOBAL_GID(pcred->egid), GR_GLOBAL_UID(cred->uid), ulong1);
|
||||
break;
|
||||
case GR_CRASH2:
|
||||
task = va_arg(ap, struct task_struct *);
|
||||
cred = __task_cred(task);
|
||||
pcred = __task_cred(task->real_parent);
|
||||
ulong1 = va_arg(ap, unsigned long);
|
||||
gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task_pid_nr(task), GR_GLOBAL_UID(cred->uid), GR_GLOBAL_UID(cred->euid), GR_GLOBAL_GID(cred->gid), GR_GLOBAL_GID(cred->egid), gr_parent_task_fullpath(task), task->real_parent->comm, task_pid_nr(task->real_parent), GR_GLOBAL_UID(pcred->uid), GR_GLOBAL_UID(pcred->euid), GR_GLOBAL_GID(pcred->gid), GR_GLOBAL_GID(pcred->egid), ulong1);
|
||||
break;
|
||||
case GR_RWXMAP:
|
||||
file = va_arg(ap, struct file *);
|
||||
gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>");
|
||||
break;
|
||||
case GR_RWXMAPVMA:
|
||||
vma = va_arg(ap, struct vm_area_struct *);
|
||||
if (vma->vm_file)
|
||||
str1 = gr_to_filename(vma->vm_file->f_path.dentry, vma->vm_file->f_path.mnt);
|
||||
else if (vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP))
|
||||
str1 = "<stack>";
|
||||
else if (vma->vm_start <= current->mm->brk &&
|
||||
vma->vm_end >= current->mm->start_brk)
|
||||
str1 = "<heap>";
|
||||
else
|
||||
str1 = "<anonymous mapping>";
|
||||
gr_log_middle_varargs(audit, msg, str1);
|
||||
break;
|
||||
case GR_PSACCT:
|
||||
{
|
||||
unsigned int wday, cday;
|
||||
__u8 whr, chr;
|
||||
__u8 wmin, cmin;
|
||||
__u8 wsec, csec;
|
||||
|
||||
task = va_arg(ap, struct task_struct *);
|
||||
wday = va_arg(ap, unsigned int);
|
||||
cday = va_arg(ap, unsigned int);
|
||||
whr = va_arg(ap, int);
|
||||
chr = va_arg(ap, int);
|
||||
wmin = va_arg(ap, int);
|
||||
cmin = va_arg(ap, int);
|
||||
wsec = va_arg(ap, int);
|
||||
csec = va_arg(ap, int);
|
||||
ulong1 = va_arg(ap, unsigned long);
|
||||
cred = __task_cred(task);
|
||||
pcred = __task_cred(task->real_parent);
|
||||
|
||||
gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task_pid_nr(task), &task->signal->curr_ip, tty_name(task->signal->tty), GR_GLOBAL_UID(cred->uid), GR_GLOBAL_UID(cred->euid), GR_GLOBAL_GID(cred->gid), GR_GLOBAL_GID(cred->egid), wday, whr, wmin, wsec, cday, chr, cmin, csec, (task->flags & PF_SIGNALED) ? "killed by signal" : "exited", ulong1, gr_parent_task_fullpath(task), task->real_parent->comm, task_pid_nr(task->real_parent), &task->real_parent->signal->curr_ip, tty_name(task->real_parent->signal->tty), GR_GLOBAL_UID(pcred->uid), GR_GLOBAL_UID(pcred->euid), GR_GLOBAL_GID(pcred->gid), GR_GLOBAL_GID(pcred->egid));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gr_log_middle(audit, msg, ap);
|
||||
}
|
||||
va_end(ap);
|
||||
// these don't need DEFAULTSECARGS printed on the end
|
||||
if (argtypes == GR_CRASH1 || argtypes == GR_CRASH2)
|
||||
gr_log_end(audit, 0);
|
||||
else
|
||||
gr_log_end(audit, 1);
|
||||
END_LOCKS(audit);
|
||||
}
|
48
grsecurity/grsec_mem.c
Normal file
48
grsecurity/grsec_mem.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
void gr_handle_msr_write(void)
|
||||
{
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_MSRWRITE_MSG);
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gr_handle_msr_write);
|
||||
|
||||
void
|
||||
gr_handle_ioperm(void)
|
||||
{
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_iopl(void)
|
||||
{
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_mem_readwrite(u64 from, u64 to)
|
||||
{
|
||||
gr_log_two_u64(GR_DONT_AUDIT, GR_MEM_READWRITE_MSG, from, to);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_handle_vm86(void)
|
||||
{
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_VM86_MSG);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_log_badprocpid(const char *entry)
|
||||
{
|
||||
gr_log_str(GR_DONT_AUDIT, GR_BADPROCPID_MSG, entry);
|
||||
return;
|
||||
}
|
65
grsecurity/grsec_mount.c
Normal file
65
grsecurity/grsec_mount.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
void
|
||||
gr_log_remount(const char *devname, const int retval)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
|
||||
if (grsec_enable_mount && (retval >= 0))
|
||||
gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_log_unmount(const char *devname, const int retval)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
|
||||
if (grsec_enable_mount && (retval >= 0))
|
||||
gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_log_mount(const char *from, struct path *to, const int retval)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
|
||||
if (grsec_enable_mount && (retval >= 0))
|
||||
gr_log_str_fs(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from ? from : "none", to->dentry, to->mnt);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_rofs_mount(struct dentry *dentry, struct vfsmount *mnt, int mnt_flags)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_ROFS
|
||||
if (grsec_enable_rofs && !(mnt_flags & MNT_READONLY)) {
|
||||
gr_log_fs_generic(GR_DO_AUDIT, GR_ROFS_MOUNT_MSG, dentry, mnt);
|
||||
return -EPERM;
|
||||
} else
|
||||
return 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_rofs_blockwrite(struct dentry *dentry, struct vfsmount *mnt, int acc_mode)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_ROFS
|
||||
struct inode *inode = d_backing_inode(dentry);
|
||||
|
||||
if (grsec_enable_rofs && (acc_mode & MAY_WRITE) &&
|
||||
inode && (S_ISBLK(inode->i_mode) || (S_ISCHR(inode->i_mode) && imajor(inode) == RAW_MAJOR))) {
|
||||
gr_log_fs_generic(GR_DO_AUDIT, GR_ROFS_BLOCKWRITE_MSG, dentry, mnt);
|
||||
return -EPERM;
|
||||
} else
|
||||
return 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
47
grsecurity/grsec_pax.c
Normal file
47
grsecurity/grsec_pax.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/grsecurity.h>
|
||||
|
||||
void
|
||||
gr_log_textrel(struct vm_area_struct * vma, bool is_textrel_rw)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
|
||||
if (grsec_enable_log_rwxmaps)
|
||||
gr_log_textrel_ulong_ulong(GR_DONT_AUDIT, GR_TEXTREL_AUDIT_MSG,
|
||||
is_textrel_rw ? "executable to writable" : "writable to executable",
|
||||
vma->vm_file, vma->vm_start, vma->vm_pgoff);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void gr_log_ptgnustack(struct file *file)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
|
||||
if (grsec_enable_log_rwxmaps)
|
||||
gr_log_rwxmap(GR_DONT_AUDIT, GR_PTGNUSTACK_MSG, file);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_log_rwxmmap(struct file *file)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
|
||||
if (grsec_enable_log_rwxmaps)
|
||||
gr_log_rwxmap(GR_DONT_AUDIT, GR_RWXMMAP_MSG, file);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_log_rwxmprotect(struct vm_area_struct *vma)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
|
||||
if (grsec_enable_log_rwxmaps)
|
||||
gr_log_rwxmap_vma(GR_DONT_AUDIT, GR_RWXMPROTECT_MSG, vma);
|
||||
#endif
|
||||
return;
|
||||
}
|
20
grsecurity/grsec_proc.c
Normal file
20
grsecurity/grsec_proc.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
int gr_proc_is_restricted(void)
|
||||
{
|
||||
#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
|
||||
const struct cred *cred = current_cred();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC_PROC_USER
|
||||
if (!uid_eq(cred->fsuid, GLOBAL_ROOT_UID))
|
||||
return -EACCES;
|
||||
#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
|
||||
if (!uid_eq(cred->fsuid, GLOBAL_ROOT_UID) && !in_group_p(grsec_proc_gid))
|
||||
return -EACCES;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
30
grsecurity/grsec_ptrace.c
Normal file
30
grsecurity/grsec_ptrace.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/security.h>
|
||||
|
||||
void
|
||||
gr_audit_ptrace(struct task_struct *task)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE
|
||||
if (grsec_enable_audit_ptrace)
|
||||
gr_log_ptrace(GR_DO_AUDIT, GR_PTRACE_AUDIT_MSG, task);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_ptrace_readexec(struct file *file, int unsafe_flags)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_PTRACE_READEXEC
|
||||
const struct dentry *dentry = file->f_path.dentry;
|
||||
const struct vfsmount *mnt = file->f_path.mnt;
|
||||
|
||||
if (grsec_enable_ptrace_readexec && (unsafe_flags & LSM_UNSAFE_PTRACE) &&
|
||||
(inode_permission(d_backing_inode(dentry), MAY_READ) || !gr_acl_handle_open(dentry, mnt, MAY_READ))) {
|
||||
gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_READEXEC_MSG, dentry, mnt);
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
248
grsecurity/grsec_sig.c
Normal file
248
grsecurity/grsec_sig.c
Normal file
@ -0,0 +1,248 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
char *signames[] = {
|
||||
[SIGSEGV] = "Segmentation fault",
|
||||
[SIGILL] = "Illegal instruction",
|
||||
[SIGABRT] = "Abort",
|
||||
[SIGBUS] = "Invalid alignment/Bus error"
|
||||
};
|
||||
|
||||
void
|
||||
gr_log_signal(const int sig, const void *addr, const struct task_struct *t)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_SIGNAL
|
||||
if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
|
||||
(sig == SIGABRT) || (sig == SIGBUS))) {
|
||||
if (task_pid_nr(t) == task_pid_nr(current)) {
|
||||
gr_log_sig_addr(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, signames[sig], addr);
|
||||
} else {
|
||||
gr_log_sig_task(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_signal(const struct task_struct *p, const int sig)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
/* ignore the 0 signal for protected task checks */
|
||||
if (task_pid_nr(current) > 1 && sig && gr_check_protected_task(p)) {
|
||||
gr_log_sig_task(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
|
||||
return -EPERM;
|
||||
} else if (gr_pid_is_chrooted((struct task_struct *)p)) {
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
|
||||
|
||||
int gr_fake_force_sig(int sig, struct task_struct *t)
|
||||
{
|
||||
unsigned long int flags;
|
||||
int ret, blocked, ignored;
|
||||
struct k_sigaction *action;
|
||||
|
||||
spin_lock_irqsave(&t->sighand->siglock, flags);
|
||||
action = &t->sighand->action[sig-1];
|
||||
ignored = action->sa.sa_handler == SIG_IGN;
|
||||
blocked = sigismember(&t->blocked, sig);
|
||||
if (blocked || ignored) {
|
||||
action->sa.sa_handler = SIG_DFL;
|
||||
if (blocked) {
|
||||
sigdelset(&t->blocked, sig);
|
||||
recalc_sigpending_and_wake(t);
|
||||
}
|
||||
}
|
||||
if (action->sa.sa_handler == SIG_DFL)
|
||||
t->signal->flags &= ~SIGNAL_UNKILLABLE;
|
||||
ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
|
||||
|
||||
spin_unlock_irqrestore(&t->sighand->siglock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define GR_USER_BAN_TIME (15 * 60)
|
||||
#define GR_DAEMON_BRUTE_TIME (30 * 60)
|
||||
|
||||
void gr_handle_brute_attach(int dumpable)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_BRUTE
|
||||
struct task_struct *p = current;
|
||||
kuid_t uid = GLOBAL_ROOT_UID;
|
||||
int is_priv = 0;
|
||||
int daemon = 0;
|
||||
|
||||
if (!grsec_enable_brute)
|
||||
return;
|
||||
|
||||
if (is_privileged_binary(p->mm->exe_file->f_path.dentry))
|
||||
is_priv = 1;
|
||||
|
||||
rcu_read_lock();
|
||||
read_lock(&tasklist_lock);
|
||||
read_lock(&grsec_exec_file_lock);
|
||||
if (!is_priv && p->real_parent && gr_is_same_file(p->real_parent->exec_file, p->exec_file)) {
|
||||
p->real_parent->brute_expires = get_seconds() + GR_DAEMON_BRUTE_TIME;
|
||||
p->real_parent->brute = 1;
|
||||
daemon = 1;
|
||||
} else {
|
||||
const struct cred *cred = __task_cred(p), *cred2;
|
||||
struct task_struct *tsk, *tsk2;
|
||||
|
||||
if (dumpable != SUID_DUMP_USER && gr_is_global_nonroot(cred->uid)) {
|
||||
struct user_struct *user;
|
||||
|
||||
uid = cred->uid;
|
||||
|
||||
/* this is put upon execution past expiration */
|
||||
user = find_user(uid);
|
||||
if (user == NULL)
|
||||
goto unlock;
|
||||
user->sugid_banned = 1;
|
||||
user->sugid_ban_expires = get_seconds() + GR_USER_BAN_TIME;
|
||||
if (user->sugid_ban_expires == ~0UL)
|
||||
user->sugid_ban_expires--;
|
||||
|
||||
/* only kill other threads of the same binary, from the same user */
|
||||
do_each_thread(tsk2, tsk) {
|
||||
cred2 = __task_cred(tsk);
|
||||
if (tsk != p && uid_eq(cred2->uid, uid) && gr_is_same_file(tsk->exec_file, p->exec_file))
|
||||
gr_fake_force_sig(SIGKILL, tsk);
|
||||
} while_each_thread(tsk2, tsk);
|
||||
}
|
||||
}
|
||||
unlock:
|
||||
read_unlock(&grsec_exec_file_lock);
|
||||
read_unlock(&tasklist_lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (gr_is_global_nonroot(uid))
|
||||
gr_log_fs_int2(GR_DONT_AUDIT, GR_BRUTE_SUID_MSG, p->exec_file->f_path.dentry, p->exec_file->f_path.mnt, GR_GLOBAL_UID(uid), GR_USER_BAN_TIME / 60);
|
||||
else if (daemon)
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_BRUTE_DAEMON_MSG);
|
||||
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void gr_handle_brute_check(void)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_BRUTE
|
||||
struct task_struct *p = current;
|
||||
|
||||
if (unlikely(p->brute)) {
|
||||
if (!grsec_enable_brute)
|
||||
p->brute = 0;
|
||||
else if (time_before(get_seconds(), p->brute_expires))
|
||||
msleep(30 * 1000);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void gr_handle_kernel_exploit(void)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_KERN_LOCKOUT
|
||||
static unsigned int num_banned_users __read_only;
|
||||
const struct cred *cred;
|
||||
struct task_struct *tsk, *tsk2;
|
||||
struct user_struct *user;
|
||||
kuid_t uid;
|
||||
|
||||
if (in_irq() || in_serving_softirq() || in_nmi())
|
||||
panic("grsec: halting the system due to suspicious kernel crash caused in interrupt context");
|
||||
|
||||
uid = current_uid();
|
||||
|
||||
if (gr_is_global_root(uid))
|
||||
panic("grsec: halting the system due to suspicious kernel crash caused by root");
|
||||
else {
|
||||
pax_open_kernel();
|
||||
num_banned_users++;
|
||||
pax_close_kernel();
|
||||
if (num_banned_users > 8)
|
||||
panic("grsec: halting the system due to suspicious kernel crash caused by a large number of different users");
|
||||
|
||||
/* kill all the processes of this user, hold a reference
|
||||
to their creds struct, and prevent them from creating
|
||||
another process until system reset
|
||||
*/
|
||||
printk(KERN_ALERT "grsec: banning user with uid %u until system restart for suspicious kernel crash\n",
|
||||
GR_GLOBAL_UID(uid));
|
||||
/* we intentionally leak this ref */
|
||||
user = get_uid(current->cred->user);
|
||||
if (user)
|
||||
user->kernel_banned = 1;
|
||||
|
||||
/* kill all processes of this user */
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_thread(tsk2, tsk) {
|
||||
cred = __task_cred(tsk);
|
||||
if (uid_eq(cred->uid, uid))
|
||||
gr_fake_force_sig(SIGKILL, tsk);
|
||||
} while_each_thread(tsk2, tsk);
|
||||
read_unlock(&tasklist_lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC_BRUTE
|
||||
static bool sugid_ban_expired(struct user_struct *user)
|
||||
{
|
||||
if (user->sugid_ban_expires != ~0UL && time_after_eq(get_seconds(), user->sugid_ban_expires)) {
|
||||
user->sugid_banned = 0;
|
||||
user->sugid_ban_expires = 0;
|
||||
free_uid(user);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
int gr_process_kernel_exec_ban(void)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_KERN_LOCKOUT
|
||||
if (unlikely(current->cred->user->kernel_banned))
|
||||
return -EPERM;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gr_process_kernel_setuid_ban(struct user_struct *user)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_KERN_LOCKOUT
|
||||
if (unlikely(user->kernel_banned))
|
||||
gr_fake_force_sig(SIGKILL, current);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gr_process_sugid_exec_ban(const struct linux_binprm *bprm)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_BRUTE
|
||||
struct user_struct *user = current->cred->user;
|
||||
if (unlikely(user->sugid_banned)) {
|
||||
if (sugid_ban_expired(user))
|
||||
return 0;
|
||||
/* disallow execution of suid/sgid binaries only */
|
||||
else if (is_privileged_binary(bprm->file->f_path.dentry))
|
||||
return -EPERM;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
244
grsecurity/grsec_sock.c
Normal file
244
grsecurity/grsec_sock.c
Normal file
@ -0,0 +1,244 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/ip.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/inet_sock.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/gracl.h>
|
||||
|
||||
extern int gr_search_udp_recvmsg(struct sock *sk, const struct sk_buff *skb);
|
||||
extern int gr_search_udp_sendmsg(struct sock *sk, struct sockaddr_in *addr);
|
||||
|
||||
EXPORT_SYMBOL_GPL(gr_search_udp_recvmsg);
|
||||
EXPORT_SYMBOL_GPL(gr_search_udp_sendmsg);
|
||||
|
||||
#ifdef CONFIG_UNIX_MODULE
|
||||
EXPORT_SYMBOL_GPL(gr_acl_handle_unix);
|
||||
EXPORT_SYMBOL_GPL(gr_acl_handle_mknod);
|
||||
EXPORT_SYMBOL_GPL(gr_handle_chroot_unix);
|
||||
EXPORT_SYMBOL_GPL(gr_handle_create);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
#define gr_conn_table_size 32749
|
||||
struct conn_table_entry {
|
||||
struct conn_table_entry *next;
|
||||
struct signal_struct *sig;
|
||||
};
|
||||
|
||||
struct conn_table_entry *gr_conn_table[gr_conn_table_size];
|
||||
DEFINE_SPINLOCK(gr_conn_table_lock);
|
||||
|
||||
extern const char * gr_socktype_to_name(unsigned char type);
|
||||
extern const char * gr_proto_to_name(unsigned char proto);
|
||||
extern const char * gr_sockfamily_to_name(unsigned char family);
|
||||
|
||||
static int
|
||||
conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
|
||||
{
|
||||
return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
|
||||
}
|
||||
|
||||
static int
|
||||
conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
|
||||
__u16 sport, __u16 dport)
|
||||
{
|
||||
if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
|
||||
sig->gr_sport == sport && sig->gr_dport == dport))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
|
||||
{
|
||||
struct conn_table_entry **match;
|
||||
unsigned int index;
|
||||
|
||||
index = conn_hash(sig->gr_saddr, sig->gr_daddr,
|
||||
sig->gr_sport, sig->gr_dport,
|
||||
gr_conn_table_size);
|
||||
|
||||
newent->sig = sig;
|
||||
|
||||
match = &gr_conn_table[index];
|
||||
newent->next = *match;
|
||||
*match = newent;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
|
||||
{
|
||||
struct conn_table_entry *match, *last = NULL;
|
||||
unsigned int index;
|
||||
|
||||
index = conn_hash(sig->gr_saddr, sig->gr_daddr,
|
||||
sig->gr_sport, sig->gr_dport,
|
||||
gr_conn_table_size);
|
||||
|
||||
match = gr_conn_table[index];
|
||||
while (match && !conn_match(match->sig,
|
||||
sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
|
||||
sig->gr_dport)) {
|
||||
last = match;
|
||||
match = match->next;
|
||||
}
|
||||
|
||||
if (match) {
|
||||
if (last)
|
||||
last->next = match->next;
|
||||
else
|
||||
gr_conn_table[index] = NULL;
|
||||
kfree(match);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
|
||||
__u16 sport, __u16 dport)
|
||||
{
|
||||
struct conn_table_entry *match;
|
||||
unsigned int index;
|
||||
|
||||
index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
|
||||
|
||||
match = gr_conn_table[index];
|
||||
while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
|
||||
match = match->next;
|
||||
|
||||
if (match)
|
||||
return match->sig;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void gr_update_task_in_ip_table(const struct inet_sock *inet)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
struct signal_struct *sig = current->signal;
|
||||
struct conn_table_entry *newent;
|
||||
|
||||
newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
|
||||
if (newent == NULL)
|
||||
return;
|
||||
/* no bh lock needed since we are called with bh disabled */
|
||||
spin_lock(&gr_conn_table_lock);
|
||||
gr_del_task_from_ip_table_nolock(sig);
|
||||
sig->gr_saddr = inet->inet_rcv_saddr;
|
||||
sig->gr_daddr = inet->inet_daddr;
|
||||
sig->gr_sport = inet->inet_sport;
|
||||
sig->gr_dport = inet->inet_dport;
|
||||
gr_add_to_task_ip_table_nolock(sig, newent);
|
||||
spin_unlock(&gr_conn_table_lock);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void gr_del_task_from_ip_table(struct task_struct *task)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
spin_lock_bh(&gr_conn_table_lock);
|
||||
gr_del_task_from_ip_table_nolock(task->signal);
|
||||
spin_unlock_bh(&gr_conn_table_lock);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
gr_attach_curr_ip(const struct sock *sk)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
struct signal_struct *p, *set;
|
||||
const struct inet_sock *inet = inet_sk(sk);
|
||||
|
||||
if (unlikely(sk->sk_protocol != IPPROTO_TCP))
|
||||
return;
|
||||
|
||||
set = current->signal;
|
||||
|
||||
spin_lock_bh(&gr_conn_table_lock);
|
||||
p = gr_lookup_task_ip_table(inet->inet_daddr, inet->inet_rcv_saddr,
|
||||
inet->inet_dport, inet->inet_sport);
|
||||
if (unlikely(p != NULL)) {
|
||||
set->curr_ip = p->curr_ip;
|
||||
set->used_accept = 1;
|
||||
gr_del_task_from_ip_table_nolock(p);
|
||||
spin_unlock_bh(&gr_conn_table_lock);
|
||||
return;
|
||||
}
|
||||
spin_unlock_bh(&gr_conn_table_lock);
|
||||
|
||||
set->curr_ip = inet->inet_daddr;
|
||||
set->used_accept = 1;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_sock_all(const int family, const int type, const int protocol)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
|
||||
if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
|
||||
(family != AF_UNIX)) {
|
||||
if (family == AF_INET)
|
||||
gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, gr_sockfamily_to_name(family), gr_socktype_to_name(type), gr_proto_to_name(protocol));
|
||||
else
|
||||
gr_log_str2_int(GR_DONT_AUDIT, GR_SOCK_NOINET_MSG, gr_sockfamily_to_name(family), gr_socktype_to_name(type), protocol);
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_sock_server(const struct sockaddr *sck)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
|
||||
if (grsec_enable_socket_server &&
|
||||
in_group_p(grsec_socket_server_gid) &&
|
||||
sck && (sck->sa_family != AF_UNIX) &&
|
||||
(sck->sa_family != AF_LOCAL)) {
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_sock_server_other(const struct sock *sck)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
|
||||
if (grsec_enable_socket_server &&
|
||||
in_group_p(grsec_socket_server_gid) &&
|
||||
sck && (sck->sk_family != AF_UNIX) &&
|
||||
(sck->sk_family != AF_LOCAL)) {
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gr_handle_sock_client(const struct sockaddr *sck)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
|
||||
if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
|
||||
sck && (sck->sa_family != AF_UNIX) &&
|
||||
(sck->sa_family != AF_LOCAL)) {
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
497
grsecurity/grsec_sysctl.c
Normal file
497
grsecurity/grsec_sysctl.c
Normal file
@ -0,0 +1,497 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
int
|
||||
gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_SYSCTL
|
||||
if (dirname == NULL || name == NULL)
|
||||
return 0;
|
||||
if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
|
||||
gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_GRKERNSEC_ROFS) || defined(CONFIG_GRKERNSEC_DENYUSB)
|
||||
static int __maybe_unused __read_only one = 1;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_ROFS) || \
|
||||
defined(CONFIG_GRKERNSEC_DENYUSB)
|
||||
struct ctl_table grsecurity_table[] = {
|
||||
#ifdef CONFIG_GRKERNSEC_SYSCTL
|
||||
#ifdef CONFIG_GRKERNSEC_SYSCTL_DISTRO
|
||||
#ifdef CONFIG_GRKERNSEC_IO
|
||||
{
|
||||
.procname = "disable_priv_io",
|
||||
.data = &grsec_disable_privio,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_LINK
|
||||
{
|
||||
.procname = "linking_restrictions",
|
||||
.data = &grsec_enable_link,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SYMLINKOWN
|
||||
{
|
||||
.procname = "enforce_symlinksifowner",
|
||||
.data = &grsec_enable_symlinkown,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
{
|
||||
.procname = "symlinkown_gid",
|
||||
.data = &grsec_symlinkown_gid,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_BRUTE
|
||||
{
|
||||
.procname = "deter_bruteforce",
|
||||
.data = &grsec_enable_brute,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_FIFO
|
||||
{
|
||||
.procname = "fifo_restrictions",
|
||||
.data = &grsec_enable_fifo,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_PTRACE_READEXEC
|
||||
{
|
||||
.procname = "ptrace_readexec",
|
||||
.data = &grsec_enable_ptrace_readexec,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SETXID
|
||||
{
|
||||
.procname = "consistent_setxid",
|
||||
.data = &grsec_enable_setxid,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_BLACKHOLE
|
||||
{
|
||||
.procname = "ip_blackhole",
|
||||
.data = &grsec_enable_blackhole,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
{
|
||||
.procname = "lastack_retries",
|
||||
.data = &grsec_lastack_retries,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_EXECLOG
|
||||
{
|
||||
.procname = "exec_logging",
|
||||
.data = &grsec_enable_execlog,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG
|
||||
{
|
||||
.procname = "rwxmap_logging",
|
||||
.data = &grsec_enable_log_rwxmaps,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SIGNAL
|
||||
{
|
||||
.procname = "signal_logging",
|
||||
.data = &grsec_enable_signal,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_FORKFAIL
|
||||
{
|
||||
.procname = "forkfail_logging",
|
||||
.data = &grsec_enable_forkfail,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_TIME
|
||||
{
|
||||
.procname = "timechange_logging",
|
||||
.data = &grsec_enable_time,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
|
||||
{
|
||||
.procname = "chroot_deny_shmat",
|
||||
.data = &grsec_enable_chroot_shmat,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
|
||||
{
|
||||
.procname = "chroot_deny_unix",
|
||||
.data = &grsec_enable_chroot_unix,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
|
||||
{
|
||||
.procname = "chroot_deny_mount",
|
||||
.data = &grsec_enable_chroot_mount,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
|
||||
{
|
||||
.procname = "chroot_deny_fchdir",
|
||||
.data = &grsec_enable_chroot_fchdir,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
|
||||
{
|
||||
.procname = "chroot_deny_chroot",
|
||||
.data = &grsec_enable_chroot_double,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
|
||||
{
|
||||
.procname = "chroot_deny_pivot",
|
||||
.data = &grsec_enable_chroot_pivot,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
|
||||
{
|
||||
.procname = "chroot_enforce_chdir",
|
||||
.data = &grsec_enable_chroot_chdir,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
|
||||
{
|
||||
.procname = "chroot_deny_chmod",
|
||||
.data = &grsec_enable_chroot_chmod,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
|
||||
{
|
||||
.procname = "chroot_deny_mknod",
|
||||
.data = &grsec_enable_chroot_mknod,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
|
||||
{
|
||||
.procname = "chroot_restrict_nice",
|
||||
.data = &grsec_enable_chroot_nice,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
|
||||
{
|
||||
.procname = "chroot_execlog",
|
||||
.data = &grsec_enable_chroot_execlog,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
|
||||
{
|
||||
.procname = "chroot_caps",
|
||||
.data = &grsec_enable_chroot_caps,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME
|
||||
{
|
||||
.procname = "chroot_deny_bad_rename",
|
||||
.data = &grsec_enable_chroot_rename,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
|
||||
{
|
||||
.procname = "chroot_deny_sysctl",
|
||||
.data = &grsec_enable_chroot_sysctl,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_TPE
|
||||
{
|
||||
.procname = "tpe",
|
||||
.data = &grsec_enable_tpe,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
{
|
||||
.procname = "tpe_gid",
|
||||
.data = &grsec_tpe_gid,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_TPE_INVERT
|
||||
{
|
||||
.procname = "tpe_invert",
|
||||
.data = &grsec_enable_tpe_invert,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_TPE_ALL
|
||||
{
|
||||
.procname = "tpe_restrict_all",
|
||||
.data = &grsec_enable_tpe_all,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
|
||||
{
|
||||
.procname = "socket_all",
|
||||
.data = &grsec_enable_socket_all,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
{
|
||||
.procname = "socket_all_gid",
|
||||
.data = &grsec_socket_all_gid,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
|
||||
{
|
||||
.procname = "socket_client",
|
||||
.data = &grsec_enable_socket_client,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
{
|
||||
.procname = "socket_client_gid",
|
||||
.data = &grsec_socket_client_gid,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
|
||||
{
|
||||
.procname = "socket_server",
|
||||
.data = &grsec_enable_socket_server,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
{
|
||||
.procname = "socket_server_gid",
|
||||
.data = &grsec_socket_server_gid,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
|
||||
{
|
||||
.procname = "audit_group",
|
||||
.data = &grsec_enable_group,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
{
|
||||
.procname = "audit_gid",
|
||||
.data = &grsec_audit_gid,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
|
||||
{
|
||||
.procname = "audit_chdir",
|
||||
.data = &grsec_enable_chdir,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
|
||||
{
|
||||
.procname = "audit_mount",
|
||||
.data = &grsec_enable_mount,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_DMESG
|
||||
{
|
||||
.procname = "dmesg",
|
||||
.data = &grsec_enable_dmesg,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
|
||||
{
|
||||
.procname = "chroot_findtask",
|
||||
.data = &grsec_enable_chroot_findtask,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_RESLOG
|
||||
{
|
||||
.procname = "resource_logging",
|
||||
.data = &grsec_resource_logging,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE
|
||||
{
|
||||
.procname = "audit_ptrace",
|
||||
.data = &grsec_enable_audit_ptrace,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE
|
||||
{
|
||||
.procname = "harden_ptrace",
|
||||
.data = &grsec_enable_harden_ptrace,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_HARDEN_IPC
|
||||
{
|
||||
.procname = "harden_ipc",
|
||||
.data = &grsec_enable_harden_ipc,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_HARDEN_TTY
|
||||
{
|
||||
.procname = "harden_tty",
|
||||
.data = &grsec_enable_harden_tty,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.procname = "grsec_lock",
|
||||
.data = &grsec_lock,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_GRKERNSEC_ROFS
|
||||
{
|
||||
.procname = "romount_protect",
|
||||
.data = &grsec_enable_rofs,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_minmax_secure,
|
||||
.extra1 = &one,
|
||||
.extra2 = &one,
|
||||
},
|
||||
#endif
|
||||
#if defined(CONFIG_GRKERNSEC_DENYUSB) && !defined(CONFIG_GRKERNSEC_DENYUSB_FORCE)
|
||||
{
|
||||
.procname = "deny_new_usb",
|
||||
.data = &grsec_deny_new_usb,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0600,
|
||||
.proc_handler = &proc_dointvec_secure,
|
||||
},
|
||||
#endif
|
||||
{ }
|
||||
};
|
||||
#endif
|
16
grsecurity/grsec_time.c
Normal file
16
grsecurity/grsec_time.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
void
|
||||
gr_log_timechange(void)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_TIME
|
||||
if (grsec_enable_time)
|
||||
gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(gr_log_timechange);
|
78
grsecurity/grsec_tpe.c
Normal file
78
grsecurity/grsec_tpe.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/grinternal.h>
|
||||
|
||||
extern int gr_acl_tpe_check(void);
|
||||
|
||||
int
|
||||
gr_tpe_allow(const struct file *file)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC
|
||||
struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
|
||||
struct inode *file_inode = d_backing_inode(file->f_path.dentry);
|
||||
const struct cred *cred = current_cred();
|
||||
char *msg = NULL;
|
||||
char *msg2 = NULL;
|
||||
|
||||
// never restrict root
|
||||
if (gr_is_global_root(cred->uid))
|
||||
return 1;
|
||||
|
||||
if (grsec_enable_tpe) {
|
||||
#ifdef CONFIG_GRKERNSEC_TPE_INVERT
|
||||
if (grsec_enable_tpe_invert && !in_group_p(grsec_tpe_gid))
|
||||
msg = "not being in trusted group";
|
||||
else if (!grsec_enable_tpe_invert && in_group_p(grsec_tpe_gid))
|
||||
msg = "being in untrusted group";
|
||||
#else
|
||||
if (in_group_p(grsec_tpe_gid))
|
||||
msg = "being in untrusted group";
|
||||
#endif
|
||||
}
|
||||
if (!msg && gr_acl_tpe_check())
|
||||
msg = "being in untrusted role";
|
||||
|
||||
// not in any affected group/role
|
||||
if (!msg)
|
||||
goto next_check;
|
||||
|
||||
if (gr_is_global_nonroot(inode->i_uid))
|
||||
msg2 = "file in non-root-owned directory";
|
||||
else if (inode->i_mode & S_IWOTH)
|
||||
msg2 = "file in world-writable directory";
|
||||
else if ((inode->i_mode & S_IWGRP) && gr_is_global_nonroot_gid(inode->i_gid))
|
||||
msg2 = "file in group-writable directory";
|
||||
else if (file_inode->i_mode & S_IWOTH)
|
||||
msg2 = "file is world-writable";
|
||||
|
||||
if (msg && msg2) {
|
||||
char fullmsg[70] = {0};
|
||||
snprintf(fullmsg, sizeof(fullmsg)-1, "%s and %s", msg, msg2);
|
||||
gr_log_str_fs(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, fullmsg, file->f_path.dentry, file->f_path.mnt);
|
||||
return 0;
|
||||
}
|
||||
msg = NULL;
|
||||
next_check:
|
||||
#ifdef CONFIG_GRKERNSEC_TPE_ALL
|
||||
if (!grsec_enable_tpe || !grsec_enable_tpe_all)
|
||||
return 1;
|
||||
|
||||
if (gr_is_global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid))
|
||||
msg = "directory not owned by user";
|
||||
else if (inode->i_mode & S_IWOTH)
|
||||
msg = "file in world-writable directory";
|
||||
else if ((inode->i_mode & S_IWGRP) && gr_is_global_nonroot_gid(inode->i_gid))
|
||||
msg = "file in group-writable directory";
|
||||
else if (file_inode->i_mode & S_IWOTH)
|
||||
msg = "file is world-writable";
|
||||
|
||||
if (msg) {
|
||||
gr_log_str_fs(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, msg, file->f_path.dentry, file->f_path.mnt);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return 1;
|
||||
}
|
18
grsecurity/grsec_tty.c
Normal file
18
grsecurity/grsec_tty.c
Normal file
@ -0,0 +1,18 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/grsecurity.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/tty.h>
|
||||
|
||||
int gr_handle_tiocsti(struct tty_struct *tty)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_HARDEN_TTY
|
||||
if (grsec_enable_harden_tty && (current->signal->tty == tty) &&
|
||||
!capable(CAP_SYS_ADMIN)) {
|
||||
gr_log_noargs(GR_DONT_AUDIT, GR_TIOCSTI_MSG);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
15
grsecurity/grsec_usb.c
Normal file
15
grsecurity/grsec_usb.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/grinternal.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
int gr_handle_new_usb(void)
|
||||
{
|
||||
#ifdef CONFIG_GRKERNSEC_DENYUSB
|
||||
if (grsec_deny_new_usb) {
|
||||
printk(KERN_ALERT "grsec: denied insert of new USB device\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gr_handle_new_usb);
|
56
grsecurity/grsum.c
Normal file
56
grsecurity/grsum.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/gracl.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/hash.h>
|
||||
|
||||
#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
|
||||
#error "crypto and sha256 must be built into the kernel"
|
||||
#endif
|
||||
|
||||
int
|
||||
chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
|
||||
{
|
||||
struct crypto_ahash *tfm;
|
||||
struct ahash_request *req;
|
||||
struct scatterlist sg[2];
|
||||
unsigned char temp_sum[GR_SHA_LEN];
|
||||
unsigned long *tmpsumptr = (unsigned long *)temp_sum;
|
||||
unsigned long *sumptr = (unsigned long *)sum;
|
||||
int retval = 1;
|
||||
|
||||
tfm = crypto_alloc_ahash("sha256", 0, CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(tfm))
|
||||
goto out_wipe;
|
||||
|
||||
sg_init_table(sg, 2);
|
||||
sg_set_buf(&sg[0], salt, GR_SALT_LEN);
|
||||
sg_set_buf(&sg[1], entry->pw, strlen((const char *)entry->pw));
|
||||
|
||||
req = ahash_request_alloc(tfm, GFP_KERNEL);
|
||||
if (!req) {
|
||||
crypto_free_ahash(tfm);
|
||||
goto out_wipe;
|
||||
}
|
||||
|
||||
ahash_request_set_callback(req, 0, NULL, NULL);
|
||||
ahash_request_set_crypt(req, sg, temp_sum, GR_SALT_LEN + strlen((const char *)entry->pw));
|
||||
|
||||
if (crypto_ahash_digest(req))
|
||||
goto out_free;
|
||||
|
||||
if (!crypto_memneq(sumptr, tmpsumptr, GR_SHA_LEN))
|
||||
retval = 0;
|
||||
|
||||
out_free:
|
||||
ahash_request_free(req);
|
||||
crypto_free_ahash(tfm);
|
||||
out_wipe:
|
||||
memset(entry->pw, 0, GR_PW_LEN);
|
||||
|
||||
return retval;
|
||||
}
|
2
include/Kbuild
Normal file
2
include/Kbuild
Normal file
@ -0,0 +1,2 @@
|
||||
# Top-level Makefile calls into asm-$(ARCH)
|
||||
# List only non-arch directories below
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acbuffer.h - Support for buffers returned by ACPI predefined names
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACBUFFER_H__
|
||||
#define __ACBUFFER_H__
|
||||
|
||||
@ -207,14 +241,4 @@ struct acpi_pld_info {
|
||||
#define ACPI_PLD_GET_HORIZ_OFFSET(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
|
||||
#define ACPI_PLD_SET_HORIZ_OFFSET(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 128+16=144, Len 16 */
|
||||
|
||||
/* Panel position defined in _PLD section of ACPI Specification 6.3 */
|
||||
|
||||
#define ACPI_PLD_PANEL_TOP 0
|
||||
#define ACPI_PLD_PANEL_BOTTOM 1
|
||||
#define ACPI_PLD_PANEL_LEFT 2
|
||||
#define ACPI_PLD_PANEL_RIGHT 3
|
||||
#define ACPI_PLD_PANEL_FRONT 4
|
||||
#define ACPI_PLD_PANEL_BACK 5
|
||||
#define ACPI_PLD_PANEL_UNKNOWN 6
|
||||
|
||||
#endif /* ACBUFFER_H */
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acconfig.h - Global configuration constants
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef _ACCONFIG_H
|
||||
#define _ACCONFIG_H
|
||||
|
||||
@ -44,7 +78,6 @@
|
||||
#define ACPI_MAX_EXTPARSE_CACHE_DEPTH 96 /* Parse tree objects */
|
||||
#define ACPI_MAX_OBJECT_CACHE_DEPTH 96 /* Interpreter operand objects */
|
||||
#define ACPI_MAX_NAMESPACE_CACHE_DEPTH 96 /* Namespace objects */
|
||||
#define ACPI_MAX_COMMENT_CACHE_DEPTH 96 /* Comments for the -ca option */
|
||||
|
||||
/*
|
||||
* Should the subsystem abort the loading of an ACPI table if the
|
||||
@ -89,15 +122,15 @@
|
||||
|
||||
/* Maximum object reference count (detects object deletion issues) */
|
||||
|
||||
#define ACPI_MAX_REFERENCE_COUNT 0x4000
|
||||
#define ACPI_MAX_REFERENCE_COUNT 0x1000
|
||||
|
||||
/* Default page size for use in mapping memory for operation regions */
|
||||
|
||||
#define ACPI_DEFAULT_PAGE_SIZE 4096 /* Must be power of 2 */
|
||||
|
||||
/* owner_id tracking. 128 entries allows for 4095 owner_ids */
|
||||
/* owner_id tracking. 8 entries allows for 255 owner_ids */
|
||||
|
||||
#define ACPI_NUM_OWNERID_MASKS 128
|
||||
#define ACPI_NUM_OWNERID_MASKS 8
|
||||
|
||||
/* Size of the root table array is increased by this increment */
|
||||
|
||||
@ -111,9 +144,9 @@
|
||||
|
||||
#define ACPI_ADDRESS_RANGE_MAX 2
|
||||
|
||||
/* Maximum time (default 30s) of While() loops before abort */
|
||||
/* Maximum number of While() loops before abort */
|
||||
|
||||
#define ACPI_MAX_LOOP_TIMEOUT 30
|
||||
#define ACPI_MAX_LOOP_COUNT 0xFFFF
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
@ -121,7 +154,7 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* Method info (in WALK_STATE), containing local variables and arguments */
|
||||
/* Method info (in WALK_STATE), containing local variables and argumetns */
|
||||
|
||||
#define ACPI_METHOD_NUM_LOCALS 8
|
||||
#define ACPI_METHOD_MAX_LOCAL 7
|
||||
@ -141,7 +174,7 @@
|
||||
|
||||
/*
|
||||
* Maximal number of elements the Result Stack can contain,
|
||||
* it may be an arbitrary value not exceeding the types of
|
||||
* it may be an arbitray value not exceeding the types of
|
||||
* result_size and result_count (now u8).
|
||||
*/
|
||||
#define ACPI_RESULTS_OBJ_NUM_MAX 255
|
||||
@ -173,22 +206,11 @@
|
||||
#define ACPI_RSDP_CHECKSUM_LENGTH 20
|
||||
#define ACPI_RSDP_XCHECKSUM_LENGTH 36
|
||||
|
||||
/*
|
||||
* SMBus, GSBus and IPMI buffer sizes. All have a 2-byte header,
|
||||
* containing both Status and Length.
|
||||
*/
|
||||
#define ACPI_SERIAL_HEADER_SIZE 2 /* Common for below. Status and Length fields */
|
||||
/* SMBus, GSBus and IPMI bidirectional buffer size */
|
||||
|
||||
#define ACPI_SMBUS_DATA_SIZE 32
|
||||
#define ACPI_SMBUS_BUFFER_SIZE ACPI_SERIAL_HEADER_SIZE + ACPI_SMBUS_DATA_SIZE
|
||||
|
||||
#define ACPI_IPMI_DATA_SIZE 64
|
||||
#define ACPI_IPMI_BUFFER_SIZE ACPI_SERIAL_HEADER_SIZE + ACPI_IPMI_DATA_SIZE
|
||||
|
||||
#define ACPI_MAX_GSBUS_DATA_SIZE 255
|
||||
#define ACPI_MAX_GSBUS_BUFFER_SIZE ACPI_SERIAL_HEADER_SIZE + ACPI_MAX_GSBUS_DATA_SIZE
|
||||
|
||||
#define ACPI_PRM_INPUT_BUFFER_SIZE 26
|
||||
#define ACPI_SMBUS_BUFFER_SIZE 34
|
||||
#define ACPI_GSBUS_BUFFER_SIZE 34
|
||||
#define ACPI_IPMI_BUFFER_SIZE 66
|
||||
|
||||
/* _sx_d and _sx_w control methods */
|
||||
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acexcep.h - Exception codes returned by the ACPI subsystem
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACEXCEP_H__
|
||||
#define __ACEXCEP_H__
|
||||
|
||||
@ -40,12 +74,12 @@
|
||||
struct acpi_exception_info {
|
||||
char *name;
|
||||
|
||||
#if defined (ACPI_HELP_APP) || defined (ACPI_ASL_COMPILER)
|
||||
#ifdef ACPI_HELP_APP
|
||||
char *description;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined (ACPI_HELP_APP) || defined (ACPI_ASL_COMPILER)
|
||||
#ifdef ACPI_HELP_APP
|
||||
#define EXCEP_TXT(name,description) {name, description}
|
||||
#else
|
||||
#define EXCEP_TXT(name,description) {name}
|
||||
@ -57,14 +91,9 @@ struct acpi_exception_info {
|
||||
#define ACPI_SUCCESS(a) (!(a))
|
||||
#define ACPI_FAILURE(a) (a)
|
||||
|
||||
#define ACPI_SKIP(a) (a == AE_CTRL_SKIP)
|
||||
#define AE_OK (acpi_status) 0x0000
|
||||
|
||||
#define ACPI_ENV_EXCEPTION(status) (((status) & AE_CODE_MASK) == AE_CODE_ENVIRONMENTAL)
|
||||
#define ACPI_AML_EXCEPTION(status) (((status) & AE_CODE_MASK) == AE_CODE_AML)
|
||||
#define ACPI_PROG_EXCEPTION(status) (((status) & AE_CODE_MASK) == AE_CODE_PROGRAMMER)
|
||||
#define ACPI_TABLE_EXCEPTION(status) (((status) & AE_CODE_MASK) == AE_CODE_ACPI_TABLES)
|
||||
#define ACPI_CNTL_EXCEPTION(status) (((status) & AE_CODE_MASK) == AE_CODE_CONTROL)
|
||||
|
||||
/*
|
||||
* Environmental exceptions
|
||||
*/
|
||||
@ -98,13 +127,8 @@ struct acpi_exception_info {
|
||||
#define AE_NOT_CONFIGURED EXCEP_ENV (0x001C)
|
||||
#define AE_ACCESS EXCEP_ENV (0x001D)
|
||||
#define AE_IO_ERROR EXCEP_ENV (0x001E)
|
||||
#define AE_NUMERIC_OVERFLOW EXCEP_ENV (0x001F)
|
||||
#define AE_HEX_OVERFLOW EXCEP_ENV (0x0020)
|
||||
#define AE_DECIMAL_OVERFLOW EXCEP_ENV (0x0021)
|
||||
#define AE_OCTAL_OVERFLOW EXCEP_ENV (0x0022)
|
||||
#define AE_END_OF_TABLE EXCEP_ENV (0x0023)
|
||||
|
||||
#define AE_CODE_ENV_MAX 0x0023
|
||||
#define AE_CODE_ENV_MAX 0x001E
|
||||
|
||||
/*
|
||||
* Programmer exceptions
|
||||
@ -168,13 +192,11 @@ struct acpi_exception_info {
|
||||
#define AE_AML_CIRCULAR_REFERENCE EXCEP_AML (0x001E)
|
||||
#define AE_AML_BAD_RESOURCE_LENGTH EXCEP_AML (0x001F)
|
||||
#define AE_AML_ILLEGAL_ADDRESS EXCEP_AML (0x0020)
|
||||
#define AE_AML_LOOP_TIMEOUT EXCEP_AML (0x0021)
|
||||
#define AE_AML_INFINITE_LOOP EXCEP_AML (0x0021)
|
||||
#define AE_AML_UNINITIALIZED_NODE EXCEP_AML (0x0022)
|
||||
#define AE_AML_TARGET_TYPE EXCEP_AML (0x0023)
|
||||
#define AE_AML_PROTOCOL EXCEP_AML (0x0024)
|
||||
#define AE_AML_BUFFER_LENGTH EXCEP_AML (0x0025)
|
||||
|
||||
#define AE_CODE_AML_MAX 0x0025
|
||||
#define AE_CODE_AML_MAX 0x0023
|
||||
|
||||
/*
|
||||
* Internal exceptions used for control
|
||||
@ -189,10 +211,11 @@ struct acpi_exception_info {
|
||||
#define AE_CTRL_TRANSFER EXCEP_CTL (0x0008)
|
||||
#define AE_CTRL_BREAK EXCEP_CTL (0x0009)
|
||||
#define AE_CTRL_CONTINUE EXCEP_CTL (0x000A)
|
||||
#define AE_CTRL_PARSE_CONTINUE EXCEP_CTL (0x000B)
|
||||
#define AE_CTRL_PARSE_PENDING EXCEP_CTL (0x000C)
|
||||
#define AE_CTRL_SKIP EXCEP_CTL (0x000B)
|
||||
#define AE_CTRL_PARSE_CONTINUE EXCEP_CTL (0x000C)
|
||||
#define AE_CTRL_PARSE_PENDING EXCEP_CTL (0x000D)
|
||||
|
||||
#define AE_CODE_CTRL_MAX 0x000C
|
||||
#define AE_CODE_CTRL_MAX 0x000D
|
||||
|
||||
/* Exception strings for acpi_format_exception */
|
||||
|
||||
@ -242,16 +265,7 @@ static const struct acpi_exception_info acpi_gbl_exception_names_env[] = {
|
||||
EXCEP_TXT("AE_NOT_CONFIGURED",
|
||||
"The interface is not part of the current subsystem configuration"),
|
||||
EXCEP_TXT("AE_ACCESS", "Permission denied for the requested operation"),
|
||||
EXCEP_TXT("AE_IO_ERROR", "An I/O error occurred"),
|
||||
EXCEP_TXT("AE_NUMERIC_OVERFLOW",
|
||||
"Overflow during string-to-integer conversion"),
|
||||
EXCEP_TXT("AE_HEX_OVERFLOW",
|
||||
"Overflow during ASCII hex-to-binary conversion"),
|
||||
EXCEP_TXT("AE_DECIMAL_OVERFLOW",
|
||||
"Overflow during ASCII decimal-to-binary conversion"),
|
||||
EXCEP_TXT("AE_OCTAL_OVERFLOW",
|
||||
"Overflow during ASCII octal-to-binary conversion"),
|
||||
EXCEP_TXT("AE_END_OF_TABLE", "Reached the end of table")
|
||||
EXCEP_TXT("AE_IO_ERROR", "An I/O error occurred")
|
||||
};
|
||||
|
||||
static const struct acpi_exception_info acpi_gbl_exception_names_pgm[] = {
|
||||
@ -311,8 +325,7 @@ static const struct acpi_exception_info acpi_gbl_exception_names_aml[] = {
|
||||
"An ACPI name contains invalid character(s)"),
|
||||
EXCEP_TXT("AE_AML_NAME_NOT_FOUND",
|
||||
"Could not resolve a named reference"),
|
||||
EXCEP_TXT("AE_AML_INTERNAL",
|
||||
"An internal error within the interpreter"),
|
||||
EXCEP_TXT("AE_AML_INTERNAL", "An internal error within the interprete"),
|
||||
EXCEP_TXT("AE_AML_INVALID_SPACE_ID",
|
||||
"An Operation Region SpaceID is invalid"),
|
||||
EXCEP_TXT("AE_AML_STRING_LIMIT",
|
||||
@ -345,15 +358,12 @@ static const struct acpi_exception_info acpi_gbl_exception_names_aml[] = {
|
||||
"The length of a Resource Descriptor in the AML is incorrect"),
|
||||
EXCEP_TXT("AE_AML_ILLEGAL_ADDRESS",
|
||||
"A memory, I/O, or PCI configuration address is invalid"),
|
||||
EXCEP_TXT("AE_AML_LOOP_TIMEOUT",
|
||||
"An AML While loop exceeded the maximum execution time"),
|
||||
EXCEP_TXT("AE_AML_INFINITE_LOOP",
|
||||
"An apparent infinite AML While loop, method was aborted"),
|
||||
EXCEP_TXT("AE_AML_UNINITIALIZED_NODE",
|
||||
"A namespace node is uninitialized or unresolved"),
|
||||
EXCEP_TXT("AE_AML_TARGET_TYPE",
|
||||
"A target operand of an incorrect type was encountered"),
|
||||
EXCEP_TXT("AE_AML_PROTOCOL", "Violation of a fixed ACPI protocol"),
|
||||
EXCEP_TXT("AE_AML_BUFFER_LENGTH",
|
||||
"The length of the buffer is invalid/incorrect")
|
||||
"A target operand of an incorrect type was encountered")
|
||||
};
|
||||
|
||||
static const struct acpi_exception_info acpi_gbl_exception_names_ctrl[] = {
|
||||
@ -368,6 +378,7 @@ static const struct acpi_exception_info acpi_gbl_exception_names_ctrl[] = {
|
||||
EXCEP_TXT("AE_CTRL_TRANSFER", "Transfer control to called method"),
|
||||
EXCEP_TXT("AE_CTRL_BREAK", "A Break has been executed"),
|
||||
EXCEP_TXT("AE_CTRL_CONTINUE", "A Continue has been executed"),
|
||||
EXCEP_TXT("AE_CTRL_SKIP", "Not currently used"),
|
||||
EXCEP_TXT("AE_CTRL_PARSE_CONTINUE", "Used to skip over bad opcodes"),
|
||||
EXCEP_TXT("AE_CTRL_PARSE_PENDING", "Used to implement AML While loops")
|
||||
};
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acnames.h - Global names and strings
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACNAMES_H__
|
||||
#define __ACNAMES_H__
|
||||
|
||||
@ -20,8 +54,6 @@
|
||||
#define METHOD_NAME__CLS "_CLS"
|
||||
#define METHOD_NAME__CRS "_CRS"
|
||||
#define METHOD_NAME__DDN "_DDN"
|
||||
#define METHOD_NAME__DIS "_DIS"
|
||||
#define METHOD_NAME__DMA "_DMA"
|
||||
#define METHOD_NAME__HID "_HID"
|
||||
#define METHOD_NAME__INI "_INI"
|
||||
#define METHOD_NAME__PLD "_PLD"
|
||||
@ -50,14 +82,11 @@
|
||||
/* Definitions of the predefined namespace names */
|
||||
|
||||
#define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */
|
||||
#define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */
|
||||
|
||||
#define ACPI_PREFIX_MIXED (u32) 0x69706341 /* "Acpi" */
|
||||
#define ACPI_PREFIX_LOWER (u32) 0x69706361 /* "acpi" */
|
||||
|
||||
/* Root name stuff */
|
||||
|
||||
#define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */
|
||||
#define ACPI_ROOT_PATHNAME "\\___"
|
||||
#define ACPI_NAMESPACE_ROOT "Namespace Root"
|
||||
#define ACPI_NS_ROOT_PATH "\\"
|
||||
|
||||
#endif /* __ACNAMES_H__ */
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acoutput.h -- debug output
|
||||
*
|
||||
* Copyright (C) 2000 - 2020, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACOUTPUT_H__
|
||||
#define __ACOUTPUT_H__
|
||||
|
||||
@ -73,16 +107,14 @@
|
||||
#define ACPI_LV_RESOURCES 0x00010000
|
||||
#define ACPI_LV_USER_REQUESTS 0x00020000
|
||||
#define ACPI_LV_PACKAGE 0x00040000
|
||||
#define ACPI_LV_EVALUATION 0x00080000
|
||||
#define ACPI_LV_VERBOSITY1 0x000FFF40 | ACPI_LV_ALL_EXCEPTIONS
|
||||
#define ACPI_LV_VERBOSITY1 0x0007FF40 | ACPI_LV_ALL_EXCEPTIONS
|
||||
|
||||
/* Trace verbosity level 2 [Function tracing and memory allocation] */
|
||||
|
||||
#define ACPI_LV_ALLOCATIONS 0x00100000
|
||||
#define ACPI_LV_FUNCTIONS 0x00200000
|
||||
#define ACPI_LV_OPTIMIZATIONS 0x00400000
|
||||
#define ACPI_LV_PARSE_TREES 0x00800000
|
||||
#define ACPI_LV_VERBOSITY2 0x00F00000 | ACPI_LV_VERBOSITY1
|
||||
#define ACPI_LV_VERBOSITY2 0x00700000 | ACPI_LV_VERBOSITY1
|
||||
#define ACPI_LV_ALL ACPI_LV_VERBOSITY2
|
||||
|
||||
/* Trace verbosity level 3 [Threading, I/O, and Interrupts] */
|
||||
@ -133,7 +165,6 @@
|
||||
#define ACPI_DB_TABLES ACPI_DEBUG_LEVEL (ACPI_LV_TABLES)
|
||||
#define ACPI_DB_FUNCTIONS ACPI_DEBUG_LEVEL (ACPI_LV_FUNCTIONS)
|
||||
#define ACPI_DB_OPTIMIZATIONS ACPI_DEBUG_LEVEL (ACPI_LV_OPTIMIZATIONS)
|
||||
#define ACPI_DB_PARSE_TREES ACPI_DEBUG_LEVEL (ACPI_LV_PARSE_TREES)
|
||||
#define ACPI_DB_VALUES ACPI_DEBUG_LEVEL (ACPI_LV_VALUES)
|
||||
#define ACPI_DB_OBJECTS ACPI_DEBUG_LEVEL (ACPI_LV_OBJECTS)
|
||||
#define ACPI_DB_ALLOCATIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALLOCATIONS)
|
||||
@ -142,7 +173,6 @@
|
||||
#define ACPI_DB_INTERRUPTS ACPI_DEBUG_LEVEL (ACPI_LV_INTERRUPTS)
|
||||
#define ACPI_DB_USER_REQUESTS ACPI_DEBUG_LEVEL (ACPI_LV_USER_REQUESTS)
|
||||
#define ACPI_DB_PACKAGE ACPI_DEBUG_LEVEL (ACPI_LV_PACKAGE)
|
||||
#define ACPI_DB_EVALUATION ACPI_DEBUG_LEVEL (ACPI_LV_EVALUATION)
|
||||
#define ACPI_DB_MUTEX ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX)
|
||||
#define ACPI_DB_EVENTS ACPI_DEBUG_LEVEL (ACPI_LV_EVENTS)
|
||||
|
||||
@ -150,10 +180,7 @@
|
||||
|
||||
/* Defaults for debug_level, debug and normal */
|
||||
|
||||
#ifndef ACPI_DEBUG_DEFAULT
|
||||
#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT | ACPI_LV_EVALUATION | ACPI_LV_REPAIR)
|
||||
#endif
|
||||
|
||||
#define ACPI_DEBUG_DEFAULT (ACPI_LV_INFO | ACPI_LV_REPAIR)
|
||||
#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_DEBUG_OBJECT | ACPI_LV_REPAIR)
|
||||
#define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
|
||||
|
||||
@ -204,7 +231,6 @@
|
||||
#define ACPI_EXCEPTION(plist) acpi_exception plist
|
||||
#define ACPI_ERROR(plist) acpi_error plist
|
||||
#define ACPI_BIOS_WARNING(plist) acpi_bios_warning plist
|
||||
#define ACPI_BIOS_EXCEPTION(plist) acpi_bios_exception plist
|
||||
#define ACPI_BIOS_ERROR(plist) acpi_bios_error plist
|
||||
#define ACPI_DEBUG_OBJECT(obj,l,i) acpi_ex_do_debug_object(obj,l,i)
|
||||
|
||||
@ -217,7 +243,6 @@
|
||||
#define ACPI_EXCEPTION(plist)
|
||||
#define ACPI_ERROR(plist)
|
||||
#define ACPI_BIOS_WARNING(plist)
|
||||
#define ACPI_BIOS_EXCEPTION(plist)
|
||||
#define ACPI_BIOS_ERROR(plist)
|
||||
#define ACPI_DEBUG_OBJECT(obj,l,i)
|
||||
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acpi.h - Master public include file used to interface to ACPICA
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACPI_H__
|
||||
#define __ACPI_H__
|
||||
|
||||
@ -24,10 +58,10 @@
|
||||
#include <acpi/actypes.h> /* ACPICA data types and structures */
|
||||
#include <acpi/acexcep.h> /* ACPICA exceptions */
|
||||
#include <acpi/actbl.h> /* ACPI table definitions */
|
||||
#include <acpi/acrestyp.h> /* Resource Descriptor structs */
|
||||
#include <acpi/platform/acenvex.h> /* Extra environment-specific items */
|
||||
#include <acpi/acoutput.h> /* Error output and Debug macros */
|
||||
#include <acpi/acrestyp.h> /* Resource Descriptor structs */
|
||||
#include <acpi/acpiosxf.h> /* OSL interfaces (ACPICA-to-OS) */
|
||||
#include <acpi/acpixf.h> /* ACPI core subsystem external interfaces */
|
||||
#include <acpi/platform/acenvex.h> /* Extra environment-specific items */
|
||||
|
||||
#endif /* __ACPI_H__ */
|
||||
|
@ -1,9 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* acpi_bus.h - ACPI Bus Driver ($Revision: 22 $)
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
|
||||
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
|
||||
#ifndef __ACPI_BUS_H__
|
||||
@ -44,23 +57,21 @@ acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
|
||||
u64 arg);
|
||||
acpi_status acpi_evaluate_ej0(acpi_handle handle);
|
||||
acpi_status acpi_evaluate_lck(acpi_handle handle, int lock);
|
||||
acpi_status acpi_evaluate_reg(acpi_handle handle, u8 space_id, u32 function);
|
||||
bool acpi_ata_match(acpi_handle handle);
|
||||
bool acpi_bay_match(acpi_handle handle);
|
||||
bool acpi_dock_match(acpi_handle handle);
|
||||
|
||||
bool acpi_check_dsm(acpi_handle handle, const guid_t *guid, u64 rev, u64 funcs);
|
||||
union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const guid_t *guid,
|
||||
bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 funcs);
|
||||
union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid,
|
||||
u64 rev, u64 func, union acpi_object *argv4);
|
||||
|
||||
static inline union acpi_object *
|
||||
acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev,
|
||||
u64 func, union acpi_object *argv4,
|
||||
acpi_object_type type)
|
||||
acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, u64 rev, u64 func,
|
||||
union acpi_object *argv4, acpi_object_type type)
|
||||
{
|
||||
union acpi_object *obj;
|
||||
|
||||
obj = acpi_evaluate_dsm(handle, guid, rev, func, argv4);
|
||||
obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4);
|
||||
if (obj && obj->type != type) {
|
||||
ACPI_FREE(obj);
|
||||
obj = NULL;
|
||||
@ -77,12 +88,10 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev,
|
||||
}
|
||||
|
||||
bool acpi_dev_found(const char *hid);
|
||||
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
|
||||
bool acpi_reduced_hardware(void);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
struct proc_dir_entry;
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#define ACPI_BUS_FILE_ROOT "acpi"
|
||||
extern struct proc_dir_entry *acpi_root_dir;
|
||||
@ -94,7 +103,6 @@ enum acpi_bus_device_type {
|
||||
ACPI_BUS_TYPE_THERMAL,
|
||||
ACPI_BUS_TYPE_POWER_BUTTON,
|
||||
ACPI_BUS_TYPE_SLEEP_BUTTON,
|
||||
ACPI_BUS_TYPE_ECDT_EC,
|
||||
ACPI_BUS_DEVICE_TYPE_COUNT
|
||||
};
|
||||
|
||||
@ -201,8 +209,7 @@ struct acpi_device_flags {
|
||||
u32 of_compatible_ok:1;
|
||||
u32 coherent_dma:1;
|
||||
u32 cca_seen:1;
|
||||
u32 enumeration_by_parent:1;
|
||||
u32 reserved:19;
|
||||
u32 reserved:20;
|
||||
};
|
||||
|
||||
/* File System */
|
||||
@ -216,7 +223,7 @@ struct acpi_device_dir {
|
||||
/* Plug and Play */
|
||||
|
||||
typedef char acpi_bus_id[8];
|
||||
typedef u64 acpi_bus_address;
|
||||
typedef unsigned long acpi_bus_address;
|
||||
typedef char acpi_device_name[40];
|
||||
typedef char acpi_device_class[20];
|
||||
|
||||
@ -234,7 +241,6 @@ struct acpi_pnp_type {
|
||||
|
||||
struct acpi_device_pnp {
|
||||
acpi_bus_id bus_id; /* Object name */
|
||||
int instance_no; /* Instance number of this object */
|
||||
struct acpi_pnp_type type; /* ID type */
|
||||
acpi_bus_address bus_address; /* _ADR */
|
||||
char *unique_id; /* _UID */
|
||||
@ -280,12 +286,6 @@ struct acpi_device_power {
|
||||
struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */
|
||||
};
|
||||
|
||||
struct acpi_dep_data {
|
||||
struct list_head node;
|
||||
acpi_handle supplier;
|
||||
acpi_handle consumer;
|
||||
};
|
||||
|
||||
/* Performance Management */
|
||||
|
||||
struct acpi_device_perf_flags {
|
||||
@ -312,11 +312,13 @@ struct acpi_device_perf {
|
||||
/* Wakeup Management */
|
||||
struct acpi_device_wakeup_flags {
|
||||
u8 valid:1; /* Can successfully enable wakeup? */
|
||||
u8 run_wake:1; /* Run-Wake GPE devices */
|
||||
u8 notifier_present:1; /* Wake-up notify handler has been installed */
|
||||
u8 enabled:1; /* Enabled for wakeup */
|
||||
};
|
||||
|
||||
struct acpi_device_wakeup_context {
|
||||
void (*func)(struct acpi_device_wakeup_context *context);
|
||||
struct work_struct work;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
@ -329,7 +331,6 @@ struct acpi_device_wakeup {
|
||||
struct acpi_device_wakeup_context context;
|
||||
struct wakeup_source *ws;
|
||||
int prepare_count;
|
||||
int enable_count;
|
||||
};
|
||||
|
||||
struct acpi_device_physical_node {
|
||||
@ -339,16 +340,10 @@ struct acpi_device_physical_node {
|
||||
bool put_online:1;
|
||||
};
|
||||
|
||||
struct acpi_device_properties {
|
||||
const guid_t *guid;
|
||||
const union acpi_object *properties;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* ACPI Device Specific Data (_DSD) */
|
||||
struct acpi_device_data {
|
||||
const union acpi_object *pointer;
|
||||
struct list_head properties;
|
||||
const union acpi_object *properties;
|
||||
const union acpi_object *of_compatible;
|
||||
struct list_head subnodes;
|
||||
};
|
||||
@ -391,52 +386,41 @@ struct acpi_data_node {
|
||||
const char *name;
|
||||
acpi_handle handle;
|
||||
struct fwnode_handle fwnode;
|
||||
struct fwnode_handle *parent;
|
||||
struct acpi_device_data data;
|
||||
struct list_head sibling;
|
||||
struct kobject kobj;
|
||||
struct completion kobj_done;
|
||||
};
|
||||
|
||||
extern const struct fwnode_operations acpi_device_fwnode_ops;
|
||||
extern const struct fwnode_operations acpi_data_fwnode_ops;
|
||||
extern const struct fwnode_operations acpi_static_fwnode_ops;
|
||||
|
||||
bool is_acpi_device_node(const struct fwnode_handle *fwnode);
|
||||
bool is_acpi_data_node(const struct fwnode_handle *fwnode);
|
||||
|
||||
static inline bool is_acpi_node(const struct fwnode_handle *fwnode)
|
||||
static inline bool is_acpi_node(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return (is_acpi_device_node(fwnode) || is_acpi_data_node(fwnode));
|
||||
return !IS_ERR_OR_NULL(fwnode) && (fwnode->type == FWNODE_ACPI
|
||||
|| fwnode->type == FWNODE_ACPI_DATA);
|
||||
}
|
||||
|
||||
#define to_acpi_device_node(__fwnode) \
|
||||
({ \
|
||||
typeof(__fwnode) __to_acpi_device_node_fwnode = __fwnode; \
|
||||
\
|
||||
is_acpi_device_node(__to_acpi_device_node_fwnode) ? \
|
||||
container_of(__to_acpi_device_node_fwnode, \
|
||||
struct acpi_device, fwnode) : \
|
||||
NULL; \
|
||||
})
|
||||
|
||||
#define to_acpi_data_node(__fwnode) \
|
||||
({ \
|
||||
typeof(__fwnode) __to_acpi_data_node_fwnode = __fwnode; \
|
||||
\
|
||||
is_acpi_data_node(__to_acpi_data_node_fwnode) ? \
|
||||
container_of(__to_acpi_data_node_fwnode, \
|
||||
struct acpi_data_node, fwnode) : \
|
||||
NULL; \
|
||||
})
|
||||
|
||||
static inline bool is_acpi_static_node(const struct fwnode_handle *fwnode)
|
||||
static inline bool is_acpi_device_node(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return !IS_ERR_OR_NULL(fwnode) &&
|
||||
fwnode->ops == &acpi_static_fwnode_ops;
|
||||
return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_ACPI;
|
||||
}
|
||||
|
||||
static inline bool acpi_data_node_match(const struct fwnode_handle *fwnode,
|
||||
static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return is_acpi_device_node(fwnode) ?
|
||||
container_of(fwnode, struct acpi_device, fwnode) : NULL;
|
||||
}
|
||||
|
||||
static inline bool is_acpi_data_node(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return fwnode && fwnode->type == FWNODE_ACPI_DATA;
|
||||
}
|
||||
|
||||
static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return is_acpi_data_node(fwnode) ?
|
||||
container_of(fwnode, struct acpi_data_node, fwnode) : NULL;
|
||||
}
|
||||
|
||||
static inline bool acpi_data_node_match(struct fwnode_handle *fwnode,
|
||||
const char *name)
|
||||
{
|
||||
return is_acpi_data_node(fwnode) ?
|
||||
@ -504,22 +488,21 @@ extern int unregister_acpi_notifier(struct notifier_block *);
|
||||
*/
|
||||
|
||||
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
|
||||
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle);
|
||||
void acpi_bus_put_acpi_device(struct acpi_device *adev);
|
||||
acpi_status acpi_bus_get_status_handle(acpi_handle handle,
|
||||
unsigned long long *sta);
|
||||
int acpi_bus_get_status(struct acpi_device *device);
|
||||
|
||||
int acpi_bus_set_power(acpi_handle handle, int state);
|
||||
const char *acpi_power_state_string(int state);
|
||||
int acpi_device_get_power(struct acpi_device *device, int *state);
|
||||
int acpi_device_set_power(struct acpi_device *device, int state);
|
||||
int acpi_bus_init_power(struct acpi_device *device);
|
||||
int acpi_device_fix_up_power(struct acpi_device *device);
|
||||
int acpi_bus_update_power(acpi_handle handle, int *state_p);
|
||||
int acpi_device_update_power(struct acpi_device *device, int *state_p);
|
||||
bool acpi_bus_power_manageable(acpi_handle handle);
|
||||
int acpi_device_power_add_dependent(struct acpi_device *adev,
|
||||
struct device *dev);
|
||||
void acpi_device_power_remove_dependent(struct acpi_device *adev,
|
||||
struct device *dev);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
bool acpi_bus_can_wakeup(acpi_handle handle);
|
||||
@ -539,8 +522,6 @@ void acpi_bus_trim(struct acpi_device *start);
|
||||
acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
|
||||
int acpi_match_device_ids(struct acpi_device *device,
|
||||
const struct acpi_device_id *ids);
|
||||
void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
|
||||
char *modalias, size_t len);
|
||||
int acpi_create_dir(struct acpi_device *);
|
||||
void acpi_remove_dir(struct acpi_device *);
|
||||
|
||||
@ -590,20 +571,9 @@ struct acpi_pci_root {
|
||||
|
||||
/* helper */
|
||||
|
||||
bool acpi_dma_supported(const struct acpi_device *adev);
|
||||
bool acpi_dma_supported(struct acpi_device *adev);
|
||||
enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev);
|
||||
int acpi_iommu_fwspec_init(struct device *dev, u32 id,
|
||||
struct fwnode_handle *fwnode,
|
||||
const struct iommu_ops *ops);
|
||||
int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset,
|
||||
u64 *size);
|
||||
int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr,
|
||||
const u32 *input_id);
|
||||
static inline int acpi_dma_configure(struct device *dev,
|
||||
enum dev_dma_attr attr)
|
||||
{
|
||||
return acpi_dma_configure_id(dev, attr, NULL);
|
||||
}
|
||||
|
||||
struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
|
||||
u64 address, bool check_children);
|
||||
int acpi_is_root_bridge(acpi_handle);
|
||||
@ -612,30 +582,16 @@ struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
|
||||
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
|
||||
int acpi_disable_wakeup_device_power(struct acpi_device *dev);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
bool acpi_device_always_present(struct acpi_device *adev);
|
||||
#else
|
||||
static inline bool acpi_device_always_present(struct acpi_device *adev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
void acpi_pm_wakeup_event(struct device *dev);
|
||||
acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
|
||||
void (*func)(struct acpi_device_wakeup_context *context));
|
||||
void (*work_func)(struct work_struct *work));
|
||||
acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
|
||||
bool acpi_pm_device_can_wakeup(struct device *dev);
|
||||
int acpi_pm_device_sleep_state(struct device *, int *, int);
|
||||
int acpi_pm_set_device_wakeup(struct device *dev, bool enable);
|
||||
int acpi_pm_device_run_wake(struct device *, bool);
|
||||
#else
|
||||
static inline void acpi_pm_wakeup_event(struct device *dev)
|
||||
{
|
||||
}
|
||||
static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
|
||||
struct device *dev,
|
||||
void (*func)(struct acpi_device_wakeup_context *context))
|
||||
void (*work_func)(struct work_struct *work))
|
||||
{
|
||||
return AE_SUPPORT;
|
||||
}
|
||||
@ -643,10 +599,6 @@ static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev)
|
||||
{
|
||||
return AE_SUPPORT;
|
||||
}
|
||||
static inline bool acpi_pm_device_can_wakeup(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
|
||||
{
|
||||
if (p)
|
||||
@ -655,16 +607,19 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
|
||||
return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3_COLD) ?
|
||||
m : ACPI_STATE_D0;
|
||||
}
|
||||
static inline int acpi_pm_set_device_wakeup(struct device *dev, bool enable)
|
||||
static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT
|
||||
bool acpi_sleep_state_supported(u8 sleep_state);
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
int acpi_pm_device_sleep_wake(struct device *, bool);
|
||||
#else
|
||||
static inline bool acpi_sleep_state_supported(u8 sleep_state) { return false; }
|
||||
static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI_SLEEP
|
||||
@ -690,46 +645,6 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
|
||||
adev->power.states[ACPI_STATE_D3_HOT].flags.explicit_set);
|
||||
}
|
||||
|
||||
bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
|
||||
|
||||
void acpi_dev_clear_dependencies(struct acpi_device *supplier);
|
||||
struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
|
||||
struct acpi_device *
|
||||
acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
|
||||
struct acpi_device *
|
||||
acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv);
|
||||
|
||||
/**
|
||||
* for_each_acpi_dev_match - iterate over ACPI devices that matching the criteria
|
||||
* @adev: pointer to the matching ACPI device, NULL at the end of the loop
|
||||
* @hid: Hardware ID of the device.
|
||||
* @uid: Unique ID of the device, pass NULL to not check _UID
|
||||
* @hrv: Hardware Revision of the device, pass -1 to not check _HRV
|
||||
*
|
||||
* The caller is responsible for invoking acpi_dev_put() on the returned device.
|
||||
*/
|
||||
#define for_each_acpi_dev_match(adev, hid, uid, hrv) \
|
||||
for (adev = acpi_dev_get_first_match_dev(hid, uid, hrv); \
|
||||
adev; \
|
||||
adev = acpi_dev_get_next_match_dev(adev, hid, uid, hrv))
|
||||
|
||||
static inline struct acpi_device *acpi_dev_get(struct acpi_device *adev)
|
||||
{
|
||||
return adev ? to_acpi_device(get_device(&adev->dev)) : NULL;
|
||||
}
|
||||
|
||||
static inline void acpi_dev_put(struct acpi_device *adev)
|
||||
{
|
||||
if (adev)
|
||||
put_device(&adev->dev);
|
||||
}
|
||||
|
||||
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle);
|
||||
|
||||
static inline void acpi_bus_put_acpi_device(struct acpi_device *adev)
|
||||
{
|
||||
acpi_dev_put(adev);
|
||||
}
|
||||
#else /* CONFIG_ACPI */
|
||||
|
||||
static inline int register_acpi_bus_type(void *bus) { return 0; }
|
||||
|
@ -1,9 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* acpi_drivers.h ($Revision: 31 $)
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
|
||||
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
|
||||
#ifndef __ACPI_DRIVERS_H__
|
||||
@ -11,6 +24,25 @@
|
||||
|
||||
#define ACPI_MAX_STRING 80
|
||||
|
||||
/*
|
||||
* Please update drivers/acpi/debug.c and Documentation/acpi/debug.txt
|
||||
* if you add to this list.
|
||||
*/
|
||||
#define ACPI_BUS_COMPONENT 0x00010000
|
||||
#define ACPI_AC_COMPONENT 0x00020000
|
||||
#define ACPI_BATTERY_COMPONENT 0x00040000
|
||||
#define ACPI_BUTTON_COMPONENT 0x00080000
|
||||
#define ACPI_SBS_COMPONENT 0x00100000
|
||||
#define ACPI_FAN_COMPONENT 0x00200000
|
||||
#define ACPI_PCI_COMPONENT 0x00400000
|
||||
#define ACPI_POWER_COMPONENT 0x00800000
|
||||
#define ACPI_CONTAINER_COMPONENT 0x01000000
|
||||
#define ACPI_SYSTEM_COMPONENT 0x02000000
|
||||
#define ACPI_THERMAL_COMPONENT 0x04000000
|
||||
#define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000
|
||||
#define ACPI_VIDEO_COMPONENT 0x10000000
|
||||
#define ACPI_PROCESSOR_COMPONENT 0x20000000
|
||||
|
||||
/*
|
||||
* _HID definitions
|
||||
* HIDs must conform to ACPI spec(6.1.4)
|
||||
@ -26,7 +58,6 @@
|
||||
#define ACPI_VIDEO_HID "LNXVIDEO"
|
||||
#define ACPI_BAY_HID "LNXIOBAY"
|
||||
#define ACPI_DOCK_HID "LNXDOCK"
|
||||
#define ACPI_ECDT_HID "LNXEC"
|
||||
/* Quirk for broken IBM BIOSes */
|
||||
#define ACPI_SMBUS_IBM_HID "SMBUSIBM"
|
||||
|
||||
@ -45,25 +76,18 @@
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* ACPI PCI Interrupt Link */
|
||||
/* ACPI PCI Interrupt Link (pci_link.c) */
|
||||
|
||||
int acpi_irq_penalty_init(void);
|
||||
int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
|
||||
int *polarity, char **name);
|
||||
int acpi_pci_link_free_irq(acpi_handle handle);
|
||||
|
||||
/* ACPI PCI Device Binding */
|
||||
/* ACPI PCI Device Binding (pci_bind.c) */
|
||||
|
||||
struct pci_bus;
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_dev *acpi_get_pci_dev(acpi_handle);
|
||||
#else
|
||||
static inline struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Arch-defined function to add a bus to the system */
|
||||
|
||||
@ -75,6 +99,14 @@ void pci_acpi_crs_quirks(void);
|
||||
static inline void pci_acpi_crs_quirks(void) { }
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Processor
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
#define ACPI_PROCESSOR_LIMIT_NONE 0x00
|
||||
#define ACPI_PROCESSOR_LIMIT_INCREMENT 0x01
|
||||
#define ACPI_PROCESSOR_LIMIT_DECREMENT 0x02
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Dock Station
|
||||
-------------------------------------------------------------------------- */
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ACPI_IO_H_
|
||||
#define _ACPI_IO_H_
|
||||
|
||||
@ -14,14 +13,12 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
|
||||
}
|
||||
#endif
|
||||
|
||||
extern bool acpi_permanent_mmap;
|
||||
|
||||
void __iomem __ref
|
||||
*acpi_os_map_iomem(acpi_physical_address phys, acpi_size size);
|
||||
void __iomem *__ref
|
||||
acpi_os_map_iomem(acpi_physical_address phys, acpi_size size);
|
||||
void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size);
|
||||
void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
|
||||
|
||||
void __iomem *acpi_os_map_generic_address(struct acpi_generic_address *addr);
|
||||
int acpi_os_map_generic_address(struct acpi_generic_address *addr);
|
||||
void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
|
||||
|
||||
#endif
|
||||
|
@ -1,8 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* acpi_lpat.h - LPAT table processing functions
|
||||
*
|
||||
* Copyright (C) 2015 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef ACPI_LPAT_H
|
||||
|
@ -1,10 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ACPI_NUMA_H
|
||||
#define __ACPI_NUMA_H
|
||||
|
||||
#ifdef CONFIG_ACPI_NUMA
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/numa.h>
|
||||
|
||||
/* Proximity bitmap length */
|
||||
#if MAX_NUMNODES > 256
|
||||
@ -17,30 +15,10 @@ extern int pxm_to_node(int);
|
||||
extern int node_to_pxm(int);
|
||||
extern int acpi_map_pxm_to_node(int);
|
||||
extern unsigned char acpi_srat_revision;
|
||||
extern void disable_srat(void);
|
||||
extern int acpi_numa __initdata;
|
||||
|
||||
extern void bad_srat(void);
|
||||
extern int srat_disabled(void);
|
||||
|
||||
#else /* CONFIG_ACPI_NUMA */
|
||||
static inline void disable_srat(void)
|
||||
{
|
||||
}
|
||||
static inline int pxm_to_node(int pxm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int node_to_pxm(int node)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ACPI_NUMA */
|
||||
|
||||
#ifdef CONFIG_ACPI_HMAT
|
||||
extern void disable_hmat(void);
|
||||
#else /* CONFIG_ACPI_HMAT */
|
||||
static inline void disable_hmat(void)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ACPI_HMAT */
|
||||
#endif /* __ACPI_NUMA_H */
|
||||
#endif /* __ACP_NUMA_H */
|
||||
|
@ -1,14 +1,48 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These
|
||||
* interfaces must be implemented by OSL to interface the
|
||||
* ACPI components to the host operating system.
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACPIOSXF_H__
|
||||
#define __ACPIOSXF_H__
|
||||
|
||||
@ -97,27 +131,6 @@ acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock handle);
|
||||
void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RAW spinlock primitives. If the OS does not provide them, fallback to
|
||||
* spinlock primitives
|
||||
*/
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_raw_lock
|
||||
# define acpi_os_create_raw_lock(out_handle) acpi_os_create_lock(out_handle)
|
||||
#endif
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_delete_raw_lock
|
||||
# define acpi_os_delete_raw_lock(handle) acpi_os_delete_lock(handle)
|
||||
#endif
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_raw_lock
|
||||
# define acpi_os_acquire_raw_lock(handle) acpi_os_acquire_lock(handle)
|
||||
#endif
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_release_raw_lock
|
||||
# define acpi_os_release_raw_lock(handle, flags) \
|
||||
acpi_os_release_lock(handle, flags)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Semaphore primitives
|
||||
*/
|
||||
@ -274,8 +287,6 @@ acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width);
|
||||
/*
|
||||
* Platform and hardware-independent physical memory interfaces
|
||||
*/
|
||||
int acpi_os_read_iomem(void __iomem *virt_addr, u64 *value, u32 width);
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_read_memory
|
||||
acpi_status
|
||||
acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width);
|
||||
@ -322,20 +333,16 @@ u64 acpi_os_get_timer(void);
|
||||
acpi_status acpi_os_signal(u32 function, void *info);
|
||||
#endif
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_enter_sleep
|
||||
acpi_status acpi_os_enter_sleep(u8 sleep_state, u32 rega_value, u32 regb_value);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Debug print routines
|
||||
*/
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_printf
|
||||
ACPI_PRINTF_LIKE(1)
|
||||
__printf(1, 2)
|
||||
void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *format, ...);
|
||||
#endif
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_vprintf
|
||||
void acpi_os_vprintf(const char *format, va_list args);
|
||||
__printf(1, 0) void acpi_os_vprintf(const char *format, va_list args);
|
||||
#endif
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_redirect_output
|
||||
@ -349,12 +356,12 @@ void acpi_os_redirect_output(void *destination);
|
||||
acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read);
|
||||
#endif
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_debugger
|
||||
acpi_status acpi_os_initialize_debugger(void);
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
|
||||
acpi_status acpi_os_initialize_command_signals(void);
|
||||
#endif
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_debugger
|
||||
void acpi_os_terminate_debugger(void);
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
|
||||
void acpi_os_terminate_command_signals(void);
|
||||
#endif
|
||||
|
||||
#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_wait_command_ready
|
||||
|
@ -1,18 +1,52 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acpixf.h - External interfaces to the ACPI subsystem
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACXFACE_H__
|
||||
#define __ACXFACE_H__
|
||||
|
||||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||||
|
||||
#define ACPI_CA_VERSION 0x20210105
|
||||
#define ACPI_CA_VERSION 0x20160831
|
||||
|
||||
#include <acpi/acconfig.h>
|
||||
#include <acpi/actypes.h>
|
||||
@ -126,14 +160,13 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE);
|
||||
ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE);
|
||||
|
||||
/*
|
||||
* Whether or not to validate (map) an entire table to verify
|
||||
* checksum/duplication in early stage before install. Set this to TRUE to
|
||||
* allow early table validation before install it to the table manager.
|
||||
* Note that enabling this option causes errors to happen in some OSPMs
|
||||
* during early initialization stages. Default behavior is to allow such
|
||||
* validation.
|
||||
* Whether or not to verify the table checksum before installation. Set
|
||||
* this to TRUE to verify the table checksum before install it to the table
|
||||
* manager. Note that enabling this option causes errors to happen in some
|
||||
* OSPMs during early initialization stages. Default behavior is to do such
|
||||
* verification.
|
||||
*/
|
||||
ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_table_validation, TRUE);
|
||||
ACPI_INIT_GLOBAL(u8, acpi_gbl_verify_table_checksum, TRUE);
|
||||
|
||||
/*
|
||||
* Optionally enable output from the AML Debug Object.
|
||||
@ -156,6 +189,18 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_copy_dsdt_locally, FALSE);
|
||||
*/
|
||||
ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE);
|
||||
|
||||
/*
|
||||
* Optionally support group module level code.
|
||||
*/
|
||||
ACPI_INIT_GLOBAL(u8, acpi_gbl_group_module_level_code, TRUE);
|
||||
|
||||
/*
|
||||
* Optionally support module level code by parsing the entire table as
|
||||
* a term_list. Default is FALSE, do not execute entire table until some
|
||||
* lock order issues are fixed.
|
||||
*/
|
||||
ACPI_INIT_GLOBAL(u8, acpi_gbl_parse_table_as_term_list, FALSE);
|
||||
|
||||
/*
|
||||
* Optionally use 32-bit FADT addresses if and when there is a conflict
|
||||
* (address mismatch) between the 32-bit and 64-bit versions of the
|
||||
@ -213,23 +258,6 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_osi_data, 0);
|
||||
*/
|
||||
ACPI_INIT_GLOBAL(u8, acpi_gbl_reduced_hardware, FALSE);
|
||||
|
||||
/*
|
||||
* Maximum timeout for While() loop iterations before forced method abort.
|
||||
* This mechanism is intended to prevent infinite loops during interpreter
|
||||
* execution within a host kernel.
|
||||
*/
|
||||
ACPI_INIT_GLOBAL(u32, acpi_gbl_max_loop_iterations, ACPI_MAX_LOOP_TIMEOUT);
|
||||
|
||||
/*
|
||||
* Optionally ignore AE_NOT_FOUND errors from named reference package elements
|
||||
* during DSDT/SSDT table loading. This reduces error "noise" in platforms
|
||||
* whose firmware is carrying around a bunch of unused package objects that
|
||||
* refer to non-existent named objects. However, If the AML actually tries to
|
||||
* use such a package, the unresolved element(s) will be replaced with NULL
|
||||
* elements.
|
||||
*/
|
||||
ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_package_resolution_errors, FALSE);
|
||||
|
||||
/*
|
||||
* This mechanism is used to trace a specified AML method. The method is
|
||||
* traced each time it is executed.
|
||||
@ -297,9 +325,6 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running);
|
||||
#define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \
|
||||
ACPI_EXTERNAL_RETURN_OK(prototype)
|
||||
|
||||
#define ACPI_HW_DEPENDENT_RETURN_UINT32(prototype) \
|
||||
ACPI_EXTERNAL_RETURN_UINT32(prototype)
|
||||
|
||||
#define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \
|
||||
ACPI_EXTERNAL_RETURN_VOID(prototype)
|
||||
|
||||
@ -310,9 +335,6 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running);
|
||||
#define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \
|
||||
static ACPI_INLINE prototype {return(AE_OK);}
|
||||
|
||||
#define ACPI_HW_DEPENDENT_RETURN_UINT32(prototype) \
|
||||
static ACPI_INLINE prototype {return(0);}
|
||||
|
||||
#define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \
|
||||
static ACPI_INLINE prototype {return;}
|
||||
|
||||
@ -458,11 +480,7 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||||
u8 physical))
|
||||
|
||||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||
acpi_load_table(struct acpi_table_header *table,
|
||||
u32 *table_idx))
|
||||
|
||||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||
acpi_unload_table(u32 table_index))
|
||||
acpi_load_table(struct acpi_table_header *table))
|
||||
|
||||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||
acpi_unload_parent_table(acpi_handle object))
|
||||
@ -488,12 +506,10 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||
acpi_get_table(acpi_string signature, u32 instance,
|
||||
struct acpi_table_header
|
||||
**out_table))
|
||||
ACPI_EXTERNAL_RETURN_VOID(void acpi_put_table(struct acpi_table_header *table))
|
||||
|
||||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||
acpi_get_table_by_index(u32 table_index,
|
||||
struct acpi_table_header
|
||||
**out_table))
|
||||
acpi_get_table_by_index(u32 table_index,
|
||||
struct acpi_table_header
|
||||
**out_table))
|
||||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||
acpi_install_table_handler(acpi_table_handler
|
||||
handler, void *context))
|
||||
@ -748,12 +764,9 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
|
||||
u32 gpe_number,
|
||||
acpi_event_status
|
||||
*event_status))
|
||||
ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_dispatch_gpe(acpi_handle gpe_device, u32 gpe_number))
|
||||
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable_all_gpes(void))
|
||||
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void))
|
||||
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_wakeup_gpes(void))
|
||||
ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_any_gpe_status_set(u32 gpe_skip_number))
|
||||
ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_any_fixed_event_status_set(void))
|
||||
|
||||
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
|
||||
acpi_get_gpe_device(u32 gpe_index,
|
||||
@ -907,12 +920,6 @@ ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3)
|
||||
acpi_bios_error(const char *module_name,
|
||||
u32 line_number,
|
||||
const char *format, ...))
|
||||
ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(4)
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_bios_exception(const char *module_name,
|
||||
u32 line_number,
|
||||
acpi_status status,
|
||||
const char *format, ...))
|
||||
ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3)
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_bios_warning(const char *module_name,
|
||||
@ -922,7 +929,7 @@ ACPI_MSG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(3)
|
||||
/*
|
||||
* Debug output
|
||||
*/
|
||||
ACPI_DBG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(6)
|
||||
ACPI_DBG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(6) __nocapture(3)
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_debug_print(u32 requested_debug_level,
|
||||
u32 line_number,
|
||||
@ -951,6 +958,15 @@ void acpi_terminate_debugger(void);
|
||||
/*
|
||||
* Divergences
|
||||
*/
|
||||
ACPI_GLOBAL(u8, acpi_gbl_permanent_mmap);
|
||||
|
||||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||
acpi_get_table_with_size(acpi_string signature,
|
||||
u32 instance,
|
||||
struct acpi_table_header
|
||||
**out_table,
|
||||
acpi_size *tbl_size))
|
||||
|
||||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||
acpi_get_data_full(acpi_handle object,
|
||||
acpi_object_handler handler,
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acrestyp.h - Defines, types, and structures for resource descriptors
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACRESTYP_H__
|
||||
#define __ACRESTYP_H__
|
||||
|
||||
@ -139,7 +173,7 @@ struct acpi_resource_irq {
|
||||
u8 descriptor_length;
|
||||
u8 triggering;
|
||||
u8 polarity;
|
||||
u8 shareable;
|
||||
u8 sharable;
|
||||
u8 wake_capable;
|
||||
u8 interrupt_count;
|
||||
u8 interrupts[1];
|
||||
@ -255,11 +289,6 @@ union acpi_resource_attribute {
|
||||
u8 type_specific;
|
||||
};
|
||||
|
||||
struct acpi_resource_label {
|
||||
u16 string_length;
|
||||
char *string_ptr;
|
||||
};
|
||||
|
||||
struct acpi_resource_source {
|
||||
u8 index;
|
||||
u16 string_length;
|
||||
@ -328,7 +357,7 @@ struct acpi_resource_extended_irq {
|
||||
u8 producer_consumer;
|
||||
u8 triggering;
|
||||
u8 polarity;
|
||||
u8 shareable;
|
||||
u8 sharable;
|
||||
u8 wake_capable;
|
||||
u8 interrupt_count;
|
||||
struct acpi_resource_source resource_source;
|
||||
@ -348,7 +377,7 @@ struct acpi_resource_gpio {
|
||||
u8 connection_type;
|
||||
u8 producer_consumer; /* For values, see Producer/Consumer above */
|
||||
u8 pin_config;
|
||||
u8 shareable; /* For values, see Interrupt Attributes above */
|
||||
u8 sharable; /* For values, see Interrupt Attributes above */
|
||||
u8 wake_capable; /* For values, see Interrupt Attributes above */
|
||||
u8 io_restriction;
|
||||
u8 triggering; /* For values, see Interrupt Attributes above */
|
||||
@ -381,7 +410,7 @@ struct acpi_resource_gpio {
|
||||
#define ACPI_IO_RESTRICT_OUTPUT 2
|
||||
#define ACPI_IO_RESTRICT_NONE_PRESERVE 3
|
||||
|
||||
/* Common structure for I2C, SPI, UART, CSI2 serial descriptors */
|
||||
/* Common structure for I2C, SPI, and UART serial descriptors */
|
||||
|
||||
#define ACPI_RESOURCE_SERIAL_COMMON \
|
||||
u8 revision_id; \
|
||||
@ -403,7 +432,6 @@ ACPI_RESOURCE_SERIAL_COMMON};
|
||||
#define ACPI_RESOURCE_SERIAL_TYPE_I2C 1
|
||||
#define ACPI_RESOURCE_SERIAL_TYPE_SPI 2
|
||||
#define ACPI_RESOURCE_SERIAL_TYPE_UART 3
|
||||
#define ACPI_RESOURCE_SERIAL_TYPE_CSI2 4
|
||||
|
||||
/* Values for slave_mode field above */
|
||||
|
||||
@ -506,86 +534,6 @@ struct acpi_resource_uart_serialbus {
|
||||
#define ACPI_UART_CLEAR_TO_SEND (1<<6)
|
||||
#define ACPI_UART_REQUEST_TO_SEND (1<<7)
|
||||
|
||||
struct acpi_resource_csi2_serialbus {
|
||||
ACPI_RESOURCE_SERIAL_COMMON u8 local_port_instance;
|
||||
u8 phy_type;
|
||||
};
|
||||
|
||||
struct acpi_resource_pin_function {
|
||||
u8 revision_id;
|
||||
u8 pin_config;
|
||||
u8 shareable; /* For values, see Interrupt Attributes above */
|
||||
u16 function_number;
|
||||
u16 pin_table_length;
|
||||
u16 vendor_length;
|
||||
struct acpi_resource_source resource_source;
|
||||
u16 *pin_table;
|
||||
u8 *vendor_data;
|
||||
};
|
||||
|
||||
struct acpi_resource_pin_config {
|
||||
u8 revision_id;
|
||||
u8 producer_consumer; /* For values, see Producer/Consumer above */
|
||||
u8 shareable; /* For values, see Interrupt Attributes above */
|
||||
u8 pin_config_type;
|
||||
u32 pin_config_value;
|
||||
u16 pin_table_length;
|
||||
u16 vendor_length;
|
||||
struct acpi_resource_source resource_source;
|
||||
u16 *pin_table;
|
||||
u8 *vendor_data;
|
||||
};
|
||||
|
||||
/* Values for pin_config_type field above */
|
||||
|
||||
#define ACPI_PIN_CONFIG_DEFAULT 0
|
||||
#define ACPI_PIN_CONFIG_BIAS_PULL_UP 1
|
||||
#define ACPI_PIN_CONFIG_BIAS_PULL_DOWN 2
|
||||
#define ACPI_PIN_CONFIG_BIAS_DEFAULT 3
|
||||
#define ACPI_PIN_CONFIG_BIAS_DISABLE 4
|
||||
#define ACPI_PIN_CONFIG_BIAS_HIGH_IMPEDANCE 5
|
||||
#define ACPI_PIN_CONFIG_BIAS_BUS_HOLD 6
|
||||
#define ACPI_PIN_CONFIG_DRIVE_OPEN_DRAIN 7
|
||||
#define ACPI_PIN_CONFIG_DRIVE_OPEN_SOURCE 8
|
||||
#define ACPI_PIN_CONFIG_DRIVE_PUSH_PULL 9
|
||||
#define ACPI_PIN_CONFIG_DRIVE_STRENGTH 10
|
||||
#define ACPI_PIN_CONFIG_SLEW_RATE 11
|
||||
#define ACPI_PIN_CONFIG_INPUT_DEBOUNCE 12
|
||||
#define ACPI_PIN_CONFIG_INPUT_SCHMITT_TRIGGER 13
|
||||
|
||||
struct acpi_resource_pin_group {
|
||||
u8 revision_id;
|
||||
u8 producer_consumer; /* For values, see Producer/Consumer above */
|
||||
u16 pin_table_length;
|
||||
u16 vendor_length;
|
||||
u16 *pin_table;
|
||||
struct acpi_resource_label resource_label;
|
||||
u8 *vendor_data;
|
||||
};
|
||||
|
||||
struct acpi_resource_pin_group_function {
|
||||
u8 revision_id;
|
||||
u8 producer_consumer; /* For values, see Producer/Consumer above */
|
||||
u8 shareable; /* For values, see Interrupt Attributes above */
|
||||
u16 function_number;
|
||||
u16 vendor_length;
|
||||
struct acpi_resource_source resource_source;
|
||||
struct acpi_resource_label resource_source_label;
|
||||
u8 *vendor_data;
|
||||
};
|
||||
|
||||
struct acpi_resource_pin_group_config {
|
||||
u8 revision_id;
|
||||
u8 producer_consumer; /* For values, see Producer/Consumer above */
|
||||
u8 shareable; /* For values, see Interrupt Attributes above */
|
||||
u8 pin_config_type; /* For values, see pin_config_type above */
|
||||
u32 pin_config_value;
|
||||
u16 vendor_length;
|
||||
struct acpi_resource_source resource_source;
|
||||
struct acpi_resource_label resource_source_label;
|
||||
u8 *vendor_data;
|
||||
};
|
||||
|
||||
/* ACPI_RESOURCE_TYPEs */
|
||||
|
||||
#define ACPI_RESOURCE_TYPE_IRQ 0
|
||||
@ -608,12 +556,7 @@ struct acpi_resource_pin_group_config {
|
||||
#define ACPI_RESOURCE_TYPE_GPIO 17 /* ACPI 5.0 */
|
||||
#define ACPI_RESOURCE_TYPE_FIXED_DMA 18 /* ACPI 5.0 */
|
||||
#define ACPI_RESOURCE_TYPE_SERIAL_BUS 19 /* ACPI 5.0 */
|
||||
#define ACPI_RESOURCE_TYPE_PIN_FUNCTION 20 /* ACPI 6.2 */
|
||||
#define ACPI_RESOURCE_TYPE_PIN_CONFIG 21 /* ACPI 6.2 */
|
||||
#define ACPI_RESOURCE_TYPE_PIN_GROUP 22 /* ACPI 6.2 */
|
||||
#define ACPI_RESOURCE_TYPE_PIN_GROUP_FUNCTION 23 /* ACPI 6.2 */
|
||||
#define ACPI_RESOURCE_TYPE_PIN_GROUP_CONFIG 24 /* ACPI 6.2 */
|
||||
#define ACPI_RESOURCE_TYPE_MAX 24
|
||||
#define ACPI_RESOURCE_TYPE_MAX 19
|
||||
|
||||
/* Master union for resource descriptors */
|
||||
|
||||
@ -640,13 +583,7 @@ union acpi_resource_data {
|
||||
struct acpi_resource_i2c_serialbus i2c_serial_bus;
|
||||
struct acpi_resource_spi_serialbus spi_serial_bus;
|
||||
struct acpi_resource_uart_serialbus uart_serial_bus;
|
||||
struct acpi_resource_csi2_serialbus csi2_serial_bus;
|
||||
struct acpi_resource_common_serialbus common_serial_bus;
|
||||
struct acpi_resource_pin_function pin_function;
|
||||
struct acpi_resource_pin_config pin_config;
|
||||
struct acpi_resource_pin_group pin_group;
|
||||
struct acpi_resource_pin_group_function pin_group_function;
|
||||
struct acpi_resource_pin_group_config pin_group_config;
|
||||
|
||||
/* Common fields */
|
||||
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: actbl.h - Basic ACPI Table Definitions
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACTBL_H__
|
||||
#define __ACTBL_H__
|
||||
|
||||
@ -38,7 +72,6 @@
|
||||
#define ACPI_SIG_XSDT "XSDT" /* Extended System Description Table */
|
||||
#define ACPI_SIG_SSDT "SSDT" /* Secondary System Description Table */
|
||||
#define ACPI_RSDP_NAME "RSDP" /* Short name for RSDP, not signature */
|
||||
#define ACPI_OEM_NAME "OEM" /* Short name for OEM, not signature */
|
||||
|
||||
/*
|
||||
* All tables and structures must be byte-packed to match the ACPI
|
||||
@ -66,14 +99,14 @@
|
||||
******************************************************************************/
|
||||
|
||||
struct acpi_table_header {
|
||||
char signature[ACPI_NAMESEG_SIZE]; /* ASCII table signature */
|
||||
char signature[ACPI_NAME_SIZE]; /* ASCII table signature */
|
||||
u32 length; /* Length of table in bytes, including this header */
|
||||
u8 revision; /* ACPI Specification minor version number */
|
||||
u8 checksum; /* To make sum of entire table == 0 */
|
||||
char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
|
||||
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
|
||||
u32 oem_revision; /* OEM revision number */
|
||||
char asl_compiler_id[ACPI_NAMESEG_SIZE]; /* ASCII ASL compiler vendor ID */
|
||||
char asl_compiler_id[ACPI_NAME_SIZE]; /* ASCII ASL compiler vendor ID */
|
||||
u32 asl_compiler_revision; /* ASL compiler version */
|
||||
};
|
||||
|
||||
@ -338,30 +371,14 @@ struct acpi_table_desc {
|
||||
union acpi_name_union signature;
|
||||
acpi_owner_id owner_id;
|
||||
u8 flags;
|
||||
u16 validation_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* Maximum value of the validation_count field in struct acpi_table_desc.
|
||||
* When reached, validation_count cannot be changed any more and the table will
|
||||
* be permanently regarded as validated.
|
||||
*
|
||||
* This is to prevent situations in which unbalanced table get/put operations
|
||||
* may cause premature table unmapping in the OS to happen.
|
||||
*
|
||||
* The maximum validation count can be defined to any value, but should be
|
||||
* greater than the maximum number of OS early stage mapping slots to avoid
|
||||
* leaking early stage table mappings to the late stage.
|
||||
*/
|
||||
#define ACPI_MAX_TABLE_VALIDATIONS ACPI_UINT16_MAX
|
||||
|
||||
/* Masks for Flags field above */
|
||||
|
||||
#define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0) /* Virtual address, external maintained */
|
||||
#define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL (1) /* Physical address, internally mapped */
|
||||
#define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL (2) /* Virtual address, internallly allocated */
|
||||
#define ACPI_TABLE_ORIGIN_MASK (3)
|
||||
#define ACPI_TABLE_IS_VERIFIED (4)
|
||||
#define ACPI_TABLE_IS_LOADED (8)
|
||||
|
||||
/*
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,21 +1,55 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: actypes.h - Common data types for the entire ACPI subsystem
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACTYPES_H__
|
||||
#define __ACTYPES_H__
|
||||
|
||||
/* acpisrc:struct_defs -- for acpisrc conversion */
|
||||
|
||||
/*
|
||||
* ACPI_MACHINE_WIDTH must be specified in an OS- or compiler-dependent
|
||||
* header and must be either 32 or 64. 16-bit ACPICA is no longer
|
||||
* supported, as of 12/2006.
|
||||
* ACPI_MACHINE_WIDTH must be specified in an OS- or compiler-dependent header
|
||||
* and must be either 32 or 64. 16-bit ACPICA is no longer supported, as of
|
||||
* 12/2006.
|
||||
*/
|
||||
#ifndef ACPI_MACHINE_WIDTH
|
||||
#error ACPI_MACHINE_WIDTH not defined
|
||||
@ -53,9 +87,9 @@
|
||||
* s64 64-bit (8 byte) signed value
|
||||
*
|
||||
* COMPILER_DEPENDENT_UINT64/s64 - These types are defined in the
|
||||
* compiler-dependent header(s) and were introduced because there is no
|
||||
* common 64-bit integer type across the various compilation models, as
|
||||
* shown in the table below.
|
||||
* compiler-dependent header(s) and were introduced because there is no common
|
||||
* 64-bit integer type across the various compilation models, as shown in
|
||||
* the table below.
|
||||
*
|
||||
* Datatype LP64 ILP64 LLP64 ILP32 LP32 16bit
|
||||
* char 8 8 8 8 8 8
|
||||
@ -72,10 +106,10 @@
|
||||
* 2) These types represent the native word size of the target mode of the
|
||||
* processor, and may be 16-bit, 32-bit, or 64-bit as required. They are
|
||||
* usually used for memory allocation, efficient loop counters, and array
|
||||
* indexes. The types are similar to the size_t type in the C library and
|
||||
* are required because there is no C type that consistently represents the
|
||||
* native data width. acpi_size is needed because there is no guarantee
|
||||
* that a kernel-level C library is present.
|
||||
* indexes. The types are similar to the size_t type in the C library and are
|
||||
* required because there is no C type that consistently represents the native
|
||||
* data width. acpi_size is needed because there is no guarantee that a
|
||||
* kernel-level C library is present.
|
||||
*
|
||||
* acpi_size 16/32/64-bit unsigned value
|
||||
* acpi_native_int 16/32/64-bit signed value
|
||||
@ -132,14 +166,12 @@ typedef u64 acpi_physical_address;
|
||||
#define ACPI_SIZE_MAX ACPI_UINT64_MAX
|
||||
|
||||
#define ACPI_USE_NATIVE_DIVIDE /* Has native 64-bit integer support */
|
||||
#define ACPI_USE_NATIVE_MATH64 /* Has native 64-bit integer support */
|
||||
|
||||
/*
|
||||
* In the case of the Itanium Processor Family (IPF), the hardware does not
|
||||
* support misaligned memory transfers. Set the MISALIGNMENT_NOT_SUPPORTED
|
||||
* flag to indicate that special precautions must be taken to avoid alignment
|
||||
* faults. (IA64 or ia64 is currently used by existing compilers to indicate
|
||||
* IPF.)
|
||||
* support misaligned memory transfers. Set the MISALIGNMENT_NOT_SUPPORTED flag
|
||||
* to indicate that special precautions must be taken to avoid alignment faults.
|
||||
* (IA64 or ia64 is currently used by existing compilers to indicate IPF.)
|
||||
*
|
||||
* Note: EM64T and other X86-64 processors support misaligned transfers,
|
||||
* so there is no need to define this flag.
|
||||
@ -245,10 +277,6 @@ typedef u64 acpi_physical_address;
|
||||
#define acpi_spinlock void *
|
||||
#endif
|
||||
|
||||
#ifndef acpi_raw_spinlock
|
||||
#define acpi_raw_spinlock acpi_spinlock
|
||||
#endif
|
||||
|
||||
#ifndef acpi_semaphore
|
||||
#define acpi_semaphore void *
|
||||
#endif
|
||||
@ -281,8 +309,8 @@ typedef u64 acpi_physical_address;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some compilers complain about unused variables. Sometimes we don't want
|
||||
* to use all the variables (for example, _acpi_module_name). This allows us
|
||||
* Some compilers complain about unused variables. Sometimes we don't want to
|
||||
* use all the variables (for example, _acpi_module_name). This allows us
|
||||
* to tell the compiler in a per-variable manner that a variable
|
||||
* is unused
|
||||
*/
|
||||
@ -291,9 +319,8 @@ typedef u64 acpi_physical_address;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* All ACPICA external functions that are available to the rest of the
|
||||
* kernel are tagged with these macros which can be defined as appropriate
|
||||
* for the host.
|
||||
* All ACPICA external functions that are available to the rest of the kernel
|
||||
* are tagged with thes macros which can be defined as appropriate for the host.
|
||||
*
|
||||
* Notes:
|
||||
* ACPI_EXPORT_SYMBOL_INIT is used for initialization and termination
|
||||
@ -356,8 +383,7 @@ typedef u64 acpi_physical_address;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* ACPI Specification constants (Do not change unless the specification
|
||||
* changes)
|
||||
* ACPI Specification constants (Do not change unless the specification changes)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
@ -375,7 +401,7 @@ typedef u64 acpi_physical_address;
|
||||
|
||||
/* Names within the namespace are 4 bytes long */
|
||||
|
||||
#define ACPI_NAMESEG_SIZE 4 /* Fixed by ACPI spec */
|
||||
#define ACPI_NAME_SIZE 4
|
||||
#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */
|
||||
#define ACPI_PATH_SEPARATOR '.'
|
||||
|
||||
@ -438,12 +464,10 @@ typedef void *acpi_handle; /* Actually a ptr to a NS Node */
|
||||
#define ACPI_NSEC_PER_MSEC 1000000L
|
||||
#define ACPI_NSEC_PER_SEC 1000000000L
|
||||
|
||||
#define ACPI_TIME_AFTER(a, b) ((s64)((b) - (a)) < 0)
|
||||
|
||||
/* Owner IDs are used to track namespace nodes for selective deletion */
|
||||
|
||||
typedef u16 acpi_owner_id;
|
||||
#define ACPI_OWNER_ID_MAX 0xFFF /* 4095 possible owner IDs */
|
||||
typedef u8 acpi_owner_id;
|
||||
#define ACPI_OWNER_ID_MAX 0xFF
|
||||
|
||||
#define ACPI_INTEGER_BIT_SIZE 64
|
||||
#define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */
|
||||
@ -455,15 +479,15 @@ typedef u16 acpi_owner_id;
|
||||
/*
|
||||
* Constants with special meanings
|
||||
*/
|
||||
#define ACPI_ROOT_OBJECT ((acpi_handle) ACPI_TO_POINTER (ACPI_MAX_PTR))
|
||||
#define ACPI_ROOT_OBJECT ACPI_ADD_PTR (acpi_handle, NULL, ACPI_MAX_PTR)
|
||||
#define ACPI_WAIT_FOREVER 0xFFFF /* u16, as per ACPI spec */
|
||||
#define ACPI_DO_NOT_WAIT 0
|
||||
|
||||
/*
|
||||
* Obsolete: Acpi integer width. In ACPI version 1 (1996), integers are
|
||||
* 32 bits. In ACPI version 2 (2000) and later, integers are max 64 bits.
|
||||
* Note that this pertains to the ACPI integer type only, not to other
|
||||
* integers used in the implementation of the ACPICA subsystem.
|
||||
* Obsolete: Acpi integer width. In ACPI version 1 (1996), integers are 32 bits.
|
||||
* In ACPI version 2 (2000) and later, integers are 64 bits. Note that this
|
||||
* pertains to the ACPI integer type only, not to other integers used in the
|
||||
* implementation of the ACPICA subsystem.
|
||||
*
|
||||
* 01/2010: This type is obsolete and has been removed from the entire ACPICA
|
||||
* code base. It remains here for compatibility with device drivers that use
|
||||
@ -502,24 +526,24 @@ typedef u64 acpi_integer;
|
||||
#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **) (acpi_uintptr_t) (p))
|
||||
#define ACPI_ADD_PTR(t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8, (a)) + (acpi_size)(b)))
|
||||
#define ACPI_SUB_PTR(t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8, (a)) - (acpi_size)(b)))
|
||||
#define ACPI_PTR_DIFF(a, b) ((acpi_size) (ACPI_CAST_PTR (u8, (a)) - ACPI_CAST_PTR (u8, (b))))
|
||||
#define ACPI_PTR_DIFF(a, b) (acpi_size) (ACPI_CAST_PTR (u8, (a)) - ACPI_CAST_PTR (u8, (b)))
|
||||
|
||||
/* Pointer/Integer type conversions */
|
||||
|
||||
#define ACPI_TO_POINTER(i) ACPI_CAST_PTR (void, (acpi_size) (i))
|
||||
#define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p, (void *) 0)
|
||||
#define ACPI_OFFSET(d, f) ACPI_PTR_DIFF (&(((d *) 0)->f), (void *) 0)
|
||||
#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void, (void *) NULL,(acpi_size) i)
|
||||
#define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p, (void *) NULL)
|
||||
#define ACPI_OFFSET(d, f) ACPI_PTR_DIFF (&(((d *) 0)->f), (void *) NULL)
|
||||
#define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i)
|
||||
#define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i)
|
||||
|
||||
/* Optimizations for 4-character (32-bit) acpi_name manipulation */
|
||||
|
||||
#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
|
||||
#define ACPI_COMPARE_NAMESEG(a,b) (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b)))
|
||||
#define ACPI_COPY_NAMESEG(dest,src) (*ACPI_CAST_PTR (u32, (dest)) = *ACPI_CAST_PTR (u32, (src)))
|
||||
#define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b)))
|
||||
#define ACPI_MOVE_NAME(dest,src) (*ACPI_CAST_PTR (u32, (dest)) = *ACPI_CAST_PTR (u32, (src)))
|
||||
#else
|
||||
#define ACPI_COMPARE_NAMESEG(a,b) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAMESEG_SIZE))
|
||||
#define ACPI_COPY_NAMESEG(dest,src) (strncpy (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAMESEG_SIZE))
|
||||
#define ACPI_COMPARE_NAME(a,b) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE))
|
||||
#define ACPI_MOVE_NAME(dest,src) (strncpy (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAME_SIZE))
|
||||
#endif
|
||||
|
||||
/* Support for the special RSDP signature (8 characters) */
|
||||
@ -527,18 +551,6 @@ typedef u64 acpi_integer;
|
||||
#define ACPI_VALIDATE_RSDP_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_SIG_RSDP, 8))
|
||||
#define ACPI_MAKE_RSDP_SIG(dest) (memcpy (ACPI_CAST_PTR (char, (dest)), ACPI_SIG_RSDP, 8))
|
||||
|
||||
/* Support for OEMx signature (x can be any character) */
|
||||
#define ACPI_IS_OEM_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_OEM_NAME, 3) &&\
|
||||
strnlen (a, ACPI_NAMESEG_SIZE) == ACPI_NAMESEG_SIZE)
|
||||
|
||||
/*
|
||||
* Algorithm to obtain access bit or byte width.
|
||||
* Can be used with access_width of struct acpi_generic_address and access_size of
|
||||
* struct acpi_resource_generic_register.
|
||||
*/
|
||||
#define ACPI_ACCESS_BIT_WIDTH(size) (1 << ((size) + 2))
|
||||
#define ACPI_ACCESS_BYTE_WIDTH(size) (1 << ((size) - 1))
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Miscellaneous constants
|
||||
@ -546,17 +558,17 @@ typedef u64 acpi_integer;
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Initialization sequence options
|
||||
* Initialization sequence
|
||||
*/
|
||||
#define ACPI_FULL_INITIALIZATION 0x0000
|
||||
#define ACPI_NO_FACS_INIT 0x0001
|
||||
#define ACPI_NO_ACPI_ENABLE 0x0002
|
||||
#define ACPI_NO_HARDWARE_INIT 0x0004
|
||||
#define ACPI_NO_EVENT_INIT 0x0008
|
||||
#define ACPI_NO_HANDLER_INIT 0x0010
|
||||
#define ACPI_NO_OBJECT_INIT 0x0020
|
||||
#define ACPI_NO_DEVICE_INIT 0x0040
|
||||
#define ACPI_NO_ADDRESS_SPACE_INIT 0x0080
|
||||
#define ACPI_FULL_INITIALIZATION 0x00
|
||||
#define ACPI_NO_ADDRESS_SPACE_INIT 0x01
|
||||
#define ACPI_NO_HARDWARE_INIT 0x02
|
||||
#define ACPI_NO_EVENT_INIT 0x04
|
||||
#define ACPI_NO_HANDLER_INIT 0x08
|
||||
#define ACPI_NO_ACPI_ENABLE 0x10
|
||||
#define ACPI_NO_DEVICE_INIT 0x20
|
||||
#define ACPI_NO_OBJECT_INIT 0x40
|
||||
#define ACPI_NO_FACS_INIT 0x80
|
||||
|
||||
/*
|
||||
* Initialization state
|
||||
@ -617,10 +629,8 @@ typedef u64 acpi_integer;
|
||||
#define ACPI_NOTIFY_LOCALITY_UPDATE (u8) 0x0B
|
||||
#define ACPI_NOTIFY_SHUTDOWN_REQUEST (u8) 0x0C
|
||||
#define ACPI_NOTIFY_AFFINITY_UPDATE (u8) 0x0D
|
||||
#define ACPI_NOTIFY_MEMORY_UPDATE (u8) 0x0E
|
||||
#define ACPI_NOTIFY_DISCONNECT_RECOVER (u8) 0x0F
|
||||
|
||||
#define ACPI_GENERIC_NOTIFY_MAX 0x0F
|
||||
#define ACPI_GENERIC_NOTIFY_MAX 0x0D
|
||||
#define ACPI_SPECIFIC_NOTIFY_MAX 0x84
|
||||
|
||||
/*
|
||||
@ -657,11 +667,10 @@ typedef u32 acpi_object_type;
|
||||
|
||||
/*
|
||||
* These are object types that do not map directly to the ACPI
|
||||
* object_type() operator. They are used for various internal purposes
|
||||
* only. If new predefined ACPI_TYPEs are added (via the ACPI
|
||||
* specification), these internal types must move upwards. (There
|
||||
* is code that depends on these values being contiguous with the
|
||||
* external types above.)
|
||||
* object_type() operator. They are used for various internal purposes only.
|
||||
* If new predefined ACPI_TYPEs are added (via the ACPI specification), these
|
||||
* internal types must move upwards. (There is code that depends on these
|
||||
* values being contiguous with the external types above.)
|
||||
*/
|
||||
#define ACPI_TYPE_LOCAL_REGION_FIELD 0x11
|
||||
#define ACPI_TYPE_LOCAL_BANK_FIELD 0x12
|
||||
@ -761,7 +770,7 @@ typedef u32 acpi_event_status;
|
||||
* | | | | +-- Type of dispatch:to method, handler, notify, or none
|
||||
* | | | +----- Interrupt type: edge or level triggered
|
||||
* | | +------- Is a Wake GPE
|
||||
* | +--------- Has been enabled automatically at init time
|
||||
* | +--------- Is GPE masked by the software GPE masking machanism
|
||||
* +------------ <Reserved>
|
||||
*/
|
||||
#define ACPI_GPE_DISPATCH_NONE (u8) 0x00
|
||||
@ -777,8 +786,6 @@ typedef u32 acpi_event_status;
|
||||
#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x08
|
||||
|
||||
#define ACPI_GPE_CAN_WAKE (u8) 0x10
|
||||
#define ACPI_GPE_AUTO_ENABLED (u8) 0x20
|
||||
#define ACPI_GPE_INITIALIZED (u8) 0x40
|
||||
|
||||
/*
|
||||
* Flags for GPE and Lock interfaces
|
||||
@ -815,16 +822,15 @@ typedef u8 acpi_adr_space_type;
|
||||
#define ACPI_ADR_SPACE_GPIO (acpi_adr_space_type) 8
|
||||
#define ACPI_ADR_SPACE_GSBUS (acpi_adr_space_type) 9
|
||||
#define ACPI_ADR_SPACE_PLATFORM_COMM (acpi_adr_space_type) 10
|
||||
#define ACPI_ADR_SPACE_PLATFORM_RT (acpi_adr_space_type) 11
|
||||
|
||||
#define ACPI_NUM_PREDEFINED_REGIONS 12
|
||||
#define ACPI_NUM_PREDEFINED_REGIONS 11
|
||||
|
||||
/*
|
||||
* Special Address Spaces
|
||||
*
|
||||
* Note: A Data Table region is a special type of operation region
|
||||
* that has its own AML opcode. However, internally, the AML
|
||||
* interpreter simply creates an operation region with an address
|
||||
* interpreter simply creates an operation region with an an address
|
||||
* space type of ACPI_ADR_SPACE_DATA_TABLE.
|
||||
*/
|
||||
#define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 0x7E /* Internal to ACPICA only */
|
||||
@ -888,13 +894,22 @@ typedef u8 acpi_adr_space_type;
|
||||
#define ACPI_ENABLE_EVENT 1
|
||||
#define ACPI_DISABLE_EVENT 0
|
||||
|
||||
/* Sleep function dispatch */
|
||||
|
||||
typedef acpi_status (*acpi_sleep_function) (u8 sleep_state);
|
||||
|
||||
struct acpi_sleep_functions {
|
||||
acpi_sleep_function legacy_function;
|
||||
acpi_sleep_function extended_function;
|
||||
};
|
||||
|
||||
/*
|
||||
* External ACPI object definition
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note: Type == ACPI_TYPE_ANY (0) is used to indicate a NULL package
|
||||
* element or an unresolved named reference.
|
||||
* Note: Type == ACPI_TYPE_ANY (0) is used to indicate a NULL package element
|
||||
* or an unresolved named reference.
|
||||
*/
|
||||
union acpi_object {
|
||||
acpi_object_type type; /* See definition of acpi_ns_type for values */
|
||||
@ -1146,12 +1161,12 @@ struct acpi_pnp_device_id {
|
||||
struct acpi_pnp_device_id_list {
|
||||
u32 count; /* Number of IDs in Ids array */
|
||||
u32 list_size; /* Size of list, including ID strings */
|
||||
struct acpi_pnp_device_id ids[]; /* ID array */
|
||||
struct acpi_pnp_device_id ids[1]; /* ID array */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure returned from acpi_get_object_info.
|
||||
* Optimized for both 32-bit and 64-bit builds.
|
||||
* Optimized for both 32- and 64-bit builds
|
||||
*/
|
||||
struct acpi_device_info {
|
||||
u32 info_size; /* Size of info, including ID strings */
|
||||
@ -1162,6 +1177,7 @@ struct acpi_device_info {
|
||||
u8 flags; /* Miscellaneous info */
|
||||
u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */
|
||||
u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */
|
||||
u32 current_status; /* _STA value */
|
||||
u64 address; /* _ADR value */
|
||||
struct acpi_pnp_device_id hardware_id; /* _HID value */
|
||||
struct acpi_pnp_device_id unique_id; /* _UID value */
|
||||
@ -1175,6 +1191,7 @@ struct acpi_device_info {
|
||||
|
||||
/* Flags for Valid field above (acpi_get_object_info) */
|
||||
|
||||
#define ACPI_VALID_STA 0x0001
|
||||
#define ACPI_VALID_ADR 0x0002
|
||||
#define ACPI_VALID_HID 0x0004
|
||||
#define ACPI_VALID_UID 0x0008
|
||||
@ -1201,18 +1218,12 @@ struct acpi_pci_id {
|
||||
u16 function;
|
||||
};
|
||||
|
||||
struct acpi_mem_mapping {
|
||||
acpi_physical_address physical_address;
|
||||
u8 *logical_address;
|
||||
acpi_size length;
|
||||
struct acpi_mem_mapping *next_mm;
|
||||
};
|
||||
|
||||
struct acpi_mem_space_context {
|
||||
u32 length;
|
||||
acpi_physical_address address;
|
||||
struct acpi_mem_mapping *cur_mm;
|
||||
struct acpi_mem_mapping *first_mm;
|
||||
acpi_physical_address mapped_physical_address;
|
||||
u8 *mapped_logical_address;
|
||||
acpi_size mapped_length;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1273,23 +1284,10 @@ typedef enum {
|
||||
#define ACPI_OSI_WIN_VISTA_SP2 0x0A
|
||||
#define ACPI_OSI_WIN_7 0x0B
|
||||
#define ACPI_OSI_WIN_8 0x0C
|
||||
#define ACPI_OSI_WIN_8_1 0x0D
|
||||
#define ACPI_OSI_WIN_10 0x0E
|
||||
#define ACPI_OSI_WIN_10_RS1 0x0F
|
||||
#define ACPI_OSI_WIN_10_RS2 0x10
|
||||
#define ACPI_OSI_WIN_10_RS3 0x11
|
||||
#define ACPI_OSI_WIN_10_RS4 0x12
|
||||
#define ACPI_OSI_WIN_10_RS5 0x13
|
||||
#define ACPI_OSI_WIN_10_19H1 0x14
|
||||
#define ACPI_OSI_WIN_10 0x0D
|
||||
|
||||
/* Definitions of getopt */
|
||||
|
||||
#define ACPI_OPT_END -1
|
||||
|
||||
/* Definitions for explicit fallthrough */
|
||||
|
||||
#ifndef ACPI_FALLTHROUGH
|
||||
#define ACPI_FALLTHROUGH do {} while(0)
|
||||
#endif
|
||||
|
||||
#endif /* __ACTYPES_H__ */
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acuuid.h - ACPI-related UUID/GUID definitions
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACUUID_H__
|
||||
#define __ACUUID_H__
|
||||
|
||||
@ -27,10 +61,6 @@
|
||||
#define UUID_PCI_HOST_BRIDGE "33db4d5b-1ff7-401c-9657-7441c03dd766"
|
||||
#define UUID_I2C_DEVICE "3cdff6f7-4267-4555-ad05-b30a3d8938de"
|
||||
#define UUID_POWER_BUTTON "dfbcf3c5-e7a5-44e6-9c1f-29c76f6e059c"
|
||||
#define UUID_MEMORY_DEVICE "03b19910-f473-11dd-87af-0800200c9a66"
|
||||
#define UUID_GENERIC_BUTTONS_DEVICE "fa6bd625-9ce8-470d-a2c7-b3ca36c4282e"
|
||||
#define UUID_NVDIMM_ROOT_DEVICE "2f10e7a4-9e91-11e4-89d3-123b93f75cba"
|
||||
#define UUID_CONTROL_METHOD_BATTERY "f18fc78b-0f15-4978-b793-53f833a1d35b"
|
||||
|
||||
/* Interfaces */
|
||||
|
||||
@ -39,7 +69,6 @@
|
||||
|
||||
/* NVDIMM - NFIT table */
|
||||
|
||||
#define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
|
||||
#define UUID_VOLATILE_MEMORY "7305944f-fdda-44e3-b16c-3f22d252e5d0"
|
||||
#define UUID_PERSISTENT_MEMORY "66f0d379-b4f3-4074-ac43-0d3318b78cdb"
|
||||
#define UUID_CONTROL_REGION "92f701f6-13b4-405d-910b-299367e8234c"
|
||||
@ -48,15 +77,6 @@
|
||||
#define UUID_VOLATILE_VIRTUAL_CD "3d5abd30-4175-87ce-6d64-d2ade523c4bb"
|
||||
#define UUID_PERSISTENT_VIRTUAL_DISK "5cea02c9-4d07-69d3-269f-4496fbe096f9"
|
||||
#define UUID_PERSISTENT_VIRTUAL_CD "08018188-42cd-bb48-100f-5387d53ded3d"
|
||||
#define UUID_NFIT_DIMM_N_MSFT "1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"
|
||||
#define UUID_NFIT_DIMM_N_HPE1 "9002c334-acf3-4c0e-9642-a235f0d53bc6"
|
||||
#define UUID_NFIT_DIMM_N_HPE2 "5008664b-b758-41a0-a03c-27c2f2d04f7e"
|
||||
#define UUID_NFIT_DIMM_N_HYPERV "5746c5f2-a9a2-4264-ad0e-e4ddc9e09e80"
|
||||
|
||||
/* Processor Properties (ACPI 6.2) */
|
||||
|
||||
#define UUID_CACHE_PROPERTIES "6DC63E77-257E-4E78-A973-A21F2796898D"
|
||||
#define UUID_PHYSICAL_PROPERTY "DDE4D59A-AA42-4349-B407-EA40F57D9FB7"
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
@ -65,9 +85,5 @@
|
||||
#define UUID_BATTERY_THERMAL_LIMIT "4c2067e3-887d-475c-9720-4af1d3ed602e"
|
||||
#define UUID_THERMAL_EXTENSIONS "14d399cd-7a27-4b18-8fb4-7cb7b9f4e500"
|
||||
#define UUID_DEVICE_PROPERTIES "daffd814-6eba-4d8c-8a91-bc9bbf4aa301"
|
||||
#define UUID_DEVICE_GRAPHS "ab02a46b-74c7-45a2-bd68-f7d344ef2153"
|
||||
#define UUID_HIERARCHICAL_DATA_EXTENSION "dbb8e3e6-5886-4ba6-8795-1319f52a966b"
|
||||
#define UUID_CORESIGHT_GRAPH "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd"
|
||||
#define UUID_USB4_CAPABILITIES "23a0d13a-26ab-486c-9c5f-0ffa525a575a"
|
||||
|
||||
#endif /* __ACUUID_H__ */
|
||||
#endif /* __AUUID_H__ */
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* apei.h - ACPI Platform Error Interface
|
||||
*/
|
||||
@ -17,13 +16,7 @@
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
enum hest_status {
|
||||
HEST_ENABLED,
|
||||
HEST_DISABLED,
|
||||
HEST_NOT_FOUND,
|
||||
};
|
||||
|
||||
extern int hest_disable;
|
||||
extern bool hest_disable;
|
||||
extern int erst_disable;
|
||||
#ifdef CONFIG_ACPI_APEI_GHES
|
||||
extern bool ghes_disable;
|
||||
@ -51,6 +44,7 @@ int erst_clear(u64 record_id);
|
||||
|
||||
int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data);
|
||||
void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
|
||||
void arch_apei_flush_tlb_one(unsigned long addr);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,14 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef ACPI_BUTTON_H
|
||||
#define ACPI_BUTTON_H
|
||||
|
||||
#define ACPI_BUTTON_HID_POWER "PNP0C0C"
|
||||
#define ACPI_BUTTON_HID_LID "PNP0C0D"
|
||||
#define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_ACPI_BUTTON)
|
||||
extern int acpi_lid_notifier_register(struct notifier_block *nb);
|
||||
extern int acpi_lid_notifier_unregister(struct notifier_block *nb);
|
||||
extern int acpi_lid_open(void);
|
||||
#else
|
||||
static inline int acpi_lid_notifier_register(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int acpi_lid_notifier_unregister(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int acpi_lid_open(void)
|
||||
{
|
||||
return 1;
|
||||
|
@ -1,32 +1,33 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* CPPC (Collaborative Processor Performance Control) methods used
|
||||
* by CPUfreq drivers.
|
||||
*
|
||||
* (C) Copyright 2014, 2015 Linaro Ltd.
|
||||
* Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
|
||||
*
|
||||
* 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; version 2
|
||||
* of the License.
|
||||
*/
|
||||
|
||||
#ifndef _CPPC_ACPI_H
|
||||
#define _CPPC_ACPI_H
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <acpi/pcc.h>
|
||||
#include <acpi/processor.h>
|
||||
|
||||
/* Support CPPCv2 and CPPCv3 */
|
||||
#define CPPC_V2_REV 2
|
||||
#define CPPC_V3_REV 3
|
||||
#define CPPC_V2_NUM_ENT 21
|
||||
#define CPPC_V3_NUM_ENT 23
|
||||
/* Only support CPPCv2 for now. */
|
||||
#define CPPC_NUM_ENT 21
|
||||
#define CPPC_REV 2
|
||||
|
||||
#define PCC_CMD_COMPLETE_MASK (1 << 0)
|
||||
#define PCC_ERROR_MASK (1 << 2)
|
||||
|
||||
#define MAX_CPC_REG_ENT 21
|
||||
#define MAX_CPC_REG_ENT 19
|
||||
|
||||
/* CPPC specific PCC commands. */
|
||||
#define CMD_READ 0
|
||||
@ -40,7 +41,7 @@ struct cpc_reg {
|
||||
u8 bit_width;
|
||||
u8 bit_offset;
|
||||
u8 access_width;
|
||||
u64 address;
|
||||
u64 __iomem address;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
@ -90,8 +91,6 @@ enum cppc_regs {
|
||||
AUTO_ACT_WINDOW,
|
||||
ENERGY_PERF,
|
||||
REFERENCE_PERF,
|
||||
LOWEST_FREQ,
|
||||
NOMINAL_FREQ,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -101,13 +100,9 @@ enum cppc_regs {
|
||||
* today.
|
||||
*/
|
||||
struct cppc_perf_caps {
|
||||
u32 guaranteed_perf;
|
||||
u32 highest_perf;
|
||||
u32 nominal_perf;
|
||||
u32 lowest_perf;
|
||||
u32 lowest_nonlinear_perf;
|
||||
u32 lowest_freq;
|
||||
u32 nominal_freq;
|
||||
};
|
||||
|
||||
struct cppc_perf_ctrls {
|
||||
@ -120,72 +115,24 @@ struct cppc_perf_fb_ctrs {
|
||||
u64 reference;
|
||||
u64 delivered;
|
||||
u64 reference_perf;
|
||||
u64 wraparound_time;
|
||||
u64 ctr_wrap_time;
|
||||
};
|
||||
|
||||
/* Per CPU container for runtime CPPC management. */
|
||||
struct cppc_cpudata {
|
||||
struct list_head node;
|
||||
int cpu;
|
||||
struct cppc_perf_caps perf_caps;
|
||||
struct cppc_perf_ctrls perf_ctrls;
|
||||
struct cppc_perf_fb_ctrs perf_fb_ctrs;
|
||||
struct cpufreq_policy *cur_policy;
|
||||
unsigned int shared_type;
|
||||
cpumask_var_t shared_cpu_map;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ACPI_CPPC_LIB
|
||||
extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf);
|
||||
extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf);
|
||||
extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
|
||||
extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
|
||||
extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
|
||||
extern bool acpi_cpc_valid(void);
|
||||
extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
|
||||
extern int acpi_get_psd_map(struct cppc_cpudata **);
|
||||
extern unsigned int cppc_get_transition_latency(int cpu);
|
||||
extern bool cpc_ffh_supported(void);
|
||||
extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
|
||||
extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
|
||||
#else /* !CONFIG_ACPI_CPPC_LIB */
|
||||
static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
static inline bool acpi_cpc_valid(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline unsigned int cppc_get_transition_latency(int cpu)
|
||||
{
|
||||
return CPUFREQ_ETERNAL;
|
||||
}
|
||||
static inline bool cpc_ffh_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
static inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
#endif /* !CONFIG_ACPI_CPPC_LIB */
|
||||
|
||||
#endif /* _CPPC_ACPI_H*/
|
||||
|
@ -1,7 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef GHES_H
|
||||
#define GHES_H
|
||||
|
||||
#include <acpi/apei.h>
|
||||
#include <acpi/hed.h>
|
||||
|
||||
@ -13,14 +9,13 @@
|
||||
* estatus: memory buffer for error status block, allocated during
|
||||
* HEST parsing.
|
||||
*/
|
||||
#define GHES_TO_CLEAR 0x0001
|
||||
#define GHES_EXITING 0x0002
|
||||
|
||||
struct ghes {
|
||||
union {
|
||||
struct acpi_hest_generic *generic;
|
||||
struct acpi_hest_generic_v2 *generic_v2;
|
||||
};
|
||||
struct acpi_hest_generic *generic;
|
||||
struct acpi_hest_generic_status *estatus;
|
||||
u64 buffer_paddr;
|
||||
unsigned long flags;
|
||||
union {
|
||||
struct list_head list;
|
||||
@ -33,14 +28,11 @@ struct ghes_estatus_node {
|
||||
struct llist_node llnode;
|
||||
struct acpi_hest_generic *generic;
|
||||
struct ghes *ghes;
|
||||
|
||||
int task_work_cpu;
|
||||
struct callback_head task_work;
|
||||
};
|
||||
|
||||
struct ghes_estatus_cache {
|
||||
u32 estatus_len;
|
||||
atomic_t count;
|
||||
atomic_unchecked_t count;
|
||||
struct acpi_hest_generic *generic;
|
||||
unsigned long long time_in;
|
||||
struct rcu_head rcu;
|
||||
@ -53,96 +45,28 @@ enum {
|
||||
GHES_SEV_PANIC = 0x3,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI_GHES
|
||||
/**
|
||||
* ghes_register_vendor_record_notifier - register a notifier for vendor
|
||||
* records that the kernel would otherwise ignore.
|
||||
* @nb: pointer to the notifier_block structure of the event handler.
|
||||
*
|
||||
* return 0 : SUCCESS, non-zero : FAIL
|
||||
*/
|
||||
int ghes_register_vendor_record_notifier(struct notifier_block *nb);
|
||||
|
||||
/**
|
||||
* ghes_unregister_vendor_record_notifier - unregister the previously
|
||||
* registered vendor record notifier.
|
||||
* @nb: pointer to the notifier_block structure of the vendor record handler.
|
||||
*/
|
||||
void ghes_unregister_vendor_record_notifier(struct notifier_block *nb);
|
||||
#endif
|
||||
|
||||
int ghes_estatus_pool_init(int num_ghes);
|
||||
|
||||
/* From drivers/edac/ghes_edac.c */
|
||||
|
||||
#ifdef CONFIG_EDAC_GHES
|
||||
void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
|
||||
void ghes_edac_report_mem_error(struct ghes *ghes, int sev,
|
||||
struct cper_sec_mem_err *mem_err);
|
||||
|
||||
int ghes_edac_register(struct ghes *ghes, struct device *dev);
|
||||
|
||||
void ghes_edac_unregister(struct ghes *ghes);
|
||||
|
||||
#else
|
||||
static inline void ghes_edac_report_mem_error(int sev,
|
||||
static inline void ghes_edac_report_mem_error(struct ghes *ghes, int sev,
|
||||
struct cper_sec_mem_err *mem_err)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int ghes_edac_register(struct ghes *ghes, struct device *dev)
|
||||
{
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ghes_edac_unregister(struct ghes *ghes)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int acpi_hest_get_version(struct acpi_hest_generic_data *gdata)
|
||||
{
|
||||
return gdata->revision >> 8;
|
||||
}
|
||||
|
||||
static inline void *acpi_hest_get_payload(struct acpi_hest_generic_data *gdata)
|
||||
{
|
||||
if (acpi_hest_get_version(gdata) >= 3)
|
||||
return (void *)(((struct acpi_hest_generic_data_v300 *)(gdata)) + 1);
|
||||
|
||||
return gdata + 1;
|
||||
}
|
||||
|
||||
static inline int acpi_hest_get_error_length(struct acpi_hest_generic_data *gdata)
|
||||
{
|
||||
return ((struct acpi_hest_generic_data *)(gdata))->error_data_length;
|
||||
}
|
||||
|
||||
static inline int acpi_hest_get_size(struct acpi_hest_generic_data *gdata)
|
||||
{
|
||||
if (acpi_hest_get_version(gdata) >= 3)
|
||||
return sizeof(struct acpi_hest_generic_data_v300);
|
||||
|
||||
return sizeof(struct acpi_hest_generic_data);
|
||||
}
|
||||
|
||||
static inline int acpi_hest_get_record_size(struct acpi_hest_generic_data *gdata)
|
||||
{
|
||||
return (acpi_hest_get_size(gdata) + acpi_hest_get_error_length(gdata));
|
||||
}
|
||||
|
||||
static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata)
|
||||
{
|
||||
return (void *)(gdata) + acpi_hest_get_record_size(gdata);
|
||||
}
|
||||
|
||||
#define apei_estatus_for_each_section(estatus, section) \
|
||||
for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
|
||||
(void *)section - (void *)(estatus + 1) < estatus->data_length; \
|
||||
section = acpi_hest_get_next(section))
|
||||
|
||||
#ifdef CONFIG_ACPI_APEI_SEA
|
||||
int ghes_notify_sea(void);
|
||||
#else
|
||||
static inline int ghes_notify_sea(void) { return -ENOENT; }
|
||||
#endif
|
||||
|
||||
#endif /* GHES_H */
|
||||
|
@ -1,9 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* hed.h - ACPI Hardware Error Device
|
||||
*
|
||||
* Copyright (C) 2009, Intel Corp.
|
||||
* Author: Huang Ying <ying.huang@intel.com>
|
||||
*
|
||||
* This file is released under the GPLv2.
|
||||
*/
|
||||
|
||||
#ifndef ACPI_HED_H
|
||||
|
@ -1,6 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* PCC (Platform Communications Channel) methods
|
||||
*
|
||||
* 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; version 2
|
||||
* of the License.
|
||||
*/
|
||||
|
||||
#ifndef _PCC_H
|
||||
@ -9,7 +13,6 @@
|
||||
#include <linux/mailbox_controller.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
|
||||
#define MAX_PCC_SUBSPACES 256
|
||||
#ifdef CONFIG_PCC
|
||||
extern struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
|
||||
int subspace_id);
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
/* _PDC bit definition for Intel processors */
|
||||
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acenv.h - Host and compiler configuration
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACENV_H__
|
||||
#define __ACENV_H__
|
||||
|
||||
@ -41,8 +75,7 @@
|
||||
(defined ACPI_NAMES_APP) || \
|
||||
(defined ACPI_SRC_APP) || \
|
||||
(defined ACPI_XTRACT_APP) || \
|
||||
(defined ACPI_EXAMPLE_APP) || \
|
||||
(defined ACPI_EFI_HELLO)
|
||||
(defined ACPI_EXAMPLE_APP)
|
||||
#define ACPI_APPLICATION
|
||||
#define ACPI_SINGLE_THREADED
|
||||
#define USE_NATIVE_ALLOCATE_ZEROED
|
||||
@ -128,17 +161,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* acpisrc CR\LF support
|
||||
* Unix file line endings do not include the carriage return.
|
||||
* If the acpisrc utility is being built using a microsoft compiler, it means
|
||||
* that it will be running on a windows machine which means that the output is
|
||||
* expected to have CR/LF newlines. If the acpisrc utility is built with
|
||||
* anything else, it will likely run on a system with LF newlines. This flag
|
||||
* tells the acpisrc utility that newlines will be in the LF format.
|
||||
*/
|
||||
#define ACPI_SRC_OS_LF_ONLY 0
|
||||
|
||||
/*! [Begin] no source code translation */
|
||||
|
||||
/******************************************************************************
|
||||
@ -265,11 +287,6 @@
|
||||
#define ACPI_INLINE
|
||||
#endif
|
||||
|
||||
/* Use ordered initialization if compiler doesn't support designated. */
|
||||
#ifndef ACPI_STRUCT_INIT
|
||||
#define ACPI_STRUCT_INIT(field, value) value
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Configurable calling conventions:
|
||||
*
|
||||
@ -340,7 +357,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#if defined (ACPI_APPLICATION) || defined(ACPI_LIBRARY)
|
||||
#ifdef ACPI_APPLICATION
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acenvex.h - Extra host and compiler configuration
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACENVEX_H__
|
||||
#define __ACENVEX_H__
|
||||
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acgcc.h - GCC specific defines, etc.
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACGCC_H__
|
||||
#define __ACGCC_H__
|
||||
|
||||
@ -14,22 +48,7 @@
|
||||
* Use compiler specific <stdarg.h> is a good practice for even when
|
||||
* -nostdinc is specified (i.e., ACPI_USE_STANDARD_HEADERS undefined.
|
||||
*/
|
||||
#ifndef va_arg
|
||||
#ifdef ACPI_USE_BUILTIN_STDARG
|
||||
typedef __builtin_va_list va_list;
|
||||
#define va_start(v, l) __builtin_va_start(v, l)
|
||||
#define va_end(v) __builtin_va_end(v)
|
||||
#define va_arg(v, l) __builtin_va_arg(v, l)
|
||||
#define va_copy(d, s) __builtin_va_copy(d, s)
|
||||
#else
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/stdarg.h>
|
||||
#else
|
||||
/* Used to build acpi tools */
|
||||
#include <stdarg.h>
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* ACPI_USE_BUILTIN_STDARG */
|
||||
#endif /* ! va_arg */
|
||||
|
||||
#define ACPI_INLINE __inline__
|
||||
|
||||
@ -55,23 +74,4 @@ typedef __builtin_va_list va_list;
|
||||
|
||||
#define COMPILER_VA_MACRO 1
|
||||
|
||||
/* GCC supports native multiply/shift on 32-bit platforms */
|
||||
|
||||
#define ACPI_USE_NATIVE_MATH64
|
||||
|
||||
/* GCC did not support __has_attribute until 5.1. */
|
||||
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Explicitly mark intentional explicit fallthrough to silence
|
||||
* -Wimplicit-fallthrough in GCC 7.1+.
|
||||
*/
|
||||
|
||||
#if __has_attribute(__fallthrough__)
|
||||
#define ACPI_FALLTHROUGH __attribute__((__fallthrough__))
|
||||
#endif
|
||||
|
||||
#endif /* __ACGCC_H__ */
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acgccex.h - Extra GCC specific defines, etc.
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACGCCEX_H__
|
||||
#define __ACGCCEX_H__
|
||||
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: acintel.h - VC specific defines, etc.
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2017, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACINTEL_H__
|
||||
#define __ACINTEL_H__
|
||||
|
||||
@ -14,9 +48,7 @@
|
||||
* Use compiler specific <stdarg.h> is a good practice for even when
|
||||
* -nostdinc is specified (i.e., ACPI_USE_STANDARD_HEADERS undefined.
|
||||
*/
|
||||
#ifndef va_arg
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
/* Configuration specific to Intel 64-bit C compiler */
|
||||
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: aclinux.h - OS specific defines, etc. for Linux
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACLINUX_H__
|
||||
#define __ACLINUX_H__
|
||||
|
||||
@ -24,19 +58,13 @@
|
||||
|
||||
#define ACPI_USE_SYSTEM_CLIBRARY
|
||||
#define ACPI_USE_DO_WHILE_0
|
||||
#define ACPI_IGNORE_PACKAGE_RESOLUTION_ERRORS
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define ACPI_USE_SYSTEM_INTTYPES
|
||||
#define ACPI_USE_GPE_POLLING
|
||||
|
||||
/* Kernel specific ACPICA configuration */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#define ACPI_PCI_CONFIGURED
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI_REDUCED_HARDWARE_ONLY
|
||||
#define ACPI_REDUCED_HARDWARE 1
|
||||
#endif
|
||||
@ -66,11 +94,6 @@
|
||||
|
||||
#define ACPI_INIT_FUNCTION __init
|
||||
|
||||
/* Use a specific bugging default separate from ACPICA */
|
||||
|
||||
#undef ACPI_DEBUG_DEFAULT
|
||||
#define ACPI_DEBUG_DEFAULT (ACPI_LV_INFO | ACPI_LV_REPAIR)
|
||||
|
||||
#ifndef CONFIG_ACPI
|
||||
|
||||
/* External globals for __KERNEL__, stubs is needed */
|
||||
@ -105,23 +128,17 @@
|
||||
/* Host-dependent types and defines for in-kernel ACPICA */
|
||||
|
||||
#define ACPI_MACHINE_WIDTH BITS_PER_LONG
|
||||
#define ACPI_USE_NATIVE_MATH64
|
||||
#define ACPI_EXPORT_SYMBOL(symbol) EXPORT_SYMBOL(symbol);
|
||||
#define strtoul simple_strtoul
|
||||
|
||||
#define acpi_cache_t struct kmem_cache
|
||||
#define acpi_spinlock spinlock_t *
|
||||
#define acpi_raw_spinlock raw_spinlock_t *
|
||||
#define acpi_cpu_flags unsigned long
|
||||
|
||||
/* Use native linux version of acpi_os_allocate_zeroed */
|
||||
|
||||
#define USE_NATIVE_ALLOCATE_ZEROED
|
||||
|
||||
/* Use logical addresses for accessing GPE registers in system memory */
|
||||
|
||||
#define ACPI_GPE_USE_LOGICAL_ADDRESSES
|
||||
|
||||
/*
|
||||
* Overrides for in-kernel ACPICA
|
||||
*/
|
||||
@ -133,18 +150,14 @@
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_object
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_raw_lock
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_delete_raw_lock
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_acquire_raw_lock
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_release_raw_lock
|
||||
|
||||
/*
|
||||
* OSL interfaces used by debugger/disassembler
|
||||
*/
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_readable
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_writable
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_debugger
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_debugger
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_initialize_command_signals
|
||||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_terminate_command_signals
|
||||
|
||||
/*
|
||||
* OSL interfaces used by utilities
|
||||
@ -165,11 +178,6 @@
|
||||
#define ACPI_MSG_BIOS_ERROR KERN_ERR "ACPI BIOS Error (bug): "
|
||||
#define ACPI_MSG_BIOS_WARNING KERN_WARNING "ACPI BIOS Warning (bug): "
|
||||
|
||||
/*
|
||||
* Linux wants to use designated initializers for function pointer structs.
|
||||
*/
|
||||
#define ACPI_STRUCT_INIT(field, value) .field = value
|
||||
|
||||
#else /* !__KERNEL__ */
|
||||
|
||||
#define ACPI_USE_STANDARD_HEADERS
|
||||
@ -192,10 +200,8 @@
|
||||
#define ACPI_FLUSH_CPU_CACHE()
|
||||
#define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread))
|
||||
|
||||
#if defined(__ia64__) || (defined(__x86_64__) && !defined(__ILP32__)) ||\
|
||||
defined(__aarch64__) || defined(__PPC64__) ||\
|
||||
defined(__s390x__) ||\
|
||||
(defined(__riscv) && (defined(__LP64__) || defined(_LP64)))
|
||||
#if defined(__ia64__) || defined(__x86_64__) ||\
|
||||
defined(__aarch64__) || defined(__PPC64__)
|
||||
#define ACPI_MACHINE_WIDTH 64
|
||||
#define COMPILER_DEPENDENT_INT64 long
|
||||
#define COMPILER_DEPENDENT_UINT64 unsigned long
|
||||
@ -204,7 +210,6 @@
|
||||
#define COMPILER_DEPENDENT_INT64 long long
|
||||
#define COMPILER_DEPENDENT_UINT64 unsigned long long
|
||||
#define ACPI_USE_NATIVE_DIVIDE
|
||||
#define ACPI_USE_NATIVE_MATH64
|
||||
#endif
|
||||
|
||||
#ifndef __cdecl
|
||||
|
@ -1,12 +1,46 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Name: aclinuxex.h - Extra OS specific defines, etc. for Linux
|
||||
*
|
||||
* Copyright (C) 2000 - 2021, Intel Corp.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2016, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACLINUXEX_H__
|
||||
#define __ACLINUXEX_H__
|
||||
|
||||
@ -90,47 +124,17 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
|
||||
lock ? AE_OK : AE_NO_MEMORY; \
|
||||
})
|
||||
|
||||
|
||||
#define acpi_os_create_raw_lock(__handle) \
|
||||
({ \
|
||||
raw_spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \
|
||||
if (lock) { \
|
||||
*(__handle) = lock; \
|
||||
raw_spin_lock_init(*(__handle)); \
|
||||
} \
|
||||
lock ? AE_OK : AE_NO_MEMORY; \
|
||||
})
|
||||
|
||||
static inline acpi_cpu_flags acpi_os_acquire_raw_lock(acpi_raw_spinlock lockp)
|
||||
{
|
||||
acpi_cpu_flags flags;
|
||||
|
||||
raw_spin_lock_irqsave(lockp, flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void acpi_os_release_raw_lock(acpi_raw_spinlock lockp,
|
||||
acpi_cpu_flags flags)
|
||||
{
|
||||
raw_spin_unlock_irqrestore(lockp, flags);
|
||||
}
|
||||
|
||||
static inline void acpi_os_delete_raw_lock(acpi_raw_spinlock handle)
|
||||
{
|
||||
ACPI_FREE(handle);
|
||||
}
|
||||
|
||||
static inline u8 acpi_os_readable(void *pointer, acpi_size length)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline acpi_status acpi_os_initialize_debugger(void)
|
||||
static inline acpi_status acpi_os_initialize_command_signals(void)
|
||||
{
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static inline void acpi_os_terminate_debugger(void)
|
||||
static inline void acpi_os_terminate_command_signals(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -138,6 +142,7 @@ static inline void acpi_os_terminate_debugger(void)
|
||||
/*
|
||||
* OSL interfaces added by Linux
|
||||
*/
|
||||
void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
@ -1,11 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ACPI_PROCESSOR_H
|
||||
#define __ACPI_PROCESSOR_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <asm/acpi.h>
|
||||
|
||||
@ -232,8 +229,6 @@ struct acpi_processor {
|
||||
struct acpi_processor_limit limit;
|
||||
struct thermal_cooling_device *cdev;
|
||||
struct device *dev; /* Processor device. */
|
||||
struct freq_qos_request perflib_req;
|
||||
struct freq_qos_request thermal_req;
|
||||
};
|
||||
|
||||
struct acpi_processor_errata {
|
||||
@ -254,12 +249,9 @@ extern int acpi_processor_register_performance(struct acpi_processor_performance
|
||||
*performance, unsigned int cpu);
|
||||
extern void acpi_processor_unregister_performance(unsigned int cpu);
|
||||
|
||||
int acpi_processor_pstate_control(void);
|
||||
/* note: this locks both the calling module and the processor module
|
||||
if a _PPC object exists, rmmod is disallowed then */
|
||||
int acpi_processor_notify_smm(struct module *calling_module);
|
||||
int acpi_processor_get_psd(acpi_handle handle,
|
||||
struct acpi_psd_package *pdomain);
|
||||
|
||||
/* parsing the _P* objects. */
|
||||
extern int acpi_processor_get_performance_info(struct acpi_processor *pr);
|
||||
@ -297,37 +289,23 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int call_on_cpu(int cpu, long (*fn)(void *), void *arg,
|
||||
bool direct)
|
||||
{
|
||||
if (direct || (is_percpu_thread() && cpu == smp_processor_id()))
|
||||
return fn(arg);
|
||||
return work_on_cpu(cpu, fn, arg);
|
||||
}
|
||||
|
||||
/* in processor_perflib.c */
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
extern bool acpi_processor_cpufreq_init;
|
||||
void acpi_processor_ignore_ppc_init(void);
|
||||
void acpi_processor_ppc_init(struct cpufreq_policy *policy);
|
||||
void acpi_processor_ppc_exit(struct cpufreq_policy *policy);
|
||||
void acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag);
|
||||
void acpi_processor_ppc_init(void);
|
||||
void acpi_processor_ppc_exit(void);
|
||||
int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag);
|
||||
extern int acpi_processor_get_bios_limit(int cpu, unsigned int *limit);
|
||||
#else
|
||||
static inline void acpi_processor_ignore_ppc_init(void)
|
||||
static inline void acpi_processor_ppc_init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static inline void acpi_processor_ppc_init(struct cpufreq_policy *policy)
|
||||
static inline void acpi_processor_ppc_exit(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static inline void acpi_processor_ppc_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static inline void acpi_processor_ppc_has_changed(struct acpi_processor *pr,
|
||||
static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr,
|
||||
int event_flag)
|
||||
{
|
||||
static unsigned int printout = 1;
|
||||
@ -338,6 +316,7 @@ static inline void acpi_processor_ppc_has_changed(struct acpi_processor *pr,
|
||||
"Consider compiling CPUfreq support into your kernel.\n");
|
||||
printout = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
|
||||
{
|
||||
@ -439,14 +418,14 @@ static inline int acpi_processor_hotplug(struct acpi_processor *pr)
|
||||
int acpi_processor_get_limit_info(struct acpi_processor *pr);
|
||||
extern const struct thermal_cooling_device_ops processor_cooling_ops;
|
||||
#if defined(CONFIG_ACPI_CPU_FREQ_PSS) & defined(CONFIG_CPU_FREQ)
|
||||
void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy);
|
||||
void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy);
|
||||
void acpi_thermal_cpufreq_init(void);
|
||||
void acpi_thermal_cpufreq_exit(void);
|
||||
#else
|
||||
static inline void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy)
|
||||
static inline void acpi_thermal_cpufreq_init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static inline void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy)
|
||||
static inline void acpi_thermal_cpufreq_exit(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ACPI_REBOOT_H
|
||||
#define __ACPI_REBOOT_H
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ACPI_VIDEO_H
|
||||
#define __ACPI_VIDEO_H
|
||||
|
||||
@ -31,17 +30,6 @@ struct acpi_device;
|
||||
#define ACPI_VIDEO_DISPLAY_LEGACY_PANEL 0x0110
|
||||
#define ACPI_VIDEO_DISPLAY_LEGACY_TV 0x0200
|
||||
|
||||
#define ACPI_VIDEO_NOTIFY_SWITCH 0x80
|
||||
#define ACPI_VIDEO_NOTIFY_PROBE 0x81
|
||||
#define ACPI_VIDEO_NOTIFY_CYCLE 0x82
|
||||
#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
|
||||
#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
|
||||
#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85
|
||||
#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
|
||||
#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
|
||||
#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
|
||||
#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
|
||||
|
||||
enum acpi_backlight_type {
|
||||
acpi_backlight_undef = -1,
|
||||
acpi_backlight_none = 0,
|
||||
|
40
include/asm-generic/4level-fixup.h
Normal file
40
include/asm-generic/4level-fixup.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef _4LEVEL_FIXUP_H
|
||||
#define _4LEVEL_FIXUP_H
|
||||
|
||||
#define __ARCH_HAS_4LEVEL_HACK
|
||||
#define __PAGETABLE_PUD_FOLDED
|
||||
|
||||
#define PUD_SHIFT PGDIR_SHIFT
|
||||
#define PUD_SIZE PGDIR_SIZE
|
||||
#define PUD_MASK PGDIR_MASK
|
||||
#define PTRS_PER_PUD 1
|
||||
|
||||
#define pud_t pgd_t
|
||||
|
||||
#define pmd_alloc(mm, pud, address) \
|
||||
((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))? \
|
||||
NULL: pmd_offset(pud, address))
|
||||
#define pmd_alloc_kernel(mm, pud, address) pmd_alloc((mm), (pud), (address))
|
||||
|
||||
#define pud_alloc(mm, pgd, address) (pgd)
|
||||
#define pud_alloc_kernel(mm, pgd, address) pud_alloc((mm), (pgd), (address))
|
||||
#define pud_offset(pgd, start) (pgd)
|
||||
#define pud_none(pud) 0
|
||||
#define pud_bad(pud) 0
|
||||
#define pud_present(pud) 1
|
||||
#define pud_ERROR(pud) do { } while (0)
|
||||
#define pud_clear(pud) pgd_clear(pud)
|
||||
#define pud_val(pud) pgd_val(pud)
|
||||
#define pud_populate(mm, pud, pmd) pgd_populate(mm, pud, pmd)
|
||||
#define pud_page(pud) pgd_page(pud)
|
||||
#define pud_page_vaddr(pud) pgd_page_vaddr(pud)
|
||||
|
||||
#undef pud_free_tlb
|
||||
#define pud_free_tlb(tlb, x, addr) do { } while (0)
|
||||
#define pud_free(mm, x) do { } while (0)
|
||||
#define __pud_free_tlb(tlb, x, addr) do { } while (0)
|
||||
|
||||
#undef pud_addr_end
|
||||
#define pud_addr_end(addr, end) (end)
|
||||
|
||||
#endif
|
1
include/asm-generic/Kbuild.asm
Normal file
1
include/asm-generic/Kbuild.asm
Normal file
@ -0,0 +1 @@
|
||||
include include/uapi/asm-generic/Kbuild.asm
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/bitops.h>
|
||||
#undef __memset
|
||||
extern void *__memset(void *, int, __kernel_size_t);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Generic C implementation of atomic counter operations. Do not include in
|
||||
* machine independent code.
|
||||
* Generic C implementation of atomic counter operations. Usable on
|
||||
* UP systems only. Do not include in machine independent code.
|
||||
*
|
||||
* Originally implemented for MN10300.
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#ifndef __ASM_GENERIC_ATOMIC_H
|
||||
#define __ASM_GENERIC_ATOMIC_H
|
||||
@ -12,39 +18,56 @@
|
||||
#include <asm/cmpxchg.h>
|
||||
#include <asm/barrier.h>
|
||||
|
||||
/*
|
||||
* atomic_$op() - $op integer to atomic variable
|
||||
* @i: integer value to $op
|
||||
* @v: pointer to the atomic variable
|
||||
*
|
||||
* Atomically $ops @i to @v. Does not strictly guarantee a memory-barrier, use
|
||||
* smp_mb__{before,after}_atomic().
|
||||
*/
|
||||
|
||||
/*
|
||||
* atomic_$op_return() - $op interer to atomic variable and returns the result
|
||||
* @i: integer value to $op
|
||||
* @v: pointer to the atomic variable
|
||||
*
|
||||
* Atomically $ops @i to @v. Does imply a full memory barrier.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
/* we can build all atomic primitives from cmpxchg */
|
||||
|
||||
#define ATOMIC_OP(op, c_op) \
|
||||
static inline void generic_atomic_##op(int i, atomic_t *v) \
|
||||
static inline void atomic_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
int c, old; \
|
||||
\
|
||||
c = v->counter; \
|
||||
while ((old = arch_cmpxchg(&v->counter, c, c c_op i)) != c) \
|
||||
while ((old = cmpxchg(&v->counter, c, c c_op i)) != c) \
|
||||
c = old; \
|
||||
}
|
||||
|
||||
#define ATOMIC_OP_RETURN(op, c_op) \
|
||||
static inline int generic_atomic_##op##_return(int i, atomic_t *v) \
|
||||
static inline int atomic_##op##_return(int i, atomic_t *v) \
|
||||
{ \
|
||||
int c, old; \
|
||||
\
|
||||
c = v->counter; \
|
||||
while ((old = arch_cmpxchg(&v->counter, c, c c_op i)) != c) \
|
||||
while ((old = cmpxchg(&v->counter, c, c c_op i)) != c) \
|
||||
c = old; \
|
||||
\
|
||||
return c c_op i; \
|
||||
}
|
||||
|
||||
#define ATOMIC_FETCH_OP(op, c_op) \
|
||||
static inline int generic_atomic_fetch_##op(int i, atomic_t *v) \
|
||||
static inline int atomic_fetch_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
int c, old; \
|
||||
\
|
||||
c = v->counter; \
|
||||
while ((old = arch_cmpxchg(&v->counter, c, c c_op i)) != c) \
|
||||
while ((old = cmpxchg(&v->counter, c, c c_op i)) != c) \
|
||||
c = old; \
|
||||
\
|
||||
return c; \
|
||||
@ -55,7 +78,7 @@ static inline int generic_atomic_fetch_##op(int i, atomic_t *v) \
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
#define ATOMIC_OP(op, c_op) \
|
||||
static inline void generic_atomic_##op(int i, atomic_t *v) \
|
||||
static inline void atomic_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@ -65,7 +88,7 @@ static inline void generic_atomic_##op(int i, atomic_t *v) \
|
||||
}
|
||||
|
||||
#define ATOMIC_OP_RETURN(op, c_op) \
|
||||
static inline int generic_atomic_##op##_return(int i, atomic_t *v) \
|
||||
static inline int atomic_##op##_return(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long flags; \
|
||||
int ret; \
|
||||
@ -78,7 +101,7 @@ static inline int generic_atomic_##op##_return(int i, atomic_t *v) \
|
||||
}
|
||||
|
||||
#define ATOMIC_FETCH_OP(op, c_op) \
|
||||
static inline int generic_atomic_fetch_##op(int i, atomic_t *v) \
|
||||
static inline int atomic_fetch_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long flags; \
|
||||
int ret; \
|
||||
@ -93,44 +116,120 @@ static inline int generic_atomic_fetch_##op(int i, atomic_t *v) \
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifndef atomic_add_return
|
||||
ATOMIC_OP_RETURN(add, +)
|
||||
#endif
|
||||
|
||||
#ifndef atomic_sub_return
|
||||
ATOMIC_OP_RETURN(sub, -)
|
||||
#endif
|
||||
|
||||
#ifndef atomic_fetch_add
|
||||
ATOMIC_FETCH_OP(add, +)
|
||||
ATOMIC_FETCH_OP(sub, -)
|
||||
ATOMIC_FETCH_OP(and, &)
|
||||
ATOMIC_FETCH_OP(or, |)
|
||||
ATOMIC_FETCH_OP(xor, ^)
|
||||
#endif
|
||||
|
||||
ATOMIC_OP(add, +)
|
||||
ATOMIC_OP(sub, -)
|
||||
#ifndef atomic_fetch_sub
|
||||
ATOMIC_FETCH_OP(sub, -)
|
||||
#endif
|
||||
|
||||
#ifndef atomic_fetch_and
|
||||
ATOMIC_FETCH_OP(and, &)
|
||||
#endif
|
||||
|
||||
#ifndef atomic_fetch_or
|
||||
ATOMIC_FETCH_OP(or, |)
|
||||
#endif
|
||||
|
||||
#ifndef atomic_fetch_xor
|
||||
ATOMIC_FETCH_OP(xor, ^)
|
||||
#endif
|
||||
|
||||
#ifndef atomic_and
|
||||
ATOMIC_OP(and, &)
|
||||
#endif
|
||||
|
||||
#ifndef atomic_or
|
||||
ATOMIC_OP(or, |)
|
||||
#endif
|
||||
|
||||
#ifndef atomic_xor
|
||||
ATOMIC_OP(xor, ^)
|
||||
#endif
|
||||
|
||||
#undef ATOMIC_FETCH_OP
|
||||
#undef ATOMIC_OP_RETURN
|
||||
#undef ATOMIC_OP
|
||||
|
||||
#define arch_atomic_add_return generic_atomic_add_return
|
||||
#define arch_atomic_sub_return generic_atomic_sub_return
|
||||
/*
|
||||
* Atomic operations that C can't guarantee us. Useful for
|
||||
* resource counting etc..
|
||||
*/
|
||||
|
||||
#define arch_atomic_fetch_add generic_atomic_fetch_add
|
||||
#define arch_atomic_fetch_sub generic_atomic_fetch_sub
|
||||
#define arch_atomic_fetch_and generic_atomic_fetch_and
|
||||
#define arch_atomic_fetch_or generic_atomic_fetch_or
|
||||
#define arch_atomic_fetch_xor generic_atomic_fetch_xor
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
|
||||
#define arch_atomic_add generic_atomic_add
|
||||
#define arch_atomic_sub generic_atomic_sub
|
||||
#define arch_atomic_and generic_atomic_and
|
||||
#define arch_atomic_or generic_atomic_or
|
||||
#define arch_atomic_xor generic_atomic_xor
|
||||
/**
|
||||
* atomic_read - read atomic variable
|
||||
* @v: pointer of type atomic_t
|
||||
*
|
||||
* Atomically reads the value of @v.
|
||||
*/
|
||||
#ifndef atomic_read
|
||||
#define atomic_read(v) READ_ONCE((v)->counter)
|
||||
#endif
|
||||
|
||||
#define arch_atomic_read(v) READ_ONCE((v)->counter)
|
||||
#define arch_atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
|
||||
/**
|
||||
* atomic_set - set atomic variable
|
||||
* @v: pointer of type atomic_t
|
||||
* @i: required value
|
||||
*
|
||||
* Atomically sets the value of @v to @i.
|
||||
*/
|
||||
#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
|
||||
|
||||
#define arch_atomic_xchg(ptr, v) (arch_xchg(&(ptr)->counter, (v)))
|
||||
#define arch_atomic_cmpxchg(v, old, new) (arch_cmpxchg(&((v)->counter), (old), (new)))
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
static inline int atomic_add_negative(int i, atomic_t *v)
|
||||
{
|
||||
return atomic_add_return(i, v) < 0;
|
||||
}
|
||||
|
||||
static inline void atomic_add(int i, atomic_t *v)
|
||||
{
|
||||
atomic_add_return(i, v);
|
||||
}
|
||||
|
||||
static inline void atomic_sub(int i, atomic_t *v)
|
||||
{
|
||||
atomic_sub_return(i, v);
|
||||
}
|
||||
|
||||
static inline void atomic_inc(atomic_t *v)
|
||||
{
|
||||
atomic_add_return(1, v);
|
||||
}
|
||||
|
||||
static inline void atomic_dec(atomic_t *v)
|
||||
{
|
||||
atomic_sub_return(1, v);
|
||||
}
|
||||
|
||||
#define atomic_dec_return(v) atomic_sub_return(1, (v))
|
||||
#define atomic_inc_return(v) atomic_add_return(1, (v))
|
||||
|
||||
#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
|
||||
#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
|
||||
#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
|
||||
|
||||
#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v)))
|
||||
#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
|
||||
|
||||
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
|
||||
{
|
||||
int c, old;
|
||||
c = atomic_read(v);
|
||||
while (c != u && (old = atomic_cmpxchg(v, c, c + a)) != c)
|
||||
c = old;
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif /* __ASM_GENERIC_ATOMIC_H */
|
||||
|
@ -1,31 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Generic implementation of 64-bit atomics using spinlocks,
|
||||
* useful on processors that don't have 64-bit atomic instructions.
|
||||
*
|
||||
* Copyright © 2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.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.
|
||||
*/
|
||||
#ifndef _ASM_GENERIC_ATOMIC64_H
|
||||
#define _ASM_GENERIC_ATOMIC64_H
|
||||
#include <linux/types.h>
|
||||
|
||||
typedef struct {
|
||||
s64 counter;
|
||||
long long counter;
|
||||
} atomic64_t;
|
||||
|
||||
typedef atomic64_t atomic64_unchecked_t;
|
||||
|
||||
#define ATOMIC64_INIT(i) { (i) }
|
||||
|
||||
extern s64 generic_atomic64_read(const atomic64_t *v);
|
||||
extern void generic_atomic64_set(atomic64_t *v, s64 i);
|
||||
extern long long atomic64_read(const atomic64_t *v);
|
||||
extern void atomic64_set(atomic64_t *v, long long i);
|
||||
|
||||
#define ATOMIC64_OP(op) \
|
||||
extern void generic_atomic64_##op(s64 a, atomic64_t *v);
|
||||
extern void atomic64_##op(long long a, atomic64_t *v);
|
||||
|
||||
#define ATOMIC64_OP_RETURN(op) \
|
||||
extern s64 generic_atomic64_##op##_return(s64 a, atomic64_t *v);
|
||||
extern long long atomic64_##op##_return(long long a, atomic64_t *v);
|
||||
|
||||
#define ATOMIC64_FETCH_OP(op) \
|
||||
extern s64 generic_atomic64_fetch_##op(s64 a, atomic64_t *v);
|
||||
extern long long atomic64_fetch_##op(long long a, atomic64_t *v);
|
||||
|
||||
#define ATOMIC64_OPS(op) ATOMIC64_OP(op) ATOMIC64_OP_RETURN(op) ATOMIC64_FETCH_OP(op)
|
||||
|
||||
@ -44,32 +49,30 @@ ATOMIC64_OPS(xor)
|
||||
#undef ATOMIC64_OP_RETURN
|
||||
#undef ATOMIC64_OP
|
||||
|
||||
extern s64 generic_atomic64_dec_if_positive(atomic64_t *v);
|
||||
extern s64 generic_atomic64_cmpxchg(atomic64_t *v, s64 o, s64 n);
|
||||
extern s64 generic_atomic64_xchg(atomic64_t *v, s64 new);
|
||||
extern s64 generic_atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u);
|
||||
extern long long atomic64_dec_if_positive(atomic64_t *v);
|
||||
extern long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n);
|
||||
extern long long atomic64_xchg(atomic64_t *v, long long new);
|
||||
extern int atomic64_add_unless(atomic64_t *v, long long a, long long u);
|
||||
|
||||
#define arch_atomic64_read generic_atomic64_read
|
||||
#define arch_atomic64_set generic_atomic64_set
|
||||
#define arch_atomic64_set_release generic_atomic64_set
|
||||
#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
|
||||
#define atomic64_inc(v) atomic64_add(1LL, (v))
|
||||
#define atomic64_inc_return(v) atomic64_add_return(1LL, (v))
|
||||
#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
|
||||
#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
|
||||
#define atomic64_dec(v) atomic64_sub(1LL, (v))
|
||||
#define atomic64_dec_return(v) atomic64_sub_return(1LL, (v))
|
||||
#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
|
||||
#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL)
|
||||
|
||||
#define arch_atomic64_add generic_atomic64_add
|
||||
#define arch_atomic64_add_return generic_atomic64_add_return
|
||||
#define arch_atomic64_fetch_add generic_atomic64_fetch_add
|
||||
#define arch_atomic64_sub generic_atomic64_sub
|
||||
#define arch_atomic64_sub_return generic_atomic64_sub_return
|
||||
#define arch_atomic64_fetch_sub generic_atomic64_fetch_sub
|
||||
|
||||
#define arch_atomic64_and generic_atomic64_and
|
||||
#define arch_atomic64_fetch_and generic_atomic64_fetch_and
|
||||
#define arch_atomic64_or generic_atomic64_or
|
||||
#define arch_atomic64_fetch_or generic_atomic64_fetch_or
|
||||
#define arch_atomic64_xor generic_atomic64_xor
|
||||
#define arch_atomic64_fetch_xor generic_atomic64_fetch_xor
|
||||
|
||||
#define arch_atomic64_dec_if_positive generic_atomic64_dec_if_positive
|
||||
#define arch_atomic64_cmpxchg generic_atomic64_cmpxchg
|
||||
#define arch_atomic64_xchg generic_atomic64_xchg
|
||||
#define arch_atomic64_fetch_add_unless generic_atomic64_fetch_add_unless
|
||||
#define atomic64_read_unchecked(v) atomic64_read(v)
|
||||
#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
|
||||
#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
|
||||
#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
|
||||
#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
|
||||
#define atomic64_inc_unchecked(v) atomic64_inc(v)
|
||||
#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
|
||||
#define atomic64_dec_unchecked(v) atomic64_dec(v)
|
||||
#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
|
||||
#define atomic64_xchg_unchecked(v, n) atomic64_xchg((v), (n))
|
||||
|
||||
#endif /* _ASM_GENERIC_ATOMIC64_H */
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifdef __NR_chmod
|
||||
__NR_chmod,
|
||||
#endif
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifdef __NR_rename
|
||||
__NR_rename,
|
||||
#endif
|
||||
@ -27,12 +26,7 @@ __NR_mknod,
|
||||
__NR_mkdirat,
|
||||
__NR_mknodat,
|
||||
__NR_unlinkat,
|
||||
#ifdef __NR_renameat
|
||||
__NR_renameat,
|
||||
#endif
|
||||
__NR_linkat,
|
||||
__NR_symlinkat,
|
||||
#endif
|
||||
#ifdef __NR_renameat2
|
||||
__NR_renameat2,
|
||||
#endif
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifdef __NR_readlink
|
||||
__NR_readlink,
|
||||
#endif
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <asm-generic/audit_dir_write.h>
|
||||
__NR_acct,
|
||||
#ifdef __NR_swapon
|
||||
@ -20,6 +19,3 @@ __NR_ftruncate64,
|
||||
#ifdef __NR_bind
|
||||
__NR_bind, /* bind can affect fs object only in one way... */
|
||||
#endif
|
||||
#ifdef __NR_fallocate
|
||||
__NR_fallocate,
|
||||
#endif
|
||||
|
@ -1,12 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Generic barrier definitions.
|
||||
* Generic barrier definitions, originally based on MN10300 definitions.
|
||||
*
|
||||
* It should be possible to use these on really simple architectures,
|
||||
* but it serves more as a starting point for new ports.
|
||||
*
|
||||
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
|
||||
* Written by David Howells (dhowells@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public Licence
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the Licence, or (at your option) any later version.
|
||||
*/
|
||||
#ifndef __ASM_GENERIC_BARRIER_H
|
||||
#define __ASM_GENERIC_BARRIER_H
|
||||
@ -14,7 +18,6 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/rwonce.h>
|
||||
|
||||
#ifndef nop
|
||||
#define nop() asm volatile ("nop")
|
||||
@ -47,6 +50,10 @@
|
||||
#define dma_wmb() wmb()
|
||||
#endif
|
||||
|
||||
#ifndef read_barrier_depends
|
||||
#define read_barrier_depends() do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifndef __smp_mb
|
||||
#define __smp_mb() mb()
|
||||
#endif
|
||||
@ -59,6 +66,10 @@
|
||||
#define __smp_wmb() wmb()
|
||||
#endif
|
||||
|
||||
#ifndef __smp_read_barrier_depends
|
||||
#define __smp_read_barrier_depends() read_barrier_depends()
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#ifndef smp_mb
|
||||
@ -73,6 +84,10 @@
|
||||
#define smp_wmb() __smp_wmb()
|
||||
#endif
|
||||
|
||||
#ifndef smp_read_barrier_depends
|
||||
#define smp_read_barrier_depends() __smp_read_barrier_depends()
|
||||
#endif
|
||||
|
||||
#else /* !CONFIG_SMP */
|
||||
|
||||
#ifndef smp_mb
|
||||
@ -87,6 +102,10 @@
|
||||
#define smp_wmb() barrier()
|
||||
#endif
|
||||
|
||||
#ifndef smp_read_barrier_depends
|
||||
#define smp_read_barrier_depends() do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifndef __smp_store_mb
|
||||
@ -113,10 +132,10 @@ do { \
|
||||
#ifndef __smp_load_acquire
|
||||
#define __smp_load_acquire(p) \
|
||||
({ \
|
||||
__unqual_scalar_typeof(*p) ___p1 = READ_ONCE(*p); \
|
||||
typeof(*p) ___p1 = READ_ONCE(*p); \
|
||||
compiletime_assert_atomic_type(*p); \
|
||||
__smp_mb(); \
|
||||
(typeof(*p))___p1; \
|
||||
___p1; \
|
||||
})
|
||||
#endif
|
||||
|
||||
@ -168,10 +187,10 @@ do { \
|
||||
#ifndef smp_load_acquire
|
||||
#define smp_load_acquire(p) \
|
||||
({ \
|
||||
__unqual_scalar_typeof(*p) ___p1 = READ_ONCE(*p); \
|
||||
typeof(*p) ___p1 = READ_ONCE(*p); \
|
||||
compiletime_assert_atomic_type(*p); \
|
||||
barrier(); \
|
||||
(typeof(*p))___p1; \
|
||||
___p1; \
|
||||
})
|
||||
#endif
|
||||
|
||||
@ -181,6 +200,7 @@ do { \
|
||||
#define virt_mb() __smp_mb()
|
||||
#define virt_rmb() __smp_rmb()
|
||||
#define virt_wmb() __smp_wmb()
|
||||
#define virt_read_barrier_depends() __smp_read_barrier_depends()
|
||||
#define virt_store_mb(var, value) __smp_store_mb(var, value)
|
||||
#define virt_mb__before_atomic() __smp_mb__before_atomic()
|
||||
#define virt_mb__after_atomic() __smp_mb__after_atomic()
|
||||
@ -200,30 +220,6 @@ do { \
|
||||
#define smp_acquire__after_ctrl_dep() smp_rmb()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* smp_cond_load_relaxed() - (Spin) wait for cond with no ordering guarantees
|
||||
* @ptr: pointer to the variable to wait on
|
||||
* @cond: boolean expression to wait for
|
||||
*
|
||||
* Equivalent to using READ_ONCE() on the condition variable.
|
||||
*
|
||||
* Due to C lacking lambda expressions we load the value of *ptr into a
|
||||
* pre-named variable @VAL to be used in @cond.
|
||||
*/
|
||||
#ifndef smp_cond_load_relaxed
|
||||
#define smp_cond_load_relaxed(ptr, cond_expr) ({ \
|
||||
typeof(ptr) __PTR = (ptr); \
|
||||
__unqual_scalar_typeof(*ptr) VAL; \
|
||||
for (;;) { \
|
||||
VAL = READ_ONCE(*__PTR); \
|
||||
if (cond_expr) \
|
||||
break; \
|
||||
cpu_relax(); \
|
||||
} \
|
||||
(typeof(*ptr))VAL; \
|
||||
})
|
||||
#endif
|
||||
|
||||
/**
|
||||
* smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering
|
||||
* @ptr: pointer to the variable to wait on
|
||||
@ -231,25 +227,24 @@ do { \
|
||||
*
|
||||
* Equivalent to using smp_load_acquire() on the condition variable but employs
|
||||
* the control dependency of the wait to reduce the barrier on many platforms.
|
||||
*
|
||||
* Due to C lacking lambda expressions we load the value of *ptr into a
|
||||
* pre-named variable @VAL to be used in @cond.
|
||||
*/
|
||||
#ifndef smp_cond_load_acquire
|
||||
#define smp_cond_load_acquire(ptr, cond_expr) ({ \
|
||||
__unqual_scalar_typeof(*ptr) _val; \
|
||||
_val = smp_cond_load_relaxed(ptr, cond_expr); \
|
||||
typeof(ptr) __PTR = (ptr); \
|
||||
typeof(*ptr) VAL; \
|
||||
for (;;) { \
|
||||
VAL = READ_ONCE(*__PTR); \
|
||||
if (cond_expr) \
|
||||
break; \
|
||||
cpu_relax(); \
|
||||
} \
|
||||
smp_acquire__after_ctrl_dep(); \
|
||||
(typeof(*ptr))_val; \
|
||||
VAL; \
|
||||
})
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pmem_wmb() ensures that all stores for which the modification
|
||||
* are written to persistent storage by preceding instructions have
|
||||
* updated persistent storage before any data access or data transfer
|
||||
* caused by subsequent instructions is initiated.
|
||||
*/
|
||||
#ifndef pmem_wmb
|
||||
#define pmem_wmb() wmb()
|
||||
#endif
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
#endif /* __ASM_GENERIC_BARRIER_H */
|
||||
|
@ -1,12 +1,10 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_GENERIC_BITOPS_H
|
||||
#define __ASM_GENERIC_BITOPS_H
|
||||
|
||||
/*
|
||||
* For the benefit of those who are trying to port Linux to another
|
||||
* architecture, here are some C-language equivalents. They should
|
||||
* generate reasonable code, so take a look at what your compiler spits
|
||||
* out before rolling your own buggy implementation in assembly language.
|
||||
* architecture, here are some C-language equivalents. You should
|
||||
* recode these in the native assembly language, if at all possible.
|
||||
*
|
||||
* C language equivalents written by Theodore Ts'o, 9/26/92
|
||||
*/
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS___FFS_H_
|
||||
#define _ASM_GENERIC_BITOPS___FFS_H_
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS___FLS_H_
|
||||
#define _ASM_GENERIC_BITOPS___FLS_H_
|
||||
|
||||
@ -10,7 +9,7 @@
|
||||
*
|
||||
* Undefined if no set bit exists, so code should check against 0 first.
|
||||
*/
|
||||
static __always_inline unsigned long __fls(unsigned long word)
|
||||
static __always_inline unsigned long __intentional_overflow(-1) __fls(unsigned long word)
|
||||
{
|
||||
int num = BITS_PER_LONG - 1;
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_
|
||||
#define _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_
|
||||
|
||||
|
@ -1,76 +1,189 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_ATOMIC_H_
|
||||
#define _ASM_GENERIC_BITOPS_ATOMIC_H_
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#include <asm/spinlock.h>
|
||||
#include <asm/cache.h> /* we use L1_CACHE_BYTES */
|
||||
|
||||
/* Use an array of spinlocks for our atomic_ts.
|
||||
* Hash function to index into a different SPINLOCK.
|
||||
* Since "a" is usually an address, use one spinlock per cacheline.
|
||||
*/
|
||||
# define ATOMIC_HASH_SIZE 4
|
||||
# define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
|
||||
|
||||
extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
|
||||
|
||||
/* Can't use raw_spin_lock_irq because of #include problems, so
|
||||
* this is the substitute */
|
||||
#define _atomic_spin_lock_irqsave(l,f) do { \
|
||||
arch_spinlock_t *s = ATOMIC_HASH(l); \
|
||||
local_irq_save(f); \
|
||||
arch_spin_lock(s); \
|
||||
} while(0)
|
||||
|
||||
#define _atomic_spin_unlock_irqrestore(l,f) do { \
|
||||
arch_spinlock_t *s = ATOMIC_HASH(l); \
|
||||
arch_spin_unlock(s); \
|
||||
local_irq_restore(f); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#else
|
||||
# define _atomic_spin_lock_irqsave(l,f) do { local_irq_save(f); } while (0)
|
||||
# define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Implementation of atomic bitops using atomic-fetch ops.
|
||||
* See Documentation/atomic_bitops.txt for details.
|
||||
* NMI events can occur at any time, including when interrupts have been
|
||||
* disabled by *_irqsave(). So you can get NMI events occurring while a
|
||||
* *_bit function is holding a spin lock. If the NMI handler also wants
|
||||
* to do bit manipulation (and they do) then you can get a deadlock
|
||||
* between the original caller of *_bit() and the NMI handler.
|
||||
*
|
||||
* by Keith Owens
|
||||
*/
|
||||
|
||||
static __always_inline void
|
||||
arch_set_bit(unsigned int nr, volatile unsigned long *p)
|
||||
/**
|
||||
* set_bit - Atomically set a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*
|
||||
* This function is atomic and may not be reordered. See __set_bit()
|
||||
* if you do not require the atomic guarantees.
|
||||
*
|
||||
* Note: there are no guarantees that this function will not be reordered
|
||||
* on non x86 architectures, so if you are writing portable code,
|
||||
* make sure not to rely on its reordering guarantees.
|
||||
*
|
||||
* Note that @nr may be almost arbitrarily large; this function is not
|
||||
* restricted to acting on a single-word quantity.
|
||||
*/
|
||||
static inline void set_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
p += BIT_WORD(nr);
|
||||
arch_atomic_long_or(BIT_MASK(nr), (atomic_long_t *)p);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
arch_clear_bit(unsigned int nr, volatile unsigned long *p)
|
||||
{
|
||||
p += BIT_WORD(nr);
|
||||
arch_atomic_long_andnot(BIT_MASK(nr), (atomic_long_t *)p);
|
||||
}
|
||||
|
||||
static __always_inline void
|
||||
arch_change_bit(unsigned int nr, volatile unsigned long *p)
|
||||
{
|
||||
p += BIT_WORD(nr);
|
||||
arch_atomic_long_xor(BIT_MASK(nr), (atomic_long_t *)p);
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
arch_test_and_set_bit(unsigned int nr, volatile unsigned long *p)
|
||||
{
|
||||
long old;
|
||||
unsigned long mask = BIT_MASK(nr);
|
||||
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
|
||||
unsigned long flags;
|
||||
|
||||
p += BIT_WORD(nr);
|
||||
if (READ_ONCE(*p) & mask)
|
||||
return 1;
|
||||
|
||||
old = arch_atomic_long_fetch_or(mask, (atomic_long_t *)p);
|
||||
return !!(old & mask);
|
||||
_atomic_spin_lock_irqsave(p, flags);
|
||||
*p |= mask;
|
||||
_atomic_spin_unlock_irqrestore(p, flags);
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
arch_test_and_clear_bit(unsigned int nr, volatile unsigned long *p)
|
||||
/**
|
||||
* clear_bit - Clears a bit in memory
|
||||
* @nr: Bit to clear
|
||||
* @addr: Address to start counting from
|
||||
*
|
||||
* clear_bit() is atomic and may not be reordered. However, it does
|
||||
* not contain a memory barrier, so if it is used for locking purposes,
|
||||
* you should call smp_mb__before_atomic() and/or smp_mb__after_atomic()
|
||||
* in order to ensure changes are visible on other processors.
|
||||
*/
|
||||
static inline void clear_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
long old;
|
||||
unsigned long mask = BIT_MASK(nr);
|
||||
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
|
||||
unsigned long flags;
|
||||
|
||||
p += BIT_WORD(nr);
|
||||
if (!(READ_ONCE(*p) & mask))
|
||||
return 0;
|
||||
|
||||
old = arch_atomic_long_fetch_andnot(mask, (atomic_long_t *)p);
|
||||
return !!(old & mask);
|
||||
_atomic_spin_lock_irqsave(p, flags);
|
||||
*p &= ~mask;
|
||||
_atomic_spin_unlock_irqrestore(p, flags);
|
||||
}
|
||||
|
||||
static __always_inline int
|
||||
arch_test_and_change_bit(unsigned int nr, volatile unsigned long *p)
|
||||
/**
|
||||
* change_bit - Toggle a bit in memory
|
||||
* @nr: Bit to change
|
||||
* @addr: Address to start counting from
|
||||
*
|
||||
* change_bit() is atomic and may not be reordered. It may be
|
||||
* reordered on other architectures than x86.
|
||||
* Note that @nr may be almost arbitrarily large; this function is not
|
||||
* restricted to acting on a single-word quantity.
|
||||
*/
|
||||
static inline void change_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
long old;
|
||||
unsigned long mask = BIT_MASK(nr);
|
||||
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
|
||||
unsigned long flags;
|
||||
|
||||
p += BIT_WORD(nr);
|
||||
old = arch_atomic_long_fetch_xor(mask, (atomic_long_t *)p);
|
||||
return !!(old & mask);
|
||||
_atomic_spin_lock_irqsave(p, flags);
|
||||
*p ^= mask;
|
||||
_atomic_spin_unlock_irqrestore(p, flags);
|
||||
}
|
||||
|
||||
#include <asm-generic/bitops/instrumented-atomic.h>
|
||||
/**
|
||||
* test_and_set_bit - Set a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It may be reordered on other architectures than x86.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = BIT_MASK(nr);
|
||||
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
|
||||
unsigned long old;
|
||||
unsigned long flags;
|
||||
|
||||
_atomic_spin_lock_irqsave(p, flags);
|
||||
old = *p;
|
||||
*p = old | mask;
|
||||
_atomic_spin_unlock_irqrestore(p, flags);
|
||||
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* test_and_clear_bit - Clear a bit and return its old value
|
||||
* @nr: Bit to clear
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It can be reorderdered on other architectures other than x86.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = BIT_MASK(nr);
|
||||
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
|
||||
unsigned long old;
|
||||
unsigned long flags;
|
||||
|
||||
_atomic_spin_lock_irqsave(p, flags);
|
||||
old = *p;
|
||||
*p = old & ~mask;
|
||||
_atomic_spin_unlock_irqrestore(p, flags);
|
||||
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* test_and_change_bit - Change a bit and return its old value
|
||||
* @nr: Bit to change
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = BIT_MASK(nr);
|
||||
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
|
||||
unsigned long old;
|
||||
unsigned long flags;
|
||||
|
||||
_atomic_spin_lock_irqsave(p, flags);
|
||||
old = *p;
|
||||
*p = old ^ mask;
|
||||
_atomic_spin_unlock_irqrestore(p, flags);
|
||||
|
||||
return (old & mask) != 0;
|
||||
}
|
||||
|
||||
#endif /* _ASM_GENERIC_BITOPS_ATOMIC_H */
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_BUILTIN___FFS_H_
|
||||
#define _ASM_GENERIC_BITOPS_BUILTIN___FFS_H_
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_BUILTIN___FLS_H_
|
||||
#define _ASM_GENERIC_BITOPS_BUILTIN___FLS_H_
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_BUILTIN_FFS_H_
|
||||
#define _ASM_GENERIC_BITOPS_BUILTIN_FFS_H_
|
||||
|
||||
@ -8,8 +7,11 @@
|
||||
*
|
||||
* This is defined the same way as
|
||||
* the libc and compiler builtin ffs routines, therefore
|
||||
* differs in spirit from ffz (man ffs).
|
||||
* differs in spirit from the above ffz (man ffs).
|
||||
*/
|
||||
#define ffs(x) __builtin_ffs(x)
|
||||
static __always_inline int ffs(int x)
|
||||
{
|
||||
return __builtin_ffs(x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_BUILTIN_FLS_H_
|
||||
#define _ASM_GENERIC_BITOPS_BUILTIN_FLS_H_
|
||||
|
||||
@ -9,7 +8,7 @@
|
||||
* This is defined the same way as ffs.
|
||||
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
|
||||
*/
|
||||
static __always_inline int fls(unsigned int x)
|
||||
static __always_inline int fls(int x)
|
||||
{
|
||||
return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_
|
||||
#define _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_EXT2_ATOMIC_SETBIT_H_
|
||||
#define _ASM_GENERIC_BITOPS_EXT2_ATOMIC_SETBIT_H_
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_EXT2_ATOMIC_H_
|
||||
#define _ASM_GENERIC_BITOPS_EXT2_ATOMIC_H_
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_FFS_H_
|
||||
#define _ASM_GENERIC_BITOPS_FFS_H_
|
||||
|
||||
@ -8,7 +7,7 @@
|
||||
*
|
||||
* This is defined the same way as
|
||||
* the libc and compiler builtin ffs routines, therefore
|
||||
* differs in spirit from ffz (man ffs).
|
||||
* differs in spirit from the above ffz (man ffs).
|
||||
*/
|
||||
static inline int ffs(int x)
|
||||
{
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
|
||||
#define _ASM_GENERIC_BITOPS_FFZ_H_
|
||||
|
||||
|
@ -1,14 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_GENERIC_BITOPS_FIND_H_
|
||||
#define _ASM_GENERIC_BITOPS_FIND_H_
|
||||
|
||||
extern unsigned long _find_next_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2, unsigned long nbits,
|
||||
unsigned long start, unsigned long invert, unsigned long le);
|
||||
extern unsigned long _find_first_bit(const unsigned long *addr, unsigned long size);
|
||||
extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size);
|
||||
extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long size);
|
||||
|
||||
#ifndef find_next_bit
|
||||
/**
|
||||
* find_next_bit - find the next set bit in a memory region
|
||||
@ -19,52 +11,8 @@ extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long siz
|
||||
* Returns the bit number for the next set bit
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val;
|
||||
|
||||
if (unlikely(offset >= size))
|
||||
return size;
|
||||
|
||||
val = *addr & GENMASK(size - 1, offset);
|
||||
return val ? __ffs(val) : size;
|
||||
}
|
||||
|
||||
return _find_next_bit(addr, NULL, size, offset, 0UL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef find_next_and_bit
|
||||
/**
|
||||
* find_next_and_bit - find the next set bit in both memory regions
|
||||
* @addr1: The first address to base the search on
|
||||
* @addr2: The second address to base the search on
|
||||
* @offset: The bitnumber to start searching at
|
||||
* @size: The bitmap size in bits
|
||||
*
|
||||
* Returns the bit number for the next set bit
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_next_and_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val;
|
||||
|
||||
if (unlikely(offset >= size))
|
||||
return size;
|
||||
|
||||
val = *addr1 & *addr2 & GENMASK(size - 1, offset);
|
||||
return val ? __ffs(val) : size;
|
||||
}
|
||||
|
||||
return _find_next_bit(addr1, addr2, size, offset, 0UL, 0);
|
||||
}
|
||||
extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
|
||||
size, unsigned long offset);
|
||||
#endif
|
||||
|
||||
#ifndef find_next_zero_bit
|
||||
@ -77,22 +25,8 @@ unsigned long find_next_and_bit(const unsigned long *addr1,
|
||||
* Returns the bit number of the next zero bit
|
||||
* If no bits are zero, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val;
|
||||
|
||||
if (unlikely(offset >= size))
|
||||
return size;
|
||||
|
||||
val = *addr | ~GENMASK(size - 1, offset);
|
||||
return val == ~0UL ? size : ffz(val);
|
||||
}
|
||||
|
||||
return _find_next_bit(addr, NULL, size, offset, ~0UL, 0);
|
||||
}
|
||||
extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned
|
||||
long size, unsigned long offset);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GENERIC_FIND_FIRST_BIT
|
||||
@ -105,17 +39,8 @@ unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
|
||||
* Returns the bit number of the first set bit.
|
||||
* If no bits are set, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *addr & GENMASK(size - 1, 0);
|
||||
|
||||
return val ? __ffs(val) : size;
|
||||
}
|
||||
|
||||
return _find_first_bit(addr, size);
|
||||
}
|
||||
extern unsigned long find_first_bit(const unsigned long *addr,
|
||||
unsigned long size);
|
||||
|
||||
/**
|
||||
* find_first_zero_bit - find the first cleared bit in a memory region
|
||||
@ -125,64 +50,13 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
|
||||
* Returns the bit number of the first cleared bit.
|
||||
* If no bits are zero, returns @size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *addr | ~GENMASK(size - 1, 0);
|
||||
|
||||
return val == ~0UL ? size : ffz(val);
|
||||
}
|
||||
|
||||
return _find_first_zero_bit(addr, size);
|
||||
}
|
||||
extern unsigned long find_first_zero_bit(const unsigned long *addr,
|
||||
unsigned long size);
|
||||
#else /* CONFIG_GENERIC_FIND_FIRST_BIT */
|
||||
|
||||
#ifndef find_first_bit
|
||||
#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
|
||||
#endif
|
||||
#ifndef find_first_zero_bit
|
||||
#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
|
||||
|
||||
#ifndef find_last_bit
|
||||
/**
|
||||
* find_last_bit - find the last set bit in a memory region
|
||||
* @addr: The address to start the search at
|
||||
* @size: The number of bits to search
|
||||
*
|
||||
* Returns the bit number of the last set bit, or size.
|
||||
*/
|
||||
static inline
|
||||
unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
|
||||
{
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *addr & GENMASK(size - 1, 0);
|
||||
|
||||
return val ? __fls(val) : size;
|
||||
}
|
||||
|
||||
return _find_last_bit(addr, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* find_next_clump8 - find next 8-bit clump with set bits in a memory region
|
||||
* @clump: location to store copy of found clump
|
||||
* @addr: address to base the search on
|
||||
* @size: bitmap size in number of bits
|
||||
* @offset: bit offset at which to start searching
|
||||
*
|
||||
* Returns the bit offset for the next set clump; the found clump value is
|
||||
* copied to the location pointed by @clump. If no bits are set, returns @size.
|
||||
*/
|
||||
extern unsigned long find_next_clump8(unsigned long *clump,
|
||||
const unsigned long *addr,
|
||||
unsigned long size, unsigned long offset);
|
||||
|
||||
#define find_first_clump8(clump, bits, size) \
|
||||
find_next_clump8((clump), (bits), (size), 0)
|
||||
|
||||
#endif /*_ASM_GENERIC_BITOPS_FIND_H_ */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user