shell bypass 403
UnknownSec Shell
:
/
usr
/
src
/
file_protector-1.1-1592
/ [
drwxr-xr-x
]
upload
mass deface
mass delete
console
info server
name :
path_tools.h
/** @file path_tools.h @brief Tools for working with 'struct path' @details Copyright (c) 2024 Acronis International GmbH @author Bruce Wang (bruce.wang@acronis.com) @since $Id: $ */ #pragma once #include "si_common.h" #ifdef BPF_PROGRAM #include "compat_ebpf.h" #else #include "file_contexts.h" #include "file_key_tools.h" #include <linux/fcntl.h> #include <linux/magic.h> static inline void make_file_context_info_common_ino(file_context_key_t* key, const struct inode *inode) { make_key_from_inode(&key->file_key, inode); #ifdef HAVE_INODE_GET_MTIME key->i_mtime.tv_sec = inode_get_mtime(inode).tv_sec; key->i_mtime.tv_nsec = inode_get_mtime(inode).tv_nsec; #else key->i_mtime.tv_sec = inode->i_mtime.tv_sec; key->i_mtime.tv_nsec = inode->i_mtime.tv_nsec; #endif #ifdef HAVE_INODE_GET_CTIME key->i_ctime.tv_sec = inode_get_ctime(inode).tv_sec; key->i_ctime.tv_nsec = inode_get_ctime(inode).tv_nsec; #else key->i_ctime.tv_sec = inode->i_ctime.tv_sec; key->i_ctime.tv_nsec = inode->i_ctime.tv_nsec; #endif } static inline bool make_file_context_info_common(file_context_info_t *info , const struct path *path , uint64_t pid_version) { if (!path || !path->dentry || !path->dentry->d_inode) { return false; } make_file_context_info_common_ino(&info->msg_info.key, path->dentry->d_inode); info->pid_key = pid_version; return true; } static inline bool make_file_context_info_open(file_context_info_t *info , const struct path *path , uint64_t pid_version , int flags) { if (!make_file_context_info_common(info, path, pid_version)) return false; if ((flags & O_ACCMODE) <= O_RDWR) { flags += 1; } info->params.open.flags = flags; return true; } static inline bool make_file_context_info_rw(file_context_info_t *info , const struct path *path , uint64_t pid_version , uint64_t low, uint64_t high) { if (!make_file_context_info_common(info, path, pid_version)) return false; info->params.rw.low = low; info->params.rw.high = high; return true; } static inline bool make_file_context_info_modify(file_context_info_t *info, const struct inode *inode, uint64_t unique_pid) { if (!inode) return false; make_file_context_info_common_ino(&info->msg_info.key, inode); info->pid_key = unique_pid; return true; } static inline bool make_file_context_req_modify(file_context_add_cache_request_t* req, const struct inode *inode, uint64_t unique_pid) { if (!inode) return false; make_key_from_inode(&req->key.file_key, inode); req->pid_key = unique_pid; return true; } #endif #ifndef NSFS_MAGIC #define NSFS_MAGIC 0x6e736673 #endif #ifndef SYSFS_MAGIC #define SYSFS_MAGIC 0x62656572 #endif #ifndef PROC_SUPER_MAGIC #define PROC_SUPER_MAGIC 0x9fa0 #endif #ifndef DEBUGFS_MAGIC #define DEBUGFS_MAGIC 0x64626720 #endif #ifndef SECURITYFS_MAGIC #define SECURITYFS_MAGIC 0x73636673 #endif #ifndef CGROUP_SUPER_MAGIC #define CGROUP_SUPER_MAGIC 0x27e0eb #endif #ifndef CGROUP2_SUPER_MAGIC #define CGROUP2_SUPER_MAGIC 0x63677270 #endif #ifndef BPF_FS_MAGIC #define BPF_FS_MAGIC 0xcafe4a11 #endif #ifndef TRACEFS_MAGIC #define TRACEFS_MAGIC 0x74726163 #endif #ifndef FUSECTL_SUPER_MAGIC #define FUSECTL_SUPER_MAGIC 0x65735543 #endif #ifndef PSTOREFS_MAGIC #define PSTOREFS_MAGIC 0x6165676C #endif #ifndef CONFIGFS_MAGIC #define CONFIGFS_MAGIC 0x62656570 #endif #ifndef HUGETLBFS_MAGIC #define HUGETLBFS_MAGIC 0x958458f6 #endif #ifndef MQUEUE_MAGIC #define MQUEUE_MAGIC 0x19800202 #endif #ifndef DEVPTS_SUPER_MAGIC #define DEVPTS_SUPER_MAGIC 0x1cd1 #endif #ifndef SELINUX_MAGIC #define SELINUX_MAGIC 0xf97cff8c #endif #ifndef BPF_PROGRAM static inline bool inode_is_usable(const struct inode *inode) { if (!inode) { return false; } if (!FP_KREAD(inode, i_sb)) { return false; } return true; } // Checks for bare minimum requirements for 'path' to be any sort of reasonable static inline bool path_is_usable(const struct path *path) { struct dentry *dentry; if (!FP_KREAD(path, mnt)) return false; dentry = FP_KREAD(path, dentry); if (!dentry) { return false; } return inode_is_usable(FP_KREAD(dentry, d_inode)); } #else static inline __attribute__((always_inline)) bool inode_is_usable(const struct inode *inode) { return !!BPF_CORE_READ(inode, i_sb); } static inline __attribute__((always_inline)) bool path_is_usable(const struct path *path) { return BPF_CORE_READ(path, mnt) && BPF_CORE_READ(path, dentry, d_inode, i_sb); } #endif static inline int magic_ok(unsigned long magic) { return magic != BPF_FS_MAGIC && magic != CGROUP_SUPER_MAGIC && magic != CGROUP2_SUPER_MAGIC && magic != CONFIGFS_MAGIC && magic != DEBUGFS_MAGIC && magic != DEVPTS_SUPER_MAGIC && magic != FUSECTL_SUPER_MAGIC && magic != HUGETLBFS_MAGIC && magic != MQUEUE_MAGIC && magic != NSFS_MAGIC && magic != PROC_SUPER_MAGIC && magic != PSTOREFS_MAGIC && magic != SECURITYFS_MAGIC && magic != SELINUX_MAGIC && magic != SYSFS_MAGIC && magic != TRACEFS_MAGIC ; } static inline int sb_ok(const struct super_block *sb) { return sb && magic_ok(FP_KREAD(sb, s_magic)); } #ifndef S_IFMT #define S_IFMT 00170000 #endif #ifndef S_IFREG #define S_IFREG 0100000 #endif #ifndef S_IFDIR #define S_IFDIR 0040000 #endif #ifndef S_ISREG #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #endif #ifndef S_ISDIR #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif static inline bool check_if_usable_inode_valid(const struct inode *inode) { umode_t mode; if (!sb_ok(FP_KREAD(inode, i_sb))) { return false; } mode = FP_KREAD(inode, i_mode); if ((S_ISREG(mode)) || (S_ISDIR(mode))) return true; else return false; } static inline bool inode_is_valid(const struct inode *inode) { if (!inode_is_usable(inode)) { return false; } return check_if_usable_inode_valid(inode); } static inline bool path_is_valid(const struct path *path) { if (!path_is_usable(path)) { return false; } return check_if_usable_inode_valid(FP_KREAD2(path, dentry, d_inode)); } static inline bool file_is_valid(struct file* f) { #ifndef BPF_PROGRAM return path_is_valid(&f->f_path); #else struct path path = BPF_CORE_READ(f, f_path); return path_is_valid(&path); #endif } #ifdef BPF_PROGRAM #define INT_MAX __INT_MAX__ #define rcu_dereference(p) (p) #endif static inline pid_t pid_from_dname(const struct dentry *d) { const unsigned char *s = (const unsigned char *)FP_KREAD(d, d_name.name); unsigned int len = FP_KREAD(d, d_name.len); unsigned int i; pid_t pid = 0; if (len <= 0 || !s) return -1; #ifdef BPF_PROGRAM // 16 should be enough for pid string length char buf[16] = {0}; long ret = bpf_probe_read_kernel_str(buf, sizeof(buf), s); if (ret <= 0) return -1; for (i = 0; i < len && i < sizeof(buf); i++) { unsigned char c = buf[i]; #else for (i = 0; i < len; i++) { unsigned char c = s[i]; #endif if (c < '0' || c > '9') return -1; /* Basic overflow guard for 32-bit int. */ if (pid > (INT_MAX - (c - '0')) / 10) return -1; pid = pid * 10 + (c - '0'); } return pid; } #ifndef BPF_PROGRAM static inline bool dname_eq(const struct dentry *d, const char *name, size_t name_len) { return d->d_name.len == name_len && !memcmp(d->d_name.name, name, name_len); } #else static inline __attribute__((always_inline)) bool dname_eq(const struct dentry *d, const char *name, size_t name_len) { unsigned int dname_len = BPF_CORE_READ(d, d_name.len); if (dname_len != name_len) return false; const unsigned char *dname = BPF_CORE_READ(d, d_name.name); if (!dname) return false; // this function is only used for short names with length <=8 char buf[8] = {0}; if (name_len > sizeof(buf)) return false; if (bpf_probe_read_kernel_str(buf, sizeof(buf), dname) <= 0) return false; for (size_t i = 0; i < name_len && i < sizeof(buf); i++) { if (buf[i] != name[i]) return false; } return true; } #endif static inline bool get_procfs_access_info(const struct path *path, pid_t *out_pid, SiProcfsAccessType *out_access_type) { if (!path || !FP_KREAD(path, mnt) || !FP_KREAD2(path, mnt, mnt_sb)) return false; if (FP_KREAD3(path, mnt, mnt_sb, s_magic) != PROC_SUPER_MAGIC) return false; { // /path/<pid>/(mem|maps|exe|comm) struct dentry *dentry = FP_KREAD(path, dentry); struct dentry *root_dentry = FP_KREAD2(path, mnt, mnt_root); struct dentry *parent, *grandparent; if (!dentry || !root_dentry) return false; rcu_read_lock(); parent = rcu_dereference(FP_KREAD(dentry, d_parent)); if (!parent) { rcu_read_unlock(); return false; } grandparent = rcu_dereference(FP_KREAD(parent, d_parent)); // grandparent must be root if (!grandparent || grandparent != root_dentry) { rcu_read_unlock(); return false; } *out_pid = pid_from_dname(parent); if (*out_pid == -1) { rcu_read_unlock(); return false; } if (dname_eq(dentry, "mem", 3)) { *out_access_type = SI_PROCFS_AT_MEM; } else if (dname_eq(dentry, "maps", 4)) { *out_access_type = SI_PROCFS_AT_MAPS; } else if (dname_eq(dentry, "exe", 3)) { *out_access_type = SI_PROCFS_AT_EXE; } else if (dname_eq(dentry, "comm", 4)) { *out_access_type = SI_PROCFS_AT_COMM; } else { rcu_read_unlock(); return false; } rcu_read_unlock(); } return true; }
© 2026 UnknownSec