shell bypass 403

Cubjrnet7 Shell

: /usr/src/file_protector-1.1-1572/ [ drwxr-xr-x ]

name : file_contexts_priv.h
/**
@file     file_contexts_priv.h
@brief    Store the opened file contexts(inode + pid), private struct definitions
@details  Copyright (c) 2024 Acronis International GmbH
@author   Bruce Wang ([email protected])
@since    $Id: $
*/

#include <linux/list.h>
#include <linux/rcupdate.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/rbtree.h>

#include "file_contexts.h"
#include "hashtable_compat.h"
#include "transport.h"

#define FILE_CONTEXT_SMALL_TABLE_SIZE_BITS 6                                              // 64
#define FILE_CONTEXT_SMALL_TABLE_MAX_SIZE (1 << (FILE_CONTEXT_SMALL_TABLE_SIZE_BITS - 1)) // 32
#define FILE_CONTEXT_SMALL_TABLE_LRU_CLEAN_SIZE (10)
#define FILE_CONTEXT_BIG_TABLE_SIZE_BITS 15                                       // 32768
#define FILE_CONTEXT_BIG_TBALE_SIZE (1 << (FILE_CONTEXT_BIG_TABLE_SIZE_BITS - 1)) // 16384
#define FILE_CONTEXT_BIG_TABLE_LRU_CLEAN_SIZE (100)
#define FILE_CONTEXT_EXPIRE_TIME_MS (180 * 1000)

#define FILE_CONTEXT_CHUNK_SIZE 4096
#define FILE_CONTEXT_CHUNK_LOWER_BOUND(N) ((uint64_t)(N / FILE_CONTEXT_CHUNK_SIZE) * FILE_CONTEXT_CHUNK_SIZE)
#define FILE_CONTEXT_CHUNK_UPPER_BOUND(N) ((uint64_t)((N + FILE_CONTEXT_CHUNK_SIZE - 1) / FILE_CONTEXT_CHUNK_SIZE) * FILE_CONTEXT_CHUNK_SIZE)

#define FILE_CONTEXT_MAX_FILE_SIZE (100 * 1024 * 1024)

/*
 size of file_context_tables_t: 786576 Bytes => 0.75MB
 size of interval_node_t: 72 Bytes
 size of file_context_rw_node_t: 192 Bytes
 size of file_context_open_file_node_t: 720 Bytes
 size of file_context_open_process_node_t: 104 Bytes

 In the scenario that all tables are full:
    2 *32768 * (sizeof(file_context_rw_node_t) + 32(estimated) * sizeof(interval_node_t)) +
    32768 * (sizeof(file_context_open_file_node_t) + 32 * sizeof(file_context_open_process_node_t)) +
    sizeof(file_context_tables_t)
    = 283 MB
*/

// Node in file_context_common_table_t
// this struct should always be the first in the assembled struct
typedef struct
{
    // node in file_context_common_table_t->hashtable
    struct hlist_node hash_node;
    uint64_t key;
    // node in file_context_common_table_t->lru_list
    bool lru_list_node_inserted;
    struct list_head lru_list_node;
    // node in temporary delete list
    struct list_head del_list_node;
    unsigned long last_access_time;
    atomic_t ref_count;
    struct kmem_cache *kmem;
    struct rcu_head rcu;
    void (*pre_free_func)(void *);
} file_context_common_node_t;

// Abstruction of tables
typedef struct
{
    struct hlist_head *hashtable;
    struct list_head lru_list;
    unsigned int size;
    uint8_t hashbits;
    unsigned int max_size;
    unsigned short clean_count;
    spinlock_t spinlock;
} file_context_common_table_t;

// A small hashtable struct to store file_context_open_process_node_t, the key is pid
typedef struct
{
    DECLARE_HASHTABLE(hashtable, FILE_CONTEXT_SMALL_TABLE_SIZE_BITS);
    file_context_common_table_t common_table;
} file_context_small_table_t;

// A big hashtable struct to store file_context_open_file_node_t, file_context_rw_node_t, the key is inode ptr
typedef struct
{
    DECLARE_HASHTABLE(hashtable, FILE_CONTEXT_BIG_TABLE_SIZE_BITS);
    file_context_common_table_t common_table;
} file_context_big_table_t;

// Node in process_table
typedef struct
{
    file_context_common_node_t common_node;
    file_context_open_process_t data;
} file_context_open_process_node_t;

// Node in open_table
typedef struct
{
    file_context_common_node_t common_node;
    // Key: pid, Value: flags
    file_context_small_table_t process_table;
    file_context_key_t key;
    file_context_open_file_t data;
} file_context_open_file_node_t;

typedef struct
{
    uint64_t low;
    uint64_t high;
    struct rb_node rb;
    // node in temporary delete list
    struct list_head del_list_node;
    struct list_head stack_node;
} interval_node_t;

// Node in read_table/write_table
typedef struct
{
    file_context_common_node_t common_node;
    // data fields
    file_context_key_t key;
    file_context_rw_t data;
} file_context_rw_node_t;

typedef struct
{
    file_context_common_node_t common_node;
    file_context_process_t data;
} file_context_process_node_t;

typedef struct
{
    file_context_common_node_t common_node;
    // data fields
    file_context_key_t key;
    file_context_small_table_t process_table;
} file_context_file_modify_node_t;

typedef struct
{
    uint64_t transport_id;

    // TODO: ref_count is excessive, it is going to be used very rarely in a normal run
    // A better idea would be using rcu to acquire the file_context_tables_t pointer
    // and avoid using reference counts altogether
    atomic_t ref_count;
    // Key: inode.ptr, Value: processes
    file_context_big_table_t open_table;
    // Key: inode.ptr, Value: intervals
    file_context_big_table_t read_table;
    // Key: inode.ptr, Value: intervals
    file_context_big_table_t write_table;

    struct rcu_head rcu;
} file_context_tables_t;

#define MAX_TRANSPORT_EXTENDED_SIZE MAX_TRANSPORT_SIZE + 1
typedef struct
{
    spinlock_t writer_lock;
    // file_context_tables_t is memory costly, malloc it only when new transport is opened
    // file_context_tables_t pointer is RCU protected
    // this is a quick fix, tables[MAX_TRANSPORT_SIZE] is used for file modified flag cache.
    // TODO: reorganize the tables
    file_context_tables_t *tables[MAX_TRANSPORT_EXTENDED_SIZE];
} file_context_manager_t;

© 2025 Cubjrnet7