Skip to content

Commit daaa8be

Browse files
kaberdavem330
authored andcommitted
[NETFILTER]: nf_queue: clean up error paths
Move duplicated error handling to end of function and add a helper function to release the device and module references from the queue entry. Signed-off-by: Patrick McHardy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4b3d15e commit daaa8be

File tree

1 file changed

+40
-53
lines changed

1 file changed

+40
-53
lines changed

net/netfilter/nf_queue.c

Lines changed: 40 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,27 @@ void nf_unregister_queue_handlers(const struct nf_queue_handler *qh)
8080
}
8181
EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
8282

83+
static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
84+
{
85+
/* Release those devices we held, or Alexey will kill me. */
86+
if (entry->indev)
87+
dev_put(entry->indev);
88+
if (entry->outdev)
89+
dev_put(entry->outdev);
90+
#ifdef CONFIG_BRIDGE_NETFILTER
91+
if (entry->skb->nf_bridge) {
92+
struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
93+
94+
if (nf_bridge->physindev)
95+
dev_put(nf_bridge->physindev);
96+
if (nf_bridge->physoutdev)
97+
dev_put(nf_bridge->physoutdev);
98+
}
99+
#endif
100+
/* Drop reference to owner of hook which queued us. */
101+
module_put(entry->elem->owner);
102+
}
103+
83104
/*
84105
* Any packet that leaves via this function must come back
85106
* through nf_reinject().
@@ -93,10 +114,10 @@ static int __nf_queue(struct sk_buff *skb,
93114
unsigned int queuenum)
94115
{
95116
int status;
96-
struct nf_queue_entry *entry;
117+
struct nf_queue_entry *entry = NULL;
97118
#ifdef CONFIG_BRIDGE_NETFILTER
98-
struct net_device *physindev = NULL;
99-
struct net_device *physoutdev = NULL;
119+
struct net_device *physindev;
120+
struct net_device *physoutdev;
100121
#endif
101122
struct nf_afinfo *afinfo;
102123
const struct nf_queue_handler *qh;
@@ -105,28 +126,16 @@ static int __nf_queue(struct sk_buff *skb,
105126
rcu_read_lock();
106127

107128
qh = rcu_dereference(queue_handler[pf]);
108-
if (!qh) {
109-
rcu_read_unlock();
110-
kfree_skb(skb);
111-
return 1;
112-
}
129+
if (!qh)
130+
goto err_unlock;
113131

114132
afinfo = nf_get_afinfo(pf);
115-
if (!afinfo) {
116-
rcu_read_unlock();
117-
kfree_skb(skb);
118-
return 1;
119-
}
133+
if (!afinfo)
134+
goto err_unlock;
120135

121136
entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC);
122-
if (!entry) {
123-
if (net_ratelimit())
124-
printk(KERN_ERR "OOM queueing packet %p\n",
125-
skb);
126-
rcu_read_unlock();
127-
kfree_skb(skb);
128-
return 1;
129-
}
137+
if (!entry)
138+
goto err_unlock;
130139

131140
*entry = (struct nf_queue_entry) {
132141
.skb = skb,
@@ -166,25 +175,18 @@ static int __nf_queue(struct sk_buff *skb,
166175
rcu_read_unlock();
167176

168177
if (status < 0) {
169-
/* James M doesn't say fuck enough. */
170-
if (indev)
171-
dev_put(indev);
172-
if (outdev)
173-
dev_put(outdev);
174-
#ifdef CONFIG_BRIDGE_NETFILTER
175-
if (physindev)
176-
dev_put(physindev);
177-
if (physoutdev)
178-
dev_put(physoutdev);
179-
#endif
180-
module_put(entry->elem->owner);
181-
kfree(entry);
182-
kfree_skb(skb);
183-
184-
return 1;
178+
nf_queue_entry_release_refs(entry);
179+
goto err;
185180
}
186181

187182
return 1;
183+
184+
err_unlock:
185+
rcu_read_unlock();
186+
err:
187+
kfree_skb(skb);
188+
kfree(entry);
189+
return 1;
188190
}
189191

190192
int nf_queue(struct sk_buff *skb,
@@ -235,22 +237,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
235237

236238
rcu_read_lock();
237239

238-
/* Release those devices we held, or Alexey will kill me. */
239-
if (entry->indev)
240-
dev_put(entry->indev);
241-
if (entry->outdev)
242-
dev_put(entry->outdev);
243-
#ifdef CONFIG_BRIDGE_NETFILTER
244-
if (skb->nf_bridge) {
245-
if (skb->nf_bridge->physindev)
246-
dev_put(skb->nf_bridge->physindev);
247-
if (skb->nf_bridge->physoutdev)
248-
dev_put(skb->nf_bridge->physoutdev);
249-
}
250-
#endif
251-
252-
/* Drop reference to owner of hook which queued us. */
253-
module_put(entry->elem->owner);
240+
nf_queue_entry_release_refs(entry);
254241

255242
/* Continue traversal iff userspace said ok... */
256243
if (verdict == NF_REPEAT) {

0 commit comments

Comments
 (0)