/**
@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 "file_contexts.h"
#include "file_key_tools.h"
#include <linux/fcntl.h>
#include <linux/magic.h>
static inline bool make_file_context_info(file_context_info_t *info
, const struct path *path
, int flags
, uint64_t low, uint64_t high
, uint64_t pid_version)
{
if (!path || !path->dentry || !path->dentry->d_inode)
{
return false;
}
make_key_from_inode(&info->msg_info.key.file_key, path->dentry->d_inode);
#ifdef HAVE_INODE_GET_MTIME
info->msg_info.key.i_mtime.tv_sec = inode_get_mtime(path->dentry->d_inode).tv_sec;
info->msg_info.key.i_mtime.tv_nsec = inode_get_mtime(path->dentry->d_inode).tv_nsec;
#else
info->msg_info.key.i_mtime.tv_sec = path->dentry->d_inode->i_mtime.tv_sec;
info->msg_info.key.i_mtime.tv_nsec = path->dentry->d_inode->i_mtime.tv_nsec;
#endif
#ifdef HAVE_INODE_GET_CTIME
info->msg_info.key.i_ctime.tv_sec = inode_get_ctime(path->dentry->d_inode).tv_sec;
info->msg_info.key.i_ctime.tv_nsec = inode_get_ctime(path->dentry->d_inode).tv_nsec;
#else
info->msg_info.key.i_ctime.tv_sec = path->dentry->d_inode->i_ctime.tv_sec;
info->msg_info.key.i_ctime.tv_nsec = path->dentry->d_inode->i_ctime.tv_nsec;
#endif
info->pid_version = pid_version;
if ((flags & O_ACCMODE) <= O_RDWR)
{
flags += 1;
}
info->flags = flags;
info->low = low;
info->high = high;
return true;
}
static inline bool make_file_context_info_with_inode(file_context_info_t *info, const struct inode *inode, uint64_t unique_pid)
{
make_key_from_inode(&info->msg_info.key.file_key, inode);
#ifdef HAVE_INODE_GET_MTIME
info->msg_info.key.i_mtime.tv_sec = inode_get_mtime(inode).tv_sec;
info->msg_info.key.i_mtime.tv_nsec = inode_get_mtime(inode).tv_nsec;
#else
info->msg_info.key.i_mtime.tv_sec = inode->i_mtime.tv_sec;
info->msg_info.key.i_mtime.tv_nsec = inode->i_mtime.tv_nsec;
#endif
#ifdef HAVE_INODE_GET_CTIME
info->msg_info.key.i_ctime.tv_sec = inode_get_ctime(inode).tv_sec;
info->msg_info.key.i_ctime.tv_nsec = inode_get_ctime(inode).tv_nsec;
#else
info->msg_info.key.i_ctime.tv_sec = inode->i_ctime.tv_sec;
info->msg_info.key.i_ctime.tv_nsec = inode->i_ctime.tv_nsec;
#endif
// currently this function uses unique_pid only
info->unique_pid = unique_pid;
return true;
}
#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
static inline bool inode_is_usable(const struct inode *inode)
{
if (!inode)
{
return false;
}
if (!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 (!path->mnt)
return false;
dentry = path->dentry;
if (!dentry)
{
return false;
}
return inode_is_usable(dentry->d_inode);
}
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(sb->s_magic);
}
static inline bool check_if_usable_inode_valid(const struct inode *inode)
{
umode_t mode;
if (!sb_ok(inode->i_sb))
{
return false;
}
mode = 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(path->dentry->d_inode);
}
static inline bool file_is_valid(struct file* f)
{
return path_is_valid(&f->f_path);
}
|