Bug#283241: kernel-image-2.6.8-1-k7: 2.6.8 and 2.6.9: utime(2) hangs on smbfs
This bug does not exist in the vanilla version of 2.6.8. A patch added somewhere in the Debian kernel-source-2.6.8 packages breaks it. I, however, cannot seem to find any patches that should touch smbfs, so I can't point it out. I just just rebuilt that particular module with the sources from kernel.org and everything works just as well as before. I believe this bug is severe enough to force a fix in Sarge! It renders smbfs TOTALLY useless. -- Sren Hansen [EMAIL PROTECTED] smime.p7s Description: S/MIME cryptographic signature
Bug#283241: kernel-image-2.6.8-1-k7: 2.6.8 and 2.6.9: utime(2) hangs on smbfs
Found the offending patch! It's called smbfs-overflow-fixes.dpatch. I've attached a patch that should fix the same overflow issues, but without breaking utime functionality. It's stolen from 2.6.10-ac7. :-) -- Sren Hansen [EMAIL PROTECTED] diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.10/fs/smbfs/proc.c linux-2.6.10/fs/smbfs/proc.c --- linux.vanilla-2.6.10/fs/smbfs/proc.c 2004-12-25 21:15:41.0 + +++ linux-2.6.10/fs/smbfs/proc.c 2004-12-26 23:03:13.0 + @@ -1427,9 +1427,9 @@ * So we must first calculate the amount of padding used by the server. */ data_off -= hdrlen; - if (data_off SMB_READX_MAX_PAD) { - PARANOIA(offset is larger than max pad!\n); - PARANOIA(%d %d\n, data_off, SMB_READX_MAX_PAD); + if (data_off SMB_READX_MAX_PAD || data_off 0) { + PARANOIA(offset is larger than SMB_READX_MAX_PAD or negative!\n); + PARANOIA(%d %d || %d 0\n, data_off, SMB_READX_MAX_PAD, data_off); req-rq_rlen = req-rq_bufsize + 1; return; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.10/fs/smbfs/request.c linux-2.6.10/fs/smbfs/request.c --- linux.vanilla-2.6.10/fs/smbfs/request.c 2004-12-25 21:15:41.0 + +++ linux-2.6.10/fs/smbfs/request.c 2004-12-26 23:06:24.0 + @@ -588,8 +588,18 @@ data_count = WVAL(inbuf, smb_drcnt); /* Modify offset for the split header/buffer we use */ - data_offset -= hdrlen; - parm_offset -= hdrlen; + if (data_count || data_offset) { + if (unlikely(data_offset hdrlen)) + goto out_bad_data; + else + data_offset -= hdrlen; + } + if (parm_count || parm_offset) { + if (unlikely(parm_offset hdrlen)) + goto out_bad_parm; + else + parm_offset -= hdrlen; + } if (parm_count == parm_tot data_count == data_tot) { /* @@ -600,18 +610,22 @@ * response that fits. */ VERBOSE(single trans2 response - dcnt=%d, pcnt=%d, doff=%d, poff=%d\n, + dcnt=%u, pcnt=%u, doff=%u, poff=%u\n, data_count, parm_count, data_offset, parm_offset); req-rq_ldata = data_count; req-rq_lparm = parm_count; req-rq_data = req-rq_buffer + data_offset; req-rq_parm = req-rq_buffer + parm_offset; + if (unlikely(parm_offset + parm_count req-rq_rlen)) + goto out_bad_parm; + if (unlikely(data_offset + data_count req-rq_rlen)) + goto out_bad_data; return 0; } VERBOSE(multi trans2 response - frag=%d, dcnt=%d, pcnt=%d, doff=%d, poff=%d\n, + frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n, req-rq_fragment, data_count, parm_count, data_offset, parm_offset); @@ -638,13 +652,15 @@ req-rq_parm = req-rq_trans2buffer; req-rq_data = req-rq_trans2buffer + parm_tot; - } else if (req-rq_total_data data_tot || - req-rq_total_parm parm_tot) + } else if (unlikely(req-rq_total_data data_tot || + req-rq_total_parm parm_tot)) goto out_data_grew; - if (parm_disp + parm_count req-rq_total_parm) + if (unlikely(parm_disp + parm_count req-rq_total_parm || + parm_offset + parm_count req-rq_rlen)) goto out_bad_parm; - if (data_disp + data_count req-rq_total_data) + if (unlikely(data_disp + data_count req-rq_total_data || + data_offset + data_count req-rq_rlen)) goto out_bad_data; inbuf = req-rq_buffer; @@ -666,10 +682,9 @@ return 1; out_too_long: - printk(KERN_ERR smb_trans2: data/param too long, data=%d, parm=%d\n, + printk(KERN_ERR smb_trans2: data/param too long, data=%u, parm=%u\n, data_tot, parm_tot); - req-rq_errno = -EIO; - goto out; + goto out_EIO; out_no_mem: printk(KERN_ERR smb_trans2: couldn't allocate data area of %d bytes\n, req-rq_trans2bufsize); @@ -677,16 +692,15 @@ goto out; out_data_grew: printk(KERN_ERR smb_trans2: data/params grew!\n); - req-rq_errno = -EIO; - goto out; + goto out_EIO; out_bad_parm: - printk(KERN_ERR smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n, - parm_disp, parm_count, parm_tot); - req-rq_errno = -EIO; - goto out; + printk(KERN_ERR smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n, + parm_disp, parm_count, parm_tot, parm_offset); + goto out_EIO; out_bad_data: - printk(KERN_ERR smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n, - data_disp, data_count, data_tot); + printk(KERN_ERR smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n, + data_disp, data_count, data_tot, data_offset); +out_EIO: req-rq_errno = -EIO; out: return req-rq_errno; smime.p7s Description: S/MIME cryptographic signature
Bug#283241: kernel-image-2.6.8-1-k7: 2.6.8 and 2.6.9: utime(2) hangs on smbfs
On Sat, Jan 08, 2005 at 06:36:27PM +0100, S?ren Hansen wrote: This bug does not exist in the vanilla version of 2.6.8. A patch added somewhere in the Debian kernel-source-2.6.8 packages breaks it. I, however, cannot seem to find any patches that should touch smbfs, so I can't point it out. I just just rebuilt that particular module with the sources from kernel.org and everything works just as well as before. I believe this bug is severe enough to force a fix in Sarge! It renders smbfs TOTALLY useless. -- S??ren Hansen [EMAIL PROTECTED] When merging to 2.6.10 I noticed we have a bunch of smbfs changes that were labelled security fixes. Can you try to rebuild the kernel (or just smbfs.ko) with the patch below reversed? #! /bin/sh -e ## PATCHNAME.dpatch by [EMAIL PROTECTED] ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Description: SMBfs overflow fixes ## DP: Patch author: unknown, stolen from -ac tree (probably Stefan Esser, Juan Quintela, and Urban Widmark) ## DP: Upstream status: unknown . $(dirname $0)/DPATCH @DPATCH@ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.9/fs/smbfs/proc.c linux-2.6.9/fs/smbfs/proc.c --- linux.vanilla-2.6.9/fs/smbfs/proc.c 2004-10-20 23:17:20.0 +0100 +++ linux-2.6.9/fs/smbfs/proc.c 2004-11-17 19:41:41.0 + @@ -1427,9 +1427,9 @@ * So we must first calculate the amount of padding used by the server. */ data_off -= hdrlen; - if (data_off SMB_READX_MAX_PAD) { - PARANOIA(offset is larger than max pad!\n); - PARANOIA(%d %d\n, data_off, SMB_READX_MAX_PAD); + if (data_off SMB_READX_MAX_PAD || data_off 0) { + PARANOIA(offset is larger than SMB_READX_MAX_PAD or negative!\n); + PARANOIA(%d %d || %d 0\n, data_off, SMB_READX_MAX_PAD, data_off); req-rq_rlen = req-rq_bufsize + 1; return; } diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.9/fs/smbfs/request.c linux-2.6.9/fs/smbfs/request.c --- linux.vanilla-2.6.9/fs/smbfs/request.c 2004-10-20 22:33:50.0 +0100 +++ linux-2.6.9/fs/smbfs/request.c 2004-11-17 19:41:41.0 + @@ -588,6 +588,10 @@ data_count = WVAL(inbuf, smb_drcnt); /* Modify offset for the split header/buffer we use */ + if (data_offset hdrlen) + goto out_bad_data; + if (parm_offset hdrlen) + goto out_bad_parm; data_offset -= hdrlen; parm_offset -= hdrlen; @@ -607,6 +611,10 @@ req-rq_lparm = parm_count; req-rq_data = req-rq_buffer + data_offset; req-rq_parm = req-rq_buffer + parm_offset; + if (parm_offset + parm_count req-rq_rlen) + goto out_bad_parm; + if (data_offset + data_count req-rq_rlen) + goto out_bad_data; return 0; } @@ -643,8 +652,12 @@ if (parm_disp + parm_count req-rq_total_parm) goto out_bad_parm; + if (parm_offset + parm_count req-rq_rlen) + goto out_bad_parm; if (data_disp + data_count req-rq_total_data) goto out_bad_data; + if (data_offset + data_count req-rq_rlen) + goto out_bad_data; inbuf = req-rq_buffer; memcpy(req-rq_parm + parm_disp, inbuf + parm_offset, parm_count); @@ -676,13 +692,13 @@ req-rq_errno = -EIO; goto out; out_bad_parm: - printk(KERN_ERR smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n, - parm_disp, parm_count, parm_tot); + printk(KERN_ERR smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d, ofs=%d\n, + parm_disp, parm_count, parm_tot, parm_offset); req-rq_errno = -EIO; goto out; out_bad_data: - printk(KERN_ERR smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n, - data_disp, data_count, data_tot); + printk(KERN_ERR smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d, ofs=%d\n, + data_disp, data_count, data_tot, data_offset); req-rq_errno = -EIO; out: return req-rq_errno;
Bug#283241: kernel-image-2.6.8-1-k7: 2.6.8 and 2.6.9: utime(2) hangs on smbfs
lr, 08 01 2005 kl. 19:35 +0100, skrev Christoph Hellwig: When merging to 2.6.10 I noticed we have a bunch of smbfs changes that were labelled security fixes. Can you try to rebuild the kernel (or just smbfs.ko) with the patch below reversed? Just as expected, that cleared it right up. The patch fixes some relevant issues, so I don't think it should just be rolled back. However, the patch, I attached to my previous mail should: * contain the overflow fixes, too * not break other stuff If you're not comfortable applying my patch, I could talk to Urban Widmark (the smbfs maintainer) and have him verify it ? -- Sren Hansen [EMAIL PROTECTED] smime.p7s Description: S/MIME cryptographic signature