Hello,

I have found a little bug in shaper.c caused the kernel Oops (at least then
length of device name less then 16 bytes) then user's SHAPER_GET_DEV ioctl
call occurs.

The following is my patch solving a problem against 2.1.125 kernel source
tree.

--- CUT HERE ---
--- linux.old/drivers/net/shaper.c      Fri Aug 21 01:33:10 1998
+++ linux/drivers/net/shaper.c  Wed Oct 28 03:30:08 1998
@@ -564,7 +564,7 @@
                case SHAPER_GET_DEV:
                        if(sh->dev==NULL)
                                return -ENODEV;
-                       memcpy(ss->ss_name, sh->dev->name, sizeof(ss->ss_name));
+                       memcpy(ss->ss_name, sh->dev->name, strlen(sh->dev->name)+1);
                        return 0;
                case SHAPER_SET_SPEED:
                        shaper_setspeed(sh,ss->ss_speed);
 
--- CUT HERE ---

I have also slightly rewrote a shapecfg program and have added to them
SHAPER_GET_DEV and SHAPER_GET_SPEED ioctl calls. (Anybody have wrote it
already ?)

Examples :

elis# shapecfg 0 attach eth3            /* attach shaper */
elis# shapecfg 0 speed 128000           /* speed setting */
elis# shapecfg 0                        /* getting properties */
shaper0 on <eth3> speed 128000
elis#

Shaper device index have limited by number 999.

--- CUT HERE ---
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <linux/types.h>
#include <net/if.h>
#include <linux/if_shaper.h>
#include <linux/sockios.h>

static unsigned char devname[] = "shaper\0\0\0";

void usage(char *name)
{       
        fprintf(stderr,"Usage: %s <index> attach <device>\n"
                       "       %s <index> speed <speed>\n"
                       "       %s <index>\n", name, name, name);
        exit(1);
}

void main(int argc, char *argv[])
{
        unsigned char *progname;
        
        int s = socket(AF_INET, SOCK_DGRAM,0);
        if (s == -1)
        {
                perror("socket");
                exit(1);
        }
        
        progname = strrchr(argv[0], '/');
        if (progname == NULL)
                progname = argv[0];
        else
                progname++;
        
        if (argc < 2)
                usage(progname);
        
        devname[6] = argv[1][0];
        if (argv[1][1]) {
                devname[7] = argv[1][1];
                if (argv[1][2]) devname[8] = argv[1][2];
        }

        if (argc == 2)
        {
                struct ifreq ifr;
                struct shaperconf *shc = (struct shaperconf *)&ifr.ifr_data;
                unsigned speed;

                strcpy(ifr.ifr_name,devname);           
                shc->ss_cmd = SHAPER_GET_SPEED;
                if (ioctl(s,SIOCDEVPRIVATE,&ifr) == -1)
                {
                        perror("SHAPER_GET_SPEED");
                        exit(1);
                }
                speed = shc->ss_speed;

                strcpy(ifr.ifr_name,devname);           
                shc->ss_cmd = SHAPER_GET_DEV;
                if (ioctl(s,SIOCDEVPRIVATE,&ifr) == -1)
                {
                        perror("SHAPER_GET_DEV");
                        exit(1);
                }

                printf("%s on <%s> speed %d\n", devname, shc->ss_name, speed);
                exit(0);
        } 

        if (argc != 4)
                usage(progname);
                
        if (strcmp(argv[2],"attach") == 0)
        {
                struct ifreq ifr;
                struct shaperconf *shc = (struct shaperconf *)&ifr.ifr_data;

                strcpy(ifr.ifr_name,devname);
                strcpy(shc->ss_name,argv[3]);
                shc->ss_cmd = SHAPER_SET_DEV;
                if (ioctl(s,SIOCDEVPRIVATE,&ifr) == -1)
                {
                        perror("SHAPER_SET_DEV");
                        exit(1);
                }
                exit(0);
        }
        if (strcmp(argv[2],"speed") == 0)
        {
                int v;
                struct ifreq ifr;
                struct shaperconf *shc = (struct shaperconf *)&ifr.ifr_data;

                strcpy(ifr.ifr_name,devname);
                sscanf(argv[3],"%d",&v);
                shc->ss_speed = v;
                shc->ss_cmd = SHAPER_SET_SPEED;
                if (ioctl(s,SIOCDEVPRIVATE,&ifr) == -1)
                {
                        perror("SHAPER_SET_SPEED");
                        exit(1);
                }
                exit(0);
        }
        usage(progname);
}
--- CUT HERE ---

I hope somebody will find my work useful.

---
Best regards,   Vladimir Ivanov
E-mail:         mailto:[EMAIL PROTECTED]
World Wide Web: http://elis.tusur.ru/~vlad

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to