hope this time i get the part ‘poke claudio@’ right

a. fix a bug.
b. get rid of some junk in ‘mask_rnhead’.
c. forbid unprivileged user to insert ‘genmask' into ‘mask_rnhead'

bug is in this line
        memcmp((caddr_t *)info.rti_info[RTAX_GENMASK] + 1, (caddr_t *)t->rn_key 
+ 1, ((struct sockaddr *)t->rn_key)->sa_len) 
to make this right, at least, it should look like this
        memcmp((caddr_t *)info.rti_info[RTAX_GENMASK] + 1, (caddr_t *)t->rn_key 
+ 1, ((struct sockaddr *)t->rn_key)->sa_len - 1)
after doing this, the whole checking seems completely unnecessary, is expected 
result from ‘rn_addmask’.

Index: net/rtsock.c
===================================================================
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.136
diff -u -p -r1.136 rtsock.c
--- net/rtsock.c        21 Jan 2014 10:08:02 -0000      1.136
+++ net/rtsock.c        21 Jan 2014 21:27:32 -0000
@@ -564,20 +564,25 @@ route_output(struct mbuf *m, ...)
                error = EINVAL;
                goto flush;
        }
-       if (info.rti_info[RTAX_GENMASK] != NULL) {
-               struct radix_node       *t;
-               t = rn_addmask(info.rti_info[RTAX_GENMASK], 0, 1);
-               if (t && info.rti_info[RTAX_GENMASK]->sa_len >=
-                   ((struct sockaddr *)t->rn_key)->sa_len &&
-                   memcmp((caddr_t *)info.rti_info[RTAX_GENMASK] + 1,
-                   (caddr_t *)t->rn_key + 1,
-                   ((struct sockaddr *)t->rn_key)->sa_len) - 1)
-                       info.rti_info[RTAX_GENMASK] =
-                           (struct sockaddr *)(t->rn_key);
-               else {
+       if (info.rti_info[RTAX_GENMASK] != NULL && rtm->rtm_type != RTM_GET) {
+               rnh = rt_gettable(info.rti_info[RTAX_DST]->sa_family, tableid);
+               if (rnh == NULL) {
+                       error = EINVAL;
+                       goto flush;
+               }
+               rn = rn_addmask(info.rti_info[RTAX_GENMASK], 0,
+                               rnh->rnh_treetop->rn_off);
+               if (rn == NULL) {
                        error = ENOBUFS;
                        goto flush;
                }
+               if (!((struct sockaddr *)rn->rn_key)->sa_len) {
+                       error = EINVAL;
+                       goto flush;
+               }
+               info.rti_info[RTAX_GENMASK] = (struct sockaddr *)rn->rn_key;
+       } else {
+               info.rti_info[RTAX_GENMASK] = NULL;
        }
 #ifdef MPLS
        info.rti_mpls = rtm->rtm_mpls;


Reply via email to