@@ -3049,27 +3049,29 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
30493049 if (!skb )
30503050 return - ENOBUFS ;
30513051
3052+ rcu_read_lock ();
3053+
30523054 tbl = neigh_find_table (ndm -> ndm_family );
30533055 if (!tbl ) {
30543056 NL_SET_ERR_MSG (extack , "Unsupported family in header for neighbor get request" );
30553057 err = - EAFNOSUPPORT ;
3056- goto err_free_skb ;
3058+ goto err_unlock ;
30573059 }
30583060
30593061 if (nla_len (tb [NDA_DST ]) != (int )tbl -> key_len ) {
30603062 NL_SET_ERR_MSG (extack , "Invalid network address in neighbor get request" );
30613063 err = - EINVAL ;
3062- goto err_free_skb ;
3064+ goto err_unlock ;
30633065 }
30643066
30653067 dst = nla_data (tb [NDA_DST ]);
30663068
30673069 if (ndm -> ndm_ifindex ) {
3068- dev = __dev_get_by_index (net , ndm -> ndm_ifindex );
3070+ dev = dev_get_by_index_rcu (net , ndm -> ndm_ifindex );
30693071 if (!dev ) {
30703072 NL_SET_ERR_MSG (extack , "Unknown device ifindex" );
30713073 err = - ENODEV ;
3072- goto err_free_skb ;
3074+ goto err_unlock ;
30733075 }
30743076 }
30753077
@@ -3080,28 +3082,31 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
30803082 if (!pn ) {
30813083 NL_SET_ERR_MSG (extack , "Proxy neighbour entry not found" );
30823084 err = - ENOENT ;
3083- goto err_free_skb ;
3085+ goto err_unlock ;
30843086 }
30853087
30863088 err = pneigh_fill_info (skb , pn , pid , seq , RTM_NEWNEIGH , 0 , tbl );
30873089 if (err )
3088- goto err_free_skb ;
3090+ goto err_unlock ;
30893091 } else {
30903092 neigh = neigh_lookup (tbl , dst , dev );
30913093 if (!neigh ) {
30923094 NL_SET_ERR_MSG (extack , "Neighbour entry not found" );
30933095 err = - ENOENT ;
3094- goto err_free_skb ;
3096+ goto err_unlock ;
30953097 }
30963098
30973099 err = neigh_fill_info (skb , neigh , pid , seq , RTM_NEWNEIGH , 0 );
30983100 neigh_release (neigh );
30993101 if (err )
3100- goto err_free_skb ;
3102+ goto err_unlock ;
31013103 }
31023104
3105+ rcu_read_unlock ();
3106+
31033107 return rtnl_unicast (skb , net , pid );
3104- err_free_skb :
3108+ err_unlock :
3109+ rcu_read_unlock ();
31053110 kfree_skb (skb );
31063111 return err ;
31073112}
@@ -3904,7 +3909,7 @@ static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
39043909 {.msgtype = RTM_NEWNEIGH , .doit = neigh_add },
39053910 {.msgtype = RTM_DELNEIGH , .doit = neigh_delete },
39063911 {.msgtype = RTM_GETNEIGH , .doit = neigh_get , .dumpit = neigh_dump_info ,
3907- .flags = RTNL_FLAG_DUMP_UNLOCKED },
3912+ .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED },
39083913 {.msgtype = RTM_GETNEIGHTBL , .dumpit = neightbl_dump_info },
39093914 {.msgtype = RTM_SETNEIGHTBL , .doit = neightbl_set },
39103915};
0 commit comments