/[linux-patches]/genpatches-2.6/historical/2.6.10/1110_smbfs-dos-fix.patch
Gentoo

Contents of /genpatches-2.6/historical/2.6.10/1110_smbfs-dos-fix.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations) (download) (as text)
Sat Jun 11 23:16:54 2005 UTC (15 years, 1 month ago) by dsd
File MIME type: text/x-diff
File size: 5325 byte(s)
Import historical releases
1 dsd 2 From: Chuck Ebbert <76306.1226@compuserve.com>
2     Subject: [PATCH] SMB security fixes for 2.6.9
3     To: Alan Cox <alan@lxorguk.ukuu.org.uk>
4     Cc: linux-kernel <linux-kernel@vger.kernel.org>
5     Message-ID: <200411222138_MC3-1-8F38-414@compuserve.com>
6    
7     The SMB patch in 2.6.9-ac10 is broken. When a reply is received and it
8     contains no data (only parms), the data_offset is zero. Since no data will
9     be copied, zero offset is perfectly valid. This patch, based on the one in
10     -ac, works for me. I also cleaned up the message printing (%u vs. %d for
11     unsigned), added unlikely() where appropriate, and removed some extra code.
12    
13     Comments welcome. Like I said, at least I can use SMB servers now.
14     With the original patch very bad things happened, like trying to save
15     files from a text editor truncated them to 0 bytes, followed by editor
16     freezing for many seconds then asking for a new name to save the file as.
17    
18     Rediff.
19    
20     diff -X dontdiff -urNp linux-2.6.10/fs/smbfs/proc.c linux-dsd/fs/smbfs/proc.c
21     --- linux-2.6.10/fs/smbfs/proc.c 2004-12-24 21:34:00.000000000 +0000
22     +++ linux-dsd/fs/smbfs/proc.c 2005-01-13 22:58:21.681636192 +0000
23     @@ -1427,9 +1427,9 @@ smb_proc_readX_data(struct smb_request *
24     * So we must first calculate the amount of padding used by the server.
25     */
26     data_off -= hdrlen;
27     - if (data_off > SMB_READX_MAX_PAD) {
28     - PARANOIA("offset is larger than max pad!\n");
29     - PARANOIA("%d > %d\n", data_off, SMB_READX_MAX_PAD);
30     + if (data_off > SMB_READX_MAX_PAD || data_off < 0) {
31     + PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n");
32     + PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off);
33     req->rq_rlen = req->rq_bufsize + 1;
34     return;
35     }
36     diff -X dontdiff -urNp linux-2.6.10/fs/smbfs/request.c linux-dsd/fs/smbfs/request.c
37     --- linux-2.6.10/fs/smbfs/request.c 2004-12-24 21:35:40.000000000 +0000
38     +++ linux-dsd/fs/smbfs/request.c 2005-01-13 23:03:51.295527264 +0000
39     @@ -588,8 +588,18 @@ static int smb_recv_trans2(struct smb_sb
40     data_count = WVAL(inbuf, smb_drcnt);
41    
42     /* Modify offset for the split header/buffer we use */
43     - data_offset -= hdrlen;
44     - parm_offset -= hdrlen;
45     + if (data_count || data_offset) {
46     + if (unlikely(data_offset < hdrlen))
47     + goto out_bad_data;
48     + else
49     + data_offset -= hdrlen;
50     + }
51     + if (parm_count || parm_offset) {
52     + if (unlikely(parm_offset < hdrlen))
53     + goto out_bad_parm;
54     + else
55     + parm_offset -= hdrlen;
56     + }
57    
58     if (parm_count == parm_tot && data_count == data_tot) {
59     /*
60     @@ -600,18 +610,22 @@ static int smb_recv_trans2(struct smb_sb
61     * response that fits.
62     */
63     VERBOSE("single trans2 response "
64     - "dcnt=%d, pcnt=%d, doff=%d, poff=%d\n",
65     + "dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
66     data_count, parm_count,
67     data_offset, parm_offset);
68     req->rq_ldata = data_count;
69     req->rq_lparm = parm_count;
70     req->rq_data = req->rq_buffer + data_offset;
71     req->rq_parm = req->rq_buffer + parm_offset;
72     + if (unlikely(parm_offset + parm_count > req->rq_rlen))
73     + goto out_bad_parm;
74     + if (unlikely(data_offset + data_count > req->rq_rlen))
75     + goto out_bad_data;
76     return 0;
77     }
78    
79     VERBOSE("multi trans2 response "
80     - "frag=%d, dcnt=%d, pcnt=%d, doff=%d, poff=%d\n",
81     + "frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
82     req->rq_fragment,
83     data_count, parm_count,
84     data_offset, parm_offset);
85     @@ -638,13 +652,15 @@ static int smb_recv_trans2(struct smb_sb
86    
87     req->rq_parm = req->rq_trans2buffer;
88     req->rq_data = req->rq_trans2buffer + parm_tot;
89     - } else if (req->rq_total_data < data_tot ||
90     - req->rq_total_parm < parm_tot)
91     + } else if (unlikely(req->rq_total_data < data_tot ||
92     + req->rq_total_parm < parm_tot))
93     goto out_data_grew;
94    
95     - if (parm_disp + parm_count > req->rq_total_parm)
96     + if (unlikely(parm_disp + parm_count > req->rq_total_parm ||
97     + parm_offset + parm_count > req->rq_rlen))
98     goto out_bad_parm;
99     - if (data_disp + data_count > req->rq_total_data)
100     + if (unlikely(data_disp + data_count > req->rq_total_data ||
101     + data_offset + data_count > req->rq_rlen))
102     goto out_bad_data;
103    
104     inbuf = req->rq_buffer;
105     @@ -666,10 +682,9 @@ static int smb_recv_trans2(struct smb_sb
106     return 1;
107    
108     out_too_long:
109     - printk(KERN_ERR "smb_trans2: data/param too long, data=%d, parm=%d\n",
110     + printk(KERN_ERR "smb_trans2: data/param too long, data=%u, parm=%u\n",
111     data_tot, parm_tot);
112     - req->rq_errno = -EIO;
113     - goto out;
114     + goto out_EIO;
115     out_no_mem:
116     printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n",
117     req->rq_trans2bufsize);
118     @@ -677,16 +692,15 @@ out_no_mem:
119     goto out;
120     out_data_grew:
121     printk(KERN_ERR "smb_trans2: data/params grew!\n");
122     - req->rq_errno = -EIO;
123     - goto out;
124     + goto out_EIO;
125     out_bad_parm:
126     - printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n",
127     - parm_disp, parm_count, parm_tot);
128     - req->rq_errno = -EIO;
129     - goto out;
130     + printk(KERN_ERR "smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
131     + parm_disp, parm_count, parm_tot, parm_offset);
132     + goto out_EIO;
133     out_bad_data:
134     - printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n",
135     - data_disp, data_count, data_tot);
136     + printk(KERN_ERR "smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
137     + data_disp, data_count, data_tot, data_offset);
138     +out_EIO:
139     req->rq_errno = -EIO;
140     out:
141     return req->rq_errno;

  ViewVC Help
Powered by ViewVC 1.1.20