Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 677 - (hide annotations) (download)
Wed Sep 10 21:27:27 2008 UTC (15 years, 8 months 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