Magellan Linux

Contents of /trunk/kernel26-magellan/patches-2.6.25-r5/0116-2.6.25.17-all-fixes.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 677 - (show annotations) (download)
Wed Sep 10 21:27:27 2008 UTC (15 years, 7 months ago) by niro
File size: 22098 byte(s)
2.6.25-magellan-r5:
- updated to linux-2.6.25.17

1 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