aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/genetlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink/genetlink.c')
-rw-r--r--net/netlink/genetlink.c66
1 files changed, 19 insertions, 47 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index c2996794eb25..6e31234a4196 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -295,66 +295,46 @@ int genl_unregister_family(struct genl_family *family)
295 return -ENOENT; 295 return -ENOENT;
296} 296}
297 297
298static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 298static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
299 int *errp)
300{ 299{
301 struct genl_ops *ops; 300 struct genl_ops *ops;
302 struct genl_family *family; 301 struct genl_family *family;
303 struct genl_info info; 302 struct genl_info info;
304 struct genlmsghdr *hdr = nlmsg_data(nlh); 303 struct genlmsghdr *hdr = nlmsg_data(nlh);
305 int hdrlen, err = -EINVAL; 304 int hdrlen, err;
306
307 if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
308 goto ignore;
309
310 if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
311 goto ignore;
312 305
313 family = genl_family_find_byid(nlh->nlmsg_type); 306 family = genl_family_find_byid(nlh->nlmsg_type);
314 if (family == NULL) { 307 if (family == NULL)
315 err = -ENOENT; 308 return -ENOENT;
316 goto errout;
317 }
318 309
319 hdrlen = GENL_HDRLEN + family->hdrsize; 310 hdrlen = GENL_HDRLEN + family->hdrsize;
320 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 311 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
321 goto errout; 312 return -EINVAL;
322 313
323 ops = genl_get_cmd(hdr->cmd, family); 314 ops = genl_get_cmd(hdr->cmd, family);
324 if (ops == NULL) { 315 if (ops == NULL)
325 err = -EOPNOTSUPP; 316 return -EOPNOTSUPP;
326 goto errout;
327 }
328 317
329 if ((ops->flags & GENL_ADMIN_PERM) && security_netlink_recv(skb, CAP_NET_ADMIN)) { 318 if ((ops->flags & GENL_ADMIN_PERM) &&
330 err = -EPERM; 319 security_netlink_recv(skb, CAP_NET_ADMIN))
331 goto errout; 320 return -EPERM;
332 }
333 321
334 if (nlh->nlmsg_flags & NLM_F_DUMP) { 322 if (nlh->nlmsg_flags & NLM_F_DUMP) {
335 if (ops->dumpit == NULL) { 323 if (ops->dumpit == NULL)
336 err = -EOPNOTSUPP; 324 return -EOPNOTSUPP;
337 goto errout;
338 }
339 325
340 *errp = err = netlink_dump_start(genl_sock, skb, nlh, 326 return netlink_dump_start(genl_sock, skb, nlh,
341 ops->dumpit, ops->done); 327 ops->dumpit, ops->done);
342 if (err == 0)
343 skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len),
344 skb->len));
345 return -1;
346 } 328 }
347 329
348 if (ops->doit == NULL) { 330 if (ops->doit == NULL)
349 err = -EOPNOTSUPP; 331 return -EOPNOTSUPP;
350 goto errout;
351 }
352 332
353 if (family->attrbuf) { 333 if (family->attrbuf) {
354 err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr, 334 err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr,
355 ops->policy); 335 ops->policy);
356 if (err < 0) 336 if (err < 0)
357 goto errout; 337 return err;
358 } 338 }
359 339
360 info.snd_seq = nlh->nlmsg_seq; 340 info.snd_seq = nlh->nlmsg_seq;
@@ -364,15 +344,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
364 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; 344 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
365 info.attrs = family->attrbuf; 345 info.attrs = family->attrbuf;
366 346
367 *errp = err = ops->doit(skb, &info); 347 return ops->doit(skb, &info);
368 return err;
369
370ignore:
371 return 0;
372
373errout:
374 *errp = err;
375 return -1;
376} 348}
377 349
378static void genl_rcv(struct sock *sk, int len) 350static void genl_rcv(struct sock *sk, int len)
@@ -586,7 +558,7 @@ static int __init genl_init(void)
586 558
587 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); 559 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
588 genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID, 560 genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID,
589 genl_rcv, THIS_MODULE); 561 genl_rcv, NULL, THIS_MODULE);
590 if (genl_sock == NULL) 562 if (genl_sock == NULL)
591 panic("GENL: Cannot initialize generic netlink\n"); 563 panic("GENL: Cannot initialize generic netlink\n");
592 564