[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CANP3RGdBM+8yZcCmgrw9LTGUbGNNRD0xAx+hLgQE64wxAyda4g@mail.gmail.com>
Date: Wed, 19 Jul 2023 14:50:53 +0200
From: Maciej Żenczykowski <maze@...gle.com>
To: Jiri Pirko <jiri@...nulli.us>
Cc: Jakub Kicinski <kuba@...nel.org>, David Ahern <dsahern@...nel.org>,
Linux Network Development Mailing List <netdev@...r.kernel.org>, "David S. Miller" <davem@...emloft.net>
Subject: Re: [PATCH net] ipv6 addrconf: fix bug where deleting a mngtmpaddr
can create a new temporary address
On Wed, Jul 19, 2023 at 8:47 AM Jiri Pirko <jiri@...nulli.us> wrote:
> Wed, Jul 19, 2023 at 01:08:32AM CEST, kuba@...nel.org wrote:
> >On Fri, 14 Jul 2023 08:49:55 -0600 David Ahern wrote:
> >> > I did consider that and I couldn't quite convince myself that simply
> >> > removing "|| list_empty()" from the if statement is necessarily correct
> >> > (thus I went with the more obviously correct change).
> >> >
> >> > Are you convinced dropping the || list_empty would work?
> >> > I assume it's there for some reason...
> >>
> >> I am hoping Jiri can recall why that part was added since it has the
> >> side effect of adding an address on a delete which should not happen.
> >
> >Did we get stuck here? Jiri are you around to answer?
>
> Most probably a bug. But, this is 10 years since the change, I don't
> remember much after this period. I didn't touch the code since :/
I *think* there might be cases where we want
addrconf_prefix_rcv_add_addr() -> manage_tempaddrs(create=false)
to result in the creation of a new temporary address.
Basically the 'create' argument is a boolean with interpretation
"was managetmpaddr added/created" as opposed to "should a temporary
address be created"
Think:
- RA comes in, we create the managetmpaddr, we call
manage_tempaddrs(create=true), a temporary address gets created
- someone comes in and deletes the temporary address (perhaps by hand?
or it expires?)
- another RA comes in, we don't create the managetmpaddr, since it
already exists, we call manage_tempaddrs(create=false),
it notices there are no temporary addresses (by virtue of the ||
list_empty check), and creates a new one.
Note that:
#define TEMP_VALID_LIFETIME (7*86400)
#define TEMP_PREFERRED_LIFETIME (86400)
but these are tweakable...
$ cat /proc/sys/net/ipv6/conf/*/temp_valid_lft | uniq -c
37 604800
$ cat /proc/sys/net/ipv6/conf/*/temp_prefered_lft | uniq -c
37 86400
so we could have these be < unsolicited RA frequency.
(that's probably a bad idea for other reasons... but that's besides the point)
I have similar misgivings about inet6_addr_modify() -> manage_tempaddrs()
if (was_managetempaddr || ifp->flags & IFA_F_MANAGETEMPADDR) {
if (was_managetempaddr &&
!(ifp->flags & IFA_F_MANAGETEMPADDR)) {
cfg->valid_lft = 0;
cfg->preferred_lft = 0;
}
manage_tempaddrs(ifp->idev, ifp, cfg->valid_lft,
cfg->preferred_lft, !was_managetempaddr,
jiffies);
}
Here create == !was_managetempaddr,
but technically we can have create == false, and yet valid/prefered != 0.
This will be the case if we have inet6_addr_modify() called where
*both* the before and after state is a managetempaddr.
Perhaps because the expiration was updated?
Anyway... because of the above I remain unconvinced that just removing
'|| list_empty' is safe...
Powered by blists - more mailing lists