{"id":30058825,"url":"https://github.com/oditynet/virusstop","last_synced_at":"2025-08-28T22:25:55.133Z","repository":{"id":306893681,"uuid":"1027569332","full_name":"oditynet/virusSTOP","owner":"oditynet","description":"Patch for kernel 6.15.8 to block viruses, trojans and unwanted programs from running. Security is ensured while the virus does not know about the protection algorithm","archived":false,"fork":false,"pushed_at":"2025-08-05T09:40:21.000Z","size":20589,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-05T11:34:42.667Z","etag":null,"topics":["antivirus","antivirus-software","kernel","mandatory","mandatory-access-control","security","virus-stop"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oditynet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-28T07:57:00.000Z","updated_at":"2025-08-05T09:40:25.000Z","dependencies_parsed_at":"2025-07-28T10:05:37.449Z","dependency_job_id":"878fef7e-cdf8-47ce-9976-612bee6071bd","html_url":"https://github.com/oditynet/virusSTOP","commit_stats":null,"previous_names":["oditynet/virusstop"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oditynet/virusSTOP","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oditynet%2FvirusSTOP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oditynet%2FvirusSTOP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oditynet%2FvirusSTOP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oditynet%2FvirusSTOP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oditynet","download_url":"https://codeload.github.com/oditynet/virusSTOP/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oditynet%2FvirusSTOP/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272567967,"owners_count":24956916,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-28T02:00:10.768Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["antivirus","antivirus-software","kernel","mandatory","mandatory-access-control","security","virus-stop"],"created_at":"2025-08-08T00:21:46.950Z","updated_at":"2025-08-28T22:25:55.076Z","avatar_url":"https://github.com/oditynet.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg alt=\"GitHub code size in bytes\" src=\"https://img.shields.io/github/languages/code-size/oditynet/virusSTOP\"\u003e\u003c/img\u003e\n\u003cimg alt=\"GitHub license\" src=\"https://img.shields.io/github/license/oditynet/virusSTOP\"\u003e\u003c/img\u003e\n\u003cimg alt=\"GitHub commit activity\" src=\"https://img.shields.io/github/commit-activity/m/oditynet/virusSTOP\"\u003e\u003c/img\u003e\n\u003cimg alt=\"GitHub Repo stars\" src=\"https://img.shields.io/github/stars/oditynet/virusSTOP\"\u003e\u003c/img\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/oditynet/virusSTOP/blob/main/logo.png\" width=\"250\" height=\"auto\" /\u003e\n  \u003ch1\u003e  virusSTOP \u003c/h1\u003e\n\u003c/div\u003e\n\n## 📚 License\nAll rights are protected. My idea, my realization. You can use in projects with my permission and with my mention in the code and in the announcements of the program and other places where your program will be described.\n\n## 📋 I can...\n\n1. Blocking the launch of programs\n2. Blocking the launch of scripts as an executable file and a file passed as an argument to the interpreter (bash, awk, sh, python and etc.)  WARNING: This is a complex implementation. It is in development and testing.\n3. You can set the attribute only through your program (work with the user.bitX attribute is blocked via setfattr )\n\n## 🛠️ Prepare \n\nI decided to try my own implementation of the mandate access in the new nucleus, otherwise colleagues are stinging on the hard work of the casoppent, installed on their systems. The nucleus version took the latter, namely Linux-6.15.8+\n\nWe prepare the system:\nIt is necessary to set the bits of the launch permit used by all the files used. (I put it both system utilities and my own)\n```\nsudo find /usr/bin -xdev -type f -exec /usr/bin/setfattr -n \"user.bitX\" -v 1 {} \\;\nsudo find /sbin -xdev -type f -exec /usr/bin/setfattr -n \"user.bitX\" -v 1 {} \\;\n```\n\nUsed patch:\n```\ncd linux/fs\n patch -p1 \u003c exec.patch\n patch -p1 \u003c namei.patch\n patch -p1 \u003c xattr.patch\n```\n\nPrepare_binPrm - understands that the attribute is not hanged on virus and Initram.\n\nvim fs/exec.c\n```bash\n\n#include \u003clinux/xattr.h\u003e\n#include \u003clinux/mnt_idmapping.h\u003e\n#include \u003clinux/fs.h\u003e\n#include \u003clinux/fs_types.h\u003e\n\nstatic int prepare_binprm(struct linux_binprm *bprm)\n{\n    loff_t pos = 0;\n    ssize_t size;\n    char value[2];\n    struct dentry *dentry;\n    struct mnt_idmap *idmap;\n    struct inode *inode;\n    const char *fstype;\n\n    dentry = file_dentry(bprm-\u003efile);\n    idmap = file_mnt_idmap(bprm-\u003efile);\n    inode = d_inode(dentry);\n    fstype = inode-\u003ei_sb-\u003es_type-\u003ename;\n\n    // Критическое исключение для tmpfs и других виртуальных ФС\n    if (strcmp(fstype, \"tmpfs\") == 0 ||\n        strcmp(fstype, \"ramfs\") == 0 ||\n        strcmp(fstype, \"devtmpfs\") == 0 ||\n        strcmp(fstype, \"proc\") == 0 ||\n        strcmp(fstype, \"sysfs\") == 0 ||\n        strcmp(fstype, \"cgroup\") == 0) {\n        goto read_file;\n    }\n\n    if (WARN_ON(!idmap)) {\n        printk(KERN_ERR \"[bitX] Failed to get idmap for file: %s\\n\", dentry-\u003ed_name.name);\n        return -EPERM;\n    }\n\n    size = vfs_getxattr(idmap, dentry, \"user.bitX\", value, sizeof(value) - 1);\n    \n    if (size == 1) {\n        value[1] = '\\0';\n        if (value[0] == '0') {\n            printk(KERN_WARNING \"[bitX] Execution denied: %s has user.bitX=0\\n\",\n                   dentry-\u003ed_name.name);\n            return -EPERM;\n        }\n    } else if (size == -ENODATA) {\n        printk(KERN_INFO \"[bitX] Execution not allowed (no bitX): %s\\n\", dentry-\u003ed_name.name);\n         return -EPERM;\n    } else if (size \u003c 0) {\n        printk(KERN_WARNING \"[bitX] Error %ld reading user.bitX for %s (FS: %s)\\n\",\n               size, dentry-\u003ed_name.name, fstype);\n        goto read_file;\n    }\n\nread_file:\n    memset(bprm-\u003ebuf, 0, BINPRM_BUF_SIZE);\n    return kernel_read(bprm-\u003efile, bprm-\u003ebuf, BINPRM_BUF_SIZE, \u0026pos);\n}\n```\n\nThe next code sets all new files by the ATRIBUT ATRIBUT prohibiting to execute:\n\n```bash\nint vfs_create(struct mnt_idmap *idmap, struct inode *dir,\n               struct dentry *dentry, umode_t mode, bool want_excl)\n{\n    // ... \n\n    if (!error) {\n        fsnotify_create(dir, dentry);\n        set_bitx_attribute(idmap, dentry); // Новая функция\n    }\n\n    return error;\n}\n```\n```bash\nint vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,\n              struct dentry *dentry, umode_t mode, dev_t dev)\n{\n    int error;\n    \n    // ... \n\n    if (!error) {\n        fsnotify_create(dir, dentry);\n        set_bitx_attribute(idmap, dentry);\n    }\n    \n    return error;\n}\n```\n```bash\nint vfs_symlink(struct mnt_idmap *idmap, struct inode *dir,\n                struct dentry *dentry, const char *oldname)\n{\n    int error;\n    \n    // ...\n\n    if (!error) {\n        fsnotify_create(dir, dentry);\n        set_bitx_attribute(idmap, dentry);\n    }\n    \n    return error;\n}\n```\n```bash\n\n#include \u003clinux/xattr.h\u003e\nstatic void set_bitx_attribute(struct mnt_idmap *idmap, struct dentry *dentry)\n{\n    const char *name = \"user.bitX\";\n    const char *value = \"0\";\n    struct inode *inode = d_inode(dentry);\n    const char *fstype;\n    \n    if (!inode) return;\n    \n    fstype = inode-\u003ei_sb-\u003es_type-\u003ename;\n    \n    // Исключаем виртуальные ФС\n    if (strcmp(fstype, \"tmpfs\") == 0 ||\n        strcmp(fstype, \"ramfs\") == 0 ||\n        strcmp(fstype, \"devtmpfs\") == 0 ||\n        strcmp(fstype, \"proc\") == 0 ||\n        strcmp(fstype, \"sysfs\") == 0 ||\n        strcmp(fstype, \"cgroup\") == 0) {\n        return;\n    }\n    \n    // Только для обычных файлов\n    if (!S_ISREG(inode-\u003ei_mode)) {\n        return;\n    }\n    \n    int xerr = vfs_setxattr(idmap, dentry, name, value, strlen(value), XATTR_CREATE);\n    \n    if (xerr) {\n        if (xerr != -EOPNOTSUPP \u0026\u0026 xerr != -ENOTSUP) {\n            printk(KERN_INFO \"[bitX] Set bitX failed for %s (err=%d, FS=%s)\\n\",\n                   dentry-\u003ed_name.name, xerr, fstype);\n        }\n    } else {\n        printk(KERN_INFO \"[bitX] Set bitX=0 for new file: %s (FS=%s)\\n\",\n               dentry-\u003ed_name.name, fstype);\n    }\n}\n```\n\n## 🌪 Build kernel:\n```\nmake\nmake modules_install\nmake install\nmkinitcpio -p linux-custom (mkinitcpio -k 6.15.8  -g /boot/initramfs-linux1.img)\n```\n\nIn the FSTAB for EXT4, add support for 'user_xattr' on and reboot.\n\n\u003cimg src=\"https://github.com/oditynet/virusSTOP/blob/main/result.png\" title=\"example\" width=\"800\" /\u003e\n\n\u003cimg src=\"https://github.com/oditynet/virusSTOP/blob/main/result1.png\" title=\"example\" width=\"800\" /\u003e\n\n\u003cimg src=\"https://github.com/oditynet/virusSTOP/blob/main/kernel_in_work.gif\" title=\"example\" width=\"800\" /\u003e\n\nNow I create a program that has a maxilled priority will allow you to install anything from under the system:\n\n\nIn xattr.c i add in  white list bitx_launcher and systemd because it wac set bitX \n```\nsystemd[1]: Hostname set to \u003cviva\u003e.\nавг 07 10:42:47 viva kernel: Unauthorized attempt to set user.bitX from /usr/lib/systemd/systemd\nавг 07 10:42:47 viva kernel: [bitX] Unauthorized1 attempt to set user.bitX from /usr/lib/systemd\u003e\nавг 07 10:42:47 viva systemd[1]: bpf-restrict-fs: LSM BPF program attached\n```\n```\n#Build launch\ngcc -o bitx_launcher bitx_launcher.c\n\n# Build lib\ngcc -shared -fPIC -o libsetbitx.so set_bitx.c -ldl\n\n# Run\n./bitx_launch /bin/bash -c \"touch test_file\"\ngetfattr -n user.bitX test_file\"\n\n```\n He tested the installation of NVIDIA drivers. It was only required to give two programs of law:\n 1) /home/odity/Downloads/linux-6.15.8/scripts/mod/modpost\n 2) /home/odity/Downloads/linux-6.15.8/scripts/basic/fixdep\n\nInstalling updates will reset all attributes, so we set hooks:\n\n```\n# /usr/share/libalpm/hooks/set-bitx.hook \n[Trigger]\nOperation = Install\nOperation = Upgrade\nType = Package\nTarget = *\n\n[Action]\nDescription = Setting user.bitX attribute for executables...\nWhen = PostTransaction\nExec = /usr/local/bin/set-bitx-for-new-files.sh\nDepends = attr\n```\n\n```\n#/usr/local/bin/set-bitx-for-new-files.sh\n\n#!/bin/bash\n\n# Логирование\nLOG_FILE=\"/var/log/pacman-bitx.log\"\necho \"$(date) - Starting bitX attribute processing\" \u003e\u003e \"$LOG_FILE\"\n\n# Получаем текущую дату в формате, как в pacman.log (например: [2023-10-01])\nTODAY=$(date +'%Y-%m-%d')\n\n# Извлекаем пакеты, установленные/обновлённые сегодня\nPACMAN_NEW_PKGS=$(grep -E \"(installed|upgraded)\" /var/log/pacman.log | grep $TODAY|awk '{print $4}' | sort -u)\n\nif [[ -z \"$PACMAN_NEW_PKGS\" ]]; then\n    echo \"$(date) - No new packages found for today\" \u003e\u003e \"$LOG_FILE\"\n    exit 0\nfi\n\necho \"$(date) - Processing packages: $PACMAN_NEW_PKGS\" \u003e\u003e \"$LOG_FILE\"\n\n# Обработка только новых пакетов\nfor package in $PACMAN_NEW_PKGS; do\n    # Получаем список файлов пакета\n    pacman -Qlq \"$package\" 2\u003e/dev/null | while read -r file; do\n        # Проверяем, что файл существует и является исполняемым\n        if [[ -f \"$file\" \u0026\u0026 -x \"$file\" ]]; then\n            # Проверяем, не установлен ли уже атрибут\n            if ! getfattr -n user.bitX \"$file\" \u0026\u003e/dev/null; then\n                echo \"Setting bitX for: $file\" \u003e\u003e \"$LOG_FILE\"\n                /usr/bin/bitx_launcher -v 1 \"$file\"\n            fi\n        fi\n    done\ndone\n\necho \"$(date) - Completed\" \u003e\u003e \"$LOG_FILE\"\n```\n\nIf we want to prohibit changes to the user.bitX attribute, we need to patch the function in the fs/xattr.c file to the following form:\n\n```\n       const char *allowed_exec = \"/usr/bin/bitx_launcher\";\n\n       // Отслеживаем только user.bitX\n       if (strcmp(name, \"user.bitX\") == 0) {\n               // Получаем путь к исполняемому файлу процесса\n               exe_file = get_task_exe_file(current);\n               if (!exe_file) {\n                       return -EPERM;\n               }\n\n               char *path = d_path(\u0026exe_file-\u003ef_path, exe_path, sizeof\n(exe_path));\n               fput(exe_file);\n\n               // Если это не bitx_launcher — запрещаем\n               if (IS_ERR(path) || strcmp(path, allowed_exec) != 0) {\n                       printk(KERN_WARNING \"[bitX] Unauthorized attempt to set user.bitX from %s\\n\", path);\n                       return -EPERM;\n               }\n\n               // Логируем значение (если нужно)\n               if (size == 1 \u0026\u0026 (*(char *)value == '0' || *(char *)value == '1')) {\n                       printk(KERN_INFO \"[bitX] user.bitX set1 to %c by %s\\n\", *(char *)value, path);\n               }\n       }\n\n        if (delegated_inode) {\n                error = break_deleg_wait(\u0026delegated_inode);\n                if (!error)\n                        goto retry_deleg;\n        }\n        if (value != orig_value)\n                kfree(value);\n\n        return error;\n}\n```\n\nNow the setfattr command can set any attribute except user.bitX. It can be set via the /usr/bin/bitx_launcher utility from the bitx_launcher.c source code, the syntax of which is '/usr/bin/bitx_launcher -v 1 file' and without an argument it will launch all parent processes of the program with the bitX=1 bit.\n\n```\ngcc -o bitx_launch bitx_launch.c\n```\n\n## ☯ Problems \n\n1) If you can't set the attribute, then reboot into a normal kernel.\n2) Compiling the kernel: you need to give rights to files in the ./scripts subfolder\n3) /usr/bin/bitx_launcher does not have self-control of its integrity, so replacing it will not be a problem\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foditynet%2Fvirusstop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foditynet%2Fvirusstop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foditynet%2Fvirusstop/lists"}