Messages in this thread Patch in this message | | | From | Gordon Oliver <> | Subject | [2.0.30pre3] aic7xxx proc overflow patch. | Date | Wed, 6 Aug 1997 23:42:17 -0400 (CST) |
| |
Hi.
This patch fixes a possible nasty bug in the aic7xxx proc info function. The proc info function had no checking whatsoever for the file length, and, if there are several LUN #'s on a single device would happily scribble all over kernel memory. Please add this to the fixes for 2.0.31
The fix was a simple check placed in several places to guard against overflow. It is a bit ugly (in that it assumes stuff about the way scsi proc reads are done), but it should work (doesn't break at least on my system).
I also killed a static buffer that was only cleared (maybe they wanted to clear "buffer" instead of "buff"?)
I accidentally deleted the mail of the person who crashed while looking at the file... could others test this. If the printk's are ever triggered, it is a bad thing, and blocks will need to be made smaller. -gordo ----------------------------------------------------------------- --- linux/drivers/scsi/aic7xxx_proc.c.pre3 Wed Aug 6 20:43:53 1997 +++ linux/drivers/scsi/aic7xxx_proc.c Wed Aug 6 23:11:32 1997 @@ -76,7 +76,6 @@ { struct Scsi_Host *HBAptr; struct aic7xxx_host *p; - static u8 buff[512]; int i; int found = FALSE; int size = 0; @@ -129,11 +128,6 @@ return (aic7xxx_set_info(buffer, length, HBAptr)); } - if (offset == 0) - { - memset(buff, 0, sizeof(buff)); - } - p = (struct aic7xxx_host *) HBAptr->hostdata; size += sprintf(BLS, "Adaptec AIC7xxx driver version: "); @@ -142,7 +136,14 @@ #if 0 size += sprintf(BLS, "%s\n", rcs_version(AIC7XXX_SEQ_VER)); #endif + if (size > 512) + printk(KERN_CRIT "aic7xxx: possible overflow at first position\n"); len += size; pos = begin + len; size = 0; + if (pos < offset) + { + begin = pos; + len = 0; + } size += sprintf(BLS, "\n"); size += sprintf(BLS, "Compile Options:\n"); @@ -167,7 +168,16 @@ #else size += sprintf(BLS, " AIC7XXX_PROC_STATS : Disabled\n"); #endif + if (size > 512) + printk(KERN_CRIT "aic7xxx: possible overflow at second position\n"); len += size; pos = begin + len; size = 0; + if (pos < offset) + { + begin = pos; + len = 0; + } + else if (pos >= offset + length) + goto stop_output; size += sprintf(BLS, "\n"); size += sprintf(BLS, "Adapter Configuration:\n"); @@ -201,7 +211,16 @@ (p->flags & ULTRA_ENABLED) ? "En" : "Dis"); size += sprintf(BLS, " Target Disconnect: %sabled\n", p->discenable ? "En" : "Dis"); + if (size > 512) + printk(KERN_CRIT "aic7xxx: possible overflow at third position\n"); len += size; pos = begin + len; size = 0; + if (pos < offset) + { + begin = pos; + len = 0; + } + else if (pos >= offset + length) + goto stop_output; #ifdef AIC7XXX_PROC_STATS { @@ -210,6 +229,7 @@ /* * XXX: Need to fix this to avoid overflow... + * Fixed - gordo. */ size += sprintf(BLS, "\n"); size += sprintf(BLS, "Statistics:\n"); @@ -247,9 +267,18 @@ sp->w_bins[9]); size += sprintf(BLS, "\n"); } + if (size > 512) + printk(KERN_CRIT "aic7xxx: possible overflow at loop %d:%d\n", target, lun); + len += size; pos = begin + len; size = 0; + if (pos < offset) + { + begin = pos; + len = 0; + } + else if (pos >= offset + length) + goto stop_output; } } - len += size; pos = begin + len; size = 0; } #endif /* AIC7XXX_PROC_STATS */ @@ -257,7 +286,11 @@ proc_debug("2pos: %ld offset: %ld len: %d\n", pos, offset, len); *start = buffer + (offset - begin); /* Start of wanted data */ len -= (offset - begin); /* Start slop */ - if (len > length) + if (len < 0) + { + len = 0; /* off end of file */ + } + else if (len > length) { len = length; /* Ending slop */ }
| |