/*
* grsecurity - access control and security hardening for Linux
* Copyright (C) 2001-2020 Bradley Spengler, Open Source Security, Inc.
* http://www.grsecurity.net [email protected]
*
* 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.
*/
#ifndef __GRINTERNAL_H
#define __GRINTERNAL_H
#ifdef CONFIG_GRKERNSEC
#include <linux/fs.h>
#include <linux/cred.h>
#include <linux/mnt_namespace.h>
#include <linux/nsproxy.h>
#include <linux/gracl.h>
#include <linux/grdefs.h>
#include <linux/grmsg.h>
extern struct gr_arg *gr_usermode __read_only;
extern unsigned char *gr_system_salt __read_only;
extern unsigned char *gr_system_sum __read_only;
extern struct path gr_real_root;
extern struct path gr_proc_mnt;
extern struct gr_policy_state *polstate;
extern struct gr_alloc_state *current_alloc_state;
extern u16 acl_sp_role_value;
extern struct acl_object_label *fakefs_obj_rw;
extern struct acl_object_label *fakefs_obj_rwx;
void gr_add_learn_entry(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
void gr_clear_learn_entries(void);
__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
const struct vfsmount *mnt);
__u32 gr_check_create(const struct dentry *new_dentry,
const struct dentry *parent,
const struct vfsmount *mnt, const __u32 mode);
__u32 gr_check_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);
int gr_check_protected_task(const struct task_struct *task);
int gr_set_acls(const int type);
int gr_acl_tpe_check(void);
char gr_roletype_to_char(void);
struct acl_role_label *__lookup_acl_role_label(const struct gr_policy_state *state, const struct task_struct *task, uid_t uid, gid_t gid);
struct acl_subject_label *lookup_acl_subj_label(u64 ino, dev_t dev, const struct acl_role_label *role);
struct acl_subject_label *lookup_acl_subj_label_deleted(u64 ino, dev_t dev, const struct acl_role_label *role);
struct acl_subject_label *__gr_get_subject_for_task(const struct gr_policy_state *state, struct task_struct *task, const char *filename, int fallback);
void __gr_apply_subject_to_task(const struct gr_policy_state *state, struct task_struct *task, struct acl_subject_label *subj);
void insert_acl_obj_label(struct acl_object_label *obj, struct acl_subject_label *subj);
void insert_acl_subj_label(struct acl_subject_label *obj, struct acl_role_label *role);
void __insert_inodev_entry(const struct gr_policy_state *state, struct inodev_entry *entry);
void assign_special_role(const char *rolename);
void gr_enable_rbac_system(void);
int gr_rbac_disable(void *unused);
extern unsigned int gr_status __read_only;
static inline int __gr_acl_is_enabled(void)
{
#ifndef CONFIG_GRKERNSEC_NO_RBAC
return (gr_status & GR_READY);
#else
/* no way to ever enable it */
return 0;
#endif
}
static inline int gr_streq(const char *a, const char *b, unsigned int lena,
unsigned int lenb)
{
if (lena != lenb)
return 0;
return !memcmp(a, b, lena);
}
static inline __u32 to_gr_audit(__u32 reqmode)
{
/* masks off auditable permission flags, then shifts them to create
auditing flags, and adds the special case of append auditing if
we're requesting write */
return (((reqmode & GR_MODES) << GR_AUDIT_SHIFT) |
((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
}
int gr_fake_force_sig(int sig, struct task_struct *t);
int gr_init_uidset(void);
void gr_free_uidset(void);
int gr_find_and_remove_uid(uid_t uid);
extern char *gr_alert_log_fmt;
extern char *gr_audit_log_fmt;
extern char *gr_alert_log_buf;
extern char *gr_audit_log_buf;
extern char *gr_shared_page[4];
void gr_handle_alertkill(struct task_struct *task);
char *gr_to_filename(const struct dentry *dentry,
const struct vfsmount *mnt);
char *gr_to_filename1(const struct dentry *dentry,
const struct vfsmount *mnt);
char *gr_to_filename2(const struct dentry *dentry,
const struct vfsmount *mnt);
char *gr_to_filename3(const struct dentry *dentry,
const struct vfsmount *mnt);
const char *gr_socktype_to_name(unsigned char type);
const char *gr_proto_to_name(unsigned char proto);
const char *gr_sockfamily_to_name(unsigned char family);
int copy_gr_arg_wrapper_compat(const char *buf, struct gr_arg_wrapper *uwrap);
int copy_gr_arg_compat(const struct gr_arg __user *buf, struct gr_arg *arg);
int copy_acl_object_label_compat(struct acl_object_label *obj, const struct acl_object_label *userp);
int copy_acl_subject_label_compat(struct acl_subject_label *subj, const struct acl_subject_label *userp);
int copy_acl_role_label_compat(struct acl_role_label *role, const struct acl_role_label *userp);
int copy_role_allowed_ip_compat(struct role_allowed_ip *roleip, const struct role_allowed_ip *userp);
int copy_role_transition_compat(struct role_transition *trans, const struct role_transition *userp);
int copy_gr_hash_struct_compat(struct gr_hash_struct *hash, const struct gr_hash_struct *userp);
int copy_pointer_from_array_compat(void *ptr, unsigned long idx, const void *userp);
int copy_acl_ip_label_compat(struct acl_ip_label *ip, const struct acl_ip_label *userp);
int copy_sprole_pw_compat(struct sprole_pw *pw, unsigned long idx, const struct sprole_pw *userp);
size_t get_gr_arg_wrapper_size_compat(void);
extern int grsec_enable_ptrace_readexec __read_only;
extern int grsec_enable_harden_ptrace __read_only;
extern int grsec_enable_link __read_only;
extern int grsec_enable_fifo __read_only;
extern int grsec_enable_execve __read_only;
extern int grsec_enable_shm __read_only;
extern int grsec_enable_execlog __read_only;
extern int grsec_enable_signal __read_only;
extern int grsec_enable_audit_ptrace __read_only;
extern int grsec_enable_forkfail __read_only;
extern int grsec_enable_time __read_only;
extern int grsec_enable_rofs __read_only;
extern int grsec_deny_new_usb __read_only;
extern int grsec_enable_chroot_shmat __read_only;
extern int grsec_enable_chroot_mount __read_only;
extern int grsec_enable_chroot_double __read_only;
extern int grsec_enable_chroot_pivot __read_only;
extern int grsec_enable_chroot_chdir __read_only;
extern int grsec_enable_chroot_chmod __read_only;
extern int grsec_enable_chroot_mknod __read_only;
extern int grsec_enable_chroot_fchdir __read_only;
extern int grsec_enable_chroot_nice __read_only;
extern int grsec_enable_chroot_execlog __read_only;
extern int grsec_enable_chroot_caps __read_only;
extern int grsec_enable_chroot_rename __read_only;
extern int grsec_enable_chroot_sysctl __read_only;
extern int grsec_enable_chroot_unix __read_only;
extern int grsec_enable_symlinkown __read_only;
extern kgid_t grsec_symlinkown_gid __read_only;
extern int grsec_enable_fuse_restrict __read_only;
extern int grsec_enable_tpe __read_only;
extern kgid_t grsec_tpe_gid __read_only;
extern int grsec_enable_tpe_all __read_only;
extern int grsec_enable_tpe_invert __read_only;
extern int grsec_enable_socket_all __read_only;
extern kgid_t grsec_socket_all_gid __read_only;
extern int grsec_enable_socket_client __read_only;
extern kgid_t grsec_socket_client_gid __read_only;
extern int grsec_enable_socket_server __read_only;
extern kgid_t grsec_socket_server_gid __read_only;
extern kgid_t grsec_audit_gid __read_only;
extern int grsec_enable_sysfs_restrict __read_only;
extern kgid_t grsec_sysfs_restrict_bypass_gid __read_only;
extern int grsec_enable_group __read_only;
extern int grsec_enable_mount __read_only;
extern int grsec_enable_chdir __read_only;
extern int grsec_resource_logging __read_only;
extern int grsec_enable_brute __read_only;
extern int grsec_enable_harden_ipc __read_only;
extern int grsec_enable_harden_tty __read_only;
extern int grsec_lock __read_only;
extern rwlock_t gr_inode_lock;
extern rwlock_t grsec_exec_file_lock;
struct cred;
#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
int gr_task_chroot_is_capable(const struct task_struct *task,
const struct cred *cred, int cap);
static inline int gr_chroot_is_capable(int cap)
{
return gr_task_chroot_is_capable(current, current_cred(), cap);
}
int gr_task_chroot_is_capable_nolog(const struct task_struct *task, int cap);
static inline int gr_chroot_is_capable_nolog(int cap)
{
return gr_task_chroot_is_capable_nolog(current, cap);
}
#else
static inline int gr_task_chroot_is_capable(const struct task_struct *task,
const struct cred *cred, int cap)
{
return 1;
}
static inline int gr_task_chroot_is_capable_nolog(const struct task_struct *task, int cap)
{
return 1;
}
static inline int gr_chroot_is_capable(int cap)
{
return 1;
}
static inline int gr_chroot_is_capable_nolog(int cap)
{
return 1;
}
#endif
int gr_task_acl_is_capable(const struct task_struct *task,
const struct cred *cred, int cap, bool log);
static inline int gr_acl_is_capable(int cap)
{
return gr_task_acl_is_capable(current, current_cred(), cap, true);
}
static inline int gr_acl_is_capable_nolog(int cap)
{
return gr_task_acl_is_capable(current, current_cred(), cap, false);
}
#define gr_task_fullpath(tsk) ((tsk)->exec_file ? \
gr_to_filename2((tsk)->exec_file->f_path.dentry, \
(tsk)->exec_file->f_path.mnt) : "/")
#define gr_parent_task_fullpath(tsk) ((tsk)->real_parent->exec_file ? \
gr_to_filename3((tsk)->real_parent->exec_file->f_path.dentry, \
(tsk)->real_parent->exec_file->f_path.mnt) : "/")
#define gr_task_fullpath0(tsk) ((tsk)->exec_file ? \
gr_to_filename((tsk)->exec_file->f_path.dentry, \
(tsk)->exec_file->f_path.mnt) : "/")
#define gr_parent_task_fullpath0(tsk) ((tsk)->real_parent->exec_file ? \
gr_to_filename1((tsk)->real_parent->exec_file->f_path.dentry, \
(tsk)->real_parent->exec_file->f_path.mnt) : "/")
#define proc_is_chrooted(tsk_a) ((tsk_a)->gr_is_chrooted)
#define have_same_root(tsk_a,tsk_b) ((tsk_a)->gr_chroot_dentry == (tsk_b)->gr_chroot_dentry)
static inline bool gr_is_same_file(const struct file *file1, const struct file *file2)
{
if (file1 && file2) {
const struct inode *inode1 = file1->f_path.dentry->d_inode;
const struct inode *inode2 = file2->f_path.dentry->d_inode;
if (inode1->i_ino == inode2->i_ino && inode1->i_sb->s_dev == inode2->i_sb->s_dev)
return true;
}
return false;
}
#define GR_CHROOT_CAPS ((kernel_cap_t){ \
BIT_ULL(CAP_LINUX_IMMUTABLE) | BIT_ULL(CAP_NET_ADMIN) | \
BIT_ULL(CAP_SYS_MODULE) | BIT_ULL(CAP_SYS_RAWIO) | \
BIT_ULL(CAP_SYS_PACCT) | BIT_ULL(CAP_SYS_ADMIN) | \
BIT_ULL(CAP_SYS_BOOT) | BIT_ULL(CAP_SYS_TIME) | \
BIT_ULL(CAP_NET_RAW) | BIT_ULL(CAP_SYS_TTY_CONFIG) | \
BIT_ULL(CAP_IPC_OWNER) | BIT_ULL(CAP_SETFCAP) | \
BIT_ULL(CAP_SYSLOG) | BIT_ULL(CAP_MAC_ADMIN) })
#define security_learn(normal_msg,args...) \
do { \
read_lock(&grsec_exec_file_lock); \
gr_add_learn_entry(normal_msg "\n", ## args); \
read_unlock(&grsec_exec_file_lock); \
} while(0)
enum {
GR_DO_AUDIT,
GR_DONT_AUDIT,
/* used for non-audit messages that we shouldn't kill the task on */
GR_DONT_AUDIT_GOOD
};
enum {
GR_RBAC,
GR_RBAC_STR,
GR_STR_RBAC,
GR_RBAC_MODE2,
GR_RBAC_MODE3,
GR_FILENAME,
GR_SYSCTL_HIDDEN,
GR_NOARGS,
GR_ONE_INT,
GR_ONE_INT_TWO_STR,
GR_ONE_STR,
GR_STR_INT,
GR_TWO_STR_INT,
GR_TWO_INT,
GR_TWO_U64,
GR_THREE_INT,
GR_FIVE_INT_TWO_STR,
GR_TWO_STR,
GR_THREE_STR,
GR_FOUR_STR,
GR_STR_FILENAME,
GR_FILENAME_STR,
GR_FILENAME_TWO_INT,
GR_FILENAME_TWO_INT_STR,
GR_TEXTREL,
GR_PTRACE,
GR_RESOURCE,
GR_CAP,
GR_SIG,
GR_SIG2,
GR_CRASH1,
GR_CRASH2,
GR_PSACCT,
GR_RWXMAP,
GR_RWXMAPVMA
};
#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
#define gr_log_fs_rbac_mode3(audit, msg, dentry, mnt, str1, str2, str3) gr_log_varargs(audit, msg, GR_RBAC_MODE3, dentry, mnt, str1, str2, str3)
#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
#define gr_log_two_u64(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_U64, num1, num2)
#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
#define gr_log_int5_str2(audit, msg, num1, num2, str1, str2) gr_log_varargs(audit, msg, GR_FIVE_INT_TWO_STR, num1, num2, str1, str2)
#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
#define gr_log_str2_int(audit, msg, str1, str2, num) gr_log_varargs(audit, msg, GR_TWO_STR_INT, str1, str2, num)
#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
#define gr_log_fs_int2_str(audit, msg, dentry, mnt, num1, num2, str) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT_STR, dentry, mnt, num1, num2, str)
#define gr_log_textrel_ulong_ulong(audit, msg, str, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, str, file, ulong1, ulong2)
#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
#define gr_log_sig_addr(audit, msg, str, addr) gr_log_varargs(audit, msg, GR_SIG, str, addr)
#define gr_log_sig_task(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG2, task, num)
#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
#define gr_log_procacct(audit, msg, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) gr_log_varargs(audit, msg, GR_PSACCT, task, num1, num2, num3, num4, num5, num6, num7, num8, num9)
#define gr_log_rwxmap(audit, msg, str) gr_log_varargs(audit, msg, GR_RWXMAP, str)
#define gr_log_rwxmap_vma(audit, msg, str) gr_log_varargs(audit, msg, GR_RWXMAPVMA, str)
void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
#endif
#endif