netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jan Kara <jack@suse.cz>
To: Johannes Berg <johannes@sipsolutions.net>
Cc: netdev@vger.kernel.org, Johannes Berg <johannes.berg@intel.com>,
	Jan Kara <jack@suse.cz>
Subject: Re: [RFC 3/8] quota/genetlink: use proper genetlink multicast APIs
Date: Mon, 18 Nov 2013 13:34:03 +0100	[thread overview]
Message-ID: <20131118123403.GC3921@quack.suse.cz> (raw)
In-Reply-To: <1384621429-24543-4-git-send-email-johannes@sipsolutions.net>

On Sat 16-11-13 18:03:44, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> The quota code is abusing the genetlink API and is using
> its family ID as the multicast group ID, which is invalid
> and may belong to somebody else (and likely will.)
> 
> Make the quota code use the correct API, but since this
> is already used as-is by userspace, reserve a family ID
> for this code and also reserve that group ID to not break
> userspace assumptions.
  Ah, sorry for messing that up. When I was writing this, libnl didn't have
support for multicast groups and so I didn't figure out from its documentation
there are any multicast groups at all... I'd also mention that
documentation of generic netlink at
http://www.linuxfoundation.org/collaborate/workgroups/networking/generic_netlink_howto
(pointed to from Documenation/networking/generic_netlink.txt) doesn't
mention anything about multicast groups either. So chances for messing
things up are pretty high...

Anyway, I'll fix quota_nld (userspace daemon consuming quota netlink
messages) to use multicast groups properly with a fallback to previous
behavior in case that fails (to keep compatibility with older kernels) and
since I don't believe anyone else is using this interface (and even
quota_nld isn't widely used), I think we can remove this hack from generic
netlink layer in a couple of years (hurray to a paragraph long sentence
;).

Thanks for fixing this and you can add:
Acked-by: Jan Kara <jack@suse.cz>

								Honza
> 
> Cc: Jan Kara <jack@suse.cz>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
>  fs/quota/netlink.c             | 17 +++++++++++++++--
>  include/uapi/linux/genetlink.h |  1 +
>  net/netlink/genetlink.c        | 10 ++++++++--
>  3 files changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
> index 16e8abb..b261ce4 100644
> --- a/fs/quota/netlink.c
> +++ b/fs/quota/netlink.c
> @@ -11,13 +11,23 @@
>  
>  /* Netlink family structure for quota */
>  static struct genl_family quota_genl_family = {
> -	.id = GENL_ID_GENERATE,
> +	/*
> +	 * Needed due to multicast group ID abuse - old code assumed
> +	 * the family ID was also a valid multicast group ID (which
> +	 * isn't true) and userspace might thus rely on it. Assign a
> +	 * static ID for this group to make dealing with that easier.
> +	 */
> +	.id = GENL_ID_VFS_DQUOT,
>  	.hdrsize = 0,
>  	.name = "VFS_DQUOT",
>  	.version = 1,
>  	.maxattr = QUOTA_NL_A_MAX,
>  };
>  
> +static struct genl_multicast_group quota_mcgrp = {
> +	.name = "VFS_DQUOT", /* not really used */
> +};
> +
>  /**
>   * quota_send_warning - Send warning to userspace about exceeded quota
>   * @type: The quota type: USRQQUOTA, GRPQUOTA,...
> @@ -78,7 +88,7 @@ void quota_send_warning(struct kqid qid, dev_t dev,
>  		goto attr_err_out;
>  	genlmsg_end(skb, msg_head);
>  
> -	genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
> +	genlmsg_multicast(skb, 0, quota_mcgrp.id, GFP_NOFS);
>  	return;
>  attr_err_out:
>  	printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
> @@ -92,6 +102,9 @@ static int __init quota_init(void)
>  	if (genl_register_family(&quota_genl_family) != 0)
>  		printk(KERN_ERR
>  		       "VFS: Failed to create quota netlink interface.\n");
> +	if (genl_register_mc_group(&quota_genl_family, &quota_mcgrp))
> +		printk(KERN_ERR
> +		       "VFS: Failed to register quota mcast group.\n");
>  	return 0;
>  };
>  
> diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h
> index c880a41..1af72d82 100644
> --- a/include/uapi/linux/genetlink.h
> +++ b/include/uapi/linux/genetlink.h
> @@ -27,6 +27,7 @@ struct genlmsghdr {
>   */
>  #define GENL_ID_GENERATE	0
>  #define GENL_ID_CTRL		NLMSG_MIN_TYPE
> +#define GENL_ID_VFS_DQUOT	(NLMSG_MIN_TYPE + 1)
>  
>  /**************************************************************************
>   * Controller
> diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
> index 8a2ed2c..d0757c6 100644
> --- a/net/netlink/genetlink.c
> +++ b/net/netlink/genetlink.c
> @@ -69,8 +69,11 @@ static struct list_head family_ht[GENL_FAM_TAB_SIZE];
>   * abuses the API and thinks it can statically use group 1.
>   * That group will typically conflict with other groups that
>   * any proper users use.
> + * Bit 17 is marked as already used since the VFS quota code
> + * also abused this API and relied on family == group ID, we
> + * cater to that by giving it a static family and group ID.
>   */
> -static unsigned long mc_group_start = 0x3;
> +static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_VFS_DQUOT);
>  static unsigned long *mc_groups = &mc_group_start;
>  static unsigned long mc_groups_longs = 1;
>  
> @@ -130,7 +133,8 @@ static u16 genl_generate_id(void)
>  	int i;
>  
>  	for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) {
> -		if (!genl_family_find_byid(id_gen_idx))
> +		if (id_gen_idx != GENL_ID_VFS_DQUOT &&
> +		    !genl_family_find_byid(id_gen_idx))
>  			return id_gen_idx;
>  		if (++id_gen_idx > GENL_MAX_ID)
>  			id_gen_idx = GENL_MIN_ID;
> @@ -169,6 +173,8 @@ int genl_register_mc_group(struct genl_family *family,
>  		id = GENL_ID_CTRL;
>  	else if (strcmp(family->name, "NET_DM") == 0)
>  		id = 1;
> +	else if (strcmp(family->name, "VFS_DQUOT") == 0)
> +		id = GENL_ID_VFS_DQUOT;
>  	else
>  		id = find_first_zero_bit(mc_groups,
>  					 mc_groups_longs * BITS_PER_LONG);
> -- 
> 1.8.4.rc3
> 
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

  reply	other threads:[~2013-11-18 12:34 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-16 17:03 [RFC 0/8] generic netlink multicast group cleanup Johannes Berg
2013-11-16 17:03 ` [RFC 1/8] genetlink: only pass array to genl_register_family_with_ops() Johannes Berg
2013-11-16 17:03 ` [RFC 2/8] drop_monitor/genetlink: use proper genetlink multicast APIs Johannes Berg
2013-11-17 22:14   ` Neil Horman
2013-11-16 17:03 ` [RFC 3/8] quota/genetlink: " Johannes Berg
2013-11-18 12:34   ` Jan Kara [this message]
2013-11-18 12:44     ` Johannes Berg
2013-11-18 14:12       ` Jan Kara
2013-11-18 14:41         ` Johannes Berg
2013-11-16 17:03 ` [RFC 4/8] hsr: don't call genl_unregister_mc_group() Johannes Berg
2013-11-16 17:03 ` [RFC 5/8] genetlink: remove genl_unregister_mc_group() Johannes Berg
2013-11-16 17:03 ` [RFC 6/8] genetlink: remove family pointer from genl_multicast_group Johannes Berg
2013-11-16 17:03 ` [RFC 7/8] genetlink: pass family to genlmsg_multicast() and friends Johannes Berg
2013-11-16 17:03 ` [RFC 8/8] genetlink: make multicast groups const, prevent abuse Johannes Berg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20131118123403.GC3921@quack.suse.cz \
    --to=jack@suse.cz \
    --cc=johannes.berg@intel.com \
    --cc=johannes@sipsolutions.net \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).