func: static int compat_do_arpt_set_ctl(struct sock *sk, int cmd, void __user unsigned int len) int ret ; if ( ! ns_capable ( sock_net ( sk ) -> user_ns , CAP_NET_ADMIN ) )  switch ( cmd )  ret = compat_do_replace ( sock_net ( sk ) , user , len ); static int compat_do_replace(struct net *net, void __user unsigned int len) int ret ; struct compat_arpt_replace tmp ; struct xt_table_info * newinfo ; void * loc_cpu_entry ; if ( copy_from_user ( & tmp , user , sizeof ( tmp ) ) != 0 )  if ( tmp . size >= INT_MAX / num_possible_cpus ( ) )  if ( tmp . num_counters >= INT_MAX / sizeof ( struct xt_counters ) )  if ( tmp . num_counters == 0 )  tmp . name [ sizeof ( tmp . name ) - 1 ] = 0; newinfo = xt_alloc_table_info ( tmp . size ); if ( ! newinfo )  loc_cpu_entry = newinfo -> entries; if ( copy_from_user ( loc_cpu_entry , user + sizeof ( tmp ) , tmp . size ) != 0 )  ret = translate_compat_table ( tmp . name , tmp . valid_hooks , & newinfo , & loc_cpu_entry , tmp . size , tmp . num_entries , tmp . hook_entry , tmp . underflow ); static int translate_compat_table(const char unsigned int struct xt_table_info void unsigned int unsigned int unsigned int unsigned int *underflows) unsigned int i , j ; struct xt_table_info * newinfo , * info ; void * pos , * entry0 , * entry1 ; struct compat_arpt_entry * iter0 ; unsigned int size ; info = * pinfo; entry0 = * pentry0; size = total_size; info -> number = number; for (i = 0; i < NF_ARP_NUMHOOKS; i++) info -> hook_entry [ i ] = 0xFFFFFFFF; info -> underflow [ i ] = 0xFFFFFFFF; j = 0; ret = check_compat_entry_size_and_hooks ( iter0 , info , & size , entry0 , entry0 + total_size , hook_entries , underflows , name ); static inline check_compat_entry_size_and_hooks(struct compat_arpt_entry struct xt_table_info unsigned int const unsigned char const unsigned char const unsigned int const unsigned int const char *name) struct xt_entry_target * t ; struct xt_target * target ; unsigned int entry_offset ; int ret , off , h ; return - EINVAL ; if ( e -> next_offset < sizeof ( struct compat_arpt_entry ) + sizeof ( struct compat_xt_entry_target ) )  return - EINVAL ; ret = check_entry ( ( struct arpt_entry * ) e , name ); static inline int check_entry(const struct arpt_entry *e, const char *name) const struct xt_entry_target * t ; if ( ! arp_checkentry ( & e -> arp ) )  static inline int arp_checkentry(const struct arpt_arp *arp) if ( arp -> flags & ~ARPT_F_MASK )  return 0 ; if ( arp -> invflags & ~ARPT_INV_MASK )  return 0 ; return 1 ; return - EINVAL ; if ( e -> target_offset + sizeof ( struct xt_entry_target ) > e -> next_offset )  return - EINVAL ; t = arpt_get_target_c ( e ); static inline const struct xt_entry_target arpt_get_target_c(const struct arpt_entry *e) return arpt_get_target ( ( struct arpt_entry * ) e ) ; if ( e -> target_offset + t -> u . target_size > e -> next_offset )  return - EINVAL ; return 0 ; if ( ret )  return ret ; off = sizeof ( struct arpt_entry ) - sizeof ( struct compat_arpt_entry ); entry_offset = ( void * ) e - ( void * ) base; t = compat_arpt_get_target ( e ); target = xt_request_find_target ( NFPROTO_ARP , t -> u . user . name , t -> u . user . revision ); if ( IS_ERR ( target ) )  ret = PTR_ERR ( target ); off += xt_compat_target_offset ( target ); ret = xt_compat_add_offset ( NFPROTO_ARP , entry_offset , off ); if ( ret )  return 0 ; return ret ; if ( ret != 0 )  if ( j != number )  for (i = 0; i < NF_ARP_NUMHOOKS; i++) if ( ! ( valid_hooks & ( 1 << i ) ) )  if ( info -> hook_entry [ i ] == 0xFFFFFFFF )  if ( info -> underflow [ i ] == 0xFFFFFFFF )  newinfo = xt_alloc_table_info ( size ); if ( ! newinfo )  newinfo -> number = number; for (i = 0; i < NF_ARP_NUMHOOKS; i++) newinfo -> hook_entry [ i ] = info -> hook_entry [ i ]; newinfo -> underflow [ i ] = info -> underflow [ i ]; entry1 = newinfo -> entries; pos = entry1; size = total_size; ret = compat_copy_entry_from_user ( iter0 , & pos , & size , name , newinfo , entry1 ); static compat_copy_entry_from_user(struct compat_arpt_entry *e, void unsigned int *size, const char struct xt_table_info *newinfo, unsigned char *base) struct arpt_entry * de ; de = ( struct arpt_entry * ) * dstptr; memcpy ( de , e , sizeof ( struct arpt_entry ) ); memcpy ( & de -> counters , & e -> counters , sizeof ( e -> counters ) ); de -> target_offset = e -> target_offset - ( origsize - * size ); de -> next_offset = e -> next_offset - ( origsize - * size ); if ( ( unsigned char * ) de - base < newinfo -> hook_entry [ h ] )  if ( ( unsigned char * ) de - base < newinfo -> underflow [ h ] )  