Annotation of /trunk/kernel26-magellan-server/patches-2.6.25-r5/0116-2.6.25.17-all-fixes.patch
Parent Directory | Revision Log
Revision 677 -
(hide annotations)
(download)
Wed Sep 10 21:27:27 2008 UTC (16 years ago) by niro
File size: 22098 byte(s)
Wed Sep 10 21:27:27 2008 UTC (16 years ago) by niro
File size: 22098 byte(s)
2.6.25-magellan-r5: - updated to linux-2.6.25.17
1 | niro | 677 | diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c |
2 | index 3e18db4..f49c970 100644 | ||
3 | --- a/arch/x86/kernel/cpu/mtrr/generic.c | ||
4 | +++ b/arch/x86/kernel/cpu/mtrr/generic.c | ||
5 | @@ -229,6 +229,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, | ||
6 | unsigned long *size, mtrr_type *type) | ||
7 | { | ||
8 | unsigned int mask_lo, mask_hi, base_lo, base_hi; | ||
9 | + unsigned int tmp, hi; | ||
10 | |||
11 | rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); | ||
12 | if ((mask_lo & 0x800) == 0) { | ||
13 | @@ -242,8 +243,18 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, | ||
14 | rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi); | ||
15 | |||
16 | /* Work out the shifted address mask. */ | ||
17 | - mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT) | ||
18 | - | mask_lo >> PAGE_SHIFT; | ||
19 | + tmp = mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT; | ||
20 | + mask_lo = size_or_mask | tmp; | ||
21 | + /* Expand tmp with high bits to all 1s*/ | ||
22 | + hi = fls(tmp); | ||
23 | + if (hi > 0) { | ||
24 | + tmp |= ~((1<<(hi - 1)) - 1); | ||
25 | + | ||
26 | + if (tmp != mask_lo) { | ||
27 | + WARN_ON("mtrr: your BIOS has set up an incorrect mask, fixing it up.\n"); | ||
28 | + mask_lo = tmp; | ||
29 | + } | ||
30 | + } | ||
31 | |||
32 | /* This works correctly if size is a power of two, i.e. a | ||
33 | contiguous range. */ | ||
34 | diff --git a/crypto/authenc.c b/crypto/authenc.c | ||
35 | index 4b22676..fd9f06c 100644 | ||
36 | --- a/crypto/authenc.c | ||
37 | +++ b/crypto/authenc.c | ||
38 | @@ -174,8 +174,9 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, | ||
39 | static void crypto_authenc_encrypt_done(struct crypto_async_request *req, | ||
40 | int err) | ||
41 | { | ||
42 | + struct aead_request *areq = req->data; | ||
43 | + | ||
44 | if (!err) { | ||
45 | - struct aead_request *areq = req->data; | ||
46 | struct crypto_aead *authenc = crypto_aead_reqtfm(areq); | ||
47 | struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc); | ||
48 | struct ablkcipher_request *abreq = aead_request_ctx(areq); | ||
49 | @@ -185,7 +186,7 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req, | ||
50 | err = crypto_authenc_genicv(areq, iv, 0); | ||
51 | } | ||
52 | |||
53 | - aead_request_complete(req->data, err); | ||
54 | + aead_request_complete(areq, err); | ||
55 | } | ||
56 | |||
57 | static int crypto_authenc_encrypt(struct aead_request *req) | ||
58 | @@ -216,14 +217,15 @@ static int crypto_authenc_encrypt(struct aead_request *req) | ||
59 | static void crypto_authenc_givencrypt_done(struct crypto_async_request *req, | ||
60 | int err) | ||
61 | { | ||
62 | + struct aead_request *areq = req->data; | ||
63 | + | ||
64 | if (!err) { | ||
65 | - struct aead_request *areq = req->data; | ||
66 | struct skcipher_givcrypt_request *greq = aead_request_ctx(areq); | ||
67 | |||
68 | err = crypto_authenc_genicv(areq, greq->giv, 0); | ||
69 | } | ||
70 | |||
71 | - aead_request_complete(req->data, err); | ||
72 | + aead_request_complete(areq, err); | ||
73 | } | ||
74 | |||
75 | static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req) | ||
76 | diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c | ||
77 | index 8e877e7..5435970 100644 | ||
78 | --- a/drivers/net/forcedeth.c | ||
79 | +++ b/drivers/net/forcedeth.c | ||
80 | @@ -5249,7 +5249,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | ||
81 | if (id->driver_data & DEV_HAS_CHECKSUM) { | ||
82 | np->rx_csum = 1; | ||
83 | np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; | ||
84 | - dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; | ||
85 | + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | ||
86 | dev->features |= NETIF_F_TSO; | ||
87 | } | ||
88 | |||
89 | @@ -5548,7 +5548,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | ||
90 | |||
91 | dev_printk(KERN_INFO, &pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n", | ||
92 | dev->features & NETIF_F_HIGHDMA ? "highdma " : "", | ||
93 | - dev->features & (NETIF_F_HW_CSUM | NETIF_F_SG) ? | ||
94 | + dev->features & (NETIF_F_IP_CSUM | NETIF_F_SG) ? | ||
95 | "csum " : "", | ||
96 | dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ? | ||
97 | "vlan " : "", | ||
98 | diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c | ||
99 | index 42d7c0a..0e4eb15 100644 | ||
100 | --- a/drivers/net/r8169.c | ||
101 | +++ b/drivers/net/r8169.c | ||
102 | @@ -2822,7 +2822,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, | ||
103 | pkt_size, PCI_DMA_FROMDEVICE); | ||
104 | rtl8169_mark_to_asic(desc, tp->rx_buf_sz); | ||
105 | } else { | ||
106 | - pci_unmap_single(pdev, addr, pkt_size, | ||
107 | + pci_unmap_single(pdev, addr, tp->rx_buf_sz, | ||
108 | PCI_DMA_FROMDEVICE); | ||
109 | tp->Rx_skbuff[entry] = NULL; | ||
110 | } | ||
111 | diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c | ||
112 | index d8160fa..9c2b7b4 100644 | ||
113 | --- a/drivers/usb/class/cdc-acm.c | ||
114 | +++ b/drivers/usb/class/cdc-acm.c | ||
115 | @@ -531,8 +531,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | ||
116 | tasklet_schedule(&acm->urb_task); | ||
117 | |||
118 | done: | ||
119 | -err_out: | ||
120 | mutex_unlock(&acm->mutex); | ||
121 | +err_out: | ||
122 | mutex_unlock(&open_mutex); | ||
123 | return rv; | ||
124 | |||
125 | diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c | ||
126 | index 59df132..4835bdc 100644 | ||
127 | --- a/drivers/video/fb_defio.c | ||
128 | +++ b/drivers/video/fb_defio.c | ||
129 | @@ -114,6 +114,17 @@ static struct vm_operations_struct fb_deferred_io_vm_ops = { | ||
130 | .page_mkwrite = fb_deferred_io_mkwrite, | ||
131 | }; | ||
132 | |||
133 | +static int fb_deferred_io_set_page_dirty(struct page *page) | ||
134 | +{ | ||
135 | + if (!PageDirty(page)) | ||
136 | + SetPageDirty(page); | ||
137 | + return 0; | ||
138 | +} | ||
139 | + | ||
140 | +static const struct address_space_operations fb_deferred_io_aops = { | ||
141 | + .set_page_dirty = fb_deferred_io_set_page_dirty, | ||
142 | +}; | ||
143 | + | ||
144 | static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma) | ||
145 | { | ||
146 | vma->vm_ops = &fb_deferred_io_vm_ops; | ||
147 | @@ -163,6 +174,14 @@ void fb_deferred_io_init(struct fb_info *info) | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(fb_deferred_io_init); | ||
150 | |||
151 | +void fb_deferred_io_open(struct fb_info *info, | ||
152 | + struct inode *inode, | ||
153 | + struct file *file) | ||
154 | +{ | ||
155 | + file->f_mapping->a_ops = &fb_deferred_io_aops; | ||
156 | +} | ||
157 | +EXPORT_SYMBOL_GPL(fb_deferred_io_open); | ||
158 | + | ||
159 | void fb_deferred_io_cleanup(struct fb_info *info) | ||
160 | { | ||
161 | void *screen_base = (void __force *) info->screen_base; | ||
162 | diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c | ||
163 | index 01072f4..79b410c 100644 | ||
164 | --- a/drivers/video/fbmem.c | ||
165 | +++ b/drivers/video/fbmem.c | ||
166 | @@ -1315,6 +1315,10 @@ fb_open(struct inode *inode, struct file *file) | ||
167 | if (res) | ||
168 | module_put(info->fbops->owner); | ||
169 | } | ||
170 | +#ifdef CONFIG_FB_DEFERRED_IO | ||
171 | + if (info->fbdefio) | ||
172 | + fb_deferred_io_open(info, inode, file); | ||
173 | +#endif | ||
174 | return res; | ||
175 | } | ||
176 | |||
177 | diff --git a/fs/cifs/file.c b/fs/cifs/file.c | ||
178 | index 40b6900..a80a917 100644 | ||
179 | --- a/fs/cifs/file.c | ||
180 | +++ b/fs/cifs/file.c | ||
181 | @@ -835,6 +835,10 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | ||
182 | return -EBADF; | ||
183 | open_file = (struct cifsFileInfo *) file->private_data; | ||
184 | |||
185 | + rc = generic_write_checks(file, poffset, &write_size, 0); | ||
186 | + if (rc) | ||
187 | + return rc; | ||
188 | + | ||
189 | xid = GetXid(); | ||
190 | |||
191 | if (*poffset > file->f_path.dentry->d_inode->i_size) | ||
192 | diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c | ||
193 | index 350680f..b392002 100644 | ||
194 | --- a/fs/cramfs/inode.c | ||
195 | +++ b/fs/cramfs/inode.c | ||
196 | @@ -44,58 +44,13 @@ static DEFINE_MUTEX(read_mutex); | ||
197 | static int cramfs_iget5_test(struct inode *inode, void *opaque) | ||
198 | { | ||
199 | struct cramfs_inode *cramfs_inode = opaque; | ||
200 | - | ||
201 | - if (inode->i_ino != CRAMINO(cramfs_inode)) | ||
202 | - return 0; /* does not match */ | ||
203 | - | ||
204 | - if (inode->i_ino != 1) | ||
205 | - return 1; | ||
206 | - | ||
207 | - /* all empty directories, char, block, pipe, and sock, share inode #1 */ | ||
208 | - | ||
209 | - if ((inode->i_mode != cramfs_inode->mode) || | ||
210 | - (inode->i_gid != cramfs_inode->gid) || | ||
211 | - (inode->i_uid != cramfs_inode->uid)) | ||
212 | - return 0; /* does not match */ | ||
213 | - | ||
214 | - if ((S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) && | ||
215 | - (inode->i_rdev != old_decode_dev(cramfs_inode->size))) | ||
216 | - return 0; /* does not match */ | ||
217 | - | ||
218 | - return 1; /* matches */ | ||
219 | + return inode->i_ino == CRAMINO(cramfs_inode) && inode->i_ino != 1; | ||
220 | } | ||
221 | |||
222 | static int cramfs_iget5_set(struct inode *inode, void *opaque) | ||
223 | { | ||
224 | - static struct timespec zerotime; | ||
225 | struct cramfs_inode *cramfs_inode = opaque; | ||
226 | - inode->i_mode = cramfs_inode->mode; | ||
227 | - inode->i_uid = cramfs_inode->uid; | ||
228 | - inode->i_size = cramfs_inode->size; | ||
229 | - inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; | ||
230 | - inode->i_gid = cramfs_inode->gid; | ||
231 | - /* Struct copy intentional */ | ||
232 | - inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; | ||
233 | inode->i_ino = CRAMINO(cramfs_inode); | ||
234 | - /* inode->i_nlink is left 1 - arguably wrong for directories, | ||
235 | - but it's the best we can do without reading the directory | ||
236 | - contents. 1 yields the right result in GNU find, even | ||
237 | - without -noleaf option. */ | ||
238 | - if (S_ISREG(inode->i_mode)) { | ||
239 | - inode->i_fop = &generic_ro_fops; | ||
240 | - inode->i_data.a_ops = &cramfs_aops; | ||
241 | - } else if (S_ISDIR(inode->i_mode)) { | ||
242 | - inode->i_op = &cramfs_dir_inode_operations; | ||
243 | - inode->i_fop = &cramfs_directory_operations; | ||
244 | - } else if (S_ISLNK(inode->i_mode)) { | ||
245 | - inode->i_op = &page_symlink_inode_operations; | ||
246 | - inode->i_data.a_ops = &cramfs_aops; | ||
247 | - } else { | ||
248 | - inode->i_size = 0; | ||
249 | - inode->i_blocks = 0; | ||
250 | - init_special_inode(inode, inode->i_mode, | ||
251 | - old_decode_dev(cramfs_inode->size)); | ||
252 | - } | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | @@ -105,12 +60,48 @@ static struct inode *get_cramfs_inode(struct super_block *sb, | ||
257 | struct inode *inode = iget5_locked(sb, CRAMINO(cramfs_inode), | ||
258 | cramfs_iget5_test, cramfs_iget5_set, | ||
259 | cramfs_inode); | ||
260 | + static struct timespec zerotime; | ||
261 | + | ||
262 | if (inode && (inode->i_state & I_NEW)) { | ||
263 | + inode->i_mode = cramfs_inode->mode; | ||
264 | + inode->i_uid = cramfs_inode->uid; | ||
265 | + inode->i_size = cramfs_inode->size; | ||
266 | + inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; | ||
267 | + inode->i_gid = cramfs_inode->gid; | ||
268 | + /* Struct copy intentional */ | ||
269 | + inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; | ||
270 | + /* inode->i_nlink is left 1 - arguably wrong for directories, | ||
271 | + but it's the best we can do without reading the directory | ||
272 | + contents. 1 yields the right result in GNU find, even | ||
273 | + without -noleaf option. */ | ||
274 | + if (S_ISREG(inode->i_mode)) { | ||
275 | + inode->i_fop = &generic_ro_fops; | ||
276 | + inode->i_data.a_ops = &cramfs_aops; | ||
277 | + } else if (S_ISDIR(inode->i_mode)) { | ||
278 | + inode->i_op = &cramfs_dir_inode_operations; | ||
279 | + inode->i_fop = &cramfs_directory_operations; | ||
280 | + } else if (S_ISLNK(inode->i_mode)) { | ||
281 | + inode->i_op = &page_symlink_inode_operations; | ||
282 | + inode->i_data.a_ops = &cramfs_aops; | ||
283 | + } else { | ||
284 | + inode->i_size = 0; | ||
285 | + inode->i_blocks = 0; | ||
286 | + init_special_inode(inode, inode->i_mode, | ||
287 | + old_decode_dev(cramfs_inode->size)); | ||
288 | + } | ||
289 | unlock_new_inode(inode); | ||
290 | } | ||
291 | return inode; | ||
292 | } | ||
293 | |||
294 | +static void cramfs_drop_inode(struct inode *inode) | ||
295 | +{ | ||
296 | + if (inode->i_ino == 1) | ||
297 | + generic_delete_inode(inode); | ||
298 | + else | ||
299 | + generic_drop_inode(inode); | ||
300 | +} | ||
301 | + | ||
302 | /* | ||
303 | * We have our own block cache: don't fill up the buffer cache | ||
304 | * with the rom-image, because the way the filesystem is set | ||
305 | @@ -535,6 +526,7 @@ static const struct super_operations cramfs_ops = { | ||
306 | .put_super = cramfs_put_super, | ||
307 | .remount_fs = cramfs_remount, | ||
308 | .statfs = cramfs_statfs, | ||
309 | + .drop_inode = cramfs_drop_inode, | ||
310 | }; | ||
311 | |||
312 | static int cramfs_get_sb(struct file_system_type *fs_type, | ||
313 | diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c | ||
314 | index b6ed383..54b8b41 100644 | ||
315 | --- a/fs/nfsd/nfs4acl.c | ||
316 | +++ b/fs/nfsd/nfs4acl.c | ||
317 | @@ -443,7 +443,7 @@ init_state(struct posix_acl_state *state, int cnt) | ||
318 | * enough space for either: | ||
319 | */ | ||
320 | alloc = sizeof(struct posix_ace_state_array) | ||
321 | - + cnt*sizeof(struct posix_ace_state); | ||
322 | + + cnt*sizeof(struct posix_user_ace_state); | ||
323 | state->users = kzalloc(alloc, GFP_KERNEL); | ||
324 | if (!state->users) | ||
325 | return -ENOMEM; | ||
326 | diff --git a/include/linux/fb.h b/include/linux/fb.h | ||
327 | index 58c57a3..e1ee345 100644 | ||
328 | --- a/include/linux/fb.h | ||
329 | +++ b/include/linux/fb.h | ||
330 | @@ -966,6 +966,9 @@ static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, | ||
331 | |||
332 | /* drivers/video/fb_defio.c */ | ||
333 | extern void fb_deferred_io_init(struct fb_info *info); | ||
334 | +extern void fb_deferred_io_open(struct fb_info *info, | ||
335 | + struct inode *inode, | ||
336 | + struct file *file); | ||
337 | extern void fb_deferred_io_cleanup(struct fb_info *info); | ||
338 | extern int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, | ||
339 | int datasync); | ||
340 | diff --git a/mm/page_alloc.c b/mm/page_alloc.c | ||
341 | index f7082af..15ff806 100644 | ||
342 | --- a/mm/page_alloc.c | ||
343 | +++ b/mm/page_alloc.c | ||
344 | @@ -717,6 +717,9 @@ int move_freepages(struct zone *zone, | ||
345 | #endif | ||
346 | |||
347 | for (page = start_page; page <= end_page;) { | ||
348 | + /* Make sure we are not inadvertently changing nodes */ | ||
349 | + VM_BUG_ON(page_to_nid(page) != zone_to_nid(zone)); | ||
350 | + | ||
351 | if (!pfn_valid_within(page_to_pfn(page))) { | ||
352 | page++; | ||
353 | continue; | ||
354 | @@ -2476,6 +2479,10 @@ static void setup_zone_migrate_reserve(struct zone *zone) | ||
355 | continue; | ||
356 | page = pfn_to_page(pfn); | ||
357 | |||
358 | + /* Watch out for overlapping nodes */ | ||
359 | + if (page_to_nid(page) != zone_to_nid(zone)) | ||
360 | + continue; | ||
361 | + | ||
362 | /* Blocks with reserved pages will never free, skip them. */ | ||
363 | if (PageReserved(page)) | ||
364 | continue; | ||
365 | diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c | ||
366 | index 4aa2b45..d11f8d6 100644 | ||
367 | --- a/net/sched/sch_prio.c | ||
368 | +++ b/net/sched/sch_prio.c | ||
369 | @@ -228,14 +228,20 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt) | ||
370 | { | ||
371 | struct prio_sched_data *q = qdisc_priv(sch); | ||
372 | struct tc_prio_qopt *qopt; | ||
373 | - struct nlattr *tb[TCA_PRIO_MAX + 1]; | ||
374 | + struct nlattr *tb[TCA_PRIO_MAX + 1] = {0}; | ||
375 | int err; | ||
376 | int i; | ||
377 | |||
378 | - err = nla_parse_nested_compat(tb, TCA_PRIO_MAX, opt, NULL, qopt, | ||
379 | - sizeof(*qopt)); | ||
380 | - if (err < 0) | ||
381 | - return err; | ||
382 | + qopt = nla_data(opt); | ||
383 | + if (nla_len(opt) < sizeof(*qopt)) | ||
384 | + return -1; | ||
385 | + | ||
386 | + if (nla_len(opt) >= sizeof(*qopt) + sizeof(struct nlattr)) { | ||
387 | + err = nla_parse_nested(tb, TCA_PRIO_MAX, | ||
388 | + (struct nlattr *) (qopt + 1), NULL); | ||
389 | + if (err < 0) | ||
390 | + return err; | ||
391 | + } | ||
392 | |||
393 | q->bands = qopt->bands; | ||
394 | /* If we're multiqueue, make sure the number of incoming bands | ||
395 | diff --git a/net/sctp/auth.c b/net/sctp/auth.c | ||
396 | index 675a5c3..52db5f6 100644 | ||
397 | --- a/net/sctp/auth.c | ||
398 | +++ b/net/sctp/auth.c | ||
399 | @@ -80,6 +80,10 @@ static struct sctp_auth_bytes *sctp_auth_create_key(__u32 key_len, gfp_t gfp) | ||
400 | { | ||
401 | struct sctp_auth_bytes *key; | ||
402 | |||
403 | + /* Verify that we are not going to overflow INT_MAX */ | ||
404 | + if ((INT_MAX - key_len) < sizeof(struct sctp_auth_bytes)) | ||
405 | + return NULL; | ||
406 | + | ||
407 | /* Allocate the shared key */ | ||
408 | key = kmalloc(sizeof(struct sctp_auth_bytes) + key_len, gfp); | ||
409 | if (!key) | ||
410 | @@ -782,6 +786,9 @@ int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep, | ||
411 | for (i = 0; i < hmacs->shmac_num_idents; i++) { | ||
412 | id = hmacs->shmac_idents[i]; | ||
413 | |||
414 | + if (id > SCTP_AUTH_HMAC_ID_MAX) | ||
415 | + return -EOPNOTSUPP; | ||
416 | + | ||
417 | if (SCTP_AUTH_HMAC_ID_SHA1 == id) | ||
418 | has_sha1 = 1; | ||
419 | |||
420 | diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c | ||
421 | index e39a0cd..4c8d9f4 100644 | ||
422 | --- a/net/sctp/endpointola.c | ||
423 | +++ b/net/sctp/endpointola.c | ||
424 | @@ -103,6 +103,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | ||
425 | |||
426 | /* Initialize the CHUNKS parameter */ | ||
427 | auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS; | ||
428 | + auth_chunks->param_hdr.length = htons(sizeof(sctp_paramhdr_t)); | ||
429 | |||
430 | /* If the Add-IP functionality is enabled, we must | ||
431 | * authenticate, ASCONF and ASCONF-ACK chunks | ||
432 | @@ -110,8 +111,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | ||
433 | if (sctp_addip_enable) { | ||
434 | auth_chunks->chunks[0] = SCTP_CID_ASCONF; | ||
435 | auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; | ||
436 | - auth_chunks->param_hdr.length = | ||
437 | - htons(sizeof(sctp_paramhdr_t) + 2); | ||
438 | + auth_chunks->param_hdr.length += htons(2); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | diff --git a/net/sctp/socket.c b/net/sctp/socket.c | ||
443 | index 2d42260..f8c66d6 100644 | ||
444 | --- a/net/sctp/socket.c | ||
445 | +++ b/net/sctp/socket.c | ||
446 | @@ -2983,6 +2983,9 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, | ||
447 | { | ||
448 | struct sctp_authchunk val; | ||
449 | |||
450 | + if (!sctp_auth_enable) | ||
451 | + return -EACCES; | ||
452 | + | ||
453 | if (optlen != sizeof(struct sctp_authchunk)) | ||
454 | return -EINVAL; | ||
455 | if (copy_from_user(&val, optval, optlen)) | ||
456 | @@ -3011,8 +3014,12 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | ||
457 | int optlen) | ||
458 | { | ||
459 | struct sctp_hmacalgo *hmacs; | ||
460 | + u32 idents; | ||
461 | int err; | ||
462 | |||
463 | + if (!sctp_auth_enable) | ||
464 | + return -EACCES; | ||
465 | + | ||
466 | if (optlen < sizeof(struct sctp_hmacalgo)) | ||
467 | return -EINVAL; | ||
468 | |||
469 | @@ -3025,8 +3032,9 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | ||
470 | goto out; | ||
471 | } | ||
472 | |||
473 | - if (hmacs->shmac_num_idents == 0 || | ||
474 | - hmacs->shmac_num_idents > SCTP_AUTH_NUM_HMACS) { | ||
475 | + idents = hmacs->shmac_num_idents; | ||
476 | + if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS || | ||
477 | + (idents * sizeof(u16)) > (optlen - sizeof(struct sctp_hmacalgo))) { | ||
478 | err = -EINVAL; | ||
479 | goto out; | ||
480 | } | ||
481 | @@ -3051,6 +3059,9 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | ||
482 | struct sctp_association *asoc; | ||
483 | int ret; | ||
484 | |||
485 | + if (!sctp_auth_enable) | ||
486 | + return -EACCES; | ||
487 | + | ||
488 | if (optlen <= sizeof(struct sctp_authkey)) | ||
489 | return -EINVAL; | ||
490 | |||
491 | @@ -3063,6 +3074,11 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | ||
492 | goto out; | ||
493 | } | ||
494 | |||
495 | + if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) { | ||
496 | + ret = -EINVAL; | ||
497 | + goto out; | ||
498 | + } | ||
499 | + | ||
500 | asoc = sctp_id2assoc(sk, authkey->sca_assoc_id); | ||
501 | if (!asoc && authkey->sca_assoc_id && sctp_style(sk, UDP)) { | ||
502 | ret = -EINVAL; | ||
503 | @@ -3088,6 +3104,9 @@ static int sctp_setsockopt_active_key(struct sock *sk, | ||
504 | struct sctp_authkeyid val; | ||
505 | struct sctp_association *asoc; | ||
506 | |||
507 | + if (!sctp_auth_enable) | ||
508 | + return -EACCES; | ||
509 | + | ||
510 | if (optlen != sizeof(struct sctp_authkeyid)) | ||
511 | return -EINVAL; | ||
512 | if (copy_from_user(&val, optval, optlen)) | ||
513 | @@ -3113,6 +3132,9 @@ static int sctp_setsockopt_del_key(struct sock *sk, | ||
514 | struct sctp_authkeyid val; | ||
515 | struct sctp_association *asoc; | ||
516 | |||
517 | + if (!sctp_auth_enable) | ||
518 | + return -EACCES; | ||
519 | + | ||
520 | if (optlen != sizeof(struct sctp_authkeyid)) | ||
521 | return -EINVAL; | ||
522 | if (copy_from_user(&val, optval, optlen)) | ||
523 | @@ -5073,19 +5095,29 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, | ||
524 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, | ||
525 | char __user *optval, int __user *optlen) | ||
526 | { | ||
527 | + struct sctp_hmacalgo __user *p = (void __user *)optval; | ||
528 | struct sctp_hmac_algo_param *hmacs; | ||
529 | - __u16 param_len; | ||
530 | + __u16 data_len = 0; | ||
531 | + u32 num_idents; | ||
532 | + | ||
533 | + if (!sctp_auth_enable) | ||
534 | + return -EACCES; | ||
535 | |||
536 | hmacs = sctp_sk(sk)->ep->auth_hmacs_list; | ||
537 | - param_len = ntohs(hmacs->param_hdr.length); | ||
538 | + data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); | ||
539 | |||
540 | - if (len < param_len) | ||
541 | + if (len < sizeof(struct sctp_hmacalgo) + data_len) | ||
542 | return -EINVAL; | ||
543 | + | ||
544 | + len = sizeof(struct sctp_hmacalgo) + data_len; | ||
545 | + num_idents = data_len / sizeof(u16); | ||
546 | + | ||
547 | if (put_user(len, optlen)) | ||
548 | return -EFAULT; | ||
549 | - if (copy_to_user(optval, hmacs->hmac_ids, len)) | ||
550 | + if (put_user(num_idents, &p->shmac_num_idents)) | ||
551 | + return -EFAULT; | ||
552 | + if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len)) | ||
553 | return -EFAULT; | ||
554 | - | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | @@ -5095,6 +5127,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | ||
559 | struct sctp_authkeyid val; | ||
560 | struct sctp_association *asoc; | ||
561 | |||
562 | + if (!sctp_auth_enable) | ||
563 | + return -EACCES; | ||
564 | + | ||
565 | if (len < sizeof(struct sctp_authkeyid)) | ||
566 | return -EINVAL; | ||
567 | if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid))) | ||
568 | @@ -5109,6 +5144,12 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | ||
569 | else | ||
570 | val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; | ||
571 | |||
572 | + len = sizeof(struct sctp_authkeyid); | ||
573 | + if (put_user(len, optlen)) | ||
574 | + return -EFAULT; | ||
575 | + if (copy_to_user(optval, &val, len)) | ||
576 | + return -EFAULT; | ||
577 | + | ||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | @@ -5119,13 +5160,16 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | ||
582 | struct sctp_authchunks val; | ||
583 | struct sctp_association *asoc; | ||
584 | struct sctp_chunks_param *ch; | ||
585 | - u32 num_chunks; | ||
586 | + u32 num_chunks = 0; | ||
587 | char __user *to; | ||
588 | |||
589 | - if (len <= sizeof(struct sctp_authchunks)) | ||
590 | + if (!sctp_auth_enable) | ||
591 | + return -EACCES; | ||
592 | + | ||
593 | + if (len < sizeof(struct sctp_authchunks)) | ||
594 | return -EINVAL; | ||
595 | |||
596 | - if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) | ||
597 | + if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) | ||
598 | return -EFAULT; | ||
599 | |||
600 | to = p->gauth_chunks; | ||
601 | @@ -5134,20 +5178,21 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | ||
602 | return -EINVAL; | ||
603 | |||
604 | ch = asoc->peer.peer_chunks; | ||
605 | + if (!ch) | ||
606 | + goto num; | ||
607 | |||
608 | /* See if the user provided enough room for all the data */ | ||
609 | num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); | ||
610 | if (len < num_chunks) | ||
611 | return -EINVAL; | ||
612 | |||
613 | - len = num_chunks; | ||
614 | - if (put_user(len, optlen)) | ||
615 | + if (copy_to_user(to, ch->chunks, num_chunks)) | ||
616 | return -EFAULT; | ||
617 | +num: | ||
618 | + len = sizeof(struct sctp_authchunks) + num_chunks; | ||
619 | + if (put_user(len, optlen)) return -EFAULT; | ||
620 | if (put_user(num_chunks, &p->gauth_number_of_chunks)) | ||
621 | return -EFAULT; | ||
622 | - if (copy_to_user(to, ch->chunks, len)) | ||
623 | - return -EFAULT; | ||
624 | - | ||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | @@ -5158,13 +5203,16 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | ||
629 | struct sctp_authchunks val; | ||
630 | struct sctp_association *asoc; | ||
631 | struct sctp_chunks_param *ch; | ||
632 | - u32 num_chunks; | ||
633 | + u32 num_chunks = 0; | ||
634 | char __user *to; | ||
635 | |||
636 | - if (len <= sizeof(struct sctp_authchunks)) | ||
637 | + if (!sctp_auth_enable) | ||
638 | + return -EACCES; | ||
639 | + | ||
640 | + if (len < sizeof(struct sctp_authchunks)) | ||
641 | return -EINVAL; | ||
642 | |||
643 | - if (copy_from_user(&val, p, sizeof(struct sctp_authchunks))) | ||
644 | + if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) | ||
645 | return -EFAULT; | ||
646 | |||
647 | to = p->gauth_chunks; | ||
648 | @@ -5177,17 +5225,21 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | ||
649 | else | ||
650 | ch = sctp_sk(sk)->ep->auth_chunk_list; | ||
651 | |||
652 | + if (!ch) | ||
653 | + goto num; | ||
654 | + | ||
655 | num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); | ||
656 | - if (len < num_chunks) | ||
657 | + if (len < sizeof(struct sctp_authchunks) + num_chunks) | ||
658 | return -EINVAL; | ||
659 | |||
660 | - len = num_chunks; | ||
661 | + if (copy_to_user(to, ch->chunks, num_chunks)) | ||
662 | + return -EFAULT; | ||
663 | +num: | ||
664 | + len = sizeof(struct sctp_authchunks) + num_chunks; | ||
665 | if (put_user(len, optlen)) | ||
666 | return -EFAULT; | ||
667 | if (put_user(num_chunks, &p->gauth_number_of_chunks)) | ||
668 | return -EFAULT; | ||
669 | - if (copy_to_user(to, ch->chunks, len)) | ||
670 | - return -EFAULT; | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c | ||
675 | index 0f8c439..5231f7a 100644 | ||
676 | --- a/net/sunrpc/sysctl.c | ||
677 | +++ b/net/sunrpc/sysctl.c | ||
678 | @@ -60,24 +60,14 @@ static int proc_do_xprt(ctl_table *table, int write, struct file *file, | ||
679 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
680 | { | ||
681 | char tmpbuf[256]; | ||
682 | - int len; | ||
683 | + size_t len; | ||
684 | + | ||
685 | if ((*ppos && !write) || !*lenp) { | ||
686 | *lenp = 0; | ||
687 | return 0; | ||
688 | } | ||
689 | - if (write) | ||
690 | - return -EINVAL; | ||
691 | - else { | ||
692 | - len = svc_print_xprts(tmpbuf, sizeof(tmpbuf)); | ||
693 | - if (!access_ok(VERIFY_WRITE, buffer, len)) | ||
694 | - return -EFAULT; | ||
695 | - | ||
696 | - if (__copy_to_user(buffer, tmpbuf, len)) | ||
697 | - return -EFAULT; | ||
698 | - } | ||
699 | - *lenp -= len; | ||
700 | - *ppos += len; | ||
701 | - return 0; | ||
702 | + len = svc_print_xprts(tmpbuf, sizeof(tmpbuf)); | ||
703 | + return simple_read_from_buffer(buffer, *lenp, ppos, tmpbuf, len); | ||
704 | } | ||
705 | |||
706 | static int |