|
|
@ -0,0 +1,320 @@ |
|
|
|
--- a/kernel/pf_ring.c
|
|
|
|
+++ b/kernel/pf_ring.c
|
|
|
|
@@ -6806,11 +6806,21 @@ int sk_detach_filter(struct sock *sk)
|
|
|
|
#endif |
|
|
|
|
|
|
|
/* ************************************* */ |
|
|
|
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0))
|
|
|
|
+#define copy_from_sockptr copy_from_user
|
|
|
|
+#define copy_to_sockptr copy_to_user
|
|
|
|
+#else
|
|
|
|
+#define copy_to_sockptr(dst,src,size) copy_to_sockptr_offset(dst, 0, src, size)
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
/* Code taken/inspired from core/sock.c */ |
|
|
|
static int ring_setsockopt(struct socket *sock, |
|
|
|
int level, int optname, |
|
|
|
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0))
|
|
|
|
char __user * optval, |
|
|
|
+#else
|
|
|
|
+ sockptr_t optval,
|
|
|
|
+#endif
|
|
|
|
unsigned |
|
|
|
int optlen) |
|
|
|
{ |
|
|
|
@@ -6842,7 +6852,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
|
|
|
|
ret = -EFAULT; |
|
|
|
|
|
|
|
- if(copy_from_user(&fprog, optval, sizeof(fprog)))
|
|
|
|
+ if(copy_from_sockptr(&fprog, optval, sizeof(fprog)))
|
|
|
|
break; |
|
|
|
|
|
|
|
if(fprog.len <= 1) { /* empty filter */ |
|
|
|
@@ -6888,7 +6898,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(cluster)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&cluster, optval, sizeof(cluster)))
|
|
|
|
+ if(copy_from_sockptr(&cluster, optval, sizeof(cluster)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
write_lock_bh(&pfr->ring_rules_lock); |
|
|
|
@@ -6911,7 +6921,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(channel_id_mask)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&channel_id_mask, optval, sizeof(channel_id_mask)))
|
|
|
|
+ if(copy_from_sockptr(&channel_id_mask, optval, sizeof(channel_id_mask)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
num_channels = 0; |
|
|
|
@@ -6967,7 +6977,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen > sizeof(name) /* Names should not be too long */ ) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&name, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&name, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
if(pfr->appl_name != NULL) |
|
|
|
@@ -6985,7 +6995,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(direction)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&direction, optval, sizeof(direction)))
|
|
|
|
+ if(copy_from_sockptr(&direction, optval, sizeof(direction)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
pfr->direction = direction; |
|
|
|
@@ -6999,7 +7009,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(sockmode)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&sockmode, optval, sizeof(sockmode)))
|
|
|
|
+ if(copy_from_sockptr(&sockmode, optval, sizeof(sockmode)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
pfr->mode = sockmode; |
|
|
|
@@ -7013,7 +7023,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(rule_inactivity)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&rule_inactivity, optval, sizeof(rule_inactivity)))
|
|
|
|
+ if(copy_from_sockptr(&rule_inactivity, optval, sizeof(rule_inactivity)))
|
|
|
|
return(-EFAULT); |
|
|
|
else { |
|
|
|
write_lock_bh(&pfr->ring_rules_lock); |
|
|
|
@@ -7027,7 +7037,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(rule_inactivity)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&rule_inactivity, optval, sizeof(rule_inactivity)))
|
|
|
|
+ if(copy_from_sockptr(&rule_inactivity, optval, sizeof(rule_inactivity)))
|
|
|
|
return(-EFAULT); |
|
|
|
else { |
|
|
|
write_lock_bh(&pfr->ring_rules_lock); |
|
|
|
@@ -7043,7 +7053,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
else { |
|
|
|
u_int8_t new_policy; |
|
|
|
|
|
|
|
- if(copy_from_user(&new_policy, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&new_policy, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
write_lock_bh(&pfr->ring_rules_lock); |
|
|
|
@@ -7075,7 +7085,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(rule == NULL) |
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
- if(copy_from_user(&rule->rule, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&rule->rule, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
INIT_LIST_HEAD(&rule->list); |
|
|
|
@@ -7099,7 +7109,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(rule == NULL) |
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
- if(copy_from_user(&rule->rule, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&rule->rule, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
write_lock_bh(&pfr->ring_rules_lock); |
|
|
|
@@ -7123,7 +7133,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
/* This is a list rule */ |
|
|
|
int rc; |
|
|
|
|
|
|
|
- if(copy_from_user(&rule_id, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&rule_id, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
write_lock_bh(&pfr->ring_rules_lock); |
|
|
|
@@ -7139,7 +7149,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
sw_filtering_hash_bucket rule; |
|
|
|
int rc; |
|
|
|
|
|
|
|
- if(copy_from_user(&rule.rule, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&rule.rule, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
write_lock_bh(&pfr->ring_rules_lock); |
|
|
|
@@ -7156,7 +7166,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(pfr->sample_rate)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&pfr->sample_rate, optval, sizeof(pfr->sample_rate)))
|
|
|
|
+ if(copy_from_sockptr(&pfr->sample_rate, optval, sizeof(pfr->sample_rate)))
|
|
|
|
return(-EFAULT); |
|
|
|
break; |
|
|
|
|
|
|
|
@@ -7164,7 +7174,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(pfr->filtering_sample_rate)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&pfr->filtering_sample_rate, optval, sizeof(pfr->filtering_sample_rate)))
|
|
|
|
+ if(copy_from_sockptr(&pfr->filtering_sample_rate, optval, sizeof(pfr->filtering_sample_rate)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
pfr->filtering_sampling_size = pfr->filtering_sample_rate; |
|
|
|
@@ -7231,7 +7241,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
else |
|
|
|
threshold = min_num_slots; |
|
|
|
|
|
|
|
- if(copy_from_user(&pfr->poll_num_pkts_watermark, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&pfr->poll_num_pkts_watermark, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
if(pfr->poll_num_pkts_watermark > threshold) |
|
|
|
@@ -7248,7 +7258,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(u_int16_t)) |
|
|
|
return(-EINVAL); |
|
|
|
else { |
|
|
|
- if(copy_from_user(&pfr->poll_watermark_timeout, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&pfr->poll_watermark_timeout, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
debug_printk(2, "--> SO_SET_POLL_WATERMARK_TIMEOUT=%u\n", pfr->poll_watermark_timeout); |
|
|
|
} |
|
|
|
@@ -7258,7 +7268,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(u_int32_t)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&pfr->bucket_len, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&pfr->bucket_len, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
debug_printk(2, "--> SO_RING_BUCKET_LEN=%d\n", pfr->bucket_len); |
|
|
|
@@ -7268,7 +7278,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(zc_dev_mapping)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&mapping, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&mapping, optval, optlen))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
debug_printk(2, "SO_SELECT_ZC_DEVICE %s\n", mapping.device_name); |
|
|
|
@@ -7278,7 +7288,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
else |
|
|
|
ret = pfring_release_zc_dev(pfr); |
|
|
|
|
|
|
|
- if(copy_to_user(optval, &mapping, optlen)) /* returning device_model*/
|
|
|
|
+ if(copy_to_sockptr(optval, &mapping, optlen)) /* returning device_model*/
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
break; |
|
|
|
@@ -7291,7 +7301,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(ring_id)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&ring_id, optval, sizeof(ring_id)))
|
|
|
|
+ if(copy_from_sockptr(&ring_id, optval, sizeof(ring_id)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
write_lock_bh(&pfr->ring_rules_lock); |
|
|
|
@@ -7303,7 +7313,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(hw_filtering_rule)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&hw_rule, optval, sizeof(hw_rule)))
|
|
|
|
+ if(copy_from_sockptr(&hw_rule, optval, sizeof(hw_rule)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
/* Check if a rule with the same id exists */ |
|
|
|
@@ -7343,7 +7353,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(u_int16_t)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&rule_id, optval, sizeof(u_int16_t)))
|
|
|
|
+ if(copy_from_sockptr(&rule_id, optval, sizeof(u_int16_t)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
/* Check if the rule we want to remove exists */ |
|
|
|
@@ -7381,7 +7391,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(elem)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&elem, optval, sizeof(elem)))
|
|
|
|
+ if(copy_from_sockptr(&elem, optval, sizeof(elem)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
if((pfr->v_filtering_dev = add_virtual_filtering_device(pfr, &elem)) == NULL) |
|
|
|
@@ -7402,14 +7412,14 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen < sizeof(ccri)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&ccri, optval, sizeof(ccri)))
|
|
|
|
+ if(copy_from_sockptr(&ccri, optval, sizeof(ccri)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
if(create_cluster_referee(pfr, ccri.cluster_id, &ccri.recovered) < 0) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
/* copying back the structure (actually we need ccri.recovered only) */ |
|
|
|
- if(copy_to_user(optval, &ccri, sizeof(ccri))) {
|
|
|
|
+ if(copy_to_sockptr(optval, &ccri, sizeof(ccri))) {
|
|
|
|
remove_cluster_referee(pfr); |
|
|
|
return(-EFAULT); |
|
|
|
} |
|
|
|
@@ -7422,7 +7432,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
{ |
|
|
|
struct public_cluster_object_info pcoi; |
|
|
|
|
|
|
|
- if(copy_from_user(&pcoi, optval, sizeof(pcoi)))
|
|
|
|
+ if(copy_from_sockptr(&pcoi, optval, sizeof(pcoi)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
if(publish_cluster_object(pfr, pcoi.cluster_id, pcoi.object_type, pcoi.object_id) < 0) |
|
|
|
@@ -7436,7 +7446,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
{ |
|
|
|
struct lock_cluster_object_info lcoi; |
|
|
|
|
|
|
|
- if(copy_from_user(&lcoi, optval, sizeof(lcoi)))
|
|
|
|
+ if(copy_from_sockptr(&lcoi, optval, sizeof(lcoi)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
if(lock_cluster_object(pfr, lcoi.cluster_id, lcoi.object_type, lcoi.object_id, lcoi.lock_mask) < 0) |
|
|
|
@@ -7450,7 +7460,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
{ |
|
|
|
struct lock_cluster_object_info lcoi; |
|
|
|
|
|
|
|
- if(copy_from_user(&lcoi, optval, sizeof(lcoi)))
|
|
|
|
+ if(copy_from_sockptr(&lcoi, optval, sizeof(lcoi)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
if(unlock_cluster_object(pfr, lcoi.cluster_id, lcoi.object_type, lcoi.object_id, lcoi.lock_mask) < 0) |
|
|
|
@@ -7465,7 +7475,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen > (sizeof(pfr->custom_bound_device_name)-1)) |
|
|
|
optlen = sizeof(pfr->custom_bound_device_name)-1; |
|
|
|
|
|
|
|
- if(copy_from_user(&pfr->custom_bound_device_name, optval, optlen)) {
|
|
|
|
+ if(copy_from_sockptr(&pfr->custom_bound_device_name, optval, optlen)) {
|
|
|
|
pfr->custom_bound_device_name[0] = '\0'; |
|
|
|
return(-EFAULT); |
|
|
|
} else |
|
|
|
@@ -7490,7 +7500,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen > (sizeof(pfr->statsString)-1)) |
|
|
|
optlen = sizeof(pfr->statsString)-1; |
|
|
|
|
|
|
|
- if(copy_from_user(&pfr->statsString, optval, optlen)) {
|
|
|
|
+ if(copy_from_sockptr(&pfr->statsString, optval, optlen)) {
|
|
|
|
pfr->statsString[0] = '\0'; |
|
|
|
return(-EFAULT); |
|
|
|
} |
|
|
|
@@ -7511,7 +7521,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(u_int32_t)) |
|
|
|
return (-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&enable_promisc, optval, optlen))
|
|
|
|
+ if(copy_from_sockptr(&enable_promisc, optval, optlen))
|
|
|
|
return (-EFAULT); |
|
|
|
|
|
|
|
if(!pfr->ring_dev || pfr->ring_dev == &none_device_element || pfr->ring_dev == &any_device_element) { |
|
|
|
@@ -7537,7 +7547,7 @@ static int ring_setsockopt(struct socket *sock,
|
|
|
|
if(optlen != sizeof(vlan_id)) |
|
|
|
return(-EINVAL); |
|
|
|
|
|
|
|
- if(copy_from_user(&vlan_id, optval, sizeof(vlan_id)))
|
|
|
|
+ if(copy_from_sockptr(&vlan_id, optval, sizeof(vlan_id)))
|
|
|
|
return(-EFAULT); |
|
|
|
|
|
|
|
pfr->vlan_id = vlan_id; |