cregit-Linux how code gets into the kernel

Release 4.11 net/netfilter/nf_sockopt.c

Directory: net/netfilter
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <linux/mutex.h>
#include <net/sock.h>

#include "nf_internals.h"

/* Sockopts only registered and called from user context, so
   net locking would be overkill.  Also, [gs]etsockopt calls may
   sleep. */
static DEFINE_MUTEX(nf_sockopt_mutex);
static LIST_HEAD(nf_sockopts);

/* Do exclusive ranges overlap? */

static inline int overlap(int min1, int max1, int min2, int max2) { return max1 > min2 && min1 < max2; }

Contributors

PersonTokensPropCommitsCommitProp
Harald Welte28100.00%1100.00%
Total28100.00%1100.00%

/* Functions to register sockopt ranges (exclusive). */
int nf_register_sockopt(struct nf_sockopt_ops *reg) { struct nf_sockopt_ops *ops; int ret = 0; mutex_lock(&nf_sockopt_mutex); list_for_each_entry(ops, &nf_sockopts, list) { if (ops->pf == reg->pf && (overlap(ops->set_optmin, ops->set_optmax, reg->set_optmin, reg->set_optmax) || overlap(ops->get_optmin, ops->get_optmax, reg->get_optmin, reg->get_optmax))) { NFDEBUG("nf_sock overlap: %u-%u/%u-%u v %u-%u/%u-%u\n", ops->set_optmin, ops->set_optmax, ops->get_optmin, ops->get_optmax, reg->set_optmin, reg->set_optmax, reg->get_optmin, reg->get_optmax); ret = -EBUSY; goto out; } } list_add(&reg->list, &nf_sockopts); out: mutex_unlock(&nf_sockopt_mutex); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Harald Welte14694.19%125.00%
Alexey Dobriyan63.87%125.00%
Pablo Neira Ayuso21.29%125.00%
Arjan van de Ven10.65%125.00%
Total155100.00%4100.00%

EXPORT_SYMBOL(nf_register_sockopt);
void nf_unregister_sockopt(struct nf_sockopt_ops *reg) { mutex_lock(&nf_sockopt_mutex); list_del(&reg->list); mutex_unlock(&nf_sockopt_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Harald Welte2893.33%150.00%
Arjan van de Ven26.67%150.00%
Total30100.00%2100.00%

EXPORT_SYMBOL(nf_unregister_sockopt);
static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, u_int8_t pf, int val, int get) { struct nf_sockopt_ops *ops; mutex_lock(&nf_sockopt_mutex); list_for_each_entry(ops, &nf_sockopts, list) { if (ops->pf == pf) { if (!try_module_get(ops->owner)) goto out_nosup; if (get) { if (val >= ops->get_optmin && val < ops->get_optmax) goto out; } else { if (val >= ops->set_optmin && val < ops->set_optmax) goto out; } module_put(ops->owner); } } out_nosup: ops = ERR_PTR(-ENOPROTOOPT); out: mutex_unlock(&nf_sockopt_mutex); return ops; }

Contributors

PersonTokensPropCommitsCommitProp
Harald Welte8360.58%114.29%
Pavel Emelyanov3324.09%114.29%
Neil Horman139.49%114.29%
Alexey Dobriyan42.92%114.29%
Pablo Neira Ayuso21.46%114.29%
Arjan van de Ven10.73%114.29%
Jan Engelhardt10.73%114.29%
Total137100.00%7100.00%

/* Call get/setsockopt() */
static int nf_sockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, int *len, int get) { struct nf_sockopt_ops *ops; int ret; ops = nf_sockopt_find(sk, pf, val, get); if (IS_ERR(ops)) return PTR_ERR(ops); if (get) ret = ops->get(sk, val, opt, len); else ret = ops->set(sk, val, opt, *len); module_put(ops->owner); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Pavel Emelyanov7871.56%125.00%
Harald Welte2623.85%125.00%
Neil Horman43.67%125.00%
Jan Engelhardt10.92%125.00%
Total109100.00%4100.00%


int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, unsigned int len) { return nf_sockopt(sk, pf, val, opt, &len, 0); }

Contributors

PersonTokensPropCommitsCommitProp
Harald Welte4095.24%133.33%
Jan Engelhardt12.38%133.33%
David S. Miller12.38%133.33%
Total42100.00%3100.00%

EXPORT_SYMBOL(nf_setsockopt);
int nf_getsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, int *len) { return nf_sockopt(sk, pf, val, opt, len, 1); }

Contributors

PersonTokensPropCommitsCommitProp
Harald Welte4097.56%150.00%
Jan Engelhardt12.44%150.00%
Total41100.00%2100.00%

EXPORT_SYMBOL(nf_getsockopt); #ifdef CONFIG_COMPAT
static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, int *len, int get) { struct nf_sockopt_ops *ops; int ret; ops = nf_sockopt_find(sk, pf, val, get); if (IS_ERR(ops)) return PTR_ERR(ops); if (get) { if (ops->compat_get) ret = ops->compat_get(sk, val, opt, len); else ret = ops->get(sk, val, opt, len); } else { if (ops->compat_set) ret = ops->compat_set(sk, val, opt, *len); else ret = ops->set(sk, val, opt, *len); } module_put(ops->owner); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Dmitry Mishin13182.91%116.67%
Pavel Emelyanov159.49%116.67%
Neil Horman74.43%116.67%
Patrick McHardy31.90%116.67%
Jan Engelhardt10.63%116.67%
Alexey Dobriyan10.63%116.67%
Total158100.00%6100.00%


int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, unsigned int len) { return compat_nf_sockopt(sk, pf, val, opt, &len, 0); }

Contributors

PersonTokensPropCommitsCommitProp
Dmitry Mishin4095.24%133.33%
David S. Miller12.38%133.33%
Jan Engelhardt12.38%133.33%
Total42100.00%3100.00%

EXPORT_SYMBOL(compat_nf_setsockopt);
int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, int *len) { return compat_nf_sockopt(sk, pf, val, opt, len, 1); }

Contributors

PersonTokensPropCommitsCommitProp
Dmitry Mishin4097.56%150.00%
Jan Engelhardt12.44%150.00%
Total41100.00%2100.00%

EXPORT_SYMBOL(compat_nf_getsockopt); #endif

Overall Contributors

PersonTokensPropCommitsCommitProp
Harald Welte44651.98%110.00%
Dmitry Mishin22626.34%110.00%
Pavel Emelyanov12714.80%110.00%
Neil Horman242.80%110.00%
Alexey Dobriyan111.28%110.00%
Arjan van de Ven80.93%110.00%
Jan Engelhardt70.82%110.00%
Pablo Neira Ayuso40.47%110.00%
Patrick McHardy30.35%110.00%
David S. Miller20.23%110.00%
Total858100.00%10100.00%
Directory: net/netfilter
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.