diff --git a/dkms.conf b/dkms.conf index e57ef67..84b291a 100644 --- a/dkms.conf +++ b/dkms.conf @@ -1,10 +1,11 @@ DEST_MODULE_LOCATION[0]="/extra" -MAKE="make KERNELDIR=/lib/modules/${kernelver}/build" -CLEAN="make clean" +MAKE="make KERNELDIR=/lib/modules/${kernelver}/build KERNEL_VERSION=$kernelver" +CLEAN="make clean KERNELDIR=/lib/modules/${kernelver}/build KERNEL_VERSION=$kernelver" BUILT_MODULE_NAME=xt_tls BUILT_MODULE_LOCATION=src/ PACKAGE_NAME=xt_tls -PACKAGE_VERSION=0.3.2 -REMAKE_INITRD=yes +PACKAGE_VERSION=0.3.6 +#REMAKE_INITRD=yes +AUTOINSTALL="no" POST_INSTALL=dkms/post-install.sh POST_REMOVE=dkms/post-remove.sh diff --git a/nbproject/private/Debug.properties b/nbproject/private/Debug.properties new file mode 100644 index 0000000..21110eb --- /dev/null +++ b/nbproject/private/Debug.properties @@ -0,0 +1,3 @@ +/home/mpolk/xt_tls/src/xt_tls.mod.c=/usr/src/linux-headers-4.15.0-112-generic#-Wp,-MD,/home/mpolk/xt_tls/src/.xt_tls.mod.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -DKBUILD_BASENAME=\"xt_tls.mod\" -DKBUILD_MODNAME=\"xt_tls\" -DMODULE -DXT_TLS_DEBUG -c -o /home/mpolk/xt_tls/src/xt_tls.mod.o /home/mpolk/xt_tls/src/xt_tls.mod.c +/home/mpolk/xt_tls/src/xt_tls_main.c=/usr/src/linux-headers-4.15.0-112-generic#-Wp,-MD,/home/mpolk/xt_tls/src/.xt_tls_main.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -DMODULE -DXT_TLS_DEBUG -DKBUILD_BASENAME=\"xt_tls_main\" -DKBUILD_MODNAME=\"xt_tls\" -c -o /home/mpolk/xt_tls/src/xt_tls_main.o /home/mpolk/xt_tls/src/xt_tls_main.c +/home/mpolk/xt_tls/src/hostset.c=/usr/src/linux-headers-4.15.0-112-generic#-Wp,-MD,/home/mpolk/xt_tls/src/.hostset.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -Wno-array-bounds -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -DMODULE -DXT_TLS_DEBUG -DKBUILD_BASENAME=\"hostset\" -DKBUILD_MODNAME=\"xt_tls\" -c -o /home/mpolk/xt_tls/src/hostset.o /home/mpolk/xt_tls/src/hostset.c diff --git a/src/hostset.c b/src/hostset.c index 427c66f..865e58e 100644 --- a/src/hostset.c +++ b/src/hostset.c @@ -34,7 +34,7 @@ static struct file_operations proc_fops = { }; // Initialize a host set -int hs_init(struct host_set *hs, const char *name) +int hs_init(struct host_set *hs, const char *name, struct proc_dir_entry *parent_dir) { kuid_t uid = make_kuid(&init_user_ns, 0); kgid_t gid = make_kgid(&init_user_ns, 0); @@ -47,7 +47,7 @@ int hs_init(struct host_set *hs, const char *name) hs->hosts = RB_ROOT; hs->filesize = 0; - hs->proc_file = proc_create_data(name, 0644, proc_fs_hostset_dir, + hs->proc_file = proc_create_data(hs->name, 0644, parent_dir, &proc_fops, hs); if (! hs->proc_file) { pr_err("Cannot create a procfs file for the host set %s\n", name); @@ -254,11 +254,14 @@ bool hs_lookup(struct host_set *hs, const char *hostname, bool suffix_matching) for (node = hs->hosts.rb_node; ! result && node;) { struct host_set_elem *hse = rb_entry(node, struct host_set_elem, rbnode); int cmp; - if (suffix_matching) { + if (! suffix_matching) { + cmp = strcmp(pattern, hse->name); + } else { size_t len = strlen(hse->name); cmp = strncmp(pattern, hse->name, len); - } else { - cmp = strcmp(pattern, hse->name); + if (cmp == 0 && len < strlen(pattern) && pattern[len] != '.') { + cmp = 1; + }//if }//if if (cmp < 0) @@ -367,6 +370,10 @@ proc_write(struct file *file, const char __user *input, size_t size, loff_t *lof char buf[MAX_HOSTNAME_LEN + 2]; int rc; +#ifdef XT_TLS_DEBUG + pr_info("proc_write %lu chars at offset %lld: %s\n", size, *loff, input); +#endif + if (size == 0) return 0; if (size > sizeof(buf) - 1) diff --git a/src/hostset.h b/src/hostset.h index d7b7d52..57e299f 100644 --- a/src/hostset.h +++ b/src/hostset.h @@ -27,8 +27,20 @@ struct host_set { };//host_set +// Descriptor holding a pointer to the host set table for the specific net namespace +struct host_set_table_descriptor { + struct net *net; + struct proc_dir_entry *proc_fs_dir, *proc_fs_hostset_dir; + struct host_set *host_sets; + struct host_set_table_descriptor *next; +};//host_set_table_descriptor + +// The list of the host sets tables we use +extern struct host_set_table_descriptor *host_set_tables; + + // Initialize a host set -int hs_init(struct host_set *hs, const char *name); +int hs_init(struct host_set *hs, const char *name, struct proc_dir_entry *parent_dir); // Increment the usage count for the host set static inline void hs_hold(struct host_set *hs) { hs->refcount++; } // Free a host set entry (taking into account its refcount) @@ -41,3 +53,18 @@ static inline bool hs_is_free(struct host_set *hs) { return hs->refcount == 0; } static inline void hs_zeroize(struct host_set *hs) { hs->refcount = 0; } // Lookup the host set for the specifed host name bool hs_lookup(struct host_set *hs, const char *hostname, bool suffix_matching); + +// Find the host set table for a given net namespace +static inline struct host_set_table_descriptor + *find_host_set_table(struct net *net, struct host_set_table_descriptor ***ppprev) +{ + struct host_set_table_descriptor **pp; + for (pp = &host_set_tables; *pp; pp = &((*pp)->next)) { + if ((*pp)->net == net) { + if (ppprev) + *ppprev = pp; + return *pp; + }//if + }//for + return NULL; +}//find_host_set_table diff --git a/src/xt_tls.h b/src/xt_tls.h index af0c20b..c687992 100644 --- a/src/xt_tls.h +++ b/src/xt_tls.h @@ -12,11 +12,10 @@ struct xt_tls_info { __u16 op_flags, inversion_flags; char host_or_set_name[MAX_HOSTNAME_LEN + 1]; - __s32 hostset_index; + struct host_set *hostset; }; #define PROC_FS_MODULE_DIR "xt_tls" #define PROC_FS_HOSTSET_SUBDIR "hostset" -extern struct proc_dir_entry *proc_fs_hostset_dir; #endif /* _XT_TLS_TARGET_H */ diff --git a/src/xt_tls_main.c b/src/xt_tls_main.c index 24f3080..1b6d53b 100644 --- a/src/xt_tls_main.c +++ b/src/xt_tls_main.c @@ -21,11 +21,8 @@ static int max_host_sets = 8; module_param(max_host_sets, int, S_IRUGO); MODULE_PARM_DESC(max_host_sets, "host set table capacity (default 8)"); -// The table of the host sets we use -static struct host_set *host_set_table; - -// The proc-fs subdirectory for hostsets -struct proc_dir_entry *proc_fs_dir, *proc_fs_hostset_dir; +// The list of the host sets tables we use +struct host_set_table_descriptor *host_set_tables = NULL; /* * Searches through skb->data and looks for a @@ -239,6 +236,7 @@ static int get_tls_hostname(const struct sk_buff *skb, char **dest) return EPROTO; } + static bool tls_mt(const struct sk_buff *skb, struct xt_action_param *par) { char *parsed_host; @@ -261,8 +259,7 @@ static bool tls_mt(const struct sk_buff *skb, struct xt_action_param *par) match = glob_match(info->host_or_set_name, parsed_host); break; case XT_TLS_OP_HOSTSET: - match = hs_lookup(&host_set_table[info->hostset_index], - parsed_host, suffix_matching); + match = hs_lookup(info->hostset, parsed_host, suffix_matching); break; }//switch @@ -283,6 +280,14 @@ static int tls_mt_check (const struct xt_mtchk_param *par) { __u16 proto; struct xt_tls_info *match_info = par->matchinfo; + struct host_set *host_set_table; + + struct host_set_table_descriptor *hst_descr = find_host_set_table(par->net, NULL); + if (hst_descr == NULL) { + pr_err("Cannot find a host set table for the net %p\n", par->net); + return -EINVAL; + }//if + host_set_table = hst_descr->host_sets; if (par->family == NFPROTO_IPV4) { proto = ((const struct ipt_ip *) par->entryinfo)->proto; @@ -323,12 +328,13 @@ static int tls_mt_check (const struct xt_mtchk_param *par) pr_err("Cannot add a new hostset: the hostset table is full\n"); return -ENOMEM; }//if - rc = hs_init(&host_set_table[i], match_info->host_or_set_name); + rc = hs_init(&host_set_table[i], match_info->host_or_set_name, + hst_descr->proc_fs_hostset_dir); if (rc) return rc; }//if - match_info->hostset_index = i; + match_info->hostset = host_set_table + i; }//if return 0; @@ -339,11 +345,11 @@ static void tls_mt_destroy(const struct xt_mtdtor_param *par) { struct xt_tls_info *match_info = par->matchinfo; #ifdef XT_TLS_DEBUG - pr_info("tls_mt_destroy: match_info: op_flags=0x%X, hostset_index=%u\n", - match_info->op_flags, match_info->hostset_index); + pr_info("tls_mt_destroy: match_info: op_flags=0x%X, hostset=%p\n", + match_info->op_flags, match_info->hostset); #endif if (match_info->op_flags & XT_TLS_OP_HOSTSET) { - hs_free(&host_set_table[match_info->hostset_index]); + hs_free(match_info->hostset); }//if }//tls_mt_destroy @@ -376,20 +382,75 @@ static struct xt_match tls_mt_regs[] __read_mostly = { static int __net_init tls_net_init(struct net *net) { - proc_fs_dir = proc_mkdir(KBUILD_MODNAME, net->proc_net); - proc_fs_hostset_dir = proc_mkdir(PROC_FS_HOSTSET_SUBDIR, proc_fs_dir); - if (! proc_fs_hostset_dir) { + int i; + struct host_set_table_descriptor *hst_descr; +#ifdef XT_TLS_DEBUG + pr_info("Initializing net %px", net); +#endif + + hst_descr = kmalloc(sizeof(struct host_set_table_descriptor), GFP_KERNEL); + if (hst_descr == NULL) { + pr_err("Cannot allocate memory for the host set table\n"); + return -ENOMEM; + }//if + + hst_descr->net = net; + + hst_descr->host_sets = kmalloc(sizeof (struct host_set) * max_host_sets, GFP_KERNEL); + if (! hst_descr->host_sets) { + pr_err("Cannot allocate memory for the host set table\n"); + kfree(hst_descr); + return -ENOMEM; + }//if +#ifdef XT_TLS_DEBUG + pr_info("Host set table allocated (%u elements max)\n", max_host_sets); +#endif + + for (i = 0; i < max_host_sets; i++) + hs_zeroize(&hst_descr->host_sets[i]); + + hst_descr->proc_fs_dir = proc_mkdir(KBUILD_MODNAME, net->proc_net); + if (! hst_descr->proc_fs_dir) { + pr_err("Cannot create /proc/net/ subdirectory for this module\n"); + kfree(hst_descr->host_sets); + kfree(hst_descr); + return -EFAULT; + }//if + hst_descr->proc_fs_hostset_dir = proc_mkdir(PROC_FS_HOSTSET_SUBDIR, hst_descr->proc_fs_dir); + if (! hst_descr->proc_fs_hostset_dir) { pr_err("Cannot create /proc/net/ subdirectory for this module\n"); + proc_remove(hst_descr->proc_fs_dir); + kfree(hst_descr->host_sets); + kfree(hst_descr); return -EFAULT; }//if + + hst_descr->next = host_set_tables; + host_set_tables = hst_descr; return 0; }//tls_net_init static void __net_exit tls_net_exit(struct net *net) { - proc_remove(proc_fs_hostset_dir); - proc_remove(proc_fs_dir); + int i; + struct host_set_table_descriptor **pprev, *hst_descr; +#ifdef XT_TLS_DEBUG + pr_info("Finalizing net %px", net); +#endif + hst_descr = find_host_set_table(net, &pprev); + if (hst_descr == NULL) { + pr_err("Cannot find a host set table for the net %p\n", net); + return; + }//if + + *pprev = hst_descr->next; + for (i = 0; i < max_host_sets; i++) + hs_destroy(hst_descr->host_sets + i); + proc_remove(hst_descr->proc_fs_hostset_dir); + proc_remove(hst_descr->proc_fs_dir); + kfree(hst_descr->host_sets); + kfree(hst_descr); }//tls_net_exit @@ -401,7 +462,6 @@ static struct pernet_operations tls_net_ops = { static int __init tls_mt_init (void) { - int i; int rc = xt_register_matches(tls_mt_regs, ARRAY_SIZE(tls_mt_regs)); if (rc) return rc; @@ -410,34 +470,14 @@ static int __init tls_mt_init (void) if (rc) { pr_err("Cannot register pernet subsys\n"); xt_unregister_matches(tls_mt_regs, ARRAY_SIZE(tls_mt_regs)); - unregister_pernet_subsys(&tls_net_ops); return rc; }//if - - host_set_table = kmalloc(sizeof (struct host_set) * max_host_sets, GFP_KERNEL); - if (! host_set_table) { - pr_err("Cannot allocate memory for the host set table\n"); - xt_unregister_matches(tls_mt_regs, ARRAY_SIZE(tls_mt_regs)); - return -ENOMEM; - }//if -#ifdef XT_TLS_DEBUG - pr_info("Host set table allocated (%u elements max)\n", max_host_sets); -#endif - - for (i = 0; i < max_host_sets; i++) - hs_zeroize(&host_set_table[i]); - return 0; } static void __exit tls_mt_exit (void) { - int i; xt_unregister_matches(tls_mt_regs, ARRAY_SIZE(tls_mt_regs)); - - for (i = 0; i < max_host_sets; i++) - hs_destroy(&host_set_table[i]); - kfree(host_set_table); unregister_pernet_subsys(&tls_net_ops); #ifdef XT_TLS_DEBUG pr_info("Host set table disposed\n"); @@ -450,5 +490,5 @@ module_exit(tls_mt_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Nils Andreas Svee "); MODULE_DESCRIPTION("Xtables: TLS (SNI) matching"); -MODULE_VERSION("0.3.1"); +MODULE_VERSION("0.3.6"); MODULE_ALIAS("ipt_tls");