summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2005-04-03 00:00:36 +0000
committerhpa <hpa>2005-04-03 00:00:36 +0000
commitee86fb27a785d21bcd77bce6e57ec757268fdfc3 (patch)
treead3a761d133bc16ea6a2fd0226d51b1ab40f987f
parent5506bad79a1cc566cd9f0137a083fe5dc266feb7 (diff)
downloadsyslinux-ee86fb27a785d21bcd77bce6e57ec757268fdfc3.tar.gz
extlinux: fix multiple directory-parsing bugs.syslinux-3.08-pre6
-rw-r--r--NEWS1
-rw-r--r--extlinux.asm29
-rw-r--r--extlinux/extlinux.c3
3 files changed, 25 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index 03a81a88..9071f35f 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ Changes in 3.08:
* libutil: Add SHA-1 and base64 functions.
* Simple menu system: add password support.
* EXTLINUX: Sparse files now handled correctly.
+ * EXTLINUX: Large directories now handled correctly.
Changes in 3.07:
* Fix chainloading (chain.c32).
diff --git a/extlinux.asm b/extlinux.asm
index 4de79922..999d4021 100644
--- a/extlinux.asm
+++ b/extlinux.asm
@@ -853,7 +853,7 @@ getonesec_ext:
mov bp,1
getlinsec_ext:
- cmp eax,[ClustSize]
+ cmp eax,[SecPerClust]
jae getlinsec ; Nothing fancy
; If we get here, at least part of what we want is in the
@@ -976,6 +976,11 @@ open_inode:
inc eax ; s_first_data_block+1
mov cl,[ClustShift]
shl eax,cl
+ push edx
+ shr edx,SECTOR_SHIFT
+ add eax,edx
+ pop edx
+ and dx,SECTOR_SIZE-1
call getcachesector ; Get the group descriptor
add si,dx
mov esi,[gs:si+bg_inode_table] ; Get inode table block #
@@ -1062,6 +1067,7 @@ searchdir:
call getfssec
pop bx
pushf ; Save EOF flag
+ push si ; Save filesystem pointer
.getent:
cmp dword [bx+d_inode],0
je .endblock
@@ -1078,6 +1084,7 @@ searchdir:
jmp .getent
.endblock:
+ pop si
popf
jnc .readdir ; There is more
.failure:
@@ -1093,17 +1100,19 @@ searchdir:
; It's a match, but it's a directory.
; Repeat operation.
+ pop bx ; Adjust stack (di)
+ pop si
call close
- pop si ; Adjust stack (di)
- pop si ; Adjust stack (flags)
+ pop bx ; Adjust stack (flags)
inc di ; Skip slash
jmp .searchloop
.finish: ; We found it; now we need to open the file
+ pop bx ; Adjust stack (di)
+ pop si
call close ; Close directory
- pop si ; Adjust stack (di)
- pop si ; Adjust stack (flags)
+ pop bx ; Adjust stack (flags)
call open_inode
.done:
pop di
@@ -1331,6 +1340,12 @@ getfssec:
push eax
push edx
push edi
+
+ movzx ecx,cx
+ cmp ecx,[si] ; Number of sectors left
+ jbe .lenok
+ mov cx,[si]
+.lenok:
.getfragment:
mov eax,[si+file_sector] ; Current start index
mov edi,eax
@@ -1369,9 +1384,9 @@ getfssec:
pop bp
add [si+file_sector],ebp ; Next sector index
sub [si],ebp ; Sectors consumed
- jz .done
jcxz .done
- jmp .getfragment
+ jnz .getfragment
+ ; Fall through
.done:
cmp dword [si],1 ; Did we run out of file?
; CF set if [SI] < 1, i.e. == 0
diff --git a/extlinux/extlinux.c b/extlinux/extlinux.c
index 05f6cf3c..195b4e5a 100644
--- a/extlinux/extlinux.c
+++ b/extlinux/extlinux.c
@@ -416,7 +416,8 @@ get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo)
geo->start = 0;
if ( !opt.sectors && !opt.heads )
- fprintf(stderr, "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n",
+ fprintf(stderr, "Warning: unable to obtain device geometry (defaulting to %d heads, %d sectors)\n"
+ " (on hard disks, this is usually harmless.)\n",
geo->heads, geo->sectors);
return 1;