<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/drivers/char, branch v2.6.16.54</title>
<subtitle>Linux kernel source tree</subtitle>
<id>https://git.amat.us/linux/atom/drivers/char?h=v2.6.16.54</id>
<link rel='self' href='https://git.amat.us/linux/atom/drivers/char?h=v2.6.16.54'/>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/'/>
<updated>2007-04-20T22:18:01Z</updated>
<entry>
<title>tty_io: fix race in master pty close/slave pty close path</title>
<updated>2007-04-20T22:18:01Z</updated>
<author>
<name>Aristeu Sergio Rozanski Filho</name>
<email>aris@ruivo.org</email>
</author>
<published>2007-04-20T22:18:01Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=fec2411aa963fafcf17823b43c2379ba3d228cd8'/>
<id>urn:sha1:fec2411aa963fafcf17823b43c2379ba3d228cd8</id>
<content type='text'>
This patch fixes a possible race that leads to double freeing an idr index.
 When the master begin to close, release_dev() is called and then
pty_close() is called:

        if (tty-&gt;driver-&gt;close)
                tty-&gt;driver-&gt;close(tty, filp);

This is done without helding any locks other than BKL.  Inside pty_close(),
being a master close, the devpts entry will be removed:

#ifdef CONFIG_UNIX98_PTYS
                if (tty-&gt;driver == ptm_driver)
                        devpts_pty_kill(tty-&gt;index);
#endif

But devpts_pty_kill() will call get_node() that may sleep while waiting for
&amp;devpts_root-&gt;d_inode-&gt;i_sem.  When this happens and the slave is being
opened, tty_open() just found the driver and index:

        driver = get_tty_driver(device, &amp;index);
        if (!driver) {
                mutex_unlock(&amp;tty_mutex);
                return -ENODEV;
        }

This part of the code is already protected under tty_mute.  The problem is
that the slave close already got an index.  Then init_dev() is called and
blocks waiting for the same &amp;devpts_root-&gt;d_inode-&gt;i_sem.

When the master close resumes, it removes the devpts entry, and the
relation between idr index and the tty is gone.  The master then sleeps
waiting for the tty_mutex on release_dev().

Slave open resumes and found no tty for that index.  As result, a NULL tty
is returned and init_dev() doesn't flow to fast_track:

        /* check whether we're reopening an existing tty */
        if (driver-&gt;flags &amp; TTY_DRIVER_DEVPTS_MEM) {
                tty = devpts_get_tty(idx);
                if (tty &amp;&amp; driver-&gt;subtype == PTY_TYPE_MASTER)
                        tty = tty-&gt;link;
        } else {
                tty = driver-&gt;ttys[idx];
        }
        if (tty) goto fast_track;

The result of this, is that a new tty will be created and init_dev() returns
sucessfull. After returning, tty_mutex is dropped and master close may resume.

Master close finds it's the only use and both sides are closing, then releases
the tty and the index. At this point, the idr index is free, but slave still
has it.

Slave open then calls pty_open() and finds that tty-&gt;link-&gt;count is 0,
because there's no master and returns error.  Then tty_open() calls
release_dev() which executes without any warning, as it was a case of last
slave close when the master is already closed (master-&gt;count == 0,
slave-&gt;count == 1).  The tty is then released with the already released idr
index.

This normally would only issue a warning on idr_remove() but in case of a
customer's critical application, it's never too simple:

thread1: opens master, gets index X
thread1: begin closing master
thread2: begin opening slave with index X
thread1: finishes closing master, index X released
thread3: opens master, gets index X, just released
thread2: fails opening slave, releases index X         &lt;----
thread4: opens master, gets index X, init_dev() then find an already in use
         and healthy tty and fails

If no more indexes are released, ptmx_open() will keep failing, as the
first free index available is X, and it will make init_dev() fail because
you're trying to "reopen a master" which isn't valid.

The patch notices when this race happens and make init_dev() fail
imediately.  The init_dev() function is called with tty_mutex held, so it's
safe to continue with tty till the end of function because release_dev()
won't make any further changes without grabbing the tty_mutex.

Without the patch, on some machines it's possible get easily idr warnings
like this one:

