Commit 817e9f2c authored by WANG Cong's avatar WANG Cong Committed by David S. Miller

act_ife: acquire ife_mod_lock before reading ifeoplist

Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
Acked-by: default avatarJamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 067a7cd0
...@@ -277,7 +277,7 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid, ...@@ -277,7 +277,7 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid,
* under ife->tcf_lock for existing action * under ife->tcf_lock for existing action
*/ */
static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
int len, bool exists) int len, bool atomic)
{ {
struct tcf_meta_info *mi = NULL; struct tcf_meta_info *mi = NULL;
struct tcf_meta_ops *ops = find_ife_oplist(metaid); struct tcf_meta_ops *ops = find_ife_oplist(metaid);
...@@ -286,7 +286,7 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, ...@@ -286,7 +286,7 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
if (!ops) if (!ops)
return -ENOENT; return -ENOENT;
mi = kzalloc(sizeof(*mi), exists ? GFP_ATOMIC : GFP_KERNEL); mi = kzalloc(sizeof(*mi), atomic ? GFP_ATOMIC : GFP_KERNEL);
if (!mi) { if (!mi) {
/*put back what find_ife_oplist took */ /*put back what find_ife_oplist took */
module_put(ops->owner); module_put(ops->owner);
...@@ -296,7 +296,7 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, ...@@ -296,7 +296,7 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
mi->metaid = metaid; mi->metaid = metaid;
mi->ops = ops; mi->ops = ops;
if (len > 0) { if (len > 0) {
ret = ops->alloc(mi, metaval, exists ? GFP_ATOMIC : GFP_KERNEL); ret = ops->alloc(mi, metaval, atomic ? GFP_ATOMIC : GFP_KERNEL);
if (ret != 0) { if (ret != 0) {
kfree(mi); kfree(mi);
module_put(ops->owner); module_put(ops->owner);
...@@ -309,17 +309,19 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, ...@@ -309,17 +309,19 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
return ret; return ret;
} }
static int use_all_metadata(struct tcf_ife_info *ife, bool exists) static int use_all_metadata(struct tcf_ife_info *ife)
{ {
struct tcf_meta_ops *o; struct tcf_meta_ops *o;
int rc = 0; int rc = 0;
int installed = 0; int installed = 0;
read_lock(&ife_mod_lock);
list_for_each_entry(o, &ifeoplist, list) { list_for_each_entry(o, &ifeoplist, list) {
rc = add_metainfo(ife, o->metaid, NULL, 0, exists); rc = add_metainfo(ife, o->metaid, NULL, 0, true);
if (rc == 0) if (rc == 0)
installed += 1; installed += 1;
} }
read_unlock(&ife_mod_lock);
if (installed) if (installed)
return 0; return 0;
...@@ -523,7 +525,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, ...@@ -523,7 +525,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
* as we can. You better have at least one else we are * as we can. You better have at least one else we are
* going to bail out * going to bail out
*/ */
err = use_all_metadata(ife, exists); err = use_all_metadata(ife);
if (err) { if (err) {
if (ret == ACT_P_CREATED) if (ret == ACT_P_CREATED)
_tcf_ife_cleanup(a, bind); _tcf_ife_cleanup(a, bind);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment