"Stable" kernel 2.6.25.7 released
"Stable" kernel 2.6.25.7 released
Posted Jun 17, 2008 16:49 UTC (Tue) by PaXTeam (guest, #24616)In reply to: "Stable" kernel 2.6.25.7 released by mhalcrow
Parent article: Stable kernel 2.6.25.7 released
not quite. on 64 bit archs count = (size_t)(2^32-1) would pass the (ssize_t) count < 0 check whereas int in_size = size would still make it -1 and trigger the bug. in other words, you had two bugs, one of using a signed type for size and second, a truncation.
Posted Jun 17, 2008 17:53 UTC (Tue)
by mhalcrow (guest, #17371)
[Link] (1 responses)
Posted Jun 17, 2008 19:38 UTC (Tue)
by PaXTeam (guest, #24616)
[Link]
"Stable" kernel 2.6.25.7 released
> not quite. on 64 bit archs
>
> count = (size_t)(2^32-1)
>
> would pass the
>
> (ssize_t) count < 0
>
> check whereas
>
> int in_size = size
>
> would still make it -1 and trigger the bug.
This is the code:
---
#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count
)
{
struct inode *inode;
loff_t pos;
inode = file->f_path.dentry->d_inode;
if (unlikely((ssize_t) count < 0))
goto Einval;
pos = *ppos;
if (unlikely((pos < 0) || (loff_t) (pos + count) < 0))
goto Einval;
if (unlikely(inode->i_flock && mandatory_lock(inode))) {
int retval = locks_mandatory_area(
read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WR
ITE,
inode, file, pos, count);
if (retval < 0)
return retval;
}
return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
Einval:
return -EINVAL;
}
---
This function pegs the value returned to MAX_RW_COUNT, which is at most 0x7FFFFFFF (it will
actually be reduced to a page boundary). If count = 0xFFFFFFFF, then 0xFFFFFFFF > 0x7FFFFFFF,
so 0x7FFFFFFF is the largest value that can be returned from this function. This is the value
that gets passed to tpm_write() as a size_t data type (see vfs_write()).
"Stable" kernel 2.6.25.7 released
thanks, i missed the limiting at the end. still, this pattern is dangerous, someone had better
audit the code for it.