10265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt/* 20265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * Kernel module to match various things tied to sockets associated with 30265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * locally generated outgoing packets. 40265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * 50265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * (C) 2000 Marc Boucher <marc@mbsi.ca> 60265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * 7edc26f7aaa23591c779d6d6fc833c0c96fbeb3c0Jan Engelhardt * Copyright © CC Computer Consultants GmbH, 2007 - 2008 80265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * 90265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * This program is free software; you can redistribute it and/or modify 100265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * it under the terms of the GNU General Public License version 2 as 110265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * published by the Free Software Foundation. 120265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt */ 130265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt#include <linux/module.h> 140265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt#include <linux/skbuff.h> 150265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt#include <linux/file.h> 160265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt#include <net/sock.h> 170265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt#include <linux/netfilter/x_tables.h> 180265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt#include <linux/netfilter/xt_owner.h> 190265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 2026711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biedermanstatic int owner_check(const struct xt_mtchk_param *par) 2126711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman{ 2226711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman struct xt_owner_match_info *info = par->matchinfo; 2326711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman 2426711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman /* For now only allow adding matches from the initial user namespace */ 2526711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman if ((info->match & (XT_OWNER_UID|XT_OWNER_GID)) && 2626711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman (current_user_ns() != &init_user_ns)) 2726711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman return -EINVAL; 2826711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman return 0; 2926711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman} 3026711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman 310265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardtstatic bool 3262fc8051083a334578c3f4b3488808f210b4565fJan Engelhardtowner_mt(const struct sk_buff *skb, struct xt_action_param *par) 330265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt{ 34f7108a20dee44e5bb037f9e48f6a207b42e6ae1cJan Engelhardt const struct xt_owner_match_info *info = par->matchinfo; 350265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt const struct file *filp; 360265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 370265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt if (skb->sk == NULL || skb->sk->sk_socket == NULL) 380265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt return (info->match ^ info->invert) == 0; 390265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt else if (info->match & info->invert & XT_OWNER_SOCKET) 400265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt /* 410265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * Socket exists but user wanted ! --socket-exists. 420265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt * (Single ampersands intended.) 430265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt */ 440265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt return false; 450265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 460265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt filp = skb->sk->sk_socket->file; 470265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt if (filp == NULL) 480265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt return ((info->match ^ info->invert) & 490265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt (XT_OWNER_UID | XT_OWNER_GID)) == 0; 500265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 5126711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman if (info->match & XT_OWNER_UID) { 5226711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min); 5326711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max); 5426711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman if ((uid_gte(filp->f_cred->fsuid, uid_min) && 5526711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman uid_lte(filp->f_cred->fsuid, uid_max)) ^ 56edc26f7aaa23591c779d6d6fc833c0c96fbeb3c0Jan Engelhardt !(info->invert & XT_OWNER_UID)) 570265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt return false; 5826711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman } 590265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 6026711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman if (info->match & XT_OWNER_GID) { 6126711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min); 6226711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max); 6326711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman if ((gid_gte(filp->f_cred->fsgid, gid_min) && 6426711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman gid_lte(filp->f_cred->fsgid, gid_max)) ^ 65edc26f7aaa23591c779d6d6fc833c0c96fbeb3c0Jan Engelhardt !(info->invert & XT_OWNER_GID)) 660265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt return false; 6726711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman } 680265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 690265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt return true; 700265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt} 710265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 726461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardtstatic struct xt_match owner_mt_reg __read_mostly = { 736461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt .name = "owner", 746461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt .revision = 1, 756461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt .family = NFPROTO_UNSPEC, 7626711a791effbea125fea4284f4d1c4fa8f7bc73Eric W. Biederman .checkentry = owner_check, 776461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt .match = owner_mt, 786461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt .matchsize = sizeof(struct xt_owner_match_info), 796461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt .hooks = (1 << NF_INET_LOCAL_OUT) | 806461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt (1 << NF_INET_POST_ROUTING), 816461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt .me = THIS_MODULE, 820265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt}; 830265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 840265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardtstatic int __init owner_mt_init(void) 850265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt{ 866461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt return xt_register_match(&owner_mt_reg); 870265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt} 880265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 890265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardtstatic void __exit owner_mt_exit(void) 900265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt{ 916461caed83412ae3e9a16785ffa64396fb66c6a6Jan Engelhardt xt_unregister_match(&owner_mt_reg); 920265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt} 930265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardt 940265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardtmodule_init(owner_mt_init); 950265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan Engelhardtmodule_exit(owner_mt_exit); 966461caed83412ae3e9a16785ffa64396fb66c6a6Jan EngelhardtMODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>"); 972ae15b64e6a1608c840c60df38e8e5eef7b2b8c3Jan EngelhardtMODULE_DESCRIPTION("Xtables: socket owner matching"); 980265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan EngelhardtMODULE_LICENSE("GPL"); 990265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan EngelhardtMODULE_ALIAS("ipt_owner"); 1000265ab44bacc1a1e0e3f5873d8ca2d5a29e33db2Jan EngelhardtMODULE_ALIAS("ip6t_owner"); 101