lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 3 Dec 2012 10:48:25 -0500
From:	chas williams - CONTRACTOR <chas@....nrl.navy.mil>
To:	Chen Gang <gang.chen@...anux.com>
Cc:	David.Woodhouse@...el.com, David Miller <davem@...emloft.net>,
	krzysiek@...lesie.net, Joe Perches <joe@...ches.com>,
	edumazet@...gle.com, netdev <netdev@...r.kernel.org>
Subject: Re: [Suggestion] net/atm :  for sprintf, need check the total write
 length whether larger than a page.

yes this seems like it should be done.  maybe this week i will try to
put something together unless you already have a patch somewhere.

On Mon, 03 Dec 2012 16:56:56 +0800
Chen Gang <gang.chen@...anux.com> wrote:

> Hello Maintainers:
> 
>   was this suggestion replied ?  (it seems not).
> 
>   and please help to check whether this suggestion is valid.
> 
>   thanks.
> 
> gchen.
> 
> 
> 于 2012年11月21日 12:29, Chen Gang 写道:
> > Hello David Miller:
> > 
> > in net/atm/atm_sysfs.c:
> >   suggest to check the write length whether larger than a page.
> >   the length of parameter buf is one page size (reference: fill_read_buffer at fs/sysfs/file.c)
> >   and the count of atm adresses are not limited (reference: atm_dev_ioctl -> atm_add_addr)
> > 
> >   thanks.
> > 
> > gchen.
> > 
> >  34 static ssize_t show_atmaddress(struct device *cdev,
> >  35                                struct device_attribute *attr, char *buf)
> >  36 {
> >  37         unsigned long flags;
> >  38         char *pos = buf;
> >  39         struct atm_dev *adev = to_atm_dev(cdev);
> >  40         struct atm_dev_addr *aaddr;
> >  41         int bin[] = { 1, 2, 10, 6, 1 }, *fmt = bin;
> >  42         int i, j;
> >  43 
> >  44         spin_lock_irqsave(&adev->lock, flags);
> >  45         list_for_each_entry(aaddr, &adev->local, entry) {
> >  46                 for (i = 0, j = 0; i < ATM_ESA_LEN; ++i, ++j) {
> >  47                         if (j == *fmt) {
> >  48                                 pos += sprintf(pos, ".");
> >  49                                 ++fmt;
> >  50                                 j = 0;
> >  51                         }
> >  52                         pos += sprintf(pos, "%02x",
> >  53                                        aaddr->addr.sas_addr.prv[i]);
> >  54                 }
> >  55                 pos += sprintf(pos, "\n");
> >  56         }
> >  57         spin_unlock_irqrestore(&adev->lock, flags);
> >  58 
> >  59         return pos - buf;
> >  60 }
> >  61 
> > 
> > 
> > 
> > in net/atm/addr.c
> > 
> >  67 int atm_add_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr,
> >  68                  enum atm_addr_type_t atype)
> >  69 {
> >  70         unsigned long flags;
> >  71         struct atm_dev_addr *this;
> >  72         struct list_head *head;
> >  73         int error;
> >  74 
> >  75         error = check_addr(addr);
> >  76         if (error)
> >  77                 return error;
> >  78         spin_lock_irqsave(&dev->lock, flags);
> >  79         if (atype == ATM_ADDR_LECS)
> >  80                 head = &dev->lecs;
> >  81         else
> >  82                 head = &dev->local;
> >  83         list_for_each_entry(this, head, entry) {
> >  84                 if (identical(&this->addr, addr)) {
> >  85                         spin_unlock_irqrestore(&dev->lock, flags);
> >  86                         return -EEXIST;
> >  87                 }
> >  88         }
> >  89         this = kmalloc(sizeof(struct atm_dev_addr), GFP_ATOMIC);
> >  90         if (!this) {
> >  91                 spin_unlock_irqrestore(&dev->lock, flags);
> >  92                 return -ENOMEM;
> >  93         }
> >  94         this->addr = *addr;
> >  95         list_add(&this->entry, head);
> >  96         spin_unlock_irqrestore(&dev->lock, flags);
> >  97         if (head == &dev->local)
> >  98                 notify_sigd(dev);
> >  99         return 0;
> > 100 }
> > 101 
> > 
> > 
> > in net/atm/resources.c
> > 
> > 195 int atm_dev_ioctl(unsigned int cmd, void __user *arg, int compat)
> > 196 {
> > 197         void __user *buf;
> > 198         int error, len, number, size = 0;
> > 199         struct atm_dev *dev;
> > 200         struct list_head *p;
> > 201         int *tmp_buf, *tmp_p;
> > 202         int __user *sioc_len;
> > 203         int __user *iobuf_len;
> > 204 
> > 205 #ifndef CONFIG_COMPAT
> > 206         compat = 0; /* Just so the compiler _knows_ */
> > 207 #endif
> > 208 
> > 209         switch (cmd) {
> > 210         case ATM_GETNAMES:
> > 211                 if (compat) {
> > 212 #ifdef CONFIG_COMPAT
> > 213                         struct compat_atm_iobuf __user *ciobuf = arg;
> > 214                         compat_uptr_t cbuf;
> > 215                         iobuf_len = &ciobuf->length;
> > 216                         if (get_user(cbuf, &ciobuf->buffer))
> > 217                                 return -EFAULT;
> > 218                         buf = compat_ptr(cbuf);
> > 219 #endif
> > 220                 } else {
> > 221                         struct atm_iobuf __user *iobuf = arg;
> > 222                         iobuf_len = &iobuf->length;
> > 223                         if (get_user(buf, &iobuf->buffer))
> > 224                                 return -EFAULT;
> > 225                 }
> > 226                 if (get_user(len, iobuf_len))
> > 227                         return -EFAULT;
> > 228                 mutex_lock(&atm_dev_mutex);
> > 229                 list_for_each(p, &atm_devs)
> > 230                         size += sizeof(int);
> > 231                 if (size > len) {
> > 232                         mutex_unlock(&atm_dev_mutex);
> > 233                         return -E2BIG;
> > 234                 }
> > 235                 tmp_buf = kmalloc(size, GFP_ATOMIC);
> > 236                 if (!tmp_buf) {
> > 237                         mutex_unlock(&atm_dev_mutex);
> > 238                         return -ENOMEM;
> > 239                 }
> > 240                 tmp_p = tmp_buf;
> > 241                 list_for_each(p, &atm_devs) {
> > 242                         dev = list_entry(p, struct atm_dev, dev_list);
> > 243                         *tmp_p++ = dev->number;
> > 244                 }
> > 245                 mutex_unlock(&atm_dev_mutex);
> > 246                 error = ((copy_to_user(buf, tmp_buf, size)) ||
> > 247                          put_user(size, iobuf_len))
> > 248                         ? -EFAULT : 0;
> > 249                 kfree(tmp_buf);
> > 250                 return error;
> > 251         default:
> > 252                 break;
> > 253         }
> > 254 
> > 255         if (compat) {
> > 256 #ifdef CONFIG_COMPAT
> > 257                 struct compat_atmif_sioc __user *csioc = arg;
> > 258                 compat_uptr_t carg;
> > 259 
> > 260                 sioc_len = &csioc->length;
> > 261                 if (get_user(carg, &csioc->arg))
> > 262                         return -EFAULT;
> > 263                 buf = compat_ptr(carg);
> > 264 
> > 265                 if (get_user(len, &csioc->length))
> > 266                         return -EFAULT;
> > 267                 if (get_user(number, &csioc->number))
> > 268                         return -EFAULT;
> > 269 #endif
> > 270         } else {
> > 271                 struct atmif_sioc __user *sioc = arg;
> > 272 
> > 273                 sioc_len = &sioc->length;
> > 274                 if (get_user(buf, &sioc->arg))
> > 275                         return -EFAULT;
> > 276                 if (get_user(len, &sioc->length))
> > 277                         return -EFAULT;
> > 278                 if (get_user(number, &sioc->number))
> > 279                         return -EFAULT;
> > 280         }
> > 281 
> > 282         dev = try_then_request_module(atm_dev_lookup(number), "atm-device-%d",
> > 283                                       number);
> > 284         if (!dev)
> > 285                 return -ENODEV;
> > 286 
> > 287         switch (cmd) {
> > 288         case ATM_GETTYPE:
> > 289                 size = strlen(dev->type) + 1;
> > 290                 if (copy_to_user(buf, dev->type, size)) {
> > 291                         error = -EFAULT;
> > 292                         goto done;
> > 293                 }
> > 294                 break;
> > 295         case ATM_GETESI:
> > 296                 size = ESI_LEN;
> > 297                 if (copy_to_user(buf, dev->esi, size)) {
> > 298                         error = -EFAULT;
> > 299                         goto done;
> > 300                 }
> > 301                 break;
> > 302         case ATM_SETESI:
> > 303         {
> > 304                 int i;
> > 305 
> > 306                 for (i = 0; i < ESI_LEN; i++)
> > 307                         if (dev->esi[i]) {
> > 308                                 error = -EEXIST;
> > 309                                 goto done;
> > 310                         }
> > 311         }
> > 312         /* fall through */
> > 313         case ATM_SETESIF:
> > 314         {
> > 315                 unsigned char esi[ESI_LEN];
> > 316 
> > 317                 if (!capable(CAP_NET_ADMIN)) {
> > 318                         error = -EPERM;
> > 319                         goto done;
> > 320                 }
> > 321                 if (copy_from_user(esi, buf, ESI_LEN)) {
> > 322                         error = -EFAULT;
> > 323                         goto done;
> > 324                 }
> > 325                 memcpy(dev->esi, esi, ESI_LEN);
> > 326                 error =  ESI_LEN;
> > 327                 goto done;
> > 328         }
> > 329         case ATM_GETSTATZ:
> > 330                 if (!capable(CAP_NET_ADMIN)) {
> > 331                         error = -EPERM;
> > 332                         goto done;
> > 333                 }
> > 334                 /* fall through */
> > 335         case ATM_GETSTAT:
> > 336                 size = sizeof(struct atm_dev_stats);
> > 337                 error = fetch_stats(dev, buf, cmd == ATM_GETSTATZ);
> > 338                 if (error)
> > 339                         goto done;
> > 340                 break;
> > 341         case ATM_GETCIRANGE:
> > 342                 size = sizeof(struct atm_cirange);
> > 343                 if (copy_to_user(buf, &dev->ci_range, size)) {
> > 344                         error = -EFAULT;
> > 345                         goto done;
> > 346                 }
> > 347                 break;
> > 348         case ATM_GETLINKRATE:
> > 349                 size = sizeof(int);
> > 350                 if (copy_to_user(buf, &dev->link_rate, size)) {
> > 351                         error = -EFAULT;
> > 352                         goto done;
> > 353                 }
> > 354                 break;
> > 355         case ATM_RSTADDR:
> > 356                 if (!capable(CAP_NET_ADMIN)) {
> > 357                         error = -EPERM;
> > 358                         goto done;
> > 359                 }
> > 360                 atm_reset_addr(dev, ATM_ADDR_LOCAL);
> > 361                 break;
> > 362         case ATM_ADDADDR:
> > 363         case ATM_DELADDR:
> > 364         case ATM_ADDLECSADDR:
> > 365         case ATM_DELLECSADDR:
> > 366         {
> > 367                 struct sockaddr_atmsvc addr;
> > 368 
> > 369                 if (!capable(CAP_NET_ADMIN)) {
> > 370                         error = -EPERM;
> > 371                         goto done;
> > 372                 }
> > 373 
> > 374                 if (copy_from_user(&addr, buf, sizeof(addr))) {
> > 375                         error = -EFAULT;
> > 376                         goto done;
> > 377                 }
> > 378                 if (cmd == ATM_ADDADDR || cmd == ATM_ADDLECSADDR)
> > 379                         error = atm_add_addr(dev, &addr,
> > 380                                              (cmd == ATM_ADDADDR ?
> > 381                                               ATM_ADDR_LOCAL : ATM_ADDR_LECS));
> > 382                 else
> > 383                         error = atm_del_addr(dev, &addr,
> > 384                                              (cmd == ATM_DELADDR ?
> > 385                                               ATM_ADDR_LOCAL : ATM_ADDR_LECS));
> > 386                 goto done;
> > 387         }
> > ...         ...
> > ...         ...
> > 
> > 
> > 
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