idr_remove called for id=15 which is not allocated.
 [&lt;c02555b9&gt;] idr_remove+0x139/0x170
 [&lt;c02a1b62&gt;] release_mem+0x182/0x230
 [&lt;c02a28e7&gt;] release_dev+0x4b7/0x700
 [&lt;c02a0ea7&gt;] tty_ldisc_enable+0x27/0x30
 [&lt;c02a1e64&gt;] init_dev+0x254/0x580
 [&lt;c02a0d64&gt;] check_tty_count+0x14/0xb0
 [&lt;c02a4f05&gt;] tty_open+0x1c5/0x340
 [&lt;c02a4d40&gt;] tty_open+0x0/0x340
 [&lt;c017388f&gt;] chrdev_open+0xaf/0x180
 [&lt;c017c2ac&gt;] open_namei+0x8c/0x760
 [&lt;c01737e0&gt;] chrdev_open+0x0/0x180
 [&lt;c0167bc9&gt;] __dentry_open+0xc9/0x210
 [&lt;c0167e2c&gt;] do_filp_open+0x5c/0x70
 [&lt;c0167a91&gt;] get_unused_fd+0x61/0xd0
 [&lt;c0167e93&gt;] do_sys_open+0x53/0x100
 [&lt;c0167f97&gt;] sys_open+0x27/0x30
 [&lt;c010303b&gt;] syscall_call+0x7/0xb

using this test application available on:
 http://www.ruivo.org/~aris/pty_sodomizer.c

Signed-off-by: Aristeu Sergio Rozanski Filho &lt;aris@ruivo.org&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
<entry>
<title>Fix buffer overflow in Omnikey CardMan 4040 driver (CVE-2007-0005)</title>
<updated>2007-03-11T06:39:14Z</updated>
<author>
<name>Marcel Holtmann</name>
<email>marcel@holtmann.org</email>
</author>
<published>2007-03-11T06:39:14Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=dfe67217aea3eb4ecbab736903f6ecee3458b8a8'/>
<id>urn:sha1:dfe67217aea3eb4ecbab736903f6ecee3458b8a8</id>
<content type='text'>
Based on a patch from Don Howard &lt;dhoward@redhat.com&gt;

When calling write() with a buffer larger than 512 bytes, the
driver's write buffer overflows, allowing to overwrite the EIP and
execute arbitrary code with kernel privileges.

In read(), there exists a similar problem, but coming from the device.
A malicous or buggy device sending more than 512 bytes can overflow
of the driver's read buffer, with the same effects as above.

Signed-off-by: Marcel Holtmann &lt;marcel@holtmann.org&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
<entry>
<title>read_zero_pagealigned() locking fix</title>
<updated>2007-01-23T15:46:22Z</updated>
<author>
<name>Hugh Dickins</name>
<email>hugh@veritas.com</email>
</author>
<published>2007-01-23T15:46:22Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=faa309e7b921b2104a42d4ac0e0122f3399a3789'/>
<id>urn:sha1:faa309e7b921b2104a42d4ac0e0122f3399a3789</id>
<content type='text'>
Ramiro Voicu hits the BUG_ON(!pte_none(*pte)) in zeromap_pte_range: kernel
bugzilla 7645.  Right: read_zero_pagealigned uses down_read of mmap_sem,
but another thread's racing read of /dev/zero, or a normal fault, can
easily set that pte again, in between zap_page_range and zeromap_page_range
getting there.  It's been wrong ever since 2.4.3.

The simple fix is to use down_write instead, but that would serialize reads
of /dev/zero more than at present: perhaps some app would be badly
affected.  So instead let zeromap_page_range return the error instead of
BUG_ON, and read_zero_pagealigned break to the slower clear_user loop in
that case - there's no need to optimize for it.

Use -EEXIST for when a pte is found: BUG_ON in mmap_zero (the other user of
zeromap_page_range), though it really isn't interesting there.  And since
mmap_zero wants -EAGAIN for out-of-memory, the zeromaps better return that
than -ENOMEM.

Signed-off-by: Hugh Dickins &lt;hugh@veritas.com&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
<entry>
<title>rtc: lockdep fix/workaround</title>
<updated>2007-01-09T02:23:35Z</updated>
<author>
<name>Peter Zijlstra</name>
<email>a.p.zijlstra@chello.nl</email>
</author>
<published>2007-01-08T08:09:15Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=80d0613d3f7076e5c478999f309d12d6ba46a220'/>
<id>urn:sha1:80d0613d3f7076e5c478999f309d12d6ba46a220</id>
<content type='text'>
BUG: warning at kernel/lockdep.c:1816/trace_hardirqs_on() (Not tainted)
 [&lt;c04051ee&gt;] show_trace_log_lvl+0x58/0x171
 [&lt;c0405802&gt;] show_trace+0xd/0x10
 [&lt;c040591b&gt;] dump_stack+0x19/0x1b
 [&lt;c043abee&gt;] trace_hardirqs_on+0xa2/0x11e
 [&lt;c06143c3&gt;] _spin_unlock_irq+0x22/0x26
 [&lt;c0541540&gt;] rtc_get_rtc_time+0x32/0x176
 [&lt;c0419ba4&gt;] hpet_rtc_interrupt+0x92/0x14d
 [&lt;c0450f94&gt;] handle_IRQ_event+0x20/0x4d
 [&lt;c0451055&gt;] __do_IRQ+0x94/0xef
 [&lt;c040678d&gt;] do_IRQ+0x9e/0xbd
 [&lt;c0404a49&gt;] common_interrupt+0x25/0x2c
DWARF2 unwinder stuck at common_interrupt+0x25/0x2c

Signed-off-by: Peter Zijlstra &lt;a.p.zijlstra@chello.nl&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
<entry>
<title>rio: typo in bitwise AND expression.</title>
<updated>2007-01-09T02:23:31Z</updated>
<author>
<name>Willy Tarreau</name>
<email>w@1wt.eu</email>
</author>
<published>2007-01-06T01:31:24Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=152ecd2726ff526aabf7510b379a1a8ffb05d3ec'/>
<id>urn:sha1:152ecd2726ff526aabf7510b379a1a8ffb05d3ec</id>
<content type='text'>
The line:

    hp-&gt;Mode &amp;= !RIO_PCI_INT_ENABLE;

is obviously wrong as RIO_PCI_INT_ENABLE=0x04 and is used as a bitmask
2 lines before. Getting no IRQ would not disable RIO_PCI_INT_ENABLE
but rather RIO_PCI_BOOT_FROM_RAM which equals 0x01.

Obvious fix is to change ! for ~.

Signed-off-by: Willy Tarreau &lt;w@1wt.eu&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
<entry>
<title>drm: allow detection of new VIA chipsets</title>
<updated>2007-01-09T02:23:31Z</updated>
<author>
<name>Chuck Short</name>
<email>zulcss@gmail.com</email>
</author>
<published>2007-01-06T00:22:29Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=c6b135f0b02f2104475ce279ac3cb7442419cd2a'/>
<id>urn:sha1:c6b135f0b02f2104475ce279ac3cb7442419cd2a</id>
<content type='text'>
Update pci ids.

Signed-off-by: Chuck Short &lt;zulcss@gmail.com&gt;
Signed-off-by: Ben Collins &lt;bcollins@ubuntu.com&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
<entry>
<title>drm: Add the P4VM800PRO PCI ID.</title>
<updated>2007-01-09T02:23:31Z</updated>
<author>
<name>Dave Airlie</name>
<email>airlied@linux.ie</email>
</author>
<published>2007-01-06T00:21:40Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=c302289dadbc28fa0dbea3d05a5830200131adc9'/>
<id>urn:sha1:c302289dadbc28fa0dbea3d05a5830200131adc9</id>
<content type='text'>
Signed-off-by: Dave Airlie &lt;airlied@linux.ie&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
<entry>
<title>hvc_console suspend fix</title>
<updated>2006-12-17T23:39:11Z</updated>
<author>
<name>Andrew Morton</name>
<email>akpm@osdl.org</email>
</author>
<published>2006-12-17T23:39:11Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=17735bd9822900d82278842f6bbe7a0e1c64c3b1'/>
<id>urn:sha1:17735bd9822900d82278842f6bbe7a0e1c64c3b1</id>
<content type='text'>
Fix http://bugzilla.kernel.org/show_bug.cgi?id=7152

Signed-off-by: Andrew Morton &lt;akpm@osdl.org&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
<entry>
<title>[WATCHDOG] sc1200wdt.c pnp unregister fix.</title>
<updated>2006-12-17T23:23:42Z</updated>
<author>
<name>Akinobu Mita</name>
<email>akinobu.mita@gmail.com</email>
</author>
<published>2006-12-17T23:23:42Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=8132c7a57ae81db8f680ed4ef07a1a32fd5ee129'/>
<id>urn:sha1:8132c7a57ae81db8f680ed4ef07a1a32fd5ee129</id>
<content type='text'>
If no devices found or invalid parameter is specified,
scl200wdt_pnp_driver is left unregistered.
It breaks global list of pnp drivers.

Signed-off-by: Akinobu Mita &lt;akinobu.mita@gmail.com&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
<entry>
<title>[WATCHDOG] sc1200wdt.c printk fix</title>
<updated>2006-12-17T23:13:47Z</updated>
<author>
<name>Dave Jones</name>
<email>davej@redhat.com</email>
</author>
<published>2006-12-17T23:13:47Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=18d16ac9bb3d73a8b1027fdf33e8dbc3cc592982'/>
<id>urn:sha1:18d16ac9bb3d73a8b1027fdf33e8dbc3cc592982</id>
<content type='text'>
Fix printk output.

sc1200wdt: build 20020303&lt;3&gt;sc1200wdt: io parameter must be specified

Signed-off-by: Dave Jones &lt;davej@redhat.com&gt;
Signed-off-by: Adrian Bunk &lt;bunk@stusta.de&gt;
</content>
</entry>
</feed>
