Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> wrote: > +#define NET_DEVICE_PATH_STACK_MAX 5 > + > +struct net_device_path_stack { > + int num_paths; > + struct net_device_path path[NET_DEVICE_PATH_STACK_MAX]; > +}; [..] > +int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, > + struct net_device_path_stack *stack) > +{ > + const struct net_device *last_dev; > + struct net_device_path_ctx ctx = { > + .dev = dev, > + .daddr = daddr, > + }; > + struct net_device_path *path; > + int ret = 0, k; > + > + stack->num_paths = 0; > + while (ctx.dev && ctx.dev->netdev_ops->ndo_fill_forward_path) { > + last_dev = ctx.dev; > + k = stack->num_paths++; > + if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) > + return -1; This guarantees k < NET_DEVICE_PATH_STACK_MAX, so we can fill entire path[]. > + path = &stack->path[k]; > + memset(path, 0, sizeof(struct net_device_path)); > + > + ret = ctx.dev->netdev_ops->ndo_fill_forward_path(&ctx, path); > + if (ret < 0) > + return -1; > + > + if (WARN_ON_ONCE(last_dev == ctx.dev)) > + return -1; > + } ... but this means that stack->num_paths == NET_DEVICE_PATH_STACK_MAX is possible, with k being last element. > + path = &stack->path[stack->num_paths++]; ... so this may result in a off by one?