Re: linux-next: manual merge of the kspp tree with the net-next tree

From: Stephen Rothwell
Date: Wed Aug 05 2020 - 00:06:03 EST


Hi all,

On Mon, 27 Jul 2020 19:27:21 +1000 Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> wrote:
>
> Today's linux-next merge of the kspp tree got a conflict in:
>
> net/ipv6/ip6_flowlabel.c
>
> between commit:
>
> ff6a4cf214ef ("net/ipv6: split up ipv6_flowlabel_opt")
>
> from the net-next tree and commit:
>
> 3f649ab728cd ("treewide: Remove uninitialized_var() usage")
>
> from the kspp tree.
>
> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging. You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.
>
> diff --cc net/ipv6/ip6_flowlabel.c
> index 215b6f5e733e,73bb047e6037..000000000000
> --- a/net/ipv6/ip6_flowlabel.c
> +++ b/net/ipv6/ip6_flowlabel.c
> @@@ -534,184 -533,181 +534,184 @@@ int ipv6_flowlabel_opt_get(struct sock
> return -ENOENT;
> }
>
> -int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
> +#define socklist_dereference(__sflp) \
> + rcu_dereference_protected(__sflp, lockdep_is_held(&ip6_sk_fl_lock))
> +
> +static int ipv6_flowlabel_put(struct sock *sk, struct in6_flowlabel_req *freq)
> {
> - int err;
> - struct net *net = sock_net(sk);
> struct ipv6_pinfo *np = inet6_sk(sk);
> - struct in6_flowlabel_req freq;
> - struct ipv6_fl_socklist *sfl1 = NULL;
> - struct ipv6_fl_socklist *sfl;
> struct ipv6_fl_socklist __rcu **sflp;
> - struct ip6_flowlabel *fl, *fl1 = NULL;
> + struct ipv6_fl_socklist *sfl;
>
> + if (freq->flr_flags & IPV6_FL_F_REFLECT) {
> + if (sk->sk_protocol != IPPROTO_TCP)
> + return -ENOPROTOOPT;
> + if (!np->repflow)
> + return -ESRCH;
> + np->flow_label = 0;
> + np->repflow = 0;
> + return 0;
> + }
>
> - if (optlen < sizeof(freq))
> - return -EINVAL;
> + spin_lock_bh(&ip6_sk_fl_lock);
> + for (sflp = &np->ipv6_fl_list;
> + (sfl = socklist_dereference(*sflp)) != NULL;
> + sflp = &sfl->next) {
> + if (sfl->fl->label == freq->flr_label)
> + goto found;
> + }
> + spin_unlock_bh(&ip6_sk_fl_lock);
> + return -ESRCH;
> +found:
> + if (freq->flr_label == (np->flow_label & IPV6_FLOWLABEL_MASK))
> + np->flow_label &= ~IPV6_FLOWLABEL_MASK;
> + *sflp = sfl->next;
> + spin_unlock_bh(&ip6_sk_fl_lock);
> + fl_release(sfl->fl);
> + kfree_rcu(sfl, rcu);
> + return 0;
> +}
>
> - if (copy_from_user(&freq, optval, sizeof(freq)))
> - return -EFAULT;
> +static int ipv6_flowlabel_renew(struct sock *sk, struct in6_flowlabel_req *freq)
> +{
> + struct ipv6_pinfo *np = inet6_sk(sk);
> + struct net *net = sock_net(sk);
> + struct ipv6_fl_socklist *sfl;
> + int err;
>
> - switch (freq.flr_action) {
> - case IPV6_FL_A_PUT:
> - if (freq.flr_flags & IPV6_FL_F_REFLECT) {
> - if (sk->sk_protocol != IPPROTO_TCP)
> - return -ENOPROTOOPT;
> - if (!np->repflow)
> - return -ESRCH;
> - np->flow_label = 0;
> - np->repflow = 0;
> - return 0;
> - }
> - spin_lock_bh(&ip6_sk_fl_lock);
> - for (sflp = &np->ipv6_fl_list;
> - (sfl = rcu_dereference_protected(*sflp,
> - lockdep_is_held(&ip6_sk_fl_lock))) != NULL;
> - sflp = &sfl->next) {
> - if (sfl->fl->label == freq.flr_label) {
> - if (freq.flr_label == (np->flow_label&IPV6_FLOWLABEL_MASK))
> - np->flow_label &= ~IPV6_FLOWLABEL_MASK;
> - *sflp = sfl->next;
> - spin_unlock_bh(&ip6_sk_fl_lock);
> - fl_release(sfl->fl);
> - kfree_rcu(sfl, rcu);
> - return 0;
> - }
> + rcu_read_lock_bh();
> + for_each_sk_fl_rcu(np, sfl) {
> + if (sfl->fl->label == freq->flr_label) {
> + err = fl6_renew(sfl->fl, freq->flr_linger,
> + freq->flr_expires);
> + rcu_read_unlock_bh();
> + return err;
> }
> - spin_unlock_bh(&ip6_sk_fl_lock);
> - return -ESRCH;
> + }
> + rcu_read_unlock_bh();
>
> - case IPV6_FL_A_RENEW:
> - rcu_read_lock_bh();
> - for_each_sk_fl_rcu(np, sfl) {
> - if (sfl->fl->label == freq.flr_label) {
> - err = fl6_renew(sfl->fl, freq.flr_linger, freq.flr_expires);
> - rcu_read_unlock_bh();
> - return err;
> - }
> - }
> - rcu_read_unlock_bh();
> + if (freq->flr_share == IPV6_FL_S_NONE &&
> + ns_capable(net->user_ns, CAP_NET_ADMIN)) {
> + struct ip6_flowlabel *fl = fl_lookup(net, freq->flr_label);
>
> - if (freq.flr_share == IPV6_FL_S_NONE &&
> - ns_capable(net->user_ns, CAP_NET_ADMIN)) {
> - fl = fl_lookup(net, freq.flr_label);
> - if (fl) {
> - err = fl6_renew(fl, freq.flr_linger, freq.flr_expires);
> - fl_release(fl);
> - return err;
> - }
> + if (fl) {
> + err = fl6_renew(fl, freq->flr_linger,
> + freq->flr_expires);
> + fl_release(fl);
> + return err;
> }
> - return -ESRCH;
> -
> - case IPV6_FL_A_GET:
> - if (freq.flr_flags & IPV6_FL_F_REFLECT) {
> - struct net *net = sock_net(sk);
> - if (net->ipv6.sysctl.flowlabel_consistency) {
> - net_info_ratelimited("Can not set IPV6_FL_F_REFLECT if flowlabel_consistency sysctl is enable\n");
> - return -EPERM;
> - }
> + }
> + return -ESRCH;
> +}
>
> - if (sk->sk_protocol != IPPROTO_TCP)
> - return -ENOPROTOOPT;
> +static int ipv6_flowlabel_get(struct sock *sk, struct in6_flowlabel_req *freq,
> + sockptr_t optval, int optlen)
> +{
> + struct ipv6_fl_socklist *sfl, *sfl1 = NULL;
> + struct ip6_flowlabel *fl, *fl1 = NULL;
> + struct ipv6_pinfo *np = inet6_sk(sk);
> + struct net *net = sock_net(sk);
> - int uninitialized_var(err);
> ++ int err;
>
> - np->repflow = 1;
> - return 0;
> + if (freq->flr_flags & IPV6_FL_F_REFLECT) {
> + if (net->ipv6.sysctl.flowlabel_consistency) {
> + net_info_ratelimited("Can not set IPV6_FL_F_REFLECT if flowlabel_consistency sysctl is enable\n");
> + return -EPERM;
> }
>
> - if (freq.flr_label & ~IPV6_FLOWLABEL_MASK)
> - return -EINVAL;
> + if (sk->sk_protocol != IPPROTO_TCP)
> + return -ENOPROTOOPT;
> + np->repflow = 1;
> + return 0;
> + }
>
> - if (net->ipv6.sysctl.flowlabel_state_ranges &&
> - (freq.flr_label & IPV6_FLOWLABEL_STATELESS_FLAG))
> - return -ERANGE;
> + if (freq->flr_label & ~IPV6_FLOWLABEL_MASK)
> + return -EINVAL;
> + if (net->ipv6.sysctl.flowlabel_state_ranges &&
> + (freq->flr_label & IPV6_FLOWLABEL_STATELESS_FLAG))
> + return -ERANGE;
>
> - fl = fl_create(net, sk, &freq, optval, optlen, &err);
> - if (!fl)
> - return err;
> - sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);
> + fl = fl_create(net, sk, freq, optval, optlen, &err);
> + if (!fl)
> + return err;
>
> - if (freq.flr_label) {
> - err = -EEXIST;
> - rcu_read_lock_bh();
> - for_each_sk_fl_rcu(np, sfl) {
> - if (sfl->fl->label == freq.flr_label) {
> - if (freq.flr_flags&IPV6_FL_F_EXCL) {
> - rcu_read_unlock_bh();
> - goto done;
> - }
> - fl1 = sfl->fl;
> - if (!atomic_inc_not_zero(&fl1->users))
> - fl1 = NULL;
> - break;
> + sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);
> +
> + if (freq->flr_label) {
> + err = -EEXIST;
> + rcu_read_lock_bh();
> + for_each_sk_fl_rcu(np, sfl) {
> + if (sfl->fl->label == freq->flr_label) {
> + if (freq->flr_flags & IPV6_FL_F_EXCL) {
> + rcu_read_unlock_bh();
> + goto done;
> }
> + fl1 = sfl->fl;
> + if (!atomic_inc_not_zero(&fl1->users))
> + fl1 = NULL;
> + break;
> }
> - rcu_read_unlock_bh();
> + }
> + rcu_read_unlock_bh();
>
> - if (!fl1)
> - fl1 = fl_lookup(net, freq.flr_label);
> - if (fl1) {
> + if (!fl1)
> + fl1 = fl_lookup(net, freq->flr_label);
> + if (fl1) {
> recheck:
> - err = -EEXIST;
> - if (freq.flr_flags&IPV6_FL_F_EXCL)
> - goto release;
> - err = -EPERM;
> - if (fl1->share == IPV6_FL_S_EXCL ||
> - fl1->share != fl->share ||
> - ((fl1->share == IPV6_FL_S_PROCESS) &&
> - (fl1->owner.pid != fl->owner.pid)) ||
> - ((fl1->share == IPV6_FL_S_USER) &&
> - !uid_eq(fl1->owner.uid, fl->owner.uid)))
> - goto release;
> -
> - err = -ENOMEM;
> - if (!sfl1)
> - goto release;
> - if (fl->linger > fl1->linger)
> - fl1->linger = fl->linger;
> - if ((long)(fl->expires - fl1->expires) > 0)
> - fl1->expires = fl->expires;
> - fl_link(np, sfl1, fl1);
> - fl_free(fl);
> - return 0;
> + err = -EEXIST;
> + if (freq->flr_flags&IPV6_FL_F_EXCL)
> + goto release;
> + err = -EPERM;
> + if (fl1->share == IPV6_FL_S_EXCL ||
> + fl1->share != fl->share ||
> + ((fl1->share == IPV6_FL_S_PROCESS) &&
> + (fl1->owner.pid != fl->owner.pid)) ||
> + ((fl1->share == IPV6_FL_S_USER) &&
> + !uid_eq(fl1->owner.uid, fl->owner.uid)))
> + goto release;
> +
> + err = -ENOMEM;
> + if (!sfl1)
> + goto release;
> + if (fl->linger > fl1->linger)
> + fl1->linger = fl->linger;
> + if ((long)(fl->expires - fl1->expires) > 0)
> + fl1->expires = fl->expires;
> + fl_link(np, sfl1, fl1);
> + fl_free(fl);
> + return 0;
>
> release:
> - fl_release(fl1);
> - goto done;
> - }
> - }
> - err = -ENOENT;
> - if (!(freq.flr_flags&IPV6_FL_F_CREATE))
> + fl_release(fl1);
> goto done;
> + }
> + }
> + err = -ENOENT;
> + if (!(freq->flr_flags & IPV6_FL_F_CREATE))
> + goto done;
>
> - err = -ENOMEM;
> - if (!sfl1)
> - goto done;
> + err = -ENOMEM;
> + if (!sfl1)
> + goto done;
>
> - err = mem_check(sk);
> - if (err != 0)
> - goto done;
> + err = mem_check(sk);
> + if (err != 0)
> + goto done;
>
> - fl1 = fl_intern(net, fl, freq.flr_label);
> - if (fl1)
> - goto recheck;
> + fl1 = fl_intern(net, fl, freq->flr_label);
> + if (fl1)
> + goto recheck;
>
> - if (!freq.flr_label) {
> - if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label,
> - &fl->label, sizeof(fl->label))) {
> - /* Intentionally ignore fault. */
> - }
> + if (!freq->flr_label) {
> + sockptr_advance(optval,
> + offsetof(struct in6_flowlabel_req, flr_label));
> + if (copy_to_sockptr(optval, &fl->label, sizeof(fl->label))) {
> + /* Intentionally ignore fault. */
> }
> -
> - fl_link(np, sfl1, fl);
> - return 0;
> -
> - default:
> - return -EINVAL;
> }
>
> + fl_link(np, sfl1, fl);
> + return 0;
> done:
> fl_free(fl);
> kfree(sfl1);

This is now a conflict between the net-next tree and Linus' tree.

--
Cheers,
Stephen Rothwell

Attachment: pgpCCzjJ3A6SD.pgp
Description: OpenPGP digital signature