From: Mark Huang Date: Mon, 8 Aug 2005 21:12:27 +0000 (+0000) Subject: Fedora Core 2 Updates 2.6.10-1.771_FC2 X-Git-Tag: fedora-2_6_10-1_771_FC2~1 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=c292415c3654d7ed363fee459e2e2ce0d09a8a53;p=linux-2.6.git Fedora Core 2 Updates 2.6.10-1.771_FC2 --- diff --git a/.config b/.config index dcb618288..c5250bc22 100644 --- a/.config +++ b/.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-ac11 -# Thu Feb 3 14:51:25 2005 +# Linux kernel version: 2.6.10-ac12 +# Wed May 18 16:34:50 2005 # CONFIG_X86=y CONFIG_MMU=y @@ -575,7 +575,7 @@ CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/.config.old b/.config.old index f11b8f03e..a4b55cf66 100644 --- a/.config.old +++ b/.config.old @@ -352,7 +352,7 @@ CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SPI_ATTRS=m diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 9c74c6030..d66ca9a70 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -22,6 +22,7 @@ #include #include +#include #include /* @@ -313,6 +314,8 @@ fastcall void smp_invalidate_interrupt(struct pt_regs *regs) unsigned long cpu; cpu = get_cpu(); + if (current->active_mm) + load_user_cs_desc(cpu, current->active_mm); if (!cpu_isset(cpu, flush_cpumask)) goto out; diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 7a67e3b63..7211494cc 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -568,7 +568,10 @@ void __init paging_init(void) set_nx(); if (nx_enabled) printk("NX (Execute Disable) protection: active\n"); + else #endif + if (exec_shield) + printk("Using x86 segment limits to approximate NX protection\n"); pagetable_init(); diff --git a/arch/i386/mm/mmap.c b/arch/i386/mm/mmap.c index 8ccbdab79..09a693d19 100644 --- a/arch/i386/mm/mmap.c +++ b/arch/i386/mm/mmap.c @@ -26,6 +26,7 @@ #include #include +#include /* * Top of mmap area (just below the process stack). @@ -38,13 +39,17 @@ static inline unsigned long mmap_base(struct mm_struct *mm) { unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; + unsigned long random_factor = 0; + + if (current->flags & PF_RELOCEXEC) + random_factor = get_random_int() % (1024*1024); if (gap < MIN_GAP) gap = MIN_GAP; else if (gap > MAX_GAP) gap = MAX_GAP; - return TASK_SIZE - (gap & PAGE_MASK); + return PAGE_ALIGN(TASK_SIZE - gap - random_factor); } /* @@ -57,9 +62,9 @@ void arch_pick_mmap_layout(struct mm_struct *mm) * Fall back to the standard layout if the personality * bit is set, or if the expected stack growth is unlimited: */ - if (sysctl_legacy_va_layout || + if ((exec_shield != 2) && (sysctl_legacy_va_layout || (current->personality & ADDR_COMPAT_LAYOUT) || - current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) { + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)){ mm->mmap_base = TASK_UNMAPPED_BASE; mm->get_unmapped_area = arch_get_unmapped_area; mm->unmap_area = arch_unmap_area; diff --git a/configs/kernel-2.6.10-i586-smp.config b/configs/kernel-2.6.10-i586-smp.config index 062b2338c..73f235f7c 100644 --- a/configs/kernel-2.6.10-i586-smp.config +++ b/configs/kernel-2.6.10-i586-smp.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-ac11 -# Thu Feb 3 14:51:24 2005 +# Linux kernel version: 2.6.10-ac12 +# Wed May 18 16:34:48 2005 # CONFIG_X86=y CONFIG_MMU=y @@ -583,7 +583,7 @@ CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/configs/kernel-2.6.10-i586.config b/configs/kernel-2.6.10-i586.config index 1172277d3..bf1fd48c5 100644 --- a/configs/kernel-2.6.10-i586.config +++ b/configs/kernel-2.6.10-i586.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-ac11 -# Thu Feb 3 14:51:24 2005 +# Linux kernel version: 2.6.10-ac12 +# Wed May 18 16:34:49 2005 # CONFIG_X86=y CONFIG_MMU=y @@ -574,7 +574,7 @@ CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/configs/kernel-2.6.10-i686-smp.config b/configs/kernel-2.6.10-i686-smp.config index b020c0d56..336dbbc6b 100644 --- a/configs/kernel-2.6.10-i686-smp.config +++ b/configs/kernel-2.6.10-i686-smp.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-ac11 -# Thu Feb 3 14:51:25 2005 +# Linux kernel version: 2.6.10-ac12 +# Wed May 18 16:34:49 2005 # CONFIG_X86=y CONFIG_MMU=y @@ -587,7 +587,7 @@ CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/configs/kernel-2.6.10-i686.config b/configs/kernel-2.6.10-i686.config index dcb618288..c5250bc22 100644 --- a/configs/kernel-2.6.10-i686.config +++ b/configs/kernel-2.6.10-i686.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-ac11 -# Thu Feb 3 14:51:25 2005 +# Linux kernel version: 2.6.10-ac12 +# Wed May 18 16:34:50 2005 # CONFIG_X86=y CONFIG_MMU=y @@ -575,7 +575,7 @@ CONFIG_CHR_DEV_SG=m # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h index 242e311a2..9a4d35377 100644 --- a/drivers/char/drm/drm_os_linux.h +++ b/drivers/char/drm/drm_os_linux.h @@ -96,9 +96,6 @@ static __inline__ int mtrr_del (int reg, unsigned long base, __copy_to_user(arg1, arg2, arg3) #define DRM_GET_USER_UNCHECKED(val, uaddr) \ __get_user(val, uaddr) -#define DRM_PUT_USER_UNCHECKED(uaddr, val) \ - __put_user(val, uaddr) - /** 'malloc' without the overhead of DRM(alloc)() */ #define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL) diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 5df72332e..77847e13c 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h @@ -892,25 +892,27 @@ do { \ } while (0) -#define OUT_RING_USER_TABLE( tab, sz ) do { \ +#define OUT_RING_TABLE( tab, sz ) do { \ int _size = (sz); \ - int __user *_tab = (tab); \ + int *_tab = (int *)(tab); \ \ if (write + _size > mask) { \ - int i = (mask+1) - write; \ - if (DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write), \ - _tab, i*4 )) \ - return DRM_ERR(EFAULT); \ + int _i = (mask+1) - write; \ + _size -= _i; \ + while (_i > 0 ) { \ + *(int *)(ring + write) = *_tab++; \ + write++; \ + _i--; \ + } \ write = 0; \ - _size -= i; \ - _tab += i; \ + _tab += _i; \ } \ \ - if (_size && DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write), \ - _tab, _size*4 )) \ - return DRM_ERR(EFAULT); \ - \ - write += _size; \ + while (_size > 0) { \ + *(ring + write) = *_tab++; \ + write++; \ + _size--; \ + } \ write &= mask; \ } while (0) diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index f3cc86eea..90bade6da 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c @@ -63,21 +63,6 @@ static __inline__ int radeon_check_and_fixup_offset( drm_radeon_private_t *dev_p return 0; } -static __inline__ int radeon_check_and_fixup_offset_user( drm_radeon_private_t *dev_priv, - drm_file_t *filp_priv, - u32 __user *offset ) { - u32 off; - - DRM_GET_USER_UNCHECKED( off, offset ); - - if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &off ) ) - return DRM_ERR( EINVAL ); - - DRM_PUT_USER_UNCHECKED( offset, off ); - - return 0; -} - static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv, drm_file_t *filp_priv, int id, @@ -85,18 +70,18 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ switch ( id ) { case RADEON_EMIT_PP_MISC: - if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, - &data[( RADEON_RB3D_DEPTHOFFSET - - RADEON_PP_MISC ) / 4] ) ) { + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &data[( RADEON_RB3D_DEPTHOFFSET + - RADEON_PP_MISC ) / 4] ) ) { DRM_ERROR( "Invalid depth buffer offset\n" ); return DRM_ERR( EINVAL ); } break; case RADEON_EMIT_PP_CNTL: - if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, - &data[( RADEON_RB3D_COLOROFFSET - - RADEON_PP_CNTL ) / 4] ) ) { + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &data[( RADEON_RB3D_COLOROFFSET + - RADEON_PP_CNTL ) / 4] ) ) { DRM_ERROR( "Invalid colour buffer offset\n" ); return DRM_ERR( EINVAL ); } @@ -108,8 +93,8 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ case R200_EMIT_PP_TXOFFSET_3: case R200_EMIT_PP_TXOFFSET_4: case R200_EMIT_PP_TXOFFSET_5: - if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, - &data[0] ) ) { + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &data[0] ) ) { DRM_ERROR( "Invalid R200 texture offset\n" ); return DRM_ERR( EINVAL ); } @@ -118,9 +103,9 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ case RADEON_EMIT_PP_TXFILTER_0: case RADEON_EMIT_PP_TXFILTER_1: case RADEON_EMIT_PP_TXFILTER_2: - if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, - &data[( RADEON_PP_TXOFFSET_0 - - RADEON_PP_TXFILTER_0 ) / 4] ) ) { + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &data[( RADEON_PP_TXOFFSET_0 + - RADEON_PP_TXFILTER_0 ) / 4] ) ) { DRM_ERROR( "Invalid R100 texture offset\n" ); return DRM_ERR( EINVAL ); } @@ -134,9 +119,8 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ case R200_EMIT_PP_CUBIC_OFFSETS_5: { int i; for ( i = 0; i < 5; i++ ) { - if ( radeon_check_and_fixup_offset_user( dev_priv, - filp_priv, - &data[i] ) ) { + if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, + &data[i] ) ) { DRM_ERROR( "Invalid R200 cubic texture offset\n" ); return DRM_ERR( EINVAL ); } @@ -219,17 +203,11 @@ static __inline__ int radeon_check_and_fixup_packet3( drm_radeon_private_t *dev_ drm_file_t *filp_priv, drm_radeon_cmd_buffer_t *cmdbuf, unsigned int *cmdsz ) { - u32 tmp[4]; - u32 __user *cmd = (u32 __user *)cmdbuf->buf; - - if ( DRM_COPY_FROM_USER_UNCHECKED( tmp, cmd, sizeof( tmp ) ) ) { - DRM_ERROR( "Failed to copy data from user space\n" ); - return DRM_ERR( EFAULT ); - } + u32 *cmd = (u32 *) cmdbuf->buf; - *cmdsz = 2 + ( ( tmp[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 ); + *cmdsz = 2 + ( ( cmd[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 ); - if ( ( tmp[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) { + if ( ( cmd[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) { DRM_ERROR( "Not a type 3 packet\n" ); return DRM_ERR( EINVAL ); } @@ -240,32 +218,27 @@ static __inline__ int radeon_check_and_fixup_packet3( drm_radeon_private_t *dev_ } /* Check client state and fix it up if necessary */ - if ( tmp[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */ + if ( cmd[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */ u32 offset; - if ( tmp[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL + if ( cmd[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { - offset = tmp[2] << 10; + offset = cmd[2] << 10; if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { DRM_ERROR( "Invalid first packet offset\n" ); return DRM_ERR( EINVAL ); } - tmp[2] = ( tmp[2] & 0xffc00000 ) | offset >> 10; + cmd[2] = ( cmd[2] & 0xffc00000 ) | offset >> 10; } - if ( ( tmp[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) && - ( tmp[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { - offset = tmp[3] << 10; + if ( ( cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) && + ( cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { + offset = cmd[3] << 10; if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { DRM_ERROR( "Invalid second packet offset\n" ); return DRM_ERR( EINVAL ); } - tmp[3] = ( tmp[3] & 0xffc00000 ) | offset >> 10; - } - - if ( DRM_COPY_TO_USER_UNCHECKED( cmd, tmp, sizeof( tmp ) ) ) { - DRM_ERROR( "Failed to copy data to user space\n" ); - return DRM_ERR( EFAULT ); + cmd[3] = ( cmd[3] & 0xffc00000 ) | offset >> 10; } } @@ -2084,7 +2057,7 @@ static int radeon_emit_packets( { int id = (int)header.packet.packet_id; int sz, reg; - int __user *data = (int __user *)cmdbuf->buf; + int *data = (int *)cmdbuf->buf; RING_LOCALS; if (id >= RADEON_MAX_STATE_PACKETS) @@ -2105,7 +2078,7 @@ static int radeon_emit_packets( BEGIN_RING(sz+1); OUT_RING( CP_PACKET0( reg, (sz-1) ) ); - OUT_RING_USER_TABLE( data, sz ); + OUT_RING_TABLE( data, sz ); ADVANCE_RING(); cmdbuf->buf += sz * sizeof(int); @@ -2119,7 +2092,6 @@ static __inline__ int radeon_emit_scalars( drm_radeon_cmd_buffer_t *cmdbuf ) { int sz = header.scalars.count; - int __user *data = (int __user *)cmdbuf->buf; int start = header.scalars.offset; int stride = header.scalars.stride; RING_LOCALS; @@ -2128,7 +2100,7 @@ static __inline__ int radeon_emit_scalars( OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); - OUT_RING_USER_TABLE( data, sz ); + OUT_RING_TABLE( cmdbuf->buf, sz ); ADVANCE_RING(); cmdbuf->buf += sz * sizeof(int); cmdbuf->bufsz -= sz * sizeof(int); @@ -2143,7 +2115,6 @@ static __inline__ int radeon_emit_scalars2( drm_radeon_cmd_buffer_t *cmdbuf ) { int sz = header.scalars.count; - int __user *data = (int __user *)cmdbuf->buf; int start = ((unsigned int)header.scalars.offset) + 0x100; int stride = header.scalars.stride; RING_LOCALS; @@ -2152,7 +2123,7 @@ static __inline__ int radeon_emit_scalars2( OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); - OUT_RING_USER_TABLE( data, sz ); + OUT_RING_TABLE( cmdbuf->buf, sz ); ADVANCE_RING(); cmdbuf->buf += sz * sizeof(int); cmdbuf->bufsz -= sz * sizeof(int); @@ -2165,7 +2136,6 @@ static __inline__ int radeon_emit_vectors( drm_radeon_cmd_buffer_t *cmdbuf ) { int sz = header.vectors.count; - int __user *data = (int __user *)cmdbuf->buf; int start = header.vectors.offset; int stride = header.vectors.stride; RING_LOCALS; @@ -2174,7 +2144,7 @@ static __inline__ int radeon_emit_vectors( OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); - OUT_RING_USER_TABLE( data, sz ); + OUT_RING_TABLE( cmdbuf->buf, sz ); ADVANCE_RING(); cmdbuf->buf += sz * sizeof(int); @@ -2189,7 +2159,6 @@ static int radeon_emit_packet3( drm_device_t *dev, { drm_radeon_private_t *dev_priv = dev->dev_private; unsigned int cmdsz; - int __user *cmd = (int __user *)cmdbuf->buf; int ret; RING_LOCALS; @@ -2202,7 +2171,7 @@ static int radeon_emit_packet3( drm_device_t *dev, } BEGIN_RING( cmdsz ); - OUT_RING_USER_TABLE( cmd, cmdsz ); + OUT_RING_TABLE( cmdbuf->buf, cmdsz ); ADVANCE_RING(); cmdbuf->buf += cmdsz * 4; @@ -2219,7 +2188,6 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, drm_radeon_private_t *dev_priv = dev->dev_private; drm_clip_rect_t box; unsigned int cmdsz; - int __user *cmd = (int __user *)cmdbuf->buf; int ret; drm_clip_rect_t __user *boxes = cmdbuf->boxes; int i = 0; @@ -2238,7 +2206,7 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, do { if ( i < cmdbuf->nbox ) { - if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) + if (DRM_COPY_FROM_USER( &box, &boxes[i], sizeof(box) )) return DRM_ERR(EFAULT); /* FIXME The second and subsequent times round * this loop, send a WAIT_UNTIL_3D_IDLE before @@ -2261,7 +2229,7 @@ static int radeon_emit_packet3_cliprect( drm_device_t *dev, } BEGIN_RING( cmdsz ); - OUT_RING_USER_TABLE( cmd, cmdsz ); + OUT_RING_TABLE( cmdbuf->buf, cmdsz ); ADVANCE_RING(); } while ( ++i < cmdbuf->nbox ); @@ -2314,7 +2282,8 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) int idx; drm_radeon_cmd_buffer_t cmdbuf; drm_radeon_cmd_header_t header; - int orig_nbox; + int orig_nbox, orig_bufsz; + char *kbuf=NULL; LOCK_TEST_WITH_RETURN( dev, filp ); @@ -2331,24 +2300,29 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); + if (cmdbuf.bufsz > 64*1024 || cmdbuf.bufsz<0) { + return DRM_ERR(EINVAL); + } - if (DRM_VERIFYAREA_READ( cmdbuf.buf, cmdbuf.bufsz )) - return DRM_ERR(EFAULT); - - if (cmdbuf.nbox && - DRM_VERIFYAREA_READ(cmdbuf.boxes, - cmdbuf.nbox * sizeof(drm_clip_rect_t))) - return DRM_ERR(EFAULT); + /* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid + * races between checking values and using those values in other code, + * and simply to avoid a lot of function calls to copy in data. + */ + orig_bufsz = cmdbuf.bufsz; + if (orig_bufsz != 0) { + kbuf = kmalloc(cmdbuf.bufsz, GFP_KERNEL); + if (kbuf == NULL) + return DRM_ERR(ENOMEM); + if (DRM_COPY_FROM_USER(kbuf, cmdbuf.buf, cmdbuf.bufsz)) + return DRM_ERR(EFAULT); + cmdbuf.buf = kbuf; + } orig_nbox = cmdbuf.nbox; while ( cmdbuf.bufsz >= sizeof(header) ) { - - if (DRM_GET_USER_UNCHECKED( header.i, (int __user *)cmdbuf.buf )) { - DRM_ERROR("__get_user %p\n", cmdbuf.buf); - return DRM_ERR(EFAULT); - } + header.i = *(int *)cmdbuf.buf; cmdbuf.buf += sizeof(header); cmdbuf.bufsz -= sizeof(header); @@ -2357,7 +2331,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) DRM_DEBUG("RADEON_CMD_PACKET\n"); if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) { DRM_ERROR("radeon_emit_packets failed\n"); - return DRM_ERR(EINVAL); + goto err; } break; @@ -2365,7 +2339,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) DRM_DEBUG("RADEON_CMD_SCALARS\n"); if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { DRM_ERROR("radeon_emit_scalars failed\n"); - return DRM_ERR(EINVAL); + goto err; } break; @@ -2373,7 +2347,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) DRM_DEBUG("RADEON_CMD_VECTORS\n"); if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { DRM_ERROR("radeon_emit_vectors failed\n"); - return DRM_ERR(EINVAL); + goto err; } break; @@ -2383,14 +2357,14 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) if ( idx < 0 || idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", idx, dma->buf_count - 1 ); - return DRM_ERR(EINVAL); + goto err; } buf = dma->buflist[idx]; if ( buf->filp != filp || buf->pending ) { DRM_ERROR( "bad buffer %p %p %d\n", buf->filp, filp, buf->pending); - return DRM_ERR(EINVAL); + goto err; } radeon_cp_discard_buffer( dev, buf ); @@ -2400,7 +2374,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) DRM_DEBUG("RADEON_CMD_PACKET3\n"); if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) { DRM_ERROR("radeon_emit_packet3 failed\n"); - return DRM_ERR(EINVAL); + goto err; } break; @@ -2408,7 +2382,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) { DRM_ERROR("radeon_emit_packet3_clip failed\n"); - return DRM_ERR(EINVAL); + goto err; } break; @@ -2416,7 +2390,7 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) DRM_DEBUG("RADEON_CMD_SCALARS2\n"); if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) { DRM_ERROR("radeon_emit_scalars2 failed\n"); - return DRM_ERR(EINVAL); + goto err; } break; @@ -2424,21 +2398,28 @@ int radeon_cp_cmdbuf( DRM_IOCTL_ARGS ) DRM_DEBUG("RADEON_CMD_WAIT\n"); if (radeon_emit_wait( dev, header.wait.flags )) { DRM_ERROR("radeon_emit_wait failed\n"); - return DRM_ERR(EINVAL); + goto err; } break; default: DRM_ERROR("bad cmd_type %d at %p\n", header.header.cmd_type, cmdbuf.buf - sizeof(header)); - return DRM_ERR(EINVAL); + goto err; } } + if (orig_bufsz != 0) + kfree(kbuf); DRM_DEBUG("DONE\n"); COMMIT_RING(); return 0; + +err: + if (orig_bufsz != 0) + kfree(kbuf); + return DRM_ERR(EINVAL); } diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 19bacae29..367f12d6c 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -556,7 +556,7 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf) info = &mxvar_table[n]; /*if (verbose) */ { printk(KERN_DEBUG " ttyM%d - ttyM%d ", n, n + hwconf->ports - 1); - printk(KERN_DEBUG " max. baud rate = %d bps.\n", hwconf->MaxCanSetBaudRate[0]); + printk(" max. baud rate = %d bps.\n", hwconf->MaxCanSetBaudRate[0]); } for (i = 0; i < hwconf->ports; i++, n++, info++) { @@ -609,18 +609,12 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf) n = board * MXSER_PORTS_PER_BOARD; info = &mxvar_table[n]; - spin_lock_irqsave(&info->slock, flags); retval = request_irq(hwconf->irq, mxser_interrupt, IRQ_T(info), "mxser", info); if (retval) { - spin_unlock_irqrestore(&info->slock, flags); printk(KERN_ERR "Board %d: %s", board, mxser_brdname[hwconf->board_type - 1]); printk(" Request irq fail,IRQ (%d) may be conflit with another device.\n", info->irq); return retval; } - - spin_unlock_irqrestore(&info->slock, flags); - - return 0; } @@ -2144,10 +2138,9 @@ intr_old: mxvar_log.rxcnt[info->port] += cnt; info->mon_data.rxcnt += cnt; info->mon_data.up_rxcnt += cnt; - - tty->ldisc.receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count); spin_unlock_irqrestore(&info->slock, flags); - + + tty_flip_buffer_push(tty); } static void mxser_transmit_chars(struct mxser_struct *info) diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index a29dffd94..64a729419 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -1143,13 +1143,13 @@ static inline int copy_from_read_buf(struct tty_struct *tty, { int retval; - ssize_t n; + size_t n; unsigned long flags; retval = 0; spin_lock_irqsave(&tty->read_lock, flags); n = min(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail); - n = min((ssize_t)*nr, n); + n = min(*nr, n); spin_unlock_irqrestore(&tty->read_lock, flags); if (n) { mb(); diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index a41704185..8eb4c417f 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1155,8 +1155,8 @@ static inline void pty_line_name(struct tty_driver *driver, int index, char *p) int i = index + driver->name_base; /* ->name is initialized to "ttyp", but "tty" is expected */ sprintf(p, "%s%c%x", - driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name, - ptychar[i >> 4 & 0xf], i & 0xf); + driver->subtype == PTY_TYPE_SLAVE ? "pty" : driver->name, + ptychar[i >> 4 & 0xf], i & 0xf); } static inline void tty_line_name(struct tty_driver *driver, int index, char *p) diff --git a/drivers/md/md.c b/drivers/md/md.c index 812ae23b2..82afc7937 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -336,8 +336,6 @@ static int sync_page_io(struct block_device *bdev, sector_t sector, int size, struct completion event; int ret; - bio_get(bio); - rw |= (1 << BIO_RW_SYNC); bio->bi_bdev = bdev; diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index e8be5a26d..73ecae14c 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -1000,7 +1000,7 @@ static void async_lcp_peek(struct asyncppp *ap, unsigned char *data, data += 4; dlen -= 4; /* data[0] is code, data[1] is length */ - while (dlen >= 2 && dlen >= data[1]) { + while (dlen >= 2 && dlen >= data[1] && data[1] >= 2) { switch (data[0]) { case LCP_MRU: val = (data[2] << 8) + data[3]; diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 7b5303bef..70cf37210 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -1100,15 +1100,18 @@ static void set_rx_mode(struct net_device *dev) entry = tp->cur_tx++ % TX_RING_SIZE; if (entry != 0) { - /* Avoid a chip errata by prefixing a dummy entry. */ - tp->tx_buffers[entry].skb = NULL; - tp->tx_buffers[entry].mapping = 0; - tp->tx_ring[entry].length = - (entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0; - tp->tx_ring[entry].buffer1 = 0; - /* Must set DescOwned later to avoid race with chip */ - dummy = entry; - entry = tp->cur_tx++ % TX_RING_SIZE; + /* Avoid a chip errata by prefixing a dummy entry. Don't do + this on the ULI526X as it triggers a different problem */ + if (!(tp->chip_id == ULI526X && (tp->revision = 0x40 || tp->revision == 0x50))) { + tp->tx_buffers[entry].skb = NULL; + tp->tx_buffers[entry].mapping = 0; + tp->tx_ring[entry].length = + (entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0; + tp->tx_ring[entry].buffer1 = 0; + /* Must set DescOwned later to avoid race with chip */ + dummy = entry; + entry = tp->cur_tx++ % TX_RING_SIZE; + } } tp->tx_buffers[entry].skb = NULL; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index d0fe0f656..4b66e7e69 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -177,7 +177,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t len = count; if (!(tun->flags & TUN_NO_PI)) { - if ((len -= sizeof(pi)) > len) + if ((len -= sizeof(pi)) > count) return -EINVAL; if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) diff --git a/drivers/net/wireless/ieee80211/ieee80211_tx.c b/drivers/net/wireless/ieee80211/ieee80211_tx.c index abf5401e4..da0002056 100644 --- a/drivers/net/wireless/ieee80211/ieee80211_tx.c +++ b/drivers/net/wireless/ieee80211/ieee80211_tx.c @@ -223,7 +223,7 @@ struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, if (!txb) return NULL; - memset(txb, sizeof(struct ieee80211_txb), 0); + memset(txb, 0, sizeof(struct ieee80211_txb)); txb->nr_frags = nr_frags; txb->frag_size = txb_size; diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 9b340d991..44095f7d8 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -63,6 +63,7 @@ static struct { {"MAXTOR", "XT-4170S", "B5A", BLIST_NOLUN}, /* locks up */ {"MAXTOR", "XT-8760S", "B7B", BLIST_NOLUN}, /* locks up */ {"MEDIAVIS", "RENO CD-ROMX2A", "2.03", BLIST_NOLUN}, /* responds to all lun */ + {"MICROTEK", "ScanMakerIII", "2.30", BLIST_NOLUN}, /* responds to all lun */ {"NEC", "CD-ROM DRIVE:841", "1.0", BLIST_NOLUN},/* locks up */ {"PHILIPS", "PCA80SC", "V4-2", BLIST_NOLUN}, /* responds to all lun */ {"RODIME", "RO3000S", "2.33", BLIST_NOLUN}, /* locks up */ @@ -121,7 +122,10 @@ static struct { {"3PARdata", "VV", NULL, BLIST_REPORTLUN2}, {"ADAPTEC", "AACRAID", NULL, BLIST_FORCELUN}, {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN}, + {"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN}, + {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_FORCELUN | BLIST_INQUIRY_36}, {"CANON", "IPUBJD", NULL, BLIST_SPARSELUN}, + {"CBOX3", "USB Storage-SMC", "300A", BLIST_FORCELUN | BLIST_INQUIRY_36}, {"CMD", "CRA-7280", NULL, BLIST_SPARSELUN}, /* CMD RAID Controller */ {"CNSI", "G7324", NULL, BLIST_SPARSELUN}, /* Chaparral G7324 RAID */ {"CNSi", "G8324", NULL, BLIST_SPARSELUN}, /* Chaparral G8324 RAID */ @@ -142,6 +146,9 @@ static struct { {"EMC", "SYMMETRIX", NULL, BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN}, {"EMULEX", "MD21/S2 ESDI", NULL, BLIST_SINGLELUN}, {"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN | BLIST_INQUIRY_36}, + {"Generic", "USB Storage-SMC", "0180", BLIST_FORCELUN | BLIST_INQUIRY_36}, + {"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN | BLIST_INQUIRY_36}, {"HITACHI", "DF400", "*", BLIST_SPARSELUN}, {"HITACHI", "DF500", "*", BLIST_SPARSELUN}, {"HITACHI", "DF600", "*", BLIST_SPARSELUN}, @@ -172,17 +179,18 @@ static struct { {"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NRC", "MBR-7", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"NRC", "MBR-7.4", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, - {"OTi", "CF CARD Reader", "2.00", BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-600", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, + {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, {"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */ {"SEAGATE", "ST3390N", "9546", BLIST_NOTQ}, {"SGI", "RAID3", "*", BLIST_SPARSELUN}, {"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "TP9100", "*", BLIST_REPORTLUN2}, {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, + {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36}, {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ {"SUN", "T300", "*", BLIST_SPARSELUN}, @@ -190,48 +198,13 @@ static struct { {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN}, {"TOSHIBA", "CDROM", NULL, BLIST_ISROM}, {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM}, + {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, {"WangDAT", "Model 2600", "01.7", BLIST_SELECT_NO_ATN}, {"WangDAT", "Model 3200", "02.2", BLIST_SELECT_NO_ATN}, {"WangDAT", "Model 1300", "02.4", BLIST_SELECT_NO_ATN}, {"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"Zzyzx", "RocketStor 500S", NULL, BLIST_SPARSELUN}, {"Zzyzx", "RocketStor 2000", NULL, BLIST_SPARSELUN}, - - /* - * USB multi card readers. - */ - {"AFT", "CF PRO-9XP", "9144", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"CBOX3", "USB Storage-SMC", "300A", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"DMI", "MultiFlash", "3.00", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"eUSB", "Compact Flash", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"GENERIC", "Card Reader CF", "v26F", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"General", "USB Disk Drive","1.00", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"Generic", "USB Storage-SMC", "0090", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"Generic", "USB Storage-SMC", "0180", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"Generic", "USB Storage-SMC", "0207", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"generic", "USB Storage-SMC", "0207", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"IC", "USB Storage-CFC", "322E", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"ICSI", "SD Card", "2.7C", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"IOI", "Media Bay", "*", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"Lexar", "Media Inc. SM/xD", "009E", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"Lexar", "USB Storage-SMC", "I18A", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"Medion", "Flash XL MMC/SD", "2.6D", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"OEI-USB", "CompactFlash", "1.01", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"OEI-USB2", "CompactFlash", "2.00", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"SMSC", "223 U HS-CF", "1.95", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"SMSC", "USB 2 HS-CF", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"TwinMOS", "7-in-1 Card RWCF", "0100", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"USB2.0", "CardReader CF RW", "0.0>", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"USB2.0", "CardReader SM RW", "0814", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"USB2.0", "CF CardReader", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"Y-E DATA", "CF Card Reader", "1.03", BLIST_FORCELUN | BLIST_INQUIRY_36}, - {"Zynet", "USB Storage-SMC", "I03A", BLIST_FORCELUN | BLIST_INQUIRY_36}, - { NULL, NULL, NULL, 0 }, }; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 161c52f2e..44cc03fe0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -70,12 +70,12 @@ MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs"); * otherwise the new scheme is used. If that fails and "use_both_schemes" * is set, then the driver will make another attempt, using the other scheme. */ -static int old_scheme_first = 0; +static int old_scheme_first = 1; module_param(old_scheme_first, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(old_scheme_first, "start with the old device initialization scheme"); -static int use_both_schemes = 0; +static int use_both_schemes = 1; module_param(use_both_schemes, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(use_both_schemes, "try the other device initialization scheme if the " diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 151814f82..a9928b729 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -775,7 +775,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) * Turn off the CS limit completely if exec-shield disabled or * NX active: */ - if (!exec_shield || executable_stack != EXSTACK_DISABLE_X) + if (!exec_shield || executable_stack != EXSTACK_DISABLE_X || nx_enabled) arch_add_exec_range(current->mm, -1); #endif @@ -797,7 +797,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) /* Do this immediately, since STACK_TOP as used in setup_arg_pages may depend on the personality. */ SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter); - if (elf_read_implies_exec(loc->elf_ex, have_pt_gnu_stack)) + if (exec_shield != 2 && + elf_read_implies_exec(loc->elf_ex, have_pt_gnu_stack)) current->personality |= READ_IMPLIES_EXEC; arch_pick_mmap_layout(current->mm); @@ -1052,6 +1053,7 @@ out_free_ph: static int load_elf_library(struct file *file) { struct elf_phdr *elf_phdata; + struct elf_phdr *eppnt; unsigned long elf_bss, bss, len; int retval, error, i, j; struct elfhdr elf_ex; @@ -1075,41 +1077,44 @@ static int load_elf_library(struct file *file) /* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */ error = -ENOMEM; - elf_phdata = (struct elf_phdr *) kmalloc(j, GFP_KERNEL); + elf_phdata = kmalloc(j, GFP_KERNEL); if (!elf_phdata) goto out; + eppnt = elf_phdata; error = -ENOEXEC; - retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata, j); + retval = kernel_read(file, elf_ex.e_phoff, (char *)eppnt, j); if (retval != j) goto out_free_ph; for (j = 0, i = 0; ip_type == PT_LOAD) j++; + if ((eppnt + i)->p_type == PT_LOAD) + j++; if (j != 1) goto out_free_ph; - while (elf_phdata->p_type != PT_LOAD) elf_phdata++; + while (eppnt->p_type != PT_LOAD) + eppnt++; /* Now use mmap to map the library into memory. */ down_write(¤t->mm->mmap_sem); error = do_mmap(file, - ELF_PAGESTART(elf_phdata->p_vaddr), - (elf_phdata->p_filesz + - ELF_PAGEOFFSET(elf_phdata->p_vaddr)), + ELF_PAGESTART(eppnt->p_vaddr), + (eppnt->p_filesz + + ELF_PAGEOFFSET(eppnt->p_vaddr)), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, - (elf_phdata->p_offset - - ELF_PAGEOFFSET(elf_phdata->p_vaddr))); + (eppnt->p_offset - + ELF_PAGEOFFSET(eppnt->p_vaddr))); up_write(¤t->mm->mmap_sem); - if (error != ELF_PAGESTART(elf_phdata->p_vaddr)) + if (error != ELF_PAGESTART(eppnt->p_vaddr)) goto out_free_ph; - elf_bss = elf_phdata->p_vaddr + elf_phdata->p_filesz; + elf_bss = eppnt->p_vaddr + eppnt->p_filesz; padzero(elf_bss); - len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr + ELF_MIN_ALIGN - 1); - bss = elf_phdata->p_memsz + elf_phdata->p_vaddr; + len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); + bss = eppnt->p_memsz + eppnt->p_vaddr; if (bss > len) do_brk(len, bss - len); error = 0; diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 23099366a..6c285efa2 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -70,6 +70,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod inode->i_data.a_ops = &cramfs_aops; } else { inode->i_size = 0; + inode->i_blocks = 0; init_special_inode(inode, inode->i_mode, old_decode_dev(cramfs_inode->size)); } diff --git a/fs/eventpoll.c b/fs/eventpoll.c index b11ab1a9c..28ecd4ddf 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -619,6 +619,7 @@ eexit_1: return error; } +#define MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) /* * Implement the event wait interface for the eventpoll file. It is the kernel @@ -635,7 +636,7 @@ asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, current, epfd, events, maxevents, timeout)); /* The maximum number of event must be greater than zero */ - if (maxevents <= 0) + if (maxevents <= 0 || maxevents > MAX_EVENTS) return -EINVAL; /* Verify that the area passed by the user is writeable */ diff --git a/fs/exec.c b/fs/exec.c index 9f70b89a0..f3629a232 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -791,7 +791,7 @@ void get_task_comm(char *buf, struct task_struct *tsk) { /* buf must be at least sizeof(tsk->comm) in size */ task_lock(tsk); - memcpy(buf, tsk->comm, sizeof(tsk->comm)); + strncpy(buf, tsk->comm, sizeof(tsk->comm)); task_unlock(tsk); } diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 64ccc7c86..06f3fb691 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -592,6 +592,7 @@ int ext2_make_empty(struct inode *inode, struct inode *parent) goto fail; } kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr, 0, chunk_size); de = (struct ext2_dir_entry_2 *)kaddr; de->name_len = 1; de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1)); diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 0ee7beb9d..b9256e65e 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -685,6 +685,8 @@ root_found: sbi->s_log_zone_size = isonum_723 (h_pri->logical_block_size); sbi->s_max_size = isonum_733(h_pri->volume_space_size); } else { + if (!pri) + goto out_freebh; rootp = (struct iso_directory_record *) pri->root_directory_record; sbi->s_nzones = isonum_733 (pri->volume_space_size); sbi->s_log_zone_size = isonum_723 (pri->logical_block_size); @@ -1395,6 +1397,9 @@ struct inode *isofs_iget(struct super_block *sb, struct inode *inode; struct isofs_iget5_callback_data data; + if (offset >= 1ul << sb->s_blocksize_bits) + return NULL; + data.block = block; data.offset = offset; diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 19d999fd4..8bdd3e409 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -53,6 +53,7 @@ if(LEN & 1) LEN++; \ CHR = ((unsigned char *) DE) + LEN; \ LEN = *((unsigned char *) DE) - LEN; \ + if (LEN<0) LEN=0; \ if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1) \ { \ LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset; \ @@ -73,6 +74,10 @@ offset1 = 0; \ pbh = sb_bread(DEV->i_sb, block); \ if(pbh){ \ + if (offset > pbh->b_size || offset + cont_size > pbh->b_size){ \ + brelse(pbh); \ + goto out; \ + } \ memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \ brelse(pbh); \ chr = (unsigned char *) buffer; \ @@ -103,12 +108,13 @@ int get_rock_ridge_filename(struct iso_directory_record * de, struct rock_ridge * rr; int sig; - while (len > 1){ /* There may be one byte for padding somewhere */ + while (len > 2){ /* There may be one byte for padding somewhere */ rr = (struct rock_ridge *) chr; - if (rr->len == 0) goto out; /* Something got screwed up here */ + if (rr->len < 3) goto out; /* Something got screwed up here */ sig = isonum_721(chr); chr += rr->len; len -= rr->len; + if (len < 0) goto out; /* corrupted isofs */ switch(sig){ case SIG('R','R'): @@ -122,6 +128,7 @@ int get_rock_ridge_filename(struct iso_directory_record * de, break; case SIG('N','M'): if (truncate) break; + if (rr->len < 5) break; /* * If the flags are 2 or 4, this indicates '.' or '..'. * We don't want to do anything with this, because it @@ -186,12 +193,13 @@ parse_rock_ridge_inode_internal(struct iso_directory_record *de, struct rock_ridge * rr; int rootflag; - while (len > 1){ /* There may be one byte for padding somewhere */ + while (len > 2){ /* There may be one byte for padding somewhere */ rr = (struct rock_ridge *) chr; - if (rr->len == 0) goto out; /* Something got screwed up here */ + if (rr->len < 3) goto out; /* Something got screwed up here */ sig = isonum_721(chr); chr += rr->len; len -= rr->len; + if (len < 0) goto out; /* corrupted isofs */ switch(sig){ #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ @@ -462,7 +470,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) struct rock_ridge *rr; if (!ISOFS_SB(inode->i_sb)->s_rock) - panic ("Cannot have symlink with high sierra variant of iso filesystem\n"); + goto error; block = ei->i_iget5_block; lock_kernel(); @@ -487,13 +495,15 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) SETUP_ROCK_RIDGE(raw_inode, chr, len); repeat: - while (len > 1) { /* There may be one byte for padding somewhere */ + while (len > 2) { /* There may be one byte for padding somewhere */ rr = (struct rock_ridge *) chr; - if (rr->len == 0) + if (rr->len < 3) goto out; /* Something got screwed up here */ sig = isonum_721(chr); chr += rr->len; len -= rr->len; + if (len < 0) + goto out; /* corrupted isofs */ switch (sig) { case SIG('R', 'R'): @@ -543,6 +553,7 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page) fail: brelse(bh); unlock_kernel(); + error: SetPageError(page); kunmap(page); unlock_page(page); diff --git a/fs/proc/generic.c b/fs/proc/generic.c index d1985331f..6c4936a38 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -60,7 +60,7 @@ proc_file_read(struct file *file, char __user *buf, size_t nbytes, return -ENOMEM; while ((nbytes > 0) && !eof) { - count = min_t(ssize_t, PROC_BLOCK_SIZE, nbytes); + count = min_t(size_t, PROC_BLOCK_SIZE, nbytes); start = NULL; if (dp->get_info) { diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 36a4ce1a6..def2511df 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -23,9 +23,6 @@ char *task_mem(struct mm_struct *mm, char *buffer) "StaBrk:\t%08lx kB\n" "Brk:\t%08lx kB\n" "StaStk:\t%08lx kB\n" -#if __i386__ - "ExecLim:\t%08lx\n" -#endif , (mm->total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), mm->locked_vm << (PAGE_SHIFT-10), @@ -33,11 +30,12 @@ char *task_mem(struct mm_struct *mm, char *buffer) data << (PAGE_SHIFT-10), mm->stack_vm << (PAGE_SHIFT-10), text, lib, (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10, - mm->start_brk, mm->brk, mm->start_stack + mm->start_brk, mm->brk, mm->start_stack); #if __i386__ - , mm->context.exec_limit + if (!nx_enabled) + buffer += sprintf(buffer, + "ExecLim:\t%08lx\n", mm->context.exec_limit); #endif - ); return buffer; } @@ -59,6 +57,9 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, static int show_map(struct seq_file *m, void *v) { +#ifdef __i386__ + struct task_struct *task = m->private; +#endif struct vm_area_struct *map = v; struct file *file = map->vm_file; int flags = map->vm_flags; @@ -77,7 +78,13 @@ static int show_map(struct seq_file *m, void *v) map->vm_end, flags & VM_READ ? 'r' : '-', flags & VM_WRITE ? 'w' : '-', - flags & VM_EXEC ? 'x' : '-', + (flags & VM_EXEC +#ifdef __i386__ + || (!nx_enabled && + (map->vm_start < task->mm->context.exec_limit)) +#endif + ) + ? 'x' : '-', flags & VM_MAYSHARE ? 's' : 'p', map->vm_pgoff << PAGE_SHIFT, MAJOR(dev), MINOR(dev), ino, &len); diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index b46b75f91..8a774f9d1 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -588,7 +588,7 @@ error_exit: /* Unlock pages prepared by reiserfs_prepare_file_region_for_write */ void reiserfs_unprepare_pages(struct page **prepared_pages, /* list of locked pages */ - int num_pages /* amount of pages */) { + size_t num_pages /* amount of pages */) { int i; // loop counter for (i=0; i < num_pages ; i++) { @@ -619,7 +619,7 @@ int reiserfs_copy_from_user_to_file_region( int offset; // offset in page for ( i = 0, offset = (pos & (PAGE_CACHE_SIZE-1)); i < num_pages ; i++,offset=0) { - int count = min_t(int,PAGE_CACHE_SIZE-offset,write_bytes); // How much of bytes to write to this page + size_t count = min_t(size_t,PAGE_CACHE_SIZE-offset,write_bytes); // How much of bytes to write to this page struct page *page=prepared_pages[i]; // Current page we process. fault_in_pages_readable( buf, count); @@ -718,8 +718,8 @@ int reiserfs_submit_file_region_for_write( struct reiserfs_transaction_handle *th, struct inode *inode, loff_t pos, /* Writing position offset */ - int num_pages, /* Number of pages to write */ - int write_bytes, /* number of bytes to write */ + size_t num_pages, /* Number of pages to write */ + size_t write_bytes, /* number of bytes to write */ struct page **prepared_pages /* list of pages */ ) { @@ -854,9 +854,9 @@ int reiserfs_check_for_tail_and_convert( struct inode *inode, /* inode to deal w int reiserfs_prepare_file_region_for_write( struct inode *inode /* Inode of the file */, loff_t pos, /* position in the file */ - int num_pages, /* number of pages to + size_t num_pages, /* number of pages to prepare */ - int write_bytes, /* Amount of bytes to be + size_t write_bytes, /* Amount of bytes to be overwritten from @pos */ struct page **prepared_pages /* pointer to array @@ -1252,10 +1252,9 @@ ssize_t reiserfs_file_write( struct file *file, /* the file we are going to writ while ( count > 0) { /* This is the main loop in which we running until some error occures or until we write all of the data. */ - int num_pages;/* amount of pages we are going to write this iteration */ - int write_bytes; /* amount of bytes to write during this iteration */ - int blocks_to_allocate; /* how much blocks we need to allocate for - this iteration */ + size_t num_pages;/* amount of pages we are going to write this iteration */ + size_t write_bytes; /* amount of bytes to write during this iteration */ + size_t blocks_to_allocate; /* how much blocks we need to allocate for this iteration */ /* (pos & (PAGE_CACHE_SIZE-1)) is an idiom for offset into a page of pos*/ num_pages = !!((pos+count) & (PAGE_CACHE_SIZE - 1)) + /* round up partial @@ -1269,7 +1268,7 @@ ssize_t reiserfs_file_write( struct file *file, /* the file we are going to writ /* If we were asked to write more data than we want to or if there is not that much space, then we shorten amount of data to write for this iteration. */ - num_pages = min_t(int, REISERFS_WRITE_PAGES_AT_A_TIME, reiserfs_can_fit_pages(inode->i_sb)); + num_pages = min_t(size_t, REISERFS_WRITE_PAGES_AT_A_TIME, reiserfs_can_fit_pages(inode->i_sb)); /* Also we should not forget to set size in bytes accordingly */ write_bytes = (num_pages << PAGE_CACHE_SHIFT) - (pos & (PAGE_CACHE_SIZE-1)); @@ -1295,7 +1294,7 @@ ssize_t reiserfs_file_write( struct file *file, /* the file we are going to writ // But overwriting files on absolutelly full volumes would not // be very efficient. Well, people are not supposed to fill // 100% of disk space anyway. - write_bytes = min_t(int, count, inode->i_sb->s_blocksize - (pos & (inode->i_sb->s_blocksize - 1))); + write_bytes = min_t(size_t, count, inode->i_sb->s_blocksize - (pos & (inode->i_sb->s_blocksize - 1))); num_pages = 1; // No blocks were claimed before, so do it now. reiserfs_claim_blocks_to_be_allocated(inode->i_sb, 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)); diff --git a/include/asm-x86_64/mmu_context.h b/include/asm-x86_64/mmu_context.h index 671e7573b..8f80f1570 100644 --- a/include/asm-x86_64/mmu_context.h +++ b/include/asm-x86_64/mmu_context.h @@ -54,10 +54,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, out_of_line_bug(); if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) { /* We were in lazy tlb mode and leave_mm disabled - * tlb flush IPI delivery. We must reload CR3 - * to make sure to use no freed page tables. + * tlb flush IPI delivery. We must flush our tlb. */ - asm volatile("movq %0,%%cr3" :: "r" (__pa(next->pgd)) : "memory"); + local_flush_tlb(); load_LDT_nolock(&next->context, cpu); } } diff --git a/include/linux/autoconf.h b/include/linux/autoconf.h index ffeeef48a..1754b854b 100644 --- a/include/linux/autoconf.h +++ b/include/linux/autoconf.h @@ -1,7 +1,7 @@ /* * Automatically generated C config: don't edit - * Linux kernel version: 2.6.10-ac11 - * Thu Feb 3 14:51:25 2005 + * Linux kernel version: 2.6.10-ac12 + * Wed May 18 16:34:50 2005 */ #define AUTOCONF_INCLUDED #define CONFIG_X86 1 @@ -576,7 +576,7 @@ /* * Some SCSI devices (e.g. CD jukebox) support multiple LUNs */ -#undef CONFIG_SCSI_MULTI_LUN +#define CONFIG_SCSI_MULTI_LUN 1 #define CONFIG_SCSI_CONSTANTS 1 #define CONFIG_SCSI_LOGGING 1 diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index afa5e0495..5977bd5f2 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h @@ -278,10 +278,9 @@ extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack); /* Fake conntrack entry for untracked connections */ extern struct ip_conntrack ip_conntrack_untracked; -extern int ip_ct_no_defrag; /* Returns new sk_buff, or NULL */ struct sk_buff * -ip_ct_gather_frags(struct sk_buff *skb); +ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user); /* Delete all conntracks which match. */ extern void diff --git a/include/net/ip.h b/include/net/ip.h index 15a1c6a2e..0a1699227 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -253,9 +253,24 @@ extern int ip_call_ra_chain(struct sk_buff *skb); /* * Functions provided by ip_fragment.o */ - -struct sk_buff *ip_defrag(struct sk_buff *skb); -extern void ipfrag_flush(void); + +enum ip_defrag_users +{ + IP_DEFRAG_LOCAL_DELIVER, + IP_DEFRAG_CALL_RA_CHAIN, + IP_DEFRAG_CONNTRACK_IN, + IP_DEFRAG_CONNTRACK_OUT, + IP_DEFRAG_NAT_OUT, + IP_DEFRAG_VS_IN, + IP_DEFRAG_VS_OUT, + IP_DEFRAG_VS_FWD, + __IP_DEFRAG_DYNAMIC_FIRST, + __IP_DEFRAG_DYNAMIC_LAST = (__IP_DEFRAG_DYNAMIC_FIRST + 32) - 1, +}; + +struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user); +extern int ip_defrag_user_id_alloc(void); +extern void ip_defrag_user_id_free(int user); extern int ip_frag_nqueues; extern atomic_t ip_frag_mem; diff --git a/mm/mmap.c b/mm/mmap.c index e4e814a5d..59591b366 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1433,11 +1433,11 @@ int expand_stack(struct vm_area_struct * vma, unsigned long address) address &= PAGE_MASK; grow = (address - vma->vm_end) >> PAGE_SHIFT; - /* Someone beat us to it */ - if (grow <= 0) { + if(address < vma->vm_end) { anon_vma_unlock(vma); return 0; } + /* Overcommit.. */ if (security_vm_enough_memory(grow)) { anon_vma_unlock(vma); @@ -1507,11 +1507,11 @@ int expand_stack(struct vm_area_struct *vma, unsigned long address) address &= PAGE_MASK; grow = (vma->vm_start - address) >> PAGE_SHIFT; - /* Someone beat us to it */ - if (grow <= 0) { + if (address >= vma->vm_start) { anon_vma_unlock(vma); return 0; } + /* Overcommit.. */ if (security_vm_enough_memory(grow)) { anon_vma_unlock(vma); diff --git a/net/atm/addr.c b/net/atm/addr.c index 96407a0bb..f7029ebf7 100644 --- a/net/atm/addr.c +++ b/net/atm/addr.c @@ -114,7 +114,7 @@ int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr) } -int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,int size) +int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,size_t size) { unsigned long flags; struct atm_dev_addr *walk; diff --git a/net/atm/addr.h b/net/atm/addr.h index 2affa3a12..3099d21fe 100644 --- a/net/atm/addr.h +++ b/net/atm/addr.h @@ -13,6 +13,6 @@ void atm_reset_addr(struct atm_dev *dev); int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr); int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr); -int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,int size); +int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc __user *buf,size_t size); #endif diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 8ff58bc2b..064641c96 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -64,7 +64,7 @@ static kmem_cache_t *bt_sock_cache; int bt_sock_register(int proto, struct net_proto_family *ops) { - if (proto >= BT_MAX_PROTO) + if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; if (bt_proto[proto]) @@ -77,7 +77,7 @@ EXPORT_SYMBOL(bt_sock_register); int bt_sock_unregister(int proto) { - if (proto >= BT_MAX_PROTO) + if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; if (!bt_proto[proto]) @@ -92,7 +92,7 @@ static int bt_sock_create(struct socket *sock, int proto) { int err = 0; - if (proto >= BT_MAX_PROTO) + if (proto < 0 || proto >= BT_MAX_PROTO) return -EINVAL; #if defined(CONFIG_KMOD) diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 441a522ec..02961c551 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -73,6 +73,7 @@ struct ipfrag_skb_cb struct ipq { struct ipq *next; /* linked list pointers */ struct list_head lru_list; /* lru list member */ + u32 user; u32 saddr; u32 daddr; u16 id; @@ -243,13 +244,13 @@ static void ipq_kill(struct ipq *ipq) /* Memory limiting on fragments. Evictor trashes the oldest * fragment queue until we are back under the threshold. */ -static void __ip_evictor(int threshold) +static void ip_evictor(void) { struct ipq *qp; struct list_head *tmp; int work; - work = atomic_read(&ip_frag_mem) - threshold; + work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh; if (work <= 0) return; @@ -274,11 +275,6 @@ static void __ip_evictor(int threshold) } } -static inline void ip_evictor(void) -{ - __ip_evictor(sysctl_ipfrag_low_thresh); -} - /* * Oops, a fragment queue timed out. Kill it and send an ICMP reply. */ @@ -325,7 +321,8 @@ static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) if(qp->id == qp_in->id && qp->saddr == qp_in->saddr && qp->daddr == qp_in->daddr && - qp->protocol == qp_in->protocol) { + qp->protocol == qp_in->protocol && + qp->user == qp_in->user) { atomic_inc(&qp->refcnt); write_unlock(&ipfrag_lock); qp_in->last_in |= COMPLETE; @@ -352,7 +349,7 @@ static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) } /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ -static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph) +static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) { struct ipq *qp; @@ -364,6 +361,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph) qp->id = iph->id; qp->saddr = iph->saddr; qp->daddr = iph->daddr; + qp->user = user; qp->len = 0; qp->meat = 0; qp->fragments = NULL; @@ -386,7 +384,7 @@ out_nomem: /* Find the correct entry in the "incomplete datagrams" queue for * this IP datagram, and create new one, if nothing is found. */ -static inline struct ipq *ip_find(struct iphdr *iph) +static inline struct ipq *ip_find(struct iphdr *iph, u32 user) { __u16 id = iph->id; __u32 saddr = iph->saddr; @@ -400,7 +398,8 @@ static inline struct ipq *ip_find(struct iphdr *iph) if(qp->id == id && qp->saddr == saddr && qp->daddr == daddr && - qp->protocol == protocol) { + qp->protocol == protocol && + qp->user == user) { atomic_inc(&qp->refcnt); read_unlock(&ipfrag_lock); return qp; @@ -408,7 +407,7 @@ static inline struct ipq *ip_find(struct iphdr *iph) } read_unlock(&ipfrag_lock); - return ip_frag_create(hash, iph); + return ip_frag_create(hash, iph, user); } /* Add new segment to existing queue. */ @@ -642,7 +641,7 @@ out_fail: } /* Process an incoming IP datagram fragment. */ -struct sk_buff *ip_defrag(struct sk_buff *skb) +struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user) { struct iphdr *iph = skb->nh.iph; struct ipq *qp; @@ -657,7 +656,7 @@ struct sk_buff *ip_defrag(struct sk_buff *skb) dev = skb->dev; /* Lookup (or create) queue header */ - if ((qp = ip_find(iph)) != NULL) { + if ((qp = ip_find(iph, user)) != NULL) { struct sk_buff *ret = NULL; spin_lock(&qp->lock); @@ -678,6 +677,29 @@ struct sk_buff *ip_defrag(struct sk_buff *skb) return NULL; } +static unsigned long ip_defrag_id_bitmap; + +int ip_defrag_user_id_alloc(void) +{ + int i; + + for (i = 0; i < 32; i++) { + if (!test_and_set_bit(i, &ip_defrag_id_bitmap)) + return i + __IP_DEFRAG_DYNAMIC_FIRST; + } + + return -ENFILE; +} +EXPORT_SYMBOL(ip_defrag_user_id_alloc); + +void ip_defrag_user_id_free(int user) +{ + user -= __IP_DEFRAG_DYNAMIC_FIRST; + if (user >= 0 && user < 32) + clear_bit(user, &ip_defrag_id_bitmap); +} +EXPORT_SYMBOL(ip_defrag_user_id_free); + void ipfrag_init(void) { ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^ @@ -689,10 +711,4 @@ void ipfrag_init(void) add_timer(&ipfrag_secret_timer); } -void ipfrag_flush(void) -{ - __ip_evictor(0); -} - EXPORT_SYMBOL(ip_defrag); -EXPORT_SYMBOL(ipfrag_flush); diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index f2e88193d..51069c0b5 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -172,7 +172,7 @@ int ip_call_ra_chain(struct sk_buff *skb) (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == skb->dev->ifindex)) { if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - skb = ip_defrag(skb); + skb = ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN); if (skb == NULL) { read_unlock(&ip_ra_lock); return 1; @@ -273,7 +273,7 @@ int ip_local_deliver(struct sk_buff *skb) */ if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - skb = ip_defrag(skb); + skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER); if (!skb) return 0; } diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index d223d1251..360765aa5 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -389,6 +389,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->priority = from->priority; to->protocol = from->protocol; to->security = from->security; + dst_release(to->dst); to->dst = dst_clone(from->dst); to->dev = from->dev; diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index 168e5b342..9b91d916c 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c @@ -545,9 +545,9 @@ u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) } static inline struct sk_buff * -ip_vs_gather_frags(struct sk_buff *skb) +ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user) { - skb = ip_defrag(skb); + skb = ip_defrag(skb, user); if (skb) ip_send_check(skb->nh.iph); return skb; @@ -621,7 +621,7 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related) /* reassemble IP fragments */ if (skb->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) { - skb = ip_vs_gather_frags(skb); + skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT); if (!skb) return NF_STOLEN; *pskb = skb; @@ -760,7 +760,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb, /* reassemble IP fragments */ if (unlikely(iph->frag_off & __constant_htons(IP_MF|IP_OFFSET) && !pp->dont_defrag)) { - skb = ip_vs_gather_frags(skb); + skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT); if (!skb) return NF_STOLEN; iph = skb->nh.iph; @@ -865,7 +865,8 @@ check_for_ip_vs_out(struct sk_buff **pskb, int (*okfn)(struct sk_buff *)) * forward to the right destination host if relevant. * Currently handles error types - unreachable, quench, ttl exceeded. */ -static int ip_vs_in_icmp(struct sk_buff **pskb, int *related) +static int +ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum) { struct sk_buff *skb = *pskb; struct iphdr *iph; @@ -879,7 +880,9 @@ static int ip_vs_in_icmp(struct sk_buff **pskb, int *related) /* reassemble IP fragments */ if (skb->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) { - skb = ip_vs_gather_frags(skb); + skb = ip_vs_gather_frags(skb, + hooknum == NF_IP_LOCAL_IN ? + IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD); if (!skb) return NF_STOLEN; *pskb = skb; @@ -988,7 +991,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb, iph = skb->nh.iph; if (unlikely(iph->protocol == IPPROTO_ICMP)) { - int related, verdict = ip_vs_in_icmp(pskb, &related); + int related, verdict = ip_vs_in_icmp(pskb, &related, hooknum); if (related) return verdict; @@ -1083,7 +1086,7 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff **pskb, if ((*pskb)->nh.iph->protocol != IPPROTO_ICMP) return NF_ACCEPT; - return ip_vs_in_icmp(pskb, &r); + return ip_vs_in_icmp(pskb, &r, hooknum); } diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index d14a4e342..2097bce4d 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -1113,29 +1113,22 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct, } } -int ip_ct_no_defrag; - /* Returns new sk_buff, or NULL */ struct sk_buff * -ip_ct_gather_frags(struct sk_buff *skb) +ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user) { struct sock *sk = skb->sk; #ifdef CONFIG_NETFILTER_DEBUG unsigned int olddebug = skb->nf_debug; #endif - if (unlikely(ip_ct_no_defrag)) { - kfree_skb(skb); - return NULL; - } - if (sk) { sock_hold(sk); skb_orphan(skb); } local_bh_disable(); - skb = ip_defrag(skb); + skb = ip_defrag(skb, user); local_bh_enable(); if (!skb) { diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 083f0327c..3cebf98de 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -381,7 +381,10 @@ static unsigned int ip_conntrack_defrag(unsigned int hooknum, /* Gather fragments. */ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - *pskb = ip_ct_gather_frags(*pskb); + *pskb = ip_ct_gather_frags(*pskb, + hooknum == NF_IP_PRE_ROUTING ? + IP_DEFRAG_CONNTRACK_IN : + IP_DEFRAG_CONNTRACK_OUT); if (!*pskb) return NF_STOLEN; } @@ -811,12 +814,6 @@ static int init_or_cleanup(int init) cleanup_defraglocalops: nf_unregister_hook(&ip_conntrack_defrag_local_out_ops); cleanup_defragops: - /* Frag queues may hold fragments with skb->dst == NULL */ - ip_ct_no_defrag = 1; - synchronize_net(); - local_bh_disable(); - ipfrag_flush(); - local_bh_enable(); nf_unregister_hook(&ip_conntrack_defrag_ops); cleanup_proc_stat: #ifdef CONFIG_PROC_FS diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 71bd2e05b..bf6667218 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -202,7 +202,7 @@ ip_nat_out(unsigned int hooknum, I'm starting to have nightmares about fragments. */ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - *pskb = ip_ct_gather_frags(*pskb); + *pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT); if (!*pskb) return NF_STOLEN; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index ed31c5320..a92e47c5a 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -463,6 +463,7 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->priority = from->priority; to->protocol = from->protocol; to->security = from->security; + dst_release(to->dst); to->dst = dst_clone(from->dst); to->dev = from->dev; diff --git a/scripts/basic/.docproc.cmd b/scripts/basic/.docproc.cmd index 951e11532..92e9d62c2 100644 --- a/scripts/basic/.docproc.cmd +++ b/scripts/basic/.docproc.cmd @@ -6,7 +6,7 @@ deps_scripts/basic/docproc := \ /usr/include/features.h \ /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stddef.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ /usr/include/bits/typesizes.h \ @@ -15,7 +15,7 @@ deps_scripts/basic/docproc := \ /usr/include/wchar.h \ /usr/include/bits/wchar.h \ /usr/include/gconv.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ @@ -40,8 +40,8 @@ deps_scripts/basic/docproc := \ /usr/include/bits/posix_opt.h \ /usr/include/bits/confname.h \ /usr/include/getopt.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/limits.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/syslimits.h \ /usr/include/limits.h \ /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h \ diff --git a/scripts/basic/.fixdep.cmd b/scripts/basic/.fixdep.cmd index 0fd3ed01e..f758b4f93 100644 --- a/scripts/basic/.fixdep.cmd +++ b/scripts/basic/.fixdep.cmd @@ -13,7 +13,7 @@ deps_scripts/basic/fixdep := \ /usr/include/gnu/stubs.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/time.h \ /usr/include/endian.h \ @@ -46,12 +46,12 @@ deps_scripts/basic/fixdep := \ /usr/include/wchar.h \ /usr/include/bits/wchar.h \ /usr/include/gconv.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/limits.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/syslimits.h \ /usr/include/limits.h \ /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h \ diff --git a/scripts/basic/.split-include.cmd b/scripts/basic/.split-include.cmd index f0039a33f..ae15eed82 100644 --- a/scripts/basic/.split-include.cmd +++ b/scripts/basic/.split-include.cmd @@ -9,7 +9,7 @@ deps_scripts/basic/split-include := \ /usr/include/gnu/stubs.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/time.h \ /usr/include/bits/stat.h \ @@ -36,7 +36,7 @@ deps_scripts/basic/split-include := \ /usr/include/wchar.h \ /usr/include/bits/wchar.h \ /usr/include/gconv.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ diff --git a/scripts/basic/docproc b/scripts/basic/docproc index e8ccea0f8..9589fe939 100755 Binary files a/scripts/basic/docproc and b/scripts/basic/docproc differ diff --git a/scripts/basic/fixdep b/scripts/basic/fixdep index 2c719e2d0..bd4b08155 100755 Binary files a/scripts/basic/fixdep and b/scripts/basic/fixdep differ diff --git a/scripts/basic/split-include b/scripts/basic/split-include index e8361c80d..b1f790e94 100755 Binary files a/scripts/basic/split-include and b/scripts/basic/split-include differ diff --git a/scripts/kconfig/.conf.o.cmd b/scripts/kconfig/.conf.o.cmd index 8544ec631..3fa04573f 100644 --- a/scripts/kconfig/.conf.o.cmd +++ b/scripts/kconfig/.conf.o.cmd @@ -9,7 +9,7 @@ deps_scripts/kconfig/conf.o := \ /usr/include/gnu/stubs.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/endian.h \ /usr/include/bits/endian.h \ @@ -41,11 +41,11 @@ deps_scripts/kconfig/conf.o := \ /usr/include/wchar.h \ /usr/include/bits/wchar.h \ /usr/include/gconv.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdbool.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdbool.h \ scripts/kconfig/lkc_proto.h \ scripts/kconfig/conf.o: $(deps_scripts/kconfig/conf.o) diff --git a/scripts/kconfig/.mconf.o.cmd b/scripts/kconfig/.mconf.o.cmd index 8066b1cc5..0e0cd7bcc 100644 --- a/scripts/kconfig/.mconf.o.cmd +++ b/scripts/kconfig/.mconf.o.cmd @@ -18,7 +18,7 @@ deps_scripts/kconfig/mconf.o := \ /usr/include/bits/sigset.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/bits/signum.h \ /usr/include/time.h \ @@ -48,14 +48,14 @@ deps_scripts/kconfig/mconf.o := \ /usr/include/sys/select.h \ /usr/include/bits/select.h \ /usr/include/sys/sysmacros.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/limits.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/syslimits.h \ /usr/include/limits.h \ /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/bits/posix2_lim.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdarg.h \ /usr/include/stdlib.h \ /usr/include/alloca.h \ /usr/include/string.h \ @@ -79,7 +79,7 @@ deps_scripts/kconfig/mconf.o := \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/sys_errlist.h \ /usr/include/bits/stdio.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdbool.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdbool.h \ scripts/kconfig/lkc_proto.h \ scripts/kconfig/mconf.o: $(deps_scripts/kconfig/mconf.o) diff --git a/scripts/kconfig/.zconf.tab.o.cmd b/scripts/kconfig/.zconf.tab.o.cmd index c5e604147..db6f48a60 100644 --- a/scripts/kconfig/.zconf.tab.o.cmd +++ b/scripts/kconfig/.zconf.tab.o.cmd @@ -8,11 +8,11 @@ deps_scripts/kconfig/zconf.tab.o := \ /usr/include/gnu/stubs.h \ /usr/include/bits/types.h \ /usr/include/bits/wordsize.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stddef.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stddef.h \ /usr/include/bits/typesizes.h \ /usr/include/endian.h \ /usr/include/bits/endian.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdarg.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdarg.h \ /usr/include/stdio.h \ /usr/include/libio.h \ /usr/include/_G_config.h \ @@ -36,7 +36,7 @@ deps_scripts/kconfig/zconf.tab.o := \ /usr/include/string.h \ /usr/include/bits/string.h \ /usr/include/bits/string2.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/stdbool.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/stdbool.h \ scripts/kconfig/lkc.h \ scripts/kconfig/expr.h \ scripts/kconfig/lkc_proto.h \ @@ -45,8 +45,8 @@ deps_scripts/kconfig/zconf.tab.o := \ /usr/include/bits/errno.h \ /usr/include/linux/errno.h \ /usr/include/asm/errno.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/limits.h \ - /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/include/syslimits.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/limits.h \ + /usr/lib/gcc/i386-redhat-linux/3.4.3/include/syslimits.h \ /usr/include/limits.h \ /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h \ diff --git a/scripts/kconfig/conf b/scripts/kconfig/conf index fa67007f0..ebb75062a 100755 Binary files a/scripts/kconfig/conf and b/scripts/kconfig/conf differ diff --git a/scripts/kconfig/conf.o b/scripts/kconfig/conf.o index efffb8b00..12f77f07b 100644 Binary files a/scripts/kconfig/conf.o and b/scripts/kconfig/conf.o differ diff --git a/scripts/kconfig/mconf.o b/scripts/kconfig/mconf.o index 1e30d9036..5c13a3e59 100644 Binary files a/scripts/kconfig/mconf.o and b/scripts/kconfig/mconf.o differ diff --git a/scripts/kconfig/zconf.tab.o b/scripts/kconfig/zconf.tab.o index 5c3941053..d64063af3 100644 Binary files a/scripts/kconfig/zconf.tab.o and b/scripts/kconfig/zconf.tab.o differ