On Sun, Jun 26, 2022 at 10:22:18AM +0200, Claudio Jeker wrote:
> Switch the state variables to track the buffer size for the sysctl to
> size_t and stop using the somewhat strange way of working with the buf
> limit from starting with a negative w_needed. Just use the less confusing
> w_needed <= w_given as limit check.

OK bluhm@

> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.329
> diff -u -p -r1.329 rtsock.c
> --- net/rtsock.c      16 Jun 2022 10:35:45 -0000      1.329
> +++ net/rtsock.c      24 Jun 2022 12:03:54 -0000
> @@ -101,7 +101,8 @@
>  const struct sockaddr route_src = { 2, PF_ROUTE, };
>  
>  struct walkarg {
> -     int     w_op, w_arg, w_given, w_needed, w_tmemsize;
> +     int     w_op, w_arg, w_tmemsize;
> +     size_t  w_given, w_needed;
>       caddr_t w_where, w_tmem;
>  };
>  
> @@ -1660,7 +1661,7 @@ again:
>       len = ALIGN(len);
>       if (cp == 0 && w != NULL && !second_time) {
>               w->w_needed += len;
> -             if (w->w_needed <= 0 && w->w_where) {
> +             if (w->w_needed <= w->w_given && w->w_where) {
>                       if (w->w_tmemsize < len) {
>                               free(w->w_tmem, M_RTABLE, w->w_tmemsize);
>                               w->w_tmem = malloc(len, M_RTABLE,
> @@ -1983,7 +1984,7 @@ sysctl_dumpentry(struct rtentry *rt, voi
>  #endif
>  
>       size = rtm_msg2(RTM_GET, RTM_VERSION, &info, NULL, w);
> -     if (w->w_where && w->w_tmem && w->w_needed <= 0) {
> +     if (w->w_where && w->w_tmem && w->w_needed <= w->w_given) {
>               struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
>  
>               rtm->rtm_pid = curproc->p_p->ps_pid;
> @@ -2021,7 +2022,7 @@ sysctl_iflist(int af, struct walkarg *w)
>               /* Copy the link-layer address first */
>               info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl);
>               len = rtm_msg2(RTM_IFINFO, RTM_VERSION, &info, 0, w);
> -             if (w->w_where && w->w_tmem && w->w_needed <= 0) {
> +             if (w->w_where && w->w_tmem && w->w_needed <= w->w_given) {
>                       struct if_msghdr *ifm;
>  
>                       ifm = (struct if_msghdr *)w->w_tmem;
> @@ -2044,7 +2045,8 @@ sysctl_iflist(int af, struct walkarg *w)
>                       info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
>                       info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
>                       len = rtm_msg2(RTM_NEWADDR, RTM_VERSION, &info, 0, w);
> -                     if (w->w_where && w->w_tmem && w->w_needed <= 0) {
> +                     if (w->w_where && w->w_tmem &&
> +                         w->w_needed <= w->w_given) {
>                               struct ifa_msghdr *ifam;
>  
>                               ifam = (struct ifa_msghdr *)w->w_tmem;
> @@ -2076,7 +2078,7 @@ sysctl_ifnames(struct walkarg *w)
>               if (w->w_arg && w->w_arg != ifp->if_index)
>                       continue;
>               w->w_needed += sizeof(ifn);
> -             if (w->w_where && w->w_needed <= 0) {
> +             if (w->w_where && w->w_needed <= w->w_given) {
>  
>                       memset(&ifn, 0, sizeof(ifn));
>                       ifn.if_index = ifp->if_index;
> @@ -2113,7 +2115,7 @@ sysctl_source(int af, u_int tableid, str
>                       return (0);
>               }
>               w->w_needed += size;
> -             if (w->w_where && w->w_needed <= 0) {
> +             if (w->w_where && w->w_needed <= w->w_given) {
>                       if ((error = copyout(sa, w->w_where, size)))
>                               return (error);
>                       w->w_where += size;
> @@ -2140,7 +2142,6 @@ sysctl_rtable(int *name, u_int namelen, 
>       bzero(&w, sizeof(w));
>       w.w_where = where;
>       w.w_given = *given;
> -     w.w_needed = 0 - w.w_given;
>       w.w_op = name[1];
>       w.w_arg = name[2];
>  
> @@ -2211,10 +2212,9 @@ sysctl_rtable(int *name, u_int namelen, 
>               break;
>       }
>       free(w.w_tmem, M_RTABLE, w.w_tmemsize);
> -     w.w_needed += w.w_given;
>       if (where) {
>               *given = w.w_where - (caddr_t)where;
> -             if (*given < w.w_needed)
> +             if (w.w_needed > w.w_given)
>                       return (ENOMEM);
>       } else if (w.w_needed == 0) {
>               *given = 0;

Reply via email to