Documentation/talpa/tecat.c | 50 ++++++++++++++++++++++++++ include/linux/sched.h | 1 + security/talpa/Kconfig | 18 +++++++++ security/talpa/Makefile | 1 + security/talpa/talpa_interceptor.c | 5 +++ security/talpa/talpa_thread_exclude.c | 63 +++++++++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 0 deletions(-) diff --git a/Documentation/talpa/tecat.c b/Documentation/talpa/tecat.c new file mode 100644 index 0000000..d963f68 --- /dev/null +++ b/Documentation/talpa/tecat.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + int talpa; + int fd; + ssize_t size; + char buffer[4096]; + int args = argc - 1; + + /* Register as an excluded client. */ + talpa = open("/dev/talpa-exclude", O_WRONLY); + if (!talpa) { + fprintf(stderr, "Cannot connect to Talpa - errno %d!\n", errno); + return 1; + } + + /* Signal Talpa that we want to be excluded. */ + if (write(talpa, "1", 1) != 1) { + fprintf(stderr, "Failed to exclude - errno %d!\n", errno); + return 1; + } + + /* Cat files given as arguments. */ + while (args > 0) { + fd = open(argv[args], O_RDONLY); + if (fd > 0) { + while ((size = read(fd, buffer, sizeof(buffer))) > 0) + write(STDOUT_FILENO, buffer, size); + close(fd); + } else { + fprintf(stderr, "%s: %s!\n", argv[args], strerror(errno)); + } + args--; + } + + /* Revert back to being intercepted. */ + if (write(talpa, "0", 1) != 1) { + fprintf(stderr, "Failed to revert - errno %d!\n", errno); + return 1; + } + + close(talpa); + + return 0; +} diff --git a/include/linux/sched.h b/include/linux/sched.h index dc7e592..3f7b739 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1502,6 +1502,7 @@ static inline void put_task_struct(struct task_struct *t) #define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ #define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ #define PF_THREAD_BOUND 0x04000000 /* Thread bound to specific cpu */ +#define PF_TALPA_EXCL 0x08000000 /* Processes which talpa should exclude */ #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ diff --git a/security/talpa/Kconfig b/security/talpa/Kconfig index c3c8dfe..2486bfa 100644 --- a/security/talpa/Kconfig +++ b/security/talpa/Kconfig @@ -36,3 +36,21 @@ config TALPA_OPERATION_EXCLUSION of filesystem objects, like directories or sockets. If you are unsure how to answer this question, answer Y. + + +config TALPA_THREAD_EXCLUSION + bool "Thread exclusions" + depends on TALPA + default y + help + This adds the ability for certain threads to register + themselves as excluded from the vetting process. It is useful + for allowing certain classes of userspace programs (for + example anti-malware or anti-rootkit scanner) to bypass + inteception which would otherwise interfere with their + operation. + + Access to this facility is controlled via permissions + on a corresponding device node. + + If you are unsure how to answer this question, answer Y. diff --git a/security/talpa/Makefile b/security/talpa/Makefile index 4aba14f..a01f8ce 100644 --- a/security/talpa/Makefile +++ b/security/talpa/Makefile @@ -10,3 +10,4 @@ talpa-y := talpa_interceptor.o \ talpa-$(CONFIG_TALPA_CACHE) += talpa_cache.o talpa-$(CONFIG_TALPA_OPERATION_EXCLUSION) += talpa_operation_exclude.o +talpa-$(CONFIG_TALPA_THREAD_EXCLUSION) += talpa_thread_exclude.o diff --git a/security/talpa/talpa_interceptor.c b/security/talpa/talpa_interceptor.c index 1770ac3..4c0cf94 100644 --- a/security/talpa/talpa_interceptor.c +++ b/security/talpa/talpa_interceptor.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "talpa_evaluation_calls.h" @@ -52,6 +53,10 @@ static int talpa_vet_file(struct file *file, int flags, enum talpa_operation op) enum talpa_action action = TALPA_NEXT; int ret = -ENOSYS; + /* Tasks marked as excluded are immediately ignored. */ + if (current->flags & PF_TALPA_EXCL) + return 0; + /* Try to allocate vetting details or block access. Cache will not be available before initcalls are run so allow all access until then. */ diff --git a/security/talpa/talpa_thread_exclude.c b/security/talpa/talpa_thread_exclude.c new file mode 100644 index 0000000..98a0e8c --- /dev/null +++ b/security/talpa/talpa_thread_exclude.c @@ -0,0 +1,63 @@ +/* + * Copyright 2008 Sophos Plc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + + +/* + * Very simple misc device driver. User can open it and exclude + * themselves from interception by writting ASCII 1 to it, or + * go back by writting ASCII 0. + */ + +static ssize_t talpa_thread_excl_write(struct file *file, const char *buf, size_t len, loff_t *ppos) +{ + if (len == 1) { + if (*buf == '1') { + current->flags |= PF_TALPA_EXCL; + return 1; + } else if (*buf == '0') { + current->flags &= ~PF_TALPA_EXCL; + return 1; + } + } + + return -EPROTO; +} + +static struct file_operations talpa_thread_excl_fops = { + .open = nonseekable_open, + .write = talpa_thread_excl_write, +}; + +static struct miscdevice misc_dev = { + MISC_DYNAMIC_MINOR, + "talpa-exclude", + &talpa_thread_excl_fops +}; + +static __init int talpa_thread_exclude_init(void) +{ + return misc_register(&misc_dev); +} + +__initcall(talpa_thread_exclude_init);