Merge upstream changes as of April 29th

This commit is contained in:
Michael Marineau 2015-07-31 15:41:48 -07:00
commit c7c750ecc2
267 changed files with 6019 additions and 1963 deletions

View file

@ -76,6 +76,11 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
if COND_emu
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h
else
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt.h
endif
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
@ -83,9 +88,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
if !COND_clang
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
endif
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
if COND_i386_pc
@ -248,9 +250,6 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
if COND_GRUB_EMU_SDL
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h
endif
if COND_GRUB_EMU_USB
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libusb.h
endif
if COND_GRUB_EMU_PCI
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libpciaccess.h
endif

View file

@ -83,8 +83,6 @@ kernel = {
x86_64_xen_ldflags = '$(TARGET_IMG_LDFLAGS)';
x86_64_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0';
ldadd = '$(LDADD_KERNEL)';
mips_loongson_ldflags = '-Wl,-Ttext,0x80200000';
powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
@ -132,6 +130,7 @@ kernel = {
common = kern/rescue_reader.c;
common = kern/term.c;
noemu = kern/compiler-rt.c;
noemu = kern/mm.c;
noemu = kern/time.c;
noemu = kern/generic/millisleep.c;
@ -159,6 +158,8 @@ kernel = {
terminfoinkernel = commands/extcmd.c;
terminfoinkernel = lib/arg.c;
softdiv = lib/division.c;
i386 = kern/i386/dl.c;
i386_xen = kern/i386/dl.c;
@ -252,6 +253,7 @@ kernel = {
powerpc_ieee1275 = kern/powerpc/cache.S;
powerpc_ieee1275 = kern/powerpc/dl.c;
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
sparc64_ieee1275 = kern/sparc64/cache.S;
sparc64_ieee1275 = kern/sparc64/dl.c;
@ -263,7 +265,7 @@ kernel = {
arm = kern/arm/cache_armv7.S;
extra_dist = kern/arm/cache.S;
arm = kern/arm/cache.c;
arm = kern/arm/misc.S;
arm = kern/arm/compiler-rt.S;
arm64 = kern/arm64/cache.c;
arm64 = kern/arm64/cache_flush.S;
@ -441,13 +443,13 @@ image = {
common = lib/xzembed/xz_dec_bcj.c;
common = lib/xzembed/xz_dec_lzma2.c;
common = lib/xzembed/xz_dec_stream.c;
common = kern/compiler-rt.c;
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed -DGRUB_EMBED_DECOMPRESSOR=1';
objcopyflags = '-O binary';
mips_ldflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC) -Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)';
ldadd = '$(TARGET_LIBGCC)';
cflags = '-Wno-unreachable-code $(TARGET_LDFLAGS_STATIC_LIBGCC)';
mips_ldflags = '-Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)';
cflags = '-Wno-unreachable-code';
enable = mips;
};
@ -459,9 +461,7 @@ image = {
cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1';
objcopyflags = '-O binary';
mips_ldflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC) -Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)';
ldadd = '$(TARGET_LIBGCC)';
cflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC)';
mips_ldflags = '-Wl,-Ttext,$(TARGET_DECOMPRESSOR_LINK_ADDR)';
enable = mips;
};
@ -479,7 +479,7 @@ image = {
name = fwstart;
mips_loongson = boot/mips/loongson/fwstart.S;
objcopyflags = '-O binary';
ldflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC) $(TARGET_LIBGCC) -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
ldflags = '-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
enable = mips_loongson;
};
@ -487,7 +487,7 @@ image = {
name = fwstart_fuloong2f;
mips_loongson = boot/mips/loongson/fuloong2f.S;
objcopyflags = '-O binary';
ldflags = '$(TARGET_LDFLAGS_STATIC_LIBGCC) $(TARGET_LIBGCC) -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
ldflags = '-Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
enable = mips_loongson;
};
@ -509,13 +509,6 @@ module = {
enable = x86;
};
module = {
name = libusb;
emu = bus/usb/emu/usb.c;
enable = emu;
condition = COND_GRUB_EMU_USB;
};
module = {
name = lsspd;
mips_loongson = commands/mips/loongson/lsspd.c;
@ -530,13 +523,6 @@ module = {
enable = usb;
};
module = {
name = emuusb;
common = bus/usb/usb.c;
enable = emu;
condition = COND_GRUB_EMU_USB;
};
module = {
name = usbserial_common;
common = bus/usb/serial/common.c;
@ -2009,11 +1995,42 @@ module = {
enable = xen;
};
module = {
name = div;
common = lib/division.c;
enable = no_softdiv;
};
module = {
name = div_test;
common = tests/div_test.c;
};
module = {
name = mul_test;
common = tests/mul_test.c;
};
module = {
name = shift_test;
common = tests/shift_test.c;
};
module = {
name = cmp_test;
common = tests/cmp_test.c;
};
module = {
name = ctz_test;
common = tests/ctz_test.c;
};
module = {
name = bswap_test;
common = tests/bswap_test.c;
};
module = {
name = videotest_checksum;
common = tests/videotest_checksum.c;

View file

@ -21,7 +21,7 @@
#include <grub/decompressor.h>
void *
memset (void *s, int c, grub_size_t len)
grub_memset (void *s, int c, grub_size_t len)
{
grub_uint8_t *ptr;
for (ptr = s; len; ptr++, len--)
@ -68,15 +68,6 @@ grub_memcmp (const void *s1, const void *s2, grub_size_t n)
return 0;
}
int memcmp (const void *s1, const void *s2, grub_size_t n)
__attribute__ ((alias ("grub_memcmp")));
void *memmove (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memmove")));
void *memcpy (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memmove")));
void *grub_decompressor_scratch;
void

View file

@ -165,8 +165,8 @@ start:
* this area.
*/
. = _start + GRUB_BOOT_MACHINE_BPB_START
. = _start + 4
.org GRUB_BOOT_MACHINE_BPB_START
.org 4
#endif
#ifdef HYBRID_BOOT
floppy
@ -174,23 +174,23 @@ start:
scratch
#endif
. = _start + GRUB_BOOT_MACHINE_BPB_END
.org GRUB_BOOT_MACHINE_BPB_END
/*
* End of BIOS parameter block.
*/
kernel_address:
LOCAL(kernel_address):
.word GRUB_BOOT_MACHINE_KERNEL_ADDR
#ifndef HYBRID_BOOT
. = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR
kernel_sector:
.org GRUB_BOOT_MACHINE_KERNEL_SECTOR
LOCAL(kernel_sector):
.long 1
kernel_sector_high:
LOCAL(kernel_sector_high):
.long 0
#endif
. = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE
.org GRUB_BOOT_MACHINE_BOOT_DRIVE
boot_drive:
.byte 0xff /* the disk to load kernel from */
/* 0xff means use the boot drive */
@ -208,7 +208,7 @@ LOCAL(after_BPB):
* possible boot drive. If GRUB is installed into a floppy,
* this does nothing (only jump).
*/
. = _start + GRUB_BOOT_MACHINE_DRIVE_CHECK
.org GRUB_BOOT_MACHINE_DRIVE_CHECK
boot_drive_check:
jmp 3f /* grub-setup may overwrite this jump */
testb $0x80, %dl
@ -275,7 +275,7 @@ real_start:
andw $1, %cx
jz LOCAL(chs_mode)
lba_mode:
LOCAL(lba_mode):
xorw %ax, %ax
movw %ax, 4(%si)
@ -290,9 +290,9 @@ lba_mode:
movw $0x0010, (%si)
/* the absolute address */
movl kernel_sector, %ebx
movl LOCAL(kernel_sector), %ebx
movl %ebx, 8(%si)
movl kernel_sector_high, %ebx
movl LOCAL(kernel_sector_high), %ebx
movl %ebx, 12(%si)
/* the segment of buffer address */
@ -361,13 +361,13 @@ LOCAL(final_init):
setup_sectors:
/* load logical sector start (top half) */
movl kernel_sector_high, %eax
movl LOCAL(kernel_sector_high), %eax
orl %eax, %eax
jnz LOCAL(geometry_error)
/* load logical sector start (bottom half) */
movl kernel_sector, %eax
movl LOCAL(kernel_sector), %eax
/* zero %edx */
xorl %edx, %edx
@ -452,7 +452,7 @@ LOCAL(copy_buffer):
popa
/* boot kernel */
jmp *(kernel_address)
jmp *(LOCAL(kernel_address))
/* END OF MAIN LOOP */
@ -511,13 +511,13 @@ LOCAL(message):
*/
#ifdef HYBRID_BOOT
. = _start + 0x1b0
kernel_sector:
.org 0x1b0
LOCAL(kernel_sector):
.long 1
kernel_sector_high:
LOCAL(kernel_sector_high):
.long 0
#endif
. = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
.org GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
nt_magic:
.long 0
.word 0
@ -528,7 +528,7 @@ nt_magic:
* sneaky, huh?
*/
. = _start + GRUB_BOOT_MACHINE_PART_START
.org GRUB_BOOT_MACHINE_PART_START
#ifndef HYBRID_BOOT
floppy
@ -536,7 +536,7 @@ nt_magic:
scratch
#endif
. = _start + GRUB_BOOT_MACHINE_PART_END
.org GRUB_BOOT_MACHINE_PART_END
/* the last 2 bytes in the sector 0 contain the signature */
.word GRUB_BOOT_MACHINE_SIGNATURE

View file

@ -43,7 +43,7 @@ _start:
LOCAL(next):
jmp 1f
. = start + 8
.org 8
bi_pvd:
.long 0 /* LBA of primary volume descriptor. */
@ -168,6 +168,6 @@ err_noboot_msg:
err_cdfail_msg:
.ascii "cdrom read fails\0"
. = start + 0x7FF
.org 0x7FF
.byte 0

View file

@ -362,7 +362,7 @@ LOCAL(message):
.word 0
.word 0
. = _start + 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE
.org 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE
LOCAL(firstlist): /* this label has to be before the first list entry!!! */
/* fill the first data listing with the default */
blocklist_default_start:

View file

@ -41,7 +41,7 @@ data_start:
xorl %ebp, %ebp
jmp LOCAL(linux_next)
. = data_start + 0x1F1
.org 0x1F1
setup_sects:
.byte CODE_SECTORS
@ -292,4 +292,4 @@ LOCAL(fail):
err_int15_msg:
.ascii "move memory fails\0"
. = _start + CODE_SECTORS * 512
.org (CODE_SECTORS * 512 + 512)

View file

@ -38,5 +38,5 @@ start:
/* This region is a junk. Do you say that this is wasteful?
But I like that the memory layout of the body is consistent
among different kernels rather than scamping just for 1.5KB. */
. = _start + 0x8200 - 0x7C00 - 0x200 - 1
.org 0x8200 - 0x7C00 - 0x200 - 1
.byte 0

View file

@ -50,23 +50,23 @@ LOCAL (base):
* This is a special data area.
*/
. = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
.org GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
LOCAL(compressed_size):
.long 0
. = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
.org GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
LOCAL(uncompressed_size):
.long 0
. = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
.org GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
reed_solomon_redundancy:
.long 0
. = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH
.org GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH
.short (LOCAL(reed_solomon_part) - _start)
/*
* This is the area for all of the special variables.
*/
. = _start + GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE
.org GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE
LOCAL(boot_dev):
.byte 0xFF, 0xFF, 0xFF
LOCAL(boot_drive):
@ -89,13 +89,13 @@ LOCAL (codestart):
sti /* we're safe again */
/* save the boot drive */
ADDR32 movb %dl, LOCAL(boot_drive)
movb %dl, LOCAL(boot_drive)
/* reset disk system (%ah = 0) */
int $0x13
/* transition to protected mode */
DATA32 call real_to_prot
calll real_to_prot
/* The ".code32" directive takes GAS out of 16-bit mode. */
.code32
@ -149,7 +149,7 @@ gate_a20_try_bios:
movw $0x2401, %ax
int $0x15
DATA32 call real_to_prot
calll real_to_prot
.code32
popl %ebp

View file

@ -31,7 +31,7 @@ _start:
jmp 1f
. = _start + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR
.org GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR
VARIABLE(grub_core_entry_addr)
.long 0
1:
@ -48,8 +48,9 @@ VARIABLE(grub_core_entry_addr)
/* Transition to protected mode. We use pushl to force generation
of a flat return address. */
pushl $1f
DATA32 jmp real_to_prot
jmp real_to_prot
.code32
1:
/* Ensure A20 is enabled. We're in qemu, so control port A works
and there is no need to wait since there is no real logic, it's
all emulated. */
@ -57,7 +58,6 @@ VARIABLE(grub_core_entry_addr)
andb $(~0x03), %al
orb $0x02, %al
outb $0x92
1:
movl EXT_C(grub_core_entry_addr), %edx
jmp *%edx
@ -66,9 +66,9 @@ VARIABLE(grub_core_entry_addr)
/* Intel, in its infinite wisdom, decided to put the i8086 entry point
*right here* and this is why we need this kludge. */
. = GRUB_BOOT_MACHINE_SIZE - 16
.org GRUB_BOOT_MACHINE_SIZE - 16
.code16
jmp _start
. = GRUB_BOOT_MACHINE_SIZE
.org GRUB_BOOT_MACHINE_SIZE

View file

@ -162,7 +162,7 @@ retry_cs5536:
b continue
. = start + GRUB_CPU_LOONGSON_FLASH_TLB_REFILL - GRUB_CPU_LOONGSON_FLASH_START
.org GRUB_CPU_LOONGSON_FLASH_TLB_REFILL - GRUB_CPU_LOONGSON_FLASH_START
tlb_refill:
mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC
mfc0 $s2, GRUB_CPU_LOONGSON_COP0_BADVADDR
@ -196,13 +196,13 @@ tlb_refill:
b fatal
addiu $a0, $a0, %lo(unhandled_tlb_refill)
. = start + GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR - GRUB_CPU_LOONGSON_FLASH_START
.org GRUB_CPU_LOONGSON_FLASH_CACHE_ERROR - GRUB_CPU_LOONGSON_FLASH_START
cache_error:
lui $a0, %hi(unhandled_cache_error)
b fatal
addiu $a0, $a0, %lo(unhandled_cache_error)
. = start + GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - GRUB_CPU_LOONGSON_FLASH_START
.org GRUB_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - GRUB_CPU_LOONGSON_FLASH_START
other_exception:
mfc0 $s0, GRUB_CPU_LOONGSON_COP0_CAUSE
mfc0 $s1, GRUB_CPU_LOONGSON_COP0_EPC

View file

@ -21,6 +21,7 @@
#include <grub/offsets.h>
#include <grub/machine/memory.h>
#include <grub/machine/kernel.h>
#include <grub/cpu/kernel.h>
#include <grub/offsets.h>
#define BASE_ADDR 8
@ -32,6 +33,7 @@
.globl __start, _start, start
.set noreorder
.set nomacro
mips_attributes
__start:
_start:
start:
@ -39,13 +41,13 @@ start:
bal codestart
nop
base:
. = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
.org GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
compressed_size:
.long 0
. = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
.org GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
uncompressed_size:
.long 0
. = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR
.org GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR
uncompressed_addr:
.long 0
codestart:
@ -150,18 +152,18 @@ digcont:
1:
jr $ra
nop
busclockstr: .asciiz "busclock="
cpuclockstr: .asciiz "cpuclock="
memsizestr: .asciiz "memsize="
highmemsizestr: .asciiz "highmemsize="
machtype_yeeloong_str1: .asciiz "machtype=8.9"
machtype_yeeloong_str2: .asciiz "machtype=lemote-yeeloong-"
machtype_fuloong2f_str: .asciiz "machtype=lemote-fuloong-2f"
machtype_fuloong2e_str: .asciiz "machtype=lemote-fuloong-2e"
pmon_yeeloong_str: .asciiz "PMON_VER=LM8"
pmon_fuloong2f_str: .asciiz "PMON_VER=LM6"
pmon_yeeloong_verstr: .asciiz "Version=LM8"
pmon_fuloong2f_verstr: .asciiz "Version=LM6"
busclockstr: .asciz "busclock="
cpuclockstr: .asciz "cpuclock="
memsizestr: .asciz "memsize="
highmemsizestr: .asciz "highmemsize="
machtype_yeeloong_str1: .asciz "machtype=8.9"
machtype_yeeloong_str2: .asciz "machtype=lemote-yeeloong-"
machtype_fuloong2f_str: .asciz "machtype=lemote-fuloong-2f"
machtype_fuloong2e_str: .asciz "machtype=lemote-fuloong-2e"
pmon_yeeloong_str: .asciz "PMON_VER=LM8"
pmon_fuloong2f_str: .asciz "PMON_VER=LM6"
pmon_yeeloong_verstr: .asciz "Version=LM8"
pmon_fuloong2f_verstr: .asciz "Version=LM6"
.p2align 2
argdone:

View file

@ -41,9 +41,9 @@ pic_base:
* After loading in that block we will execute it by jumping to the
* load address plus the size of the prepended A.OUT header (32 bytes).
*/
. = _start + GRUB_BOOT_MACHINE_BOOT_DEVPATH
.org GRUB_BOOT_MACHINE_BOOT_DEVPATH
boot_path:
. = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE
.org GRUB_BOOT_MACHINE_KERNEL_BYTE
boot_path_end:
kernel_byte: .xword (2 << 9)
kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR
@ -52,7 +52,7 @@ kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR
#define boot_path_end (_start + 1024)
#include <grub/offsets.h>
. = _start + 8
.org 8
kernel_byte: .xword (2 << 9)
kernel_size: .word 512
kernel_address: .word GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS
@ -224,7 +224,7 @@ bootpath_known:
#else
nop
#endif
. = _start + GRUB_BOOT_MACHINE_CODE_END
.org GRUB_BOOT_MACHINE_CODE_END
/* the last 4 bytes in the sector 0 contain the signature */
.word GRUB_BOOT_MACHINE_SIGNATURE

View file

@ -136,7 +136,7 @@ lastlist:
.word 0
.word 0
. = _start + (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE)
.org (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE)
blocklist_default_start:
.word 0
.word 2

View file

@ -55,7 +55,8 @@ grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base,
int err;
err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr);
if (err)
grub_util_error ("mapping 0x%x failed (error %d)\n", base, err);
grub_util_error ("mapping 0x%llx failed (error %d)\n",
(unsigned long long) base, err);
return addr;
}
@ -66,12 +67,12 @@ grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem,
pci_device_unmap_range (dev, mem, size);
}
GRUB_MOD_INIT (pci)
GRUB_MOD_INIT (emupci)
{
pci_system_init ();
}
GRUB_MOD_FINI (pci)
GRUB_MOD_FINI (emupci)
{
pci_system_cleanup ();
}

View file

@ -1,203 +0,0 @@
/* usb.c -- libusb USB support for GRUB. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <usb.h>
#include <grub/usb.h>
#include <grub/dl.h>
GRUB_MOD_LICENSE ("GPLv3+");
static struct grub_usb_controller_dev usb_controller =
{
.name = "libusb"
};
static struct grub_usb_device *grub_usb_devs[128];
struct usb_bus *busses;
static grub_err_t
grub_libusb_devices (void)
{
struct usb_bus *bus;
int last = 0;
busses = usb_get_busses();
for (bus = busses; bus; bus = bus->next)
{
struct usb_device *usbdev;
struct grub_usb_device *dev;
for (usbdev = bus->devices; usbdev; usbdev = usbdev->next)
{
struct usb_device_descriptor *desc = &usbdev->descriptor;
grub_err_t err;
if (! desc->bcdUSB)
continue;
dev = grub_malloc (sizeof (*dev));
if (! dev)
return grub_errno;
dev->data = usbdev;
/* Fill in all descriptors. */
err = grub_usb_device_initialize (dev);
if (err)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
/* Register the device. */
grub_usb_devs[last++] = dev;
}
}
return GRUB_USB_ERR_NONE;
}
void
grub_usb_poll_devices (void)
{
/* TODO: recheck grub_usb_devs */
}
int
grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data)
{
int i;
for (i = 0; i < 128; i++)
{
if (grub_usb_devs[i])
{
if (hook (grub_usb_devs[i], hook_data))
return 1;
}
}
return 0;
}
grub_usb_err_t
grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused)))
{
return GRUB_USB_ERR_NONE;
}
grub_usb_err_t
grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
grub_uint8_t request, grub_uint16_t value,
grub_uint16_t idx, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_control_msg (devh, reqtype, request,
value, idx, data, size, 20) < 0)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
usb_close (devh);
return GRUB_USB_ERR_NONE;
}
grub_usb_err_t
grub_usb_bulk_read (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_claim_interface (devh, 0) < 1)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
if (usb_bulk_read (devh, endpoint, data, size, 20) < 1)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
usb_release_interface (devh, 0);
usb_close (devh);
return GRUB_USB_ERR_NONE;
}
grub_usb_err_t
grub_usb_bulk_write (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_claim_interface (devh, 0) < 0)
goto fail;
if (usb_bulk_write (devh, endpoint, data, size, 20) < 0)
goto fail;
if (usb_release_interface (devh, 0) < 0)
goto fail;
usb_close (devh);
return GRUB_USB_ERR_NONE;
fail:
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
GRUB_MOD_INIT (libusb)
{
usb_init();
usb_find_busses();
usb_find_devices();
if (grub_libusb_devices ())
return;
grub_usb_controller_dev_register (&usb_controller);
return;
}
GRUB_MOD_FINI (libusb)
{
return;
}

View file

@ -625,9 +625,7 @@ grub_uhci_check_transfer (grub_usb_controller_t dev,
return GRUB_USB_ERR_NONE;
}
grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status);
if (!(errtd->ctrl_status & (1 << 23)))
if (errtd && !(errtd->ctrl_status & (1 << 23)))
{
grub_usb_err_t err = GRUB_USB_ERR_NONE;

View file

@ -31,7 +31,7 @@ grub_usb_bulk_maxpacket (grub_usb_device_t dev,
struct grub_usb_desc_endp *endpoint)
{
/* Use the maximum packet size given in the endpoint descriptor. */
if (dev->initialized && endpoint)
if (dev->initialized && endpoint && (unsigned int) endpoint->maxpacket)
return endpoint->maxpacket;
return 64;

View file

@ -131,6 +131,8 @@ grub_acpi_get_rsdpv1 (void)
return grub_machine_acpi_get_rsdpv1 ();
}
#if defined (__i386__) || defined (__x86_64__)
static inline int
iszero (grub_uint8_t *reg, int size)
{
@ -141,7 +143,6 @@ iszero (grub_uint8_t *reg, int size)
return 1;
}
#if defined (__i386__) || defined (__x86_64__)
/* Context for grub_acpi_create_ebda. */
struct grub_acpi_create_ebda_ctx {
int ebda_len;
@ -227,7 +228,7 @@ grub_acpi_create_ebda (void)
grub_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
v2inebda = target;
target += v2->length;
target = (grub_uint8_t *) ((((grub_addr_t) target - 1) | 0xf) + 1);
target = (grub_uint8_t *) ALIGN_UP((grub_addr_t) target, 16);
v2 = 0;
break;
}
@ -246,7 +247,7 @@ grub_acpi_create_ebda (void)
grub_dprintf ("acpi", "Copying rsdpv1 to %p\n", target);
v1inebda = target;
target += sizeof (struct grub_acpi_rsdp_v10);
target = (grub_uint8_t *) ((((grub_addr_t) target - 1) | 0xf) + 1);
target = (grub_uint8_t *) ALIGN_UP((grub_addr_t) target, 16);
v1 = 0;
break;
}
@ -265,7 +266,7 @@ grub_acpi_create_ebda (void)
grub_memcpy (target, v2, v2->length);
v2inebda = target;
target += v2->length;
target = (grub_uint8_t *) ((((grub_addr_t) target - 1) | 0xf) + 1);
target = (grub_uint8_t *) ALIGN_UP((grub_addr_t) target, 16);
v2 = 0;
break;
}
@ -282,7 +283,7 @@ grub_acpi_create_ebda (void)
grub_memcpy (target, v1, sizeof (struct grub_acpi_rsdp_v10));
v1inebda = target;
target += sizeof (struct grub_acpi_rsdp_v10);
target = (grub_uint8_t *) ((((grub_addr_t) target - 1) | 0xf) + 1);
target = (grub_uint8_t *) ALIGN_UP((grub_addr_t) target, 16);
v1 = 0;
break;
}

View file

@ -23,6 +23,8 @@
#include <grub/i18n.h>
#include <grub/disk.h>
GRUB_MOD_LICENSE ("GPLv3+");
static grub_err_t
grub_rescue_cmd_info (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),

View file

@ -476,8 +476,8 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
be at least 12 bytes and aligned on a 4-byte boundary. */
for (header = buffer;
((char *) header <=
(char *) buffer + len - (type == IS_MULTIBOOT2 ? 16 : 12))
|| (header = 0); header += step)
(char *) buffer + len - (type == IS_MULTIBOOT2 ? 16 : 12));
header += step)
{
if (header[0] == magic
&& !(grub_le_to_cpu32 (header[0])
@ -485,11 +485,12 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
+ grub_le_to_cpu32 (header[2])
+ (type == IS_MULTIBOOT2
? grub_le_to_cpu32 (header[3]) : 0)))
break;
{
ret = 1;
break;
}
}
if (header != 0)
ret = 1;
grub_free (buffer);
break;
}

View file

@ -40,10 +40,10 @@ grub_file_check_netbsdXX (grub_elf_t elf)
return 0;
if (grub_file_seek (elf->file, elf->ehdr.ehdrXX.e_shoff) == (grub_off_t) -1)
return 0;
goto fail;
if (grub_file_read (elf->file, s0, shsize) != (grub_ssize_t) shsize)
return 0;
goto fail;
s = (Elf_Shdr *) ((char *) s0 + elf->ehdr.ehdrXX.e_shstrndx * shentsize);
stroff = s->sh_offset;
@ -54,18 +54,21 @@ grub_file_check_netbsdXX (grub_elf_t elf)
char name[sizeof(".note.netbsd.ident")];
grub_memset (name, 0, sizeof (name));
if (grub_file_seek (elf->file, stroff + s->sh_name) == (grub_off_t) -1)
return grub_errno;
goto fail;
if (grub_file_read (elf->file, name, sizeof (name)) != (grub_ssize_t) sizeof (name))
{
if (grub_errno)
return grub_errno;
goto fail;
continue;
}
if (grub_memcmp (name, ".note.netbsd.ident",
sizeof(".note.netbsd.ident")) != 0)
continue;
grub_free (s0);
return 1;
}
fail:
grub_free (s0);
return 0;
}

View file

@ -235,6 +235,8 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
return grub_errno;
}
grub_device_close (dev);
grub_printf_ (N_("New MBR is written to `%s'\n"), args[0]);
return GRUB_ERR_NONE;

View file

@ -329,6 +329,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args)
break;
}
default:
grub_disk_close (disk);
return grub_error (GRUB_ERR_IO, "not an ATA device");
}

View file

@ -107,6 +107,14 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
return grub_errno;
}
if (!tempo)
{
grub_file_close (file);
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid tempo in %s"),
args[0]);
return grub_errno;
}
tempo = grub_le_to_cpu32 (tempo);
grub_dprintf ("play","tempo = %d\n", tempo);
@ -131,6 +139,13 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
tempo = grub_strtoul (args[0], &end, 0);
if (!tempo)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid tempo in %s"),
args[0]);
return grub_errno;
}
if (*end)
/* Was not a number either, assume it was supposed to be a file name. */
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), args[0]);

View file

@ -292,7 +292,7 @@ find_key_code (char *key)
{
unsigned i;
for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
for (i = 0; i < ARRAY_SIZE(keysym_table); i++)
{
if (keysym_table[i].unshifted_name
&& grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
@ -311,7 +311,7 @@ find_ascii_code (char *key)
{
unsigned i;
for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
for (i = 0; i < ARRAY_SIZE(keysym_table); i++)
{
if (keysym_table[i].unshifted_name
&& grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
@ -352,15 +352,13 @@ grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args)
{
unsigned i;
for (i = 0; i < sizeof (simple_flag_offsets)
/ sizeof (simple_flag_offsets[0]); i++)
for (i = 0; i < ARRAY_SIZE(simple_flag_offsets); i++)
grub_sendkey_set_simple_flag (simple_flag_offsets[i],
grub_sendkey_parse_op(state[i]));
}
/* Set noled. */
noled = (state[sizeof (simple_flag_offsets)
/ sizeof (simple_flag_offsets[0])].set);
noled = (state[ARRAY_SIZE(simple_flag_offsets)].set);
return GRUB_ERR_NONE;
}

View file

@ -57,14 +57,20 @@ legacy_file (const char *filename)
file = grub_file_open (filename);
if (! file)
return grub_errno;
{
grub_free (suffix);
return grub_errno;
}
menu = grub_env_get_menu ();
if (! menu)
{
menu = grub_zalloc (sizeof (*menu));
if (! menu)
return grub_errno;
{
grub_free (suffix);
return grub_errno;
}
grub_env_set_menu (menu);
}
@ -77,6 +83,7 @@ legacy_file (const char *filename)
if (!buf && grub_errno)
{
grub_file_close (file);
grub_free (suffix);
return grub_errno;
}
@ -173,6 +180,8 @@ legacy_file (const char *filename)
if (!args)
{
grub_file_close (file);
grub_free (suffix);
grub_free (entrysrc);
return grub_errno;
}
args[0] = entryname;
@ -376,6 +385,8 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
if (part && grub_strcmp (part->partmap->name, "msdos") == 0)
bsd_slice = part->number;
}
if (dev)
grub_device_close (dev);
}
/* k*BSD didn't really work well with grub-legacy. */

View file

@ -106,7 +106,7 @@ grub_mac_bless_inode (grub_device_t dev, grub_uint32_t inode, int is_dir,
ablk_size = grub_be_to_cpu32 (volheader.hfs.blksz);
ablk_start = grub_be_to_cpu16 (volheader.hfs.first_block);
embedded_offset = (ablk_start
+ extent_start
+ ((grub_uint64_t) extent_start)
* (ablk_size >> GRUB_DISK_SECTOR_BITS));
err =
@ -183,7 +183,7 @@ grub_cmd_macbless (grub_command_t cmd, int argc, char **args)
{
char *device_name;
char *path = 0;
grub_device_t dev;
grub_device_t dev = 0;
grub_err_t err;
if (argc != 1)
@ -197,13 +197,12 @@ grub_cmd_macbless (grub_command_t cmd, int argc, char **args)
else
path = path + 1;
if (!path || *path == 0 || !device_name)
if (!path || *path == 0 || !dev)
{
if (dev)
grub_device_close (dev);
grub_free (device_name);
grub_free (path);
return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
}

View file

@ -57,6 +57,7 @@ get_uuid (const char *name, char **uuid, int getnative)
if (!dev->disk)
{
grub_dprintf ("nativedisk", "Skipping non-disk\n");
grub_device_close (dev);
return 0;
}
@ -90,6 +91,7 @@ get_uuid (const char *name, char **uuid, int getnative)
case GRUB_DISK_DEVICE_MEMDISK_ID:
grub_dprintf ("nativedisk", "Skipping native disk %s\n",
dev->disk->name);
grub_device_close (dev);
return 0;
/* FIXME: those probably need special handling. */

View file

@ -243,11 +243,19 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
}
if (argc == 1)
return show_help (dev);
{
err = show_help (dev);
grub_device_close (dev);
return err;
}
for (i = 1; i < argc; i++)
if (grub_strcmp (args[i], "help") == 0)
return show_help (dev);
{
err = show_help (dev);
grub_device_close (dev);
return err;
}
parsed = (int *) grub_zalloc (argc * sizeof (int));
@ -274,8 +282,11 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
break;
}
if (! cur)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown argument `%s'"),
{
grub_device_close (dev);
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown argument `%s'"),
args[i]);
}
ptool = cur;
pargs = (struct grub_parttool_args *)
grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args));

View file

@ -119,7 +119,10 @@ syslinux_file (grub_extcmd_context_t ctxt, const char *filename)
{
menu = grub_zalloc (sizeof (*menu));
if (! menu)
return grub_errno;
{
grub_free (result);
return grub_errno;
}
grub_env_set_menu (menu);
}

View file

@ -332,7 +332,7 @@ test_parse (char **args, int *argn, int argc)
get_fileinfo (args[*argn + 1], &ctx);
update_val (ctx.file_exists && ctx.file_info.dir, &ctx);
(*argn) += 2;
return ctx.or || ctx.and;
continue;
}
if (grub_strcmp (args[*argn], "-e") == 0)
@ -340,7 +340,7 @@ test_parse (char **args, int *argn, int argc)
get_fileinfo (args[*argn + 1], &ctx);
update_val (ctx.file_exists, &ctx);
(*argn) += 2;
return ctx.or || ctx.and;
continue;
}
if (grub_strcmp (args[*argn], "-f") == 0)
@ -349,7 +349,7 @@ test_parse (char **args, int *argn, int argc)
/* FIXME: check for other types. */
update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx);
(*argn) += 2;
return ctx.or || ctx.and;
continue;
}
if (grub_strcmp (args[*argn], "-s") == 0)
@ -362,7 +362,7 @@ test_parse (char **args, int *argn, int argc)
grub_file_close (file);
grub_errno = GRUB_ERR_NONE;
(*argn) += 2;
return ctx.or || ctx.and;
continue;
}
/* String tests. */

View file

@ -80,7 +80,7 @@ grub_cmd_tr (grub_extcmd_context_t ctxt, int argc, char **args)
} else if (argc > 3)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters");
if (argc <= 0 && (!s1 || !s2 || !input))
if (!s1 || !s2 || !input)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing parameters");
if (grub_strlen (s1) != grub_strlen (s2))

View file

@ -33,6 +33,13 @@
GRUB_MOD_LICENSE ("GPLv3+");
struct grub_verified
{
grub_file_t file;
void *buf;
};
typedef struct grub_verified *grub_verified_t;
enum
{
OPTION_SKIP_SIG = 0
@ -301,7 +308,7 @@ grub_load_public_key (grub_file_t f)
if (!sk)
goto fail;
grub_memset (fingerprint_context, 0, sizeof (fingerprint_context));
grub_memset (fingerprint_context, 0, GRUB_MD_SHA1->contextsize);
GRUB_MD_SHA1->init (fingerprint_context);
GRUB_MD_SHA1->write (fingerprint_context, "\x99", 1);
len_be = grub_cpu_to_be16 (len);
@ -447,7 +454,7 @@ grub_verify_signature_real (char *buf, grub_size_t size,
grub_err_t err;
grub_size_t i;
gcry_mpi_t mpis[10];
grub_uint8_t type;
grub_uint8_t type = 0;
err = read_packet_header (sig, &type, &len);
if (err)
@ -802,19 +809,39 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
static int sec = 0;
static void
verified_free (grub_verified_t verified)
{
if (verified)
{
grub_free (verified->buf);
grub_free (verified);
}
}
static grub_ssize_t
verified_read (struct grub_file *file, char *buf, grub_size_t len)
{
grub_memcpy (buf, (char *) file->data + file->offset, len);
grub_verified_t verified = file->data;
grub_memcpy (buf, (char *) verified->buf + file->offset, len);
return len;
}
static grub_err_t
verified_close (struct grub_file *file)
{
grub_free (file->data);
grub_verified_t verified = file->data;
grub_file_close (verified->file);
verified_free (verified);
file->data = 0;
return GRUB_ERR_NONE;
/* device and name are freed by parent */
file->device = 0;
file->name = 0;
return grub_errno;
}
struct grub_fs verified_fs =
@ -832,6 +859,7 @@ grub_pubkey_open (grub_file_t io, const char *filename)
grub_err_t err;
grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX];
grub_file_t ret;
grub_verified_t verified;
if (!sec)
return io;
@ -857,7 +885,10 @@ grub_pubkey_open (grub_file_t io, const char *filename)
ret = grub_malloc (sizeof (*ret));
if (!ret)
return NULL;
{
grub_file_close (sig);
return NULL;
}
*ret = *io;
ret->fs = &verified_fs;
@ -866,29 +897,46 @@ grub_pubkey_open (grub_file_t io, const char *filename)
{
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"big file signature isn't implemented yet");
return NULL;
}
ret->data = grub_malloc (ret->size);
if (!ret->data)
{
grub_file_close (sig);
grub_free (ret);
return NULL;
}
if (grub_file_read (io, ret->data, ret->size) != (grub_ssize_t) ret->size)
verified = grub_malloc (sizeof (*verified));
if (!verified)
{
grub_file_close (sig);
grub_free (ret);
return NULL;
}
verified->buf = grub_malloc (ret->size);
if (!verified->buf)
{
grub_file_close (sig);
grub_free (verified);
grub_free (ret);
return NULL;
}
if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
filename);
grub_file_close (sig);
verified_free (verified);
grub_free (ret);
return NULL;
}
err = grub_verify_signature_real (ret->data, ret->size, 0, sig, NULL);
err = grub_verify_signature_real (verified->buf, ret->size, 0, sig, NULL);
grub_file_close (sig);
if (err)
return NULL;
io->device = 0;
io->name = 0;
grub_file_close (io);
{
verified_free (verified);
grub_free (ret);
return NULL;
}
verified->file = io;
ret->data = verified;
return ret;
}

View file

@ -245,7 +245,10 @@ match_devices_iter (const char *name, void *data)
t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
if (! t)
return 1;
{
grub_free (buffer);
return 1;
}
ctx->devs = t;
ctx->devs[ctx->ndev++] = buffer;
@ -290,7 +293,8 @@ struct match_files_ctx
/* Helper for match_files. */
static int
match_files_iter (const char *name, const struct grub_dirhook_info *info,
match_files_iter (const char *name,
const struct grub_dirhook_info *info __attribute__((unused)),
void *data)
{
struct match_files_ctx *ctx = data;

View file

@ -72,13 +72,13 @@ AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_uint8_t * dst,
grub_size_t i;
grub_uint8_t *bufblock;
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN || hash->mdlen == 0)
return GPG_ERR_INV_ARG;
bufblock = grub_zalloc (blocksize);
if (bufblock == NULL)
return GPG_ERR_OUT_OF_MEMORY;
if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN)
return GPG_ERR_INV_ARG;
grub_memset (bufblock, 0, blocksize);
for (i = 0; i < blocknumbers - 1; i++)
{

View file

@ -198,7 +198,7 @@ grub_ahci_pciinit (grub_pci_device_t dev,
| GRUB_PCI_COMMAND_MEM_ENABLED);
hba = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK,
sizeof (hba));
sizeof (*hba));
grub_dprintf ("ahci", "dev: %x:%x.%x\n", dev.bus, dev.device, dev.function);
grub_dprintf ("ahci", "tfd[0]: %x\n",

View file

@ -216,6 +216,12 @@ grub_ata_setaddress (struct grub_ata *dev,
unsigned int head;
unsigned int sect;
if (dev->sectors_per_track == 0
|| dev->heads == 0)
return grub_error (GRUB_ERR_OUT_OF_RANGE,
"sector %d cannot be addressed "
"using CHS addressing", sector);
/* Calculate the sector, cylinder and head to use. */
sect = ((grub_uint32_t) sector % dev->sectors_per_track) + 1;
cylinder = (((grub_uint32_t) sector / dev->sectors_per_track)

View file

@ -110,20 +110,23 @@ grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher,
{
grub_uint8_t *inptr, *outptr, *end;
grub_uint8_t ivt[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
if (cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
return GPG_ERR_INV_ARG;
grub_size_t blocksize;
if (!cipher->cipher->decrypt)
return GPG_ERR_NOT_SUPPORTED;
if (size % cipher->cipher->blocksize != 0)
blocksize = cipher->cipher->blocksize;
if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
|| ((size & (blocksize - 1)) != 0))
return GPG_ERR_INV_ARG;
if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
return GPG_ERR_INV_ARG;
end = (grub_uint8_t *) in + size;
for (inptr = in, outptr = out; inptr < end;
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
inptr += blocksize, outptr += blocksize)
{
grub_memcpy (ivt, inptr, cipher->cipher->blocksize);
grub_memcpy (ivt, inptr, blocksize);
cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize);
grub_crypto_xor (iv, ivt, outptr, cipher->cipher->blocksize);
grub_crypto_xor (outptr, outptr, iv, blocksize);
grub_crypto_xor (iv, ivt, outptr, blocksize);
}
return GPG_ERR_NO_ERROR;
}
@ -135,20 +138,23 @@ grub_crypto_pcbc_encrypt (grub_crypto_cipher_handle_t cipher,
{
grub_uint8_t *inptr, *outptr, *end;
grub_uint8_t ivt[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
if (cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
return GPG_ERR_INV_ARG;
if (!cipher->cipher->decrypt)
grub_size_t blocksize;
if (!cipher->cipher->encrypt)
return GPG_ERR_NOT_SUPPORTED;
if (size % cipher->cipher->blocksize != 0)
blocksize = cipher->cipher->blocksize;
if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
return GPG_ERR_INV_ARG;
if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
|| ((size & (blocksize - 1)) != 0))
return GPG_ERR_INV_ARG;
end = (grub_uint8_t *) in + size;
for (inptr = in, outptr = out; inptr < end;
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
inptr += blocksize, outptr += blocksize)
{
grub_memcpy (ivt, inptr, cipher->cipher->blocksize);
grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize);
grub_memcpy (ivt, inptr, blocksize);
grub_crypto_xor (outptr, outptr, iv, blocksize);
cipher->cipher->encrypt (cipher->ctx, outptr, inptr);
grub_crypto_xor (iv, ivt, outptr, cipher->cipher->blocksize);
grub_crypto_xor (iv, ivt, outptr, blocksize);
}
return GPG_ERR_NO_ERROR;
}
@ -372,11 +378,13 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
break;
case GRUB_CRYPTODISK_MODE_ECB:
if (do_encrypt)
grub_crypto_ecb_encrypt (dev->cipher, data + i, data + i,
(1U << dev->log_sector_size));
err = grub_crypto_ecb_encrypt (dev->cipher, data + i, data + i,
(1U << dev->log_sector_size));
else
grub_crypto_ecb_decrypt (dev->cipher, data + i, data + i,
(1U << dev->log_sector_size));
err = grub_crypto_ecb_decrypt (dev->cipher, data + i, data + i,
(1U << dev->log_sector_size));
if (err)
return err;
break;
default:
return GPG_ERR_NOT_IMPLEMENTED;

View file

@ -71,10 +71,12 @@ is_lv_readable (struct grub_diskfilter_lv *lv, int easily)
case GRUB_DISKFILTER_RAID6:
if (!easily)
need--;
/* Fallthrough. */
case GRUB_DISKFILTER_RAID4:
case GRUB_DISKFILTER_RAID5:
if (!easily)
need--;
/* Fallthrough. */
case GRUB_DISKFILTER_STRIPED:
break;
@ -483,6 +485,96 @@ grub_diskfilter_read_node (const struct grub_diskfilter_node *node,
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown node '%s'", node->name);
}
static grub_err_t
validate_segment (struct grub_diskfilter_segment *seg);
static grub_err_t
validate_lv (struct grub_diskfilter_lv *lv)
{
unsigned int i;
if (!lv)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown volume");
if (!lv->vg || lv->vg->extent_size == 0)
return grub_error (GRUB_ERR_READ_ERROR, "invalid volume");
for (i = 0; i < lv->segment_count; i++)
{
grub_err_t err;
err = validate_segment (&lv->segments[i]);
if (err)
return err;
}
return GRUB_ERR_NONE;
}
static grub_err_t
validate_node (const struct grub_diskfilter_node *node)
{
/* Check whether we actually know the physical volume we want to
read from. */
if (node->pv)
return GRUB_ERR_NONE;
if (node->lv)
return validate_lv (node->lv);
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown node '%s'", node->name);
}
static grub_err_t
validate_segment (struct grub_diskfilter_segment *seg)
{
grub_err_t err;
if (seg->stripe_size == 0 || seg->node_count == 0)
return grub_error(GRUB_ERR_BAD_FS, "invalid segment");
switch (seg->type)
{
case GRUB_DISKFILTER_RAID10:
{
grub_uint8_t near, far;
near = seg->layout & 0xFF;
far = (seg->layout >> 8) & 0xFF;
if ((seg->layout >> 16) == 0 && far == 0)
return grub_error(GRUB_ERR_BAD_FS, "invalid segment");
if (near > seg->node_count)
return grub_error(GRUB_ERR_BAD_FS, "invalid segment");
break;
}
case GRUB_DISKFILTER_STRIPED:
case GRUB_DISKFILTER_MIRROR:
break;
case GRUB_DISKFILTER_RAID4:
case GRUB_DISKFILTER_RAID5:
if (seg->node_count <= 1)
return grub_error(GRUB_ERR_BAD_FS, "invalid segment");
break;
case GRUB_DISKFILTER_RAID6:
if (seg->node_count <= 2)
return grub_error(GRUB_ERR_BAD_FS, "invalid segment");
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unsupported RAID level %d", seg->type);
}
unsigned i;
for (i = 0; i < seg->node_count; i++)
{
err = validate_node (&seg->nodes[i]);
if (err)
return err;
}
return GRUB_ERR_NONE;
}
static grub_err_t
read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector,
grub_size_t size, char *buf)
@ -494,6 +586,7 @@ read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector,
if (seg->node_count == 1)
return grub_diskfilter_read_node (&seg->nodes[0],
sector, size, buf);
/* Fallthrough. */
case GRUB_DISKFILTER_MIRROR:
case GRUB_DISKFILTER_RAID10:
{
@ -848,6 +941,23 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
for (lv = vg->lvs; lv; lv = lv->next)
{
grub_err_t err;
/* RAID 1 and single-disk RAID 0 don't use a chunksize but code
assumes one so set one. */
for (i = 0; i < lv->segment_count; i++)
{
if (lv->segments[i].type == 1)
lv->segments[i].stripe_size = 64;
if (lv->segments[i].type == GRUB_DISKFILTER_STRIPED
&& lv->segments[i].node_count == 1
&& lv->segments[i].stripe_size == 0)
lv->segments[i].stripe_size = 64;
}
err = validate_lv(lv);
if (err)
return err;
lv->number = lv_num++;
if (lv->fullname)
@ -888,12 +998,6 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
lv->fullname = tmp;
}
}
/* RAID 1 doesn't use a chunksize but code assumes one so set
one. */
for (i = 0; i < lv->segment_count; i++)
if (lv->segments[i].type == 1)
lv->segments[i].stripe_size = 64;
lv->vg = vg;
}
/* Add our new array to the list. */
vg->next = array_list;
@ -926,6 +1030,11 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
n = layout & 0xFF;
if (n == 1)
n = (layout >> 8) & 0xFF;
if (n == 0)
{
grub_free (uuid);
return NULL;
}
totsize = grub_divmod64 (nmemb * disk_size, n, 0);
}
@ -939,6 +1048,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
break;
default:
grub_free (uuid);
return NULL;
}
@ -952,7 +1062,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
array->lvs->segments->extent_count = totsize;
}
if (array->lvs->segments
if (array->lvs && array->lvs->segments
&& array->lvs->segments->raid_member_size > disk_size)
array->lvs->segments->raid_member_size = disk_size;
@ -961,7 +1071,10 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
}
array = grub_zalloc (sizeof (*array));
if (!array)
return NULL;
{
grub_free (uuid);
return NULL;
}
array->uuid = uuid;
array->uuid_len = uuidlen;
if (name)
@ -983,8 +1096,16 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
goto fail;
array->lvs->segment_count = 1;
array->lvs->visible = 1;
array->lvs->name = array->name;
array->lvs->fullname = array->name;
if (array->name)
{
array->lvs->name = grub_strdup (array->name);
if (!array->lvs->name)
goto fail;
array->lvs->fullname = grub_strdup (array->name);
if (!array->lvs->fullname)
goto fail;
}
array->lvs->vg = array;
array->lvs->idname = grub_malloc (sizeof ("mduuid/") + 2 * uuidlen);
if (!array->lvs->idname)
@ -1034,13 +1155,26 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
return array;
fail:
grub_free (array->lvs);
if (array->lvs)
{
grub_free (array->lvs->name);
grub_free (array->lvs->fullname);
grub_free (array->lvs->idname);
if (array->lvs->segments)
{
grub_free (array->lvs->segments->nodes);
grub_free (array->lvs->segments);
}
grub_free (array->lvs);
}
while (array->pvs)
{
pv = array->pvs->next;
grub_free (array->pvs);
array->pvs = pv;
}
grub_free (array->name);
grub_free (array->uuid);
grub_free (array);
return NULL;
}
@ -1143,10 +1277,9 @@ free_array (void)
{
unsigned i;
vg->lvs = lv->next;
if (lv->name != lv->fullname)
grub_free (lv->fullname);
if (lv->name != vg->name)
grub_free (lv->name);
grub_free (lv->fullname);
grub_free (lv->name);
grub_free (lv->idname);
for (i = 0; i < lv->segment_count; i++)
grub_free (lv->segments[i].nodes);
grub_free (lv->segments);

View file

@ -99,6 +99,8 @@ grub_dmraid_nv_detect (grub_disk_t disk,
struct grub_nv_super sb;
int level;
grub_uint64_t disk_size;
grub_uint32_t capacity;
grub_uint8_t total_volumes;
char *uuid;
if (disk->partition)
@ -124,11 +126,17 @@ grub_dmraid_nv_detect (grub_disk_t disk,
return NULL;
}
capacity = grub_le_to_cpu32 (sb.capacity);
total_volumes = sb.array.total_volumes;
switch (sb.array.raid_level)
{
case NV_LEVEL_0:
level = 0;
disk_size = sb.capacity / sb.array.total_volumes;
if (total_volumes == 0)
/* Not RAID. */
return NULL;
disk_size = capacity / total_volumes;
break;
case NV_LEVEL_1:
@ -138,7 +146,10 @@ grub_dmraid_nv_detect (grub_disk_t disk,
case NV_LEVEL_5:
level = 5;
disk_size = sb.capacity / (sb.array.total_volumes - 1);
if (total_volumes == 0 || total_volumes == 1)
/* Not RAID. */
return NULL;
disk_size = capacity / (total_volumes - 1);
break;
default:

View file

@ -803,7 +803,6 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
{
int is_cdrom = 0;
struct grub_efidisk_get_device_name_ctx ctx;
char *dev_name;
grub_efi_device_path_t *dup_dp;
@ -824,9 +823,6 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)))
break;
if (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE)
is_cdrom = 1;
dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
dup_ldp->length = sizeof (*dup_ldp);
@ -861,10 +857,13 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
if (! ctx.partition_name)
{
/* No partition found. In most cases partition is embed in
the root path anyway, so this is not critical.
This happens only if partition is on partmap that GRUB
doesn't need to access root.
*/
grub_disk_close (parent);
if (is_cdrom)
return grub_strdup (device_name);
return 0;
return grub_strdup (device_name);
}
dev_name = grub_xasprintf ("%s,%s", parent->name,

View file

@ -212,7 +212,8 @@ grub_util_get_geli_uuid (const char *dev)
s = grub_util_get_fd_size (fd, dev, &log_secsize);
s >>= log_secsize;
grub_util_fd_seek (fd, (s << log_secsize) - 512);
if (grub_util_fd_seek (fd, (s << log_secsize) - 512) < 0)
grub_util_error ("%s", _("couldn't read ELI metadata"));
uuid = xmalloc (GRUB_MD_SHA256->mdlen * 2 + 1);
if (grub_util_fd_read (fd, (void *) &hdr, 512) < 0)
@ -225,13 +226,16 @@ grub_util_get_geli_uuid (const char *dev)
/* Look for GELI magic sequence. */
if (grub_memcmp (header->magic, GELI_MAGIC, sizeof (GELI_MAGIC))
|| grub_le_to_cpu32 (header->version) > 5
|| grub_le_to_cpu32 (header->version) > 7
|| grub_le_to_cpu32 (header->version) < 1)
grub_util_error ("%s", _("wrong ELI magic or version"));
err = make_uuid ((void *) &hdr, uuid);
if (err)
return NULL;
{
grub_free (uuid);
return NULL;
}
return uuid;
}
@ -265,7 +269,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
/* Look for GELI magic sequence. */
if (grub_memcmp (header.magic, GELI_MAGIC, sizeof (GELI_MAGIC))
|| grub_le_to_cpu32 (header.version) > 5
|| grub_le_to_cpu32 (header.version) > 7
|| grub_le_to_cpu32 (header.version) < 1)
{
grub_dprintf ("geli", "wrong magic %02x\n", header.magic[0]);
@ -332,19 +336,29 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
{
secondary_cipher = grub_crypto_cipher_open (ciph);
if (!secondary_cipher)
return NULL;
{
grub_crypto_cipher_close (cipher);
return NULL;
}
}
if (grub_le_to_cpu16 (header.keylen) > 1024)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d",
grub_le_to_cpu16 (header.keylen));
grub_crypto_cipher_close (cipher);
grub_crypto_cipher_close (secondary_cipher);
return NULL;
}
newdev = grub_zalloc (sizeof (struct grub_cryptodisk));
if (!newdev)
return NULL;
{
grub_crypto_cipher_close (cipher);
grub_crypto_cipher_close (secondary_cipher);
return NULL;
}
newdev->cipher = cipher;
newdev->secondary_cipher = secondary_cipher;
newdev->offset = 0;
@ -391,6 +405,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
grub_uint8_t geomkey[GRUB_CRYPTO_MAX_MDLEN];
grub_uint8_t verify_key[GRUB_CRYPTO_MAX_MDLEN];
grub_uint8_t zero[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
grub_uint8_t geli_cipher_key[64];
char passphrase[MAX_PASSPHRASE] = "";
unsigned i;
gcry_err_code_t gcry_err;
@ -514,6 +529,19 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
continue;
grub_printf_ (N_("Slot %d opened\n"), i);
if (grub_le_to_cpu32 (header.version) >= 7)
{
/* GELI >=7 uses the cipher_key */
grub_memcpy (geli_cipher_key, candidate_key.cipher_key,
sizeof (candidate_key.cipher_key));
}
else
{
/* GELI <=6 uses the iv_key */
grub_memcpy (geli_cipher_key, candidate_key.iv_key,
sizeof (candidate_key.iv_key));
}
/* Set the master key. */
if (!dev->rekey)
{
@ -530,13 +558,13 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
grub_size_t real_keysize = keysize;
if (grub_le_to_cpu16 (header.alg) == 0x16)
real_keysize *= 2;
/* For a reason I don't know, the IV key is used in rekeying. */
grub_memcpy (dev->rekey_key, candidate_key.iv_key,
sizeof (candidate_key.iv_key));
grub_memcpy (dev->rekey_key, geli_cipher_key,
sizeof (geli_cipher_key));
dev->rekey_derived_size = real_keysize;
dev->last_rekey = -1;
COMPILE_TIME_ASSERT (sizeof (dev->rekey_key)
>= sizeof (candidate_key.iv_key));
>= sizeof (geli_cipher_key));
}
dev->iv_prefix_len = sizeof (candidate_key.iv_key);

View file

@ -382,7 +382,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
/* Some buggy BIOSes doesn't return the total sectors
correctly but returns zero. So if it is zero, compute
it by C/H/S returned by the LBA BIOS call. */
total_sectors = drp->cylinders * drp->heads * drp->sectors;
total_sectors = ((grub_uint64_t) drp->cylinders)
* drp->heads * drp->sectors;
if (drp->bytes_per_sector
&& !(drp->bytes_per_sector & (drp->bytes_per_sector - 1))
&& drp->bytes_per_sector >= 512
@ -419,8 +420,14 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
}
}
if (data->sectors == 0)
data->sectors = 63;
if (data->heads == 0)
data->heads = 255;
if (! total_sectors)
total_sectors = data->cylinders * data->heads * data->sectors;
total_sectors = ((grub_uint64_t) data->cylinders)
* data->heads * data->sectors;
}
disk->total_sectors = total_sectors;

View file

@ -113,6 +113,11 @@ grub_nand_open (const char *name, grub_disk_t disk)
}
data->block_size = (args.size1 >> GRUB_DISK_SECTOR_BITS);
if (!data->block_size)
{
grub_error (GRUB_ERR_UNKNOWN_DEVICE, "invalid block size");
goto fail;
}
INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3);
args.method = (grub_ieee1275_cell_t) "size";

View file

@ -34,7 +34,8 @@ struct ofdisk_hash_ent
char *open_path;
char *grub_devpath;
int is_boot;
int is_cdrom;
int is_removable;
int block_size_fails;
/* Pointer to shortest available name on nodes representing canonical names,
otherwise NULL. */
const char *shortest;
@ -42,6 +43,10 @@ struct ofdisk_hash_ent
struct ofdisk_hash_ent *next;
};
static grub_err_t
grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
struct ofdisk_hash_ent *op);
#define OFDISK_HASH_SZ 8
static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ];
@ -123,7 +128,7 @@ ofdisk_hash_add_real (char *devpath)
}
static int
check_string_cdrom (const char *str)
check_string_removable (const char *str)
{
const char *ptr = grub_strrchr (str, '/');
@ -131,7 +136,7 @@ check_string_cdrom (const char *str)
ptr++;
else
ptr = str;
return (grub_strncmp (ptr, "cdrom", 5) == 0);
return (grub_strncmp (ptr, "cdrom", 5) == 0 || grub_strncmp (ptr, "fd", 2) == 0);
}
static struct ofdisk_hash_ent *
@ -147,8 +152,8 @@ ofdisk_hash_add (char *devpath, char *curcan)
{
p->shortest = p->devpath;
p->grub_shortest = p->grub_devpath;
if (check_string_cdrom (devpath))
p->is_cdrom = 1;
if (check_string_removable (devpath))
p->is_removable = 1;
return p;
}
@ -158,8 +163,8 @@ ofdisk_hash_add (char *devpath, char *curcan)
else
grub_free (curcan);
if (check_string_cdrom (devpath) || check_string_cdrom (curcan))
pcan->is_cdrom = 1;
if (check_string_removable (devpath) || check_string_removable (curcan))
pcan->is_removable = 1;
if (!pcan)
grub_errno = GRUB_ERR_NONE;
@ -330,7 +335,7 @@ grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
}
}
if (!ent->is_boot && ent->is_cdrom)
if (!ent->is_boot && ent->is_removable)
continue;
if (hook (ent->grub_shortest, hook_data))
@ -375,6 +380,8 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
/* XXX: This should be large enough for any possible case. */
char prop[64];
grub_ssize_t actual;
grub_uint32_t block_size = 0;
grub_err_t err;
if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
@ -405,14 +412,6 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device");
}
grub_uint32_t block_size = 0;
if (grub_ofdisk_get_block_size (devpath, &block_size) == 0)
{
for (disk->log_sector_size = 0;
(1U << disk->log_sector_size) < block_size;
disk->log_sector_size++);
}
/* XXX: There is no property to read the number of blocks. There
should be a property `#blocks', but it is not there. Perhaps it
is possible to use seek for this. */
@ -429,6 +428,18 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
return grub_errno;
disk->id = (unsigned long) op;
disk->data = op->open_path;
err = grub_ofdisk_get_block_size (devpath, &block_size, op);
if (err)
return err;
if (block_size != 0)
{
for (disk->log_sector_size = 0;
(1U << disk->log_sector_size) < block_size;
disk->log_sector_size++);
}
else
disk->log_sector_size = 9;
}
return 0;
@ -589,8 +600,9 @@ grub_ofdisk_init (void)
grub_disk_dev_register (&grub_ofdisk_dev);
}
grub_err_t
grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size)
static grub_err_t
grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
struct ofdisk_hash_ent *op)
{
struct size_args_ieee1275
{
@ -612,20 +624,34 @@ grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size)
if (! last_ihandle)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
*block_size = 0;
if (op->block_size_fails >= 2)
return GRUB_ERR_NONE;
INIT_IEEE1275_COMMON (&args_ieee1275.common, "call-method", 2, 2);
args_ieee1275.method = (grub_ieee1275_cell_t) "block-size";
args_ieee1275.ihandle = last_ihandle;
args_ieee1275.result = 1;
*block_size = GRUB_DISK_SECTOR_SIZE;
if ((IEEE1275_CALL_ENTRY_FN (&args_ieee1275) == -1) || (args_ieee1275.result))
grub_dprintf ("disk", "can't get block size\n");
else
if (args_ieee1275.size1
&& !(args_ieee1275.size1 & (args_ieee1275.size1 - 1))
&& args_ieee1275.size1 >= 512 && args_ieee1275.size1 <= 16384)
if (IEEE1275_CALL_ENTRY_FN (&args_ieee1275) == -1)
{
grub_dprintf ("disk", "can't get block size: failed call-method\n");
op->block_size_fails++;
}
else if (args_ieee1275.result)
{
grub_dprintf ("disk", "can't get block size: %lld\n",
(long long) args_ieee1275.result);
op->block_size_fails++;
}
else if (args_ieee1275.size1
&& !(args_ieee1275.size1 & (args_ieee1275.size1 - 1))
&& args_ieee1275.size1 >= 512 && args_ieee1275.size1 <= 16384)
{
op->block_size_fails = 0;
*block_size = args_ieee1275.size1;
}
return 0;
}

View file

@ -143,6 +143,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d",
grub_be_to_cpu32 (header.keyBytes));
grub_crypto_cipher_close (cipher);
return NULL;
}
@ -181,9 +182,10 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
}
if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
{
grub_crypto_cipher_close (cipher);
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
cipher->cipher->blocksize);
grub_crypto_cipher_close (cipher);
grub_crypto_cipher_close (secondary_cipher);
return NULL;
}
if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
@ -191,6 +193,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
grub_crypto_cipher_close (cipher);
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
secondary_cipher->cipher->blocksize);
grub_crypto_cipher_close (secondary_cipher);
return NULL;
}
}
@ -200,9 +203,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
cipheriv = ciphermode + sizeof ("lrw-") - 1;
if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
{
grub_crypto_cipher_close (cipher);
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d",
cipher->cipher->blocksize);
grub_crypto_cipher_close (cipher);
return NULL;
}
}
@ -225,6 +228,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
|| cipher->cipher->blocksize == 0)
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported benbi blocksize: %d",
cipher->cipher->blocksize);
/* FIXME should we return an error here? */
for (benbi_log = 0;
(cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE;
benbi_log++);
@ -243,6 +247,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
if (!essiv_hash)
{
grub_crypto_cipher_close (cipher);
grub_crypto_cipher_close (secondary_cipher);
grub_error (GRUB_ERR_FILE_NOT_FOUND,
"Couldn't load %s hash", hash_str);
return NULL;
@ -251,12 +256,14 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
if (!essiv_cipher)
{
grub_crypto_cipher_close (cipher);
grub_crypto_cipher_close (secondary_cipher);
return NULL;
}
}
else
{
grub_crypto_cipher_close (cipher);
grub_crypto_cipher_close (secondary_cipher);
grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s",
cipheriv);
return NULL;
@ -276,7 +283,12 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
newdev = grub_zalloc (sizeof (struct grub_cryptodisk));
if (!newdev)
return NULL;
{
grub_crypto_cipher_close (cipher);
grub_crypto_cipher_close (essiv_cipher);
grub_crypto_cipher_close (secondary_cipher);
return NULL;
}
newdev->cipher = cipher;
newdev->offset = grub_be_to_cpu32 (header.payloadOffset);
newdev->source_disk = NULL;
@ -451,6 +463,7 @@ luks_recover_key (grub_disk_t source,
return GRUB_ERR_NONE;
}
grub_free (split_key);
return GRUB_ACCESS_DENIED;
}

View file

@ -426,7 +426,7 @@ grub_lvm_detect (grub_disk_t disk,
#endif
goto lvs_fail;
}
lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
lv->segments = grub_zalloc (sizeof (*seg) * lv->segment_count);
seg = lv->segments;
for (i = 0; i < lv->segment_count; i++)
@ -577,13 +577,17 @@ grub_lvm_detect (grub_disk_t disk,
if (is_pvmove)
seg->node_count = 1;
}
else if (grub_memcmp (p, "raid", sizeof ("raid") - 1)
== 0 && (p[sizeof ("raid") - 1] >= '4'
&& p[sizeof ("raid") - 1] <= '6')
else if (grub_memcmp (p, "raid", sizeof ("raid") - 1) == 0
&& ((p[sizeof ("raid") - 1] >= '4'
&& p[sizeof ("raid") - 1] <= '6')
|| p[sizeof ("raid") - 1] == '1')
&& p[sizeof ("raidX") - 1] == '"')
{
switch (p[sizeof ("raid") - 1])
{
case '1':
seg->type = GRUB_DISKFILTER_MIRROR;
break;
case '4':
seg->type = GRUB_DISKFILTER_RAID4;
seg->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC;
@ -608,16 +612,18 @@ grub_lvm_detect (grub_disk_t disk,
goto lvs_segment_fail;
}
seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
if (p == NULL)
if (seg->type != GRUB_DISKFILTER_MIRROR)
{
seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
if (p == NULL)
{
#ifdef GRUB_UTIL
grub_util_info ("unknown stripe_size\n");
grub_util_info ("unknown stripe_size\n");
#endif
goto lvs_segment_fail;
goto lvs_segment_fail;
}
}
seg->nodes = grub_zalloc (sizeof (seg->nodes[0])
* seg->node_count);
@ -625,7 +631,7 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL)
{
#ifdef GRUB_UTIL
grub_util_info ("unknown mirrors\n");
grub_util_info ("unknown raids\n");
#endif
goto lvs_segment_fail2;
}

View file

@ -63,6 +63,16 @@ grub_raid6_init_table (void)
}
}
static unsigned
mod_255 (unsigned x)
{
while (x > 0xff)
x = (x >> 8) + (x & 0xff);
if (x == 0xff)
return 0;
return x;
}
static grub_err_t
grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p,
char *buf, grub_disk_addr_t sector, grub_size_t size)
@ -162,11 +172,11 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p,
grub_crypto_xor (qbuf, qbuf, buf, size);
c = ((255 ^ bad1)
+ (255 ^ powx_inv[(powx[bad2 + (bad1 ^ 255)] ^ 1)])) % 255;
c = mod_255((255 ^ bad1)
+ (255 ^ powx_inv[(powx[bad2 + (bad1 ^ 255)] ^ 1)]));
grub_raid_block_mulx (c, qbuf, size);
c = ((unsigned) bad2 + c) % 255;
c = mod_255((unsigned) bad2 + c);
grub_raid_block_mulx (c, pbuf, size);
grub_crypto_xor (pbuf, pbuf, qbuf, size);

View file

@ -40,6 +40,7 @@ struct virtdisk
grub_xen_evtchn_t evtchn;
void *dma_page;
grub_xen_grant_t dma_grant;
struct virtdisk *compat_next;
};
#define xen_wmb() mb()
@ -47,6 +48,7 @@ struct virtdisk
static struct virtdisk *virtdisks;
static grub_size_t vdiskcnt;
struct virtdisk *compat_head;
static int
grub_virtdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
@ -66,20 +68,32 @@ grub_virtdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
static grub_err_t
grub_virtdisk_open (const char *name, grub_disk_t disk)
{
grub_size_t i;
int i;
grub_uint32_t secsize;
char fdir[200];
char *buf;
int num = -1;
struct virtdisk *vd;
for (i = 0; i < vdiskcnt; i++)
if (grub_strcmp (name, virtdisks[i].fullname) == 0)
/* For compatibility with pv-grub legacy menu.lst accept hdX as disk name */
if (name[0] == 'h' && name[1] == 'd' && name[2])
{
num = grub_strtoul (name + 2, 0, 10);
if (grub_errno)
{
grub_errno = 0;
num = -1;
}
}
for (i = 0, vd = compat_head; vd; vd = vd->compat_next, i++)
if (i == num || grub_strcmp (name, vd->fullname) == 0)
break;
if (i == vdiskcnt)
if (!vd)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a virtdisk");
disk->data = &virtdisks[i];
disk->id = i;
disk->data = vd;
disk->id = vd - virtdisks;
grub_snprintf (fdir, sizeof (fdir), "%s/sectors", virtdisks[i].backend_dir);
grub_snprintf (fdir, sizeof (fdir), "%s/sectors", vd->backend_dir);
buf = grub_xenstore_get_file (fdir, NULL);
if (!buf)
return grub_errno;
@ -87,8 +101,7 @@ grub_virtdisk_open (const char *name, grub_disk_t disk)
if (grub_errno)
return grub_errno;
grub_snprintf (fdir, sizeof (fdir), "%s/sector-size",
virtdisks[i].backend_dir);
grub_snprintf (fdir, sizeof (fdir), "%s/sector-size", vd->backend_dir);
buf = grub_xenstore_get_file (fdir, NULL);
if (!buf)
return grub_errno;
@ -264,6 +277,7 @@ fill (const char *dir, void *data)
grub_err_t err;
void *buf;
struct evtchn_alloc_unbound alloc_unbound;
struct virtdisk **prev = &compat_head, *vd = compat_head;
/* Shouldn't happen unles some hotplug happened. */
if (vdiskcnt >= *ctr)
@ -374,6 +388,19 @@ fill (const char *dir, void *data)
virtdisks[vdiskcnt].frontend_dir = grub_strdup (fdir);
/* For compatibility with pv-grub maintain linked list sorted by handle
value in increasing order. This allows mapping of (hdX) disk names
from legacy menu.lst */
while (vd)
{
if (vd->handle > virtdisks[vdiskcnt].handle)
break;
prev = &vd->compat_next;
vd = vd->compat_next;
}
virtdisks[vdiskcnt].compat_next = vd;
*prev = &virtdisks[vdiskcnt];
vdiskcnt++;
return 0;

View file

@ -777,6 +777,7 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
if (grub_file_read (font->file, glyph->bitmap, len) != len)
{
remove_font (font);
grub_free (glyph);
return 0;
}
}
@ -1285,7 +1286,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
- grub_font_get_xheight (combining_glyphs[i]->font) - 1;
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
/* Fallthrough. */
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
do_blit (combining_glyphs[i], targetx,
-(ctx.bounds.height + ctx.bounds.y + space
@ -1326,6 +1327,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
+ combining_glyphs[i]->height);
if (space <= 0)
space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
/* Fallthrough. */
case GRUB_UNICODE_STACK_ATTACHED_BELOW:
do_blit (combining_glyphs[i], targetx, -(ctx.bounds.y - space),

View file

@ -680,6 +680,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
grub_uint64_t stripen;
grub_uint64_t stripe_offset;
grub_uint64_t off = addr - grub_le_to_cpu64 (key->offset);
grub_uint64_t chunk_stripe_length;
grub_uint16_t nstripes;
unsigned redundancy = 1;
unsigned i, j;
@ -690,15 +692,17 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
"couldn't find the chunk descriptor");
}
nstripes = grub_le_to_cpu16 (chunk->nstripes) ? : 1;
chunk_stripe_length = grub_le_to_cpu64 (chunk->stripe_length) ? : 512;
grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T
"+0x%" PRIxGRUB_UINT64_T
" (%d stripes (%d substripes) of %"
PRIxGRUB_UINT64_T ")\n",
grub_le_to_cpu64 (key->offset),
grub_le_to_cpu64 (chunk->size),
grub_le_to_cpu16 (chunk->nstripes),
nstripes,
grub_le_to_cpu16 (chunk->nsubstripes),
grub_le_to_cpu64 (chunk->stripe_length));
chunk_stripe_length);
switch (grub_le_to_cpu64 (chunk->type)
& ~GRUB_BTRFS_CHUNK_TYPE_BITS_DONTCARE)
@ -708,8 +712,10 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
grub_uint64_t stripe_length;
grub_dprintf ("btrfs", "single\n");
stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size),
grub_le_to_cpu16 (chunk->nstripes),
nstripes,
NULL);
if (stripe_length == 0)
stripe_length = 512;
stripen = grub_divmod64 (off, stripe_length, &stripe_offset);
csize = (stripen + 1) * stripe_length - off;
break;
@ -730,33 +736,34 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
grub_uint64_t low;
grub_dprintf ("btrfs", "RAID0\n");
middle = grub_divmod64 (off,
grub_le_to_cpu64 (chunk->stripe_length),
chunk_stripe_length,
&low);
high = grub_divmod64 (middle, grub_le_to_cpu16 (chunk->nstripes),
high = grub_divmod64 (middle, nstripes,
&stripen);
stripe_offset =
low + grub_le_to_cpu64 (chunk->stripe_length) * high;
csize = grub_le_to_cpu64 (chunk->stripe_length) - low;
low + chunk_stripe_length * high;
csize = chunk_stripe_length - low;
break;
}
case GRUB_BTRFS_CHUNK_TYPE_RAID10:
{
grub_uint64_t middle, high;
grub_uint64_t low;
grub_uint16_t nsubstripes;
nsubstripes = grub_le_to_cpu16 (chunk->nsubstripes) ? : 1;
middle = grub_divmod64 (off,
grub_le_to_cpu64 (chunk->stripe_length),
chunk_stripe_length,
&low);
high = grub_divmod64 (middle,
grub_le_to_cpu16 (chunk->nstripes)
/ grub_le_to_cpu16 (chunk->nsubstripes),
nstripes / nsubstripes ? : 1,
&stripen);
stripen *= grub_le_to_cpu16 (chunk->nsubstripes);
redundancy = grub_le_to_cpu16 (chunk->nsubstripes);
stripe_offset = low + grub_le_to_cpu64 (chunk->stripe_length)
stripen *= nsubstripes;
redundancy = nsubstripes;
stripe_offset = low + chunk_stripe_length
* high;
csize = grub_le_to_cpu64 (chunk->stripe_length) - low;
csize = chunk_stripe_length - low;
break;
}
default:

View file

@ -74,8 +74,7 @@ grub_cbfs_find_file (struct grub_archelp_data *data, char **name,
(void) mtime;
offset = grub_be_to_cpu32 (hd.offset);
if (mode)
*mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME;
*mode = GRUB_ARCHELP_ATTR_FILE | GRUB_ARCHELP_ATTR_NOTIME;
namesize = offset;
if (namesize >= sizeof (hd))
@ -144,7 +143,7 @@ static struct grub_archelp_data *
grub_cbfs_mount (grub_disk_t disk)
{
struct cbfs_file hd;
struct grub_archelp_data *data;
struct grub_archelp_data *data = NULL;
grub_uint32_t ptr;
grub_off_t header_off;
struct cbfs_header head;
@ -196,6 +195,7 @@ grub_cbfs_mount (grub_disk_t disk)
return data;
fail:
grub_free (data);
grub_error (GRUB_ERR_BAD_FS, "not a cbfs filesystem");
return 0;
}

View file

@ -61,8 +61,15 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
modeval = read_number (hd.mode, ARRAY_SIZE (hd.mode));
namesize = read_number (hd.namesize, ARRAY_SIZE (hd.namesize));
if (mode)
*mode = modeval;
/* Don't allow negative numbers. */
if (namesize >= 0x80000000)
{
/* Probably a corruption, don't attempt to recover. */
*mode = GRUB_ARCHELP_ATTR_END;
return GRUB_ERR_NONE;
}
*mode = modeval;
*name = grub_malloc (namesize + 1);
if (*name == NULL)

View file

@ -100,6 +100,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* Extents used */
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
/* The set of back-incompatible features this driver DOES support. Add (OR)
@ -107,6 +108,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define EXT2_DRIVER_SUPPORTED_INCOMPAT ( EXT2_FEATURE_INCOMPAT_FILETYPE \
| EXT4_FEATURE_INCOMPAT_EXTENTS \
| EXT4_FEATURE_INCOMPAT_FLEX_BG \
| EXT2_FEATURE_INCOMPAT_META_BG \
| EXT4_FEATURE_INCOMPAT_64BIT)
/* List of rationales for the ignored "incompatible" features:
* needs_recovery: Not really back-incompatible - was added as such to forbid
@ -114,8 +116,13 @@ GRUB_MOD_LICENSE ("GPLv3+");
* journal because they will ignore the journal, but the next
* ext3 driver to mount the volume will find the journal and
* replay it, potentially corrupting the metadata written by
* the ext2 drivers. Safe to ignore for this RO driver. */
#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER )
* the ext2 drivers. Safe to ignore for this RO driver.
* mmp: Not really back-incompatible - was added as such to
* avoid multiple read-write mounts. Safe to ignore for this
* RO driver.
*/
#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \
| EXT4_FEATURE_INCOMPAT_MMP)
#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U
@ -331,16 +338,68 @@ static grub_dl_t my_mod;
/* Check is a = b^x for some x. */
static inline int
is_power_of (grub_uint64_t a, grub_uint32_t b)
{
grub_uint64_t c;
/* Prevent overflow assuming b < 8. */
if (a >= (1LL << 60))
return 0;
for (c = 1; c <= a; c *= b);
return (c == a);
}
static inline int
group_has_super_block (struct grub_ext2_data *data, grub_uint64_t group)
{
if (!(data->sblock.feature_ro_compat
& grub_cpu_to_le32_compile_time(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)))
return 1;
/* Algorithm looked up in Linux source. */
if (group <= 1)
return 1;
/* Even number is never a power of odd number. */
if (!(group & 1))
return 0;
return (is_power_of(group, 7) || is_power_of(group, 5) ||
is_power_of(group, 3));
}
/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of
the mounted filesystem DATA. */
inline static grub_err_t
grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
grub_ext2_blockgroup (struct grub_ext2_data *data, grub_uint64_t group,
struct grub_ext2_block_group *blkgrp)
{
grub_uint64_t full_offset = (group << data->log_group_desc_size);
grub_uint64_t block, offset;
block = (full_offset >> LOG2_BLOCK_SIZE (data));
offset = (full_offset & ((1 << LOG2_BLOCK_SIZE (data)) - 1));
if ((data->sblock.feature_incompat
& grub_cpu_to_le32_compile_time (EXT2_FEATURE_INCOMPAT_META_BG))
&& block >= grub_le_to_cpu32(data->sblock.first_meta_bg))
{
grub_uint64_t first_block_group;
/* Find the first block group for which a descriptor
is stored in given block. */
first_block_group = (block << (LOG2_BLOCK_SIZE (data)
- data->log_group_desc_size));
block = (first_block_group
* grub_le_to_cpu32(data->sblock.blocks_per_group));
if (group_has_super_block (data, first_block_group))
block++;
}
else
/* Superblock. */
block++;
return grub_disk_read (data->disk,
((grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
<< LOG2_EXT2_BLOCK_SIZE (data)),
group << data->log_group_desc_size,
((grub_le_to_cpu32 (data->sblock.first_data_block)
+ block)
<< LOG2_EXT2_BLOCK_SIZE (data)), offset,
sizeof (struct grub_ext2_block_group), blkgrp);
}
@ -484,6 +543,10 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
indirect:
do {
/* If the indirect block is zero, all child blocks are absent
(i.e. filled with zeros.) */
if (indir == 0)
return 0;
if (grub_disk_read (data->disk,
((grub_disk_addr_t) grub_le_to_cpu32 (indir))
<< log2_blksz,
@ -573,7 +636,12 @@ grub_ext2_mount (grub_disk_t disk)
/* Make sure this is an ext2 filesystem. */
if (data->sblock.magic != grub_cpu_to_le16_compile_time (EXT2_MAGIC)
|| grub_le_to_cpu32 (data->sblock.log2_block_size) >= 16)
|| grub_le_to_cpu32 (data->sblock.log2_block_size) >= 16
|| data->sblock.inodes_per_group == 0
/* 20 already means 1GiB blocks. We don't want to deal with blocks overflowing int32. */
|| grub_le_to_cpu32 (data->sblock.log2_block_size) > 20
|| EXT2_INODE_SIZE (data) == 0
|| EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data) == 0)
{
grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");
goto fail;

View file

@ -1136,7 +1136,7 @@ grub_fat_label (grub_device_t device, char **label)
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
return 0;
goto fail;
}
err = grub_fat_iterate_init (&ctxt);

View file

@ -252,6 +252,13 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
grub_disk_addr_t i, blockcnt;
int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS);
if (pos > filesize)
{
grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("attempt to read past the end of file"));
return -1;
}
/* Adjust LEN so it we can't read past the end of the file. */
if (pos + len > filesize)
len = filesize - pos;

View file

@ -330,6 +330,7 @@ grub_hfs_mount (grub_disk_t disk)
/* Check if this is a HFS filesystem. */
if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC
|| data->sblock.blksz == 0
|| (data->sblock.blksz & grub_cpu_to_be32_compile_time (0xc00001ff)))
{
grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem");
@ -367,6 +368,11 @@ grub_hfs_mount (grub_disk_t disk)
data->cat_root = grub_be_to_cpu32 (treehead.head.root_node);
data->cat_size = grub_be_to_cpu16 (treehead.head.node_size);
if (data->cat_size == 0
|| data->blksz < data->cat_size
|| data->blksz < data->ext_size)
goto fail;
/* Lookup the root directory node in the catalog tree using the
volume name. */
key.parent_dir = grub_cpu_to_be32_compile_time (1);
@ -686,6 +692,7 @@ grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx,
int i;
struct grub_hfs_extent *dat;
int blk;
grub_uint16_t reccnt;
dat = (struct grub_hfs_extent *) (type == 0
? (&data->sblock.catalog_recs)
@ -704,8 +711,12 @@ grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx,
return grub_errno;
}
reccnt = grub_be_to_cpu16 (node->node.reccnt);
if (reccnt > (nodesize >> 1))
reccnt = (nodesize >> 1);
/* Iterate over all records in this node. */
for (i = 0; i < grub_be_to_cpu16 (node->node.reccnt); i++)
for (i = 0; i < reccnt; i++)
{
int pos = (nodesize >> 1) - 1 - i;
struct pointer
@ -713,16 +724,19 @@ grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx,
grub_uint8_t keylen;
grub_uint8_t key;
} GRUB_PACKED *pnt;
pnt = (struct pointer *) (grub_be_to_cpu16 (node->offsets[pos])
+ node->rawnode);
grub_uint16_t off = grub_be_to_cpu16 (node->offsets[pos]);
if (off > nodesize - sizeof(*pnt))
continue;
pnt = (struct pointer *) (off + node->rawnode);
if (nodesize < (grub_size_t) off + pnt->keylen + 1)
continue;
struct grub_hfs_record rec =
{
&pnt->key,
pnt->keylen,
&pnt->key + pnt->keylen +(pnt->keylen + 1) % 2,
nodesize - grub_be_to_cpu16 (node->offsets[pos])
- pnt->keylen - 1
nodesize - off - pnt->keylen - 1
};
if (node_hook (&node->node, &rec, hook_arg))
@ -1300,6 +1314,12 @@ grub_hfs_open (struct grub_file *file, const char *name)
data = grub_hfs_mount (file->device->disk);
if (!data)
{
grub_dl_unref (my_mod);
return grub_errno;
}
if (grub_hfs_find_dir (data, name, &frec, 0))
{
grub_free (data);

View file

@ -336,6 +336,9 @@ grub_hfsplus_mount (grub_disk_t disk)
data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) &&
(header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE));
if (data->catalog_tree.nodesize < 2)
goto fail;
if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0,
sizeof (struct grub_hfsplus_btnode),
sizeof (header), (char *) &header) <= 0)
@ -350,6 +353,9 @@ grub_hfsplus_mount (grub_disk_t disk)
data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize);
if (data->extoverflow_tree.nodesize < 2)
goto fail;
if (grub_hfsplus_read_file (&data->attr_tree.file, 0, 0,
sizeof (struct grub_hfsplus_btnode),
sizeof (header), (char *) &header) <= 0)
@ -723,7 +729,10 @@ list_nodes (void *record, void *hook_arg)
/* If the name is obviously invalid, skip this node. */
if (catkey->name[i] == 0)
return 0;
{
grub_free (filename);
return 0;
}
}
*grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name,
@ -745,7 +754,10 @@ list_nodes (void *record, void *hook_arg)
callback function. */
node = grub_malloc (sizeof (*node));
if (!node)
return 1;
{
grub_free (filename);
return 1;
}
node->data = ctx->dir->data;
node->compressed = 0;
node->cbuf = 0;
@ -780,8 +792,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
};
struct grub_hfsplus_key_internal intern;
struct grub_hfsplus_btnode *node;
grub_disk_addr_t ptr;
struct grub_hfsplus_btnode *node = NULL;
grub_disk_addr_t ptr = 0;
{
struct grub_fshelp_node *fsnode;
@ -964,8 +976,8 @@ grub_hfsplus_label (grub_device_t device, char **label)
struct grub_hfsplus_catkey *catkey;
int i, label_len;
struct grub_hfsplus_key_internal intern;
struct grub_hfsplus_btnode *node;
grub_disk_addr_t ptr;
struct grub_hfsplus_btnode *node = NULL;
grub_disk_addr_t ptr = 0;
*label = 0;

View file

@ -959,14 +959,15 @@ grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_iso9660_data *data =
(struct grub_iso9660_data *) file->data;
grub_err_t err;
/* XXX: The file is stored in as a single extent. */
data->disk->read_hook = file->read_hook;
data->disk->read_hook_data = file->read_hook_data;
read_node (data->node, file->offset, len, buf);
err = read_node (data->node, file->offset, len, buf);
data->disk->read_hook = NULL;
if (grub_errno)
if (err || grub_errno)
return -1;
return len;

View file

@ -65,7 +65,6 @@ typedef grub_uint16_t grub_minix_uintn_t;
#define grub_minix_to_cpu_n grub_minix_to_cpu16
#endif
#define GRUB_MINIX_INODE_BLKSZ(data) sizeof (grub_minix_uintn_t)
#ifdef MODE_MINIX3
typedef grub_uint32_t grub_minix_ino_t;
#define grub_minix_to_cpu_ino grub_minix_to_cpu32
@ -83,19 +82,6 @@ typedef grub_uint16_t grub_minix_ino_t;
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_to_cpu_n \
(data->inode.double_indir_zone))
#ifndef MODE_MINIX3
#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \
+ grub_minix_to_cpu16 (data->sblock.log2_zone_size))
#endif
#define GRUB_MINIX_ZONESZ ((grub_uint64_t) data->block_size << \
(GRUB_DISK_SECTOR_BITS + grub_minix_to_cpu16 (data->sblock.log2_zone_size)))
#ifdef MODE_MINIX3
#define GRUB_MINIX_ZONE2SECT(zone) ((zone) * data->block_size)
#else
#define GRUB_MINIX_ZONE2SECT(zone) ((zone) << GRUB_MINIX_LOG2_ZONESZ)
#endif
#ifdef MODE_MINIX3
struct grub_minix_sblock
@ -172,6 +158,7 @@ struct grub_minix_data
{
struct grub_minix_sblock sblock;
struct grub_minix_inode inode;
grub_uint32_t block_per_zone;
grub_minix_ino_t ino;
int linknest;
grub_disk_t disk;
@ -184,15 +171,32 @@ static grub_dl_t my_mod;
static grub_err_t grub_minix_find_file (struct grub_minix_data *data,
const char *path);
#ifdef MODE_MINIX3
static inline grub_disk_addr_t
grub_minix_zone2sect (struct grub_minix_data *data, grub_minix_uintn_t zone)
{
return ((grub_disk_addr_t) zone) * data->block_size;
}
#else
static inline grub_disk_addr_t
grub_minix_zone2sect (struct grub_minix_data *data, grub_minix_uintn_t zone)
{
int log2_zonesz = (GRUB_MINIX_LOG2_BSIZE
+ grub_minix_to_cpu16 (data->sblock.log2_zone_size));
return (((grub_disk_addr_t) zone) << log2_zonesz);
}
#endif
/* Read the block pointer in ZONE, on the offset NUM. */
static grub_minix_uintn_t
grub_get_indir (struct grub_minix_data *data,
grub_get_indir (struct grub_minix_data *data,
grub_minix_uintn_t zone,
grub_minix_uintn_t num)
{
grub_minix_uintn_t indirn;
grub_disk_read (data->disk,
GRUB_MINIX_ZONE2SECT(zone),
grub_minix_zone2sect(data, zone),
sizeof (grub_minix_uintn_t) * num,
sizeof (grub_minix_uintn_t), (char *) &indirn);
return grub_minix_to_cpu_n (indirn);
@ -202,8 +206,6 @@ static grub_minix_uintn_t
grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
{
grub_minix_uintn_t indir;
const grub_uint32_t block_per_zone = (GRUB_MINIX_ZONESZ
/ GRUB_MINIX_INODE_BLKSZ (data));
/* Direct block. */
if (blk < GRUB_MINIX_INODE_DIR_BLOCKS)
@ -211,33 +213,33 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
/* Indirect block. */
blk -= GRUB_MINIX_INODE_DIR_BLOCKS;
if (blk < block_per_zone)
if (blk < data->block_per_zone)
{
indir = grub_get_indir (data, GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
return indir;
}
/* Double indirect block. */
blk -= block_per_zone;
if (blk < block_per_zone * block_per_zone)
blk -= data->block_per_zone;
if (blk < (grub_uint64_t) data->block_per_zone * (grub_uint64_t) data->block_per_zone)
{
indir = grub_get_indir (data, GRUB_MINIX_INODE_DINDIR_ZONE (data),
blk / block_per_zone);
blk / data->block_per_zone);
indir = grub_get_indir (data, indir, blk % block_per_zone);
indir = grub_get_indir (data, indir, blk % data->block_per_zone);
return indir;
}
#if defined (MODE_MINIX3) || defined (MODE_MINIX2)
blk -= block_per_zone * block_per_zone;
if (blk < ((grub_uint64_t) block_per_zone * (grub_uint64_t) block_per_zone
* (grub_uint64_t) block_per_zone))
blk -= data->block_per_zone * data->block_per_zone;
if (blk < ((grub_uint64_t) data->block_per_zone * (grub_uint64_t) data->block_per_zone
* (grub_uint64_t) data->block_per_zone))
{
indir = grub_get_indir (data, grub_minix_to_cpu_n (data->inode.triple_indir_zone),
(blk / block_per_zone) / block_per_zone);
indir = grub_get_indir (data, indir, (blk / block_per_zone) % block_per_zone);
indir = grub_get_indir (data, indir, blk % block_per_zone);
(blk / data->block_per_zone) / data->block_per_zone);
indir = grub_get_indir (data, indir, (blk / data->block_per_zone) % data->block_per_zone);
indir = grub_get_indir (data, indir, blk % data->block_per_zone);
return indir;
}
@ -262,6 +264,13 @@ grub_minix_read_file (struct grub_minix_data *data,
grub_uint32_t posblock;
grub_uint32_t blockoff;
if (pos > GRUB_MINIX_INODE_SIZE (data))
{
grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("attempt to read past the end of file"));
return -1;
}
/* Adjust len so it we can't read past the end of the file. */
if (len + pos > GRUB_MINIX_INODE_SIZE (data))
len = GRUB_MINIX_INODE_SIZE (data) - pos;
@ -278,7 +287,7 @@ grub_minix_read_file (struct grub_minix_data *data,
for (i = posblock; i < blockcnt; i++)
{
grub_disk_addr_t blknr;
grub_minix_uintn_t blknr;
grub_uint64_t blockend = data->block_size << GRUB_DISK_SECTOR_BITS;
grub_off_t skipfirst = 0;
@ -307,7 +316,7 @@ grub_minix_read_file (struct grub_minix_data *data,
data->disk->read_hook = read_hook;
data->disk->read_hook_data = read_hook_data;
grub_disk_read (data->disk,
GRUB_MINIX_ZONE2SECT(blknr),
grub_minix_zone2sect(data, blknr),
skipfirst, blockend, buf);
data->disk->read_hook = 0;
if (grub_errno)
@ -333,7 +342,8 @@ grub_minix_read_inode (struct grub_minix_data *data, grub_minix_ino_t ino)
/* The first inode in minix is inode 1. */
ino--;
block = GRUB_MINIX_ZONE2SECT (2 + grub_minix_to_cpu16 (sblock->inode_bmap_size)
block = grub_minix_zone2sect (data,
2 + grub_minix_to_cpu16 (sblock->inode_bmap_size)
+ grub_minix_to_cpu16 (sblock->zone_bmap_size));
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
@ -508,6 +518,12 @@ grub_minix_mount (grub_disk_t disk)
data->block_size = 2;
#endif
data->block_per_zone = (((grub_uint64_t) data->block_size << \
(GRUB_DISK_SECTOR_BITS + grub_minix_to_cpu16 (data->sblock.log2_zone_size)))
/ sizeof (grub_minix_uintn_t));
if (!data->block_per_zone)
goto fail;
return data;
fail:

View file

@ -724,6 +724,10 @@ grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp)
if (grub_le_to_cpu32 (sbp->s_rev_level) != NILFS_SUPORT_REV)
return 0;
/* 20 already means 1GiB blocks. We don't want to deal with blocks overflowing int32. */
if (grub_le_to_cpu32 (sbp->s_log_block_size) > 20)
return 0;
return 1;
}

View file

@ -618,7 +618,10 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
ustr = get_utf8 (np, ns);
if (ustr == NULL)
return 0;
{
grub_free (fdiro);
return 0;
}
if (namespace)
type |= GRUB_FSHELP_CASE_INSENSITIVE;
@ -917,12 +920,16 @@ grub_ntfs_mount (grub_disk_t disk)
if (bpb.clusters_per_mft > 0)
data->mft_size = ((grub_disk_addr_t) bpb.clusters_per_mft) << data->log_spc;
else if (-bpb.clusters_per_mft < GRUB_NTFS_BLK_SHR || -bpb.clusters_per_mft >= 31)
goto fail;
else
data->mft_size = 1ULL << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR);
if (bpb.clusters_per_index > 0)
data->idx_size = (((grub_disk_addr_t) bpb.clusters_per_index)
<< data->log_spc);
else if (-bpb.clusters_per_index < GRUB_NTFS_BLK_SHR || -bpb.clusters_per_index >= 31)
goto fail;
else
data->idx_size = 1ULL << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR);

View file

@ -1090,7 +1090,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node,
switch (found.type)
{
case GRUB_REISERFS_DIRECT:
block = found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS);
block = ((grub_disk_addr_t) found.block_number) * (block_size >> GRUB_DISK_SECTOR_BITS);
grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block);
if (initial_position < current_position + item_size)
{

View file

@ -173,10 +173,11 @@ grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block,
struct grub_sfs_btree *tree;
int i;
grub_uint32_t next;
grub_size_t blocksize = GRUB_DISK_SECTOR_SIZE << data->log_blocksize;
treeblock = grub_malloc (GRUB_DISK_SECTOR_SIZE << data->log_blocksize);
if (!block)
return 0;
treeblock = grub_malloc (blocksize);
if (!treeblock)
return grub_errno;
next = grub_be_to_cpu32 (data->rblock.btree);
tree = (struct grub_sfs_btree *) treeblock;
@ -184,17 +185,21 @@ grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block,
/* Handle this level in the btree. */
do
{
grub_uint16_t nnodes;
grub_disk_read (data->disk,
((grub_disk_addr_t) next) << data->log_blocksize,
0, GRUB_DISK_SECTOR_SIZE << data->log_blocksize,
treeblock);
0, blocksize, treeblock);
if (grub_errno)
{
grub_free (treeblock);
return grub_errno;
}
for (i = grub_be_to_cpu16 (tree->nodes) - 1; i >= 0; i--)
nnodes = grub_be_to_cpu16 (tree->nodes);
if (nnodes * (grub_uint32_t) (tree)->nodesize > blocksize)
break;
for (i = (int) nnodes - 1; i >= 0; i--)
{
#define EXTNODE(tree, index) \

View file

@ -986,6 +986,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
case 1:
if (ptr[1])
goto fail;
/* Fallthrough. */
case 2:
/* in 4 bytes. out: 1 byte. */
optr = out;

View file

@ -465,7 +465,13 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
&& INODE_SIZE (data) <= sizeof (data->inode.symlink))
grub_strcpy (symlink, (char *) data->inode.symlink);
else
grub_ufs_read_file (data, 0, 0, 0, sz, symlink);
{
if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0)
{
grub_free(symlink);
return grub_errno;
}
}
symlink[sz] = '\0';
/* The symlink is an absolute path, go back to the root inode. */
@ -604,7 +610,8 @@ grub_ufs_mount (grub_disk_t disk)
endiannesses. */
if (data->sblock.magic == grub_cpu_to_ufs32_compile_time (GRUB_UFS_MAGIC)
&& data->sblock.bsize != 0
&& ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0))
&& ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0)
&& data->sblock.ino_per_group != 0)
{
for (data->log2_blksz = 0;
(1U << data->log2_blksz) < grub_ufs_to_cpu32 (data->sblock.bsize);

View file

@ -252,7 +252,6 @@ struct grub_zfs_data
uberblock_t current_uberblock;
int mounted;
grub_uint64_t guid;
};
@ -286,7 +285,7 @@ static const char *spa_feature_names[] = {
static int
check_feature(const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx);
static int
static grub_err_t
check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct grub_zfs_data* data );
static grub_err_t
@ -957,7 +956,7 @@ nvpair_value (const char *nvp,char **val,
static grub_err_t
check_pool_label (struct grub_zfs_data *data,
struct grub_zfs_device_desc *diskdesc,
int *inserted)
int *inserted, int original)
{
grub_uint64_t pool_state, txg = 0;
char *nvlist,*features;
@ -1081,11 +1080,12 @@ check_pool_label (struct grub_zfs_data *data,
grub_dprintf ("zfs", "check 11 passed\n");
if (data->mounted && data->guid != poolguid)
return grub_error (GRUB_ERR_BAD_FS, "another zpool");
else
if (original)
data->guid = poolguid;
if (data->guid != poolguid)
return grub_error (GRUB_ERR_BAD_FS, "another zpool");
{
char *nv;
nv = grub_zfs_nvlist_lookup_nvlist (nvlist, ZPOOL_CONFIG_VDEV_TREE);
@ -1186,7 +1186,7 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data,
}
grub_dprintf ("zfs", "label ok %d\n", label);
err = check_pool_label (data, &desc, inserted);
err = check_pool_label (data, &desc, inserted, original);
if (err || !*inserted)
{
grub_errno = GRUB_ERR_NONE;
@ -1501,6 +1501,9 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc,
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"raidz%d is not supported", desc->nparity);
if (desc->n_children <= desc->nparity || desc->n_children < 1)
return grub_error(GRUB_ERR_BAD_FS, "too little devices for given parity");
orig_s = (((len + (1 << desc->ashift) - 1) >> desc->ashift)
+ (desc->n_children - desc->nparity) - 1);
s = orig_s;
@ -1972,7 +1975,7 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf,
dn->endian)
<< SPA_MINBLOCKSHIFT;
*buf = grub_malloc (size);
if (*buf)
if (!*buf)
{
err = grub_errno;
break;
@ -2010,12 +2013,14 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf,
*/
static grub_err_t
mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian,
int objsize, const char *name, grub_uint64_t * value,
grub_uint16_t objsize, const char *name, grub_uint64_t * value,
int case_insensitive)
{
int i, chunks;
grub_uint16_t i, chunks;
mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk;
if (objsize < MZAP_ENT_LEN)
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name);
chunks = objsize / MZAP_ENT_LEN - 1;
for (i = 0; i < chunks; i++)
{
@ -2423,7 +2428,7 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val,
struct grub_zfs_data *data, int case_insensitive)
{
grub_uint64_t block_type;
int size;
grub_uint16_t size;
void *zapbuf;
grub_err_t err;
grub_zfs_endian_t endian;
@ -2804,6 +2809,9 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
dnode_path->dn.endian)
<< SPA_MINBLOCKSHIFT);
if (blksz == 0)
return grub_error(GRUB_ERR_BAD_FS, "0-sized block");
sym_value = grub_malloc (sym_sz);
if (!sym_value)
return grub_errno;
@ -2829,6 +2837,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
if (!path_buf)
{
grub_free (oldpathbuf);
if (free_symval)
grub_free (sym_value);
return grub_errno;
}
grub_memcpy (path, sym_value, sym_sz);
@ -3606,8 +3616,6 @@ zfs_mount (grub_device_t dev)
ub_endian) >> 63) & 1;
grub_free (osp);
data->mounted = 1;
return data;
}
@ -3798,6 +3806,12 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t len)
blksz = grub_zfs_to_cpu16 (data->dnode.dn.dn_datablkszsec,
data->dnode.endian) << SPA_MINBLOCKSHIFT;
if (blksz == 0)
{
grub_error (GRUB_ERR_BAD_FS, "0-sized block");
return -1;
}
/*
* Entire Dnode is too big to fit into the space available. We
* will need to read it in chunks. This could be optimized to
@ -3969,7 +3983,12 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx)
dnode_end_t dn;
grub_memset (&info, 0, sizeof (info));
dnode_get (&(ctx->data->subvol.mdn), val, 0, &dn, ctx->data);
err = dnode_get (&(ctx->data->subvol.mdn), val, 0, &dn, ctx->data);
if (err)
{
grub_print_error ();
return 0;
}
if (dn.dn.dn_bonustype == DMU_OT_SA)
{
@ -4190,11 +4209,11 @@ check_feature (const char *name, grub_uint64_t val,
* errnum: Failure.
*/
static int
static grub_err_t
check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct grub_zfs_data* data )
{
grub_uint64_t objnum;
grub_uint8_t errnum = 0;
grub_err_t errnum = 0;
dnode_end_t dn,mosmdn;
mzap_phys_t* mzp;
grub_zfs_endian_t endianzap;

View file

@ -238,7 +238,7 @@ grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher,
grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize);
}
for (j = 0; j < 8; j++)
mac[15 - j] ^= ((psize * 8) >> (8 * j));
mac[15 - j] ^= ((((grub_uint64_t) psize) * 8) >> (8 * j));
grub_gcm_mul (mac, h);
if (mac_out)
@ -354,6 +354,7 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key,
if (err)
{
grub_errno = GRUB_ERR_NONE;
grub_crypto_cipher_close (cipher);
continue;
}
@ -362,6 +363,7 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key,
if (err)
{
grub_errno = GRUB_ERR_NONE;
grub_crypto_cipher_close (cipher);
continue;
}
@ -372,6 +374,7 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key,
{
grub_dprintf ("zfs", "key loading failed\n");
grub_errno = GRUB_ERR_NONE;
grub_crypto_cipher_close (cipher);
continue;
}
@ -381,21 +384,25 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key,
{
grub_dprintf ("zfs", "key loading failed\n");
grub_errno = GRUB_ERR_NONE;
grub_crypto_cipher_close (cipher);
continue;
}
ret = grub_crypto_cipher_open (GRUB_CIPHER_AES);
if (!ret)
{
grub_errno = GRUB_ERR_NONE;
grub_crypto_cipher_close (cipher);
continue;
}
err = grub_crypto_cipher_set_key (ret, decrypted, keylen);
if (err)
{
grub_errno = GRUB_ERR_NONE;
grub_crypto_cipher_close (ret);
continue;
}
grub_errno = GRUB_ERR_NONE;
grub_crypto_cipher_close (ret);
grub_crypto_cipher_close (cipher);
continue;
}
grub_crypto_cipher_close (cipher);
return ret;
}
return NULL;

View file

@ -130,10 +130,12 @@ print_vdev_info (char *nvlist, int tab)
grub_free (bootpath);
grub_free (devid);
grub_free (path);
grub_free (type);
return GRUB_ERR_NONE;
}
char is_mirror=(grub_strcmp(type,VDEV_TYPE_MIRROR) == 0);
char is_raidz=(grub_strcmp(type,VDEV_TYPE_RAIDZ) == 0);
grub_free (type);
if (is_mirror || is_raidz)
{

View file

@ -138,51 +138,53 @@ circprog_paint (void *vself, const grub_video_rect_t *region)
(height - center_height) / 2, 0, 0,
center_width, center_height);
int radius = grub_min (height, width) / 2 - grub_max (tick_height, tick_width) / 2 - 1;
unsigned nticks;
unsigned tick_begin;
unsigned tick_end;
if (self->end <= self->start
|| self->value <= self->start)
nticks = 0;
else
nticks = ((unsigned) (self->num_ticks
* (self->value - self->start)))
/ ((unsigned) (self->end - self->start));
/* Do ticks appear or disappear as the value approached the end? */
if (self->ticks_disappear)
if (self->num_ticks)
{
tick_begin = nticks;
tick_end = self->num_ticks;
int radius = grub_min (height, width) / 2 - grub_max (tick_height, tick_width) / 2 - 1;
unsigned nticks;
unsigned tick_begin;
unsigned tick_end;
if (self->end <= self->start
|| self->value <= self->start)
nticks = 0;
else
nticks = ((unsigned) (self->num_ticks
* (self->value - self->start)))
/ ((unsigned) (self->end - self->start));
/* Do ticks appear or disappear as the value approached the end? */
if (self->ticks_disappear)
{
tick_begin = nticks;
tick_end = self->num_ticks;
}
else
{
tick_begin = 0;
tick_end = nticks;
}
unsigned i;
for (i = tick_begin; i < tick_end; i++)
{
int x;
int y;
int angle;
/* Calculate the location of the tick. */
angle = self->start_angle
+ i * GRUB_TRIG_ANGLE_MAX / self->num_ticks;
x = width / 2 + (grub_cos (angle) * radius / GRUB_TRIG_FRACTION_SCALE);
y = height / 2 + (grub_sin (angle) * radius / GRUB_TRIG_FRACTION_SCALE);
/* Adjust (x,y) so the tick is centered. */
x -= tick_width / 2;
y -= tick_height / 2;
/* Draw the tick. */
grub_video_blit_bitmap (self->tick_bitmap, GRUB_VIDEO_BLIT_BLEND,
x, y, 0, 0, tick_width, tick_height);
}
}
else
{
tick_begin = 0;
tick_end = nticks;
}
unsigned i;
for (i = tick_begin; i < tick_end; i++)
{
int x;
int y;
int angle;
/* Calculate the location of the tick. */
angle = self->start_angle
+ i * GRUB_TRIG_ANGLE_MAX / self->num_ticks;
x = width / 2 + (grub_cos (angle) * radius / GRUB_TRIG_FRACTION_SCALE);
y = height / 2 + (grub_sin (angle) * radius / GRUB_TRIG_FRACTION_SCALE);
/* Adjust (x,y) so the tick is centered. */
x -= tick_width / 2;
y -= tick_height / 2;
/* Draw the tick. */
grub_video_blit_bitmap (self->tick_bitmap, GRUB_VIDEO_BLIT_BLEND,
x, y, 0, 0, tick_width, tick_height);
}
grub_gui_restore_viewport (&vpsave);
}

View file

@ -131,6 +131,9 @@ get_num_shown_items (list_impl_t self)
int max_top_pad = grub_max (item_top_pad, sel_top_pad);
int max_bottom_pad = grub_max (item_bottom_pad, sel_bottom_pad);
if (item_height + item_vspace <= 0)
return 1;
return (self->bounds.height + item_vspace - 2 * boxpad
- max_top_pad - max_bottom_pad
- box_top_pad - box_bottom_pad) / (item_height + item_vspace);

View file

@ -118,9 +118,15 @@ draw_filled_rect_bar (grub_gui_progress_bar_t self)
f.width + 2, f.height + 2);
/* Bar background. */
int barwidth = (f.width
* (self->value - self->start)
/ (self->end - self->start));
unsigned barwidth;
if (self->end <= self->start
|| self->value <= self->start)
barwidth = 0;
else
barwidth = (f.width
* (self->value - self->start)
/ (self->end - self->start));
grub_video_fill_rect (grub_video_map_rgba_color (self->bg_color),
f.x + barwidth, f.y,
f.width - barwidth, f.height);

View file

@ -106,8 +106,10 @@ grub_gfxmenu_icon_manager_set_theme_path (grub_gfxmenu_icon_manager_t mgr,
const char *path)
{
/* Clear the cache if the theme path has changed. */
if (((mgr->theme_path == 0) != (path == 0))
|| (grub_strcmp (mgr->theme_path, path) != 0))
if (mgr->theme_path == 0 && path == 0)
return;
if (mgr->theme_path == 0 || path == 0
|| grub_strcmp (mgr->theme_path, path) != 0)
grub_gfxmenu_icon_manager_clear_cache (mgr);
grub_free (mgr->theme_path);

View file

@ -774,6 +774,8 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
view->canvas->component.ops->destroy (view->canvas);
view->canvas = grub_gui_canvas_new ();
if (!view->canvas)
goto fail;
((grub_gui_component_t) view->canvas)
->ops->set_bounds ((grub_gui_component_t) view->canvas,
&view->screen);

View file

@ -1,5 +1,5 @@
/* Hierarchical argument parsing help output
Copyright (C) 1995-2005, 2007, 2009-2013 Free Software Foundation, Inc.
Copyright (C) 1995-2005, 2007, 2009-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
@ -650,7 +650,7 @@ hol_find_entry (struct hol *hol, const char *name)
return 0;
}
/* If an entry with the long option NAME occurs in HOL, set it's special
/* If an entry with the long option NAME occurs in HOL, set its special
sort position to GROUP. */
static void
hol_set_group (struct hol *hol, const char *name, int group)
@ -1507,11 +1507,15 @@ argp_doc (const struct argp *argp, const struct argp_state *state,
if (vt)
{
if (post)
inp_text = vt + 1;
{
inp_text = vt + 1;
if (! *inp_text)
inp_text = 0;
}
else
{
inp_text_len = vt - argp->doc;
inp_text = __strndup (argp->doc, inp_text_len);
inp_text = inp_text_len ? __strndup (argp->doc, inp_text_len) : 0;
}
}
else

View file

@ -1161,6 +1161,19 @@ grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused)))
return file;
}
static grub_uint8_t
mod_31 (grub_uint16_t v)
{
/* At most 2 iterations for any number that
we can get here.
In any case faster than real division. */
while (v > 0x1f)
v = (v & 0x1f) + (v >> 5);
if (v == 0x1f)
return 0;
return v;
}
static int
test_zlib_header (grub_gzio_t gzio)
{
@ -1178,7 +1191,10 @@ test_zlib_header (grub_gzio_t gzio)
return 0;
}
if ((cmf * 256U + flg) % 31U)
/* Usually it would be: (cmf * 256 + flg) % 31 != 0. */
/* But 256 == 8 (31). */
/* By multiplying by 4 and using 32 == 1 (31). We get our formula. */
if (mod_31 (cmf + flg * 4) != 0)
{
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, N_("unsupported gzip format"));
return 0;

View file

@ -403,8 +403,6 @@ test_header (grub_file_t file)
return 1;
CORRUPTED:
grub_free(name);
return 0;
}

View file

@ -58,25 +58,22 @@ FUNCTION(__aeabi_lmul)
ldmfd sp!, {r4, fp}
bx lr
.macro division parent
.macro division32 parent
stmfd sp!, {lr}
sub sp, sp, #12
mov r2, r1
add r1, sp, #4
str r1, [sp, #0]
mov r1, #0
mov r3, #0
sub sp, sp, #8 @ Allocate naturally aligned 64-bit space
stmfd sp!, {r3,lr} @ Dummy r3 to maintain stack alignment
add r2, sp, #8 @ Set r2 to address of 64-bit space
bl \parent
ldr r1, [sp, #4]
add sp, sp, #12
ldmfd sp!, {lr}
ldr r1, [sp, #8] @ Extract remainder
ldmfd sp!, {r3,lr} @ Pop into an unused arg/scratch register
add sp, sp, #8
bx lr
.endm
FUNCTION(__aeabi_uidivmod)
division grub_divmod64
division32 grub_divmod32
FUNCTION(__aeabi_idivmod)
division32 grub_divmod32s
/*
* Null divide-by-zero handler

View file

@ -78,9 +78,9 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
const Elf_Rel *rel, *max;
for (rel = (const Elf_Rel *) ((grub_addr_t) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
rel++)
max = (const Elf_Rel *) ((grub_addr_t) rel + s->sh_size);
rel + 1 <= max;
rel = (const Elf_Rel *) ((grub_addr_t) rel + s->sh_entsize))
switch (ELF_R_TYPE (rel->r_info))
{
case R_ARM_CALL:
@ -205,6 +205,21 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
*/
case R_ARM_V4BX:
break;
case R_ARM_THM_MOVW_ABS_NC:
case R_ARM_THM_MOVT_ABS:
{
grub_uint32_t offset;
offset = grub_arm_thm_movw_movt_get_value((grub_uint16_t *) target);
offset += sym_addr;
if (ELF_R_TYPE (rel->r_info) == R_ARM_THM_MOVT_ABS)
offset >>= 16;
else
offset &= 0xffff;
grub_arm_thm_movw_movt_set_value((grub_uint16_t *) target, offset);
}
break;
case R_ARM_THM_JUMP19:
{
/* Thumb instructions can be 16-bit aligned */

View file

@ -25,6 +25,20 @@
#include <grub/i18n.h>
#include <grub/arm/reloc.h>
static inline grub_uint32_t
thumb_get_instruction_word (grub_uint16_t *target)
{
/* Extract instruction word in alignment-safe manner */
return grub_le_to_cpu16 ((*target)) << 16 | grub_le_to_cpu16 (*(target + 1));
}
static inline void
thumb_set_instruction_word (grub_uint16_t *target, grub_uint32_t insword)
{
*target = grub_cpu_to_le16 (insword >> 16);
*(target + 1) = grub_cpu_to_le16 (insword & 0xffff);
}
/*
* R_ARM_ABS32
*
@ -56,9 +70,7 @@ grub_arm_thm_call_get_offset (grub_uint16_t *target)
grub_uint32_t insword;
grub_int32_t offset;
/* Extract instruction word in alignment-safe manner */
insword = (grub_le_to_cpu16 (*target) << 16)
| (grub_le_to_cpu16(*(target + 1)));
insword = thumb_get_instruction_word (target);
/* Extract bitfields from instruction words */
sign = (insword >> 26) & 1;
@ -83,9 +95,7 @@ grub_arm_thm_call_set_offset (grub_uint16_t *target, grub_int32_t offset)
grub_uint32_t insword;
int is_blx;
/* Extract instruction word in alignment-safe manner */
insword = (grub_le_to_cpu16 (*target) << 16)
| (grub_le_to_cpu16(*(target + 1)));
insword = thumb_get_instruction_word (target);
if (((insword >> 12) & 0xd) == 0xc)
is_blx = 1;
@ -108,9 +118,7 @@ grub_arm_thm_call_set_offset (grub_uint16_t *target, grub_int32_t offset)
(((offset >> 12) & 0x03ff) << 16) |
(j1 << 13) | (j2 << 11) | ((offset >> 1) & 0x07ff);
/* Write instruction word back in alignment-safe manner */
*target = grub_cpu_to_le16 ((insword >> 16) & 0xffff);
*(target + 1) = grub_cpu_to_le16 (insword & 0xffff);
thumb_set_instruction_word (target, insword);
grub_dprintf ("dl", " *insword = 0x%08x", insword);
@ -123,9 +131,7 @@ grub_arm_thm_jump19_get_offset (grub_uint16_t *target)
grub_int32_t offset;
grub_uint32_t insword;
/* Extract instruction word in alignment-safe manner */
insword = (grub_le_to_cpu16 (*target) << 16)
| (grub_le_to_cpu16(*(target + 1)));
insword = thumb_get_instruction_word (target);
/* Extract and sign extend offset */
offset = ((insword >> 26) & 1) << 19
@ -149,9 +155,7 @@ grub_arm_thm_jump19_set_offset (grub_uint16_t *target, grub_int32_t offset)
offset >>= 1;
offset &= 0xfffff;
/* Extract instruction word in alignment-safe manner */
insword = grub_le_to_cpu16 ((*target)) << 16
| grub_le_to_cpu16 (*(target + 1));
insword = thumb_get_instruction_word (target);
/* Reassemble instruction word and write back */
insword &= insmask;
@ -160,8 +164,7 @@ grub_arm_thm_jump19_set_offset (grub_uint16_t *target, grub_int32_t offset)
| ((offset >> 17) & 1) << 13
| ((offset >> 11) & 0x3f) << 16
| (offset & 0x7ff);
*target = grub_cpu_to_le16 (insword >> 16);
*(target + 1) = grub_cpu_to_le16 (insword & 0xffff);
thumb_set_instruction_word (target, insword);
}
int
@ -172,6 +175,32 @@ grub_arm_thm_jump19_check_offset (grub_int32_t offset)
return 1;
}
grub_uint16_t
grub_arm_thm_movw_movt_get_value (grub_uint16_t *target)
{
grub_uint32_t insword;
insword = thumb_get_instruction_word (target);
return ((insword & 0xf0000) >> 4) | ((insword & 0x04000000) >> 15) | \
((insword & 0x7000) >> 4) | (insword & 0xff);
}
void
grub_arm_thm_movw_movt_set_value (grub_uint16_t *target, grub_uint16_t value)
{
grub_uint32_t insword;
const grub_uint32_t insmask = 0xfbf08f00;
insword = thumb_get_instruction_word (target);
insword &= insmask;
insword |= ((value & 0xf000) << 4) | ((value & 0x0800) << 15) | \
((value & 0x0700) << 4) | (value & 0xff);
thumb_set_instruction_word (target, insword);
}
/***********************************************************
* ARM (A32) relocations: *

View file

@ -0,0 +1,404 @@
/* compiler-rt.c - compiler helpers. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010-2014 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/misc.h>
#include <grub/compiler-rt.h>
#ifndef GRUB_EMBED_DECOMPRESSOR
void * GRUB_BUILTIN_ATTR
memcpy (void *dest, const void *src, grub_size_t n)
{
return grub_memmove (dest, src, n);
}
void * GRUB_BUILTIN_ATTR
memmove (void *dest, const void *src, grub_size_t n)
{
return grub_memmove (dest, src, n);
}
int GRUB_BUILTIN_ATTR
memcmp (const void *s1, const void *s2, grub_size_t n)
{
return grub_memcmp (s1, s2, n);
}
void * GRUB_BUILTIN_ATTR
memset (void *s, int c, grub_size_t n)
{
return grub_memset (s, c, n);
}
#ifdef __APPLE__
void GRUB_BUILTIN_ATTR
__bzero (void *s, grub_size_t n)
{
grub_memset (s, 0, n);
}
#endif
#if GRUB_DIVISION_IN_SOFTWARE
grub_uint32_t
__udivsi3 (grub_uint32_t a, grub_uint32_t b)
{
return grub_divmod64 (a, b, 0);
}
grub_int32_t
__divsi3 (grub_int32_t a, grub_int32_t b)
{
return grub_divmod64s (a, b, 0);
}
grub_uint32_t
__umodsi3 (grub_uint32_t a, grub_uint32_t b)
{
grub_uint64_t ret;
grub_divmod64 (a, b, &ret);
return ret;
}
grub_int32_t
__modsi3 (grub_int32_t a, grub_int32_t b)
{
grub_int64_t ret;
grub_divmod64s (a, b, &ret);
return ret;
}
grub_uint64_t
__udivdi3 (grub_uint64_t a, grub_uint64_t b)
{
return grub_divmod64 (a, b, 0);
}
grub_uint64_t
__umoddi3 (grub_uint64_t a, grub_uint64_t b)
{
grub_uint64_t ret;
grub_divmod64 (a, b, &ret);
return ret;
}
grub_int64_t
__divdi3 (grub_int64_t a, grub_int64_t b)
{
return grub_divmod64s (a, b, 0);
}
grub_int64_t
__moddi3 (grub_int64_t a, grub_int64_t b)
{
grub_int64_t ret;
grub_divmod64s (a, b, &ret);
return ret;
}
#endif
#endif
#ifdef NEED_CTZDI2
unsigned
__ctzdi2 (grub_uint64_t x)
{
unsigned ret = 0;
if (!x)
return 64;
if (!(x & 0xffffffff))
{
x >>= 32;
ret |= 32;
}
if (!(x & 0xffff))
{
x >>= 16;
ret |= 16;
}
if (!(x & 0xff))
{
x >>= 8;
ret |= 8;
}
if (!(x & 0xf))
{
x >>= 4;
ret |= 4;
}
if (!(x & 0x3))
{
x >>= 2;
ret |= 2;
}
if (!(x & 0x1))
{
x >>= 1;
ret |= 1;
}
return ret;
}
#endif
#ifdef NEED_CTZSI2
unsigned
__ctzsi2 (grub_uint32_t x)
{
unsigned ret = 0;
if (!x)
return 32;
if (!(x & 0xffff))
{
x >>= 16;
ret |= 16;
}
if (!(x & 0xff))
{
x >>= 8;
ret |= 8;
}
if (!(x & 0xf))
{
x >>= 4;
ret |= 4;
}
if (!(x & 0x3))
{
x >>= 2;
ret |= 2;
}
if (!(x & 0x1))
{
x >>= 1;
ret |= 1;
}
return ret;
}
#endif
#if defined (__clang__) && !defined(GRUB_EMBED_DECOMPRESSOR)
/* clang emits references to abort(). */
void __attribute__ ((noreturn))
abort (void)
{
grub_fatal ("compiler abort");
}
#endif
#if (defined (__MINGW32__) || defined (__CYGWIN__))
void __register_frame_info (void)
{
}
void __deregister_frame_info (void)
{
}
void ___chkstk_ms (void)
{
}
void __chkstk_ms (void)
{
}
#endif
union component64
{
grub_uint64_t full;
struct
{
#ifdef GRUB_CPU_WORDS_BIGENDIAN
grub_uint32_t high;
grub_uint32_t low;
#else
grub_uint32_t low;
grub_uint32_t high;
#endif
};
};
#if defined (__powerpc__) || defined (__arm__) || defined(__mips__)
/* Based on libgcc2.c from gcc suite. */
grub_uint64_t
__lshrdi3 (grub_uint64_t u, int b)
{
if (b == 0)
return u;
const union component64 uu = {.full = u};
const int bm = 32 - b;
union component64 w;
if (bm <= 0)
{
w.high = 0;
w.low = (grub_uint32_t) uu.high >> -bm;
}
else
{
const grub_uint32_t carries = (grub_uint32_t) uu.high << bm;
w.high = (grub_uint32_t) uu.high >> b;
w.low = ((grub_uint32_t) uu.low >> b) | carries;
}
return w.full;
}
/* Based on libgcc2.c from gcc suite. */
grub_uint64_t
__ashrdi3 (grub_uint64_t u, int b)
{
if (b == 0)
return u;
const union component64 uu = {.full = u};
const int bm = 32 - b;
union component64 w;
if (bm <= 0)
{
/* w.high = 1..1 or 0..0 */
w.high = ((grub_int32_t) uu.high) >> (32 - 1);
w.low = ((grub_int32_t) uu.high) >> -bm;
}
else
{
const grub_uint32_t carries = ((grub_uint32_t) uu.high) << bm;
w.high = ((grub_int32_t) uu.high) >> b;
w.low = ((grub_uint32_t) uu.low >> b) | carries;
}
return w.full;
}
/* Based on libgcc2.c from gcc suite. */
grub_uint64_t
__ashldi3 (grub_uint64_t u, int b)
{
if (b == 0)
return u;
const union component64 uu = {.full = u};
const int bm = 32 - b;
union component64 w;
if (bm <= 0)
{
w.low = 0;
w.high = (grub_uint32_t) uu.low << -bm;
}
else
{
const grub_uint32_t carries = (grub_uint32_t) uu.low >> bm;
w.low = (grub_uint32_t) uu.low << b;
w.high = ((grub_uint32_t) uu.high << b) | carries;
}
return w.full;
}
/* Based on libgcc2.c from gcc suite. */
int
__ucmpdi2 (grub_uint64_t a, grub_uint64_t b)
{
union component64 ac, bc;
ac.full = a;
bc.full = b;
if (ac.high < bc.high)
return 0;
else if (ac.high > bc.high)
return 2;
if (ac.low < bc.low)
return 0;
else if (ac.low > bc.low)
return 2;
return 1;
}
#endif
#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || defined(__arm__)
/* Based on libgcc2.c from gcc suite. */
grub_uint32_t
__bswapsi2 (grub_uint32_t u)
{
return ((((u) & 0xff000000) >> 24)
| (((u) & 0x00ff0000) >> 8)
| (((u) & 0x0000ff00) << 8)
| (((u) & 0x000000ff) << 24));
}
/* Based on libgcc2.c from gcc suite. */
grub_uint64_t
__bswapdi2 (grub_uint64_t u)
{
return ((((u) & 0xff00000000000000ull) >> 56)
| (((u) & 0x00ff000000000000ull) >> 40)
| (((u) & 0x0000ff0000000000ull) >> 24)
| (((u) & 0x000000ff00000000ull) >> 8)
| (((u) & 0x00000000ff000000ull) << 8)
| (((u) & 0x0000000000ff0000ull) << 24)
| (((u) & 0x000000000000ff00ull) << 40)
| (((u) & 0x00000000000000ffull) << 56));
}
#endif
#ifdef __arm__
grub_uint32_t
__aeabi_uidiv (grub_uint32_t a, grub_uint32_t b)
__attribute__ ((alias ("__udivsi3")));
grub_int32_t
__aeabi_idiv (grub_int32_t a, grub_int32_t b)
__attribute__ ((alias ("__divsi3")));
void *__aeabi_memcpy (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memcpy")));
void *__aeabi_memset (void *s, int c, grub_size_t n)
__attribute__ ((alias ("memset")));
int
__aeabi_ulcmp (grub_uint64_t a, grub_uint64_t b)
{
return __ucmpdi2 (a, b) - 1;
}
grub_uint64_t
__aeabi_lasr (grub_uint64_t u, int b)
__attribute__ ((alias ("__ashrdi3")));
grub_uint64_t
__aeabi_llsr (grub_uint64_t u, int b)
__attribute__ ((alias ("__lshrdi3")));
grub_uint64_t
__aeabi_llsl (grub_uint64_t u, int b)
__attribute__ ((alias ("__ashldi3")));
#endif

View file

@ -348,7 +348,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
mod->symtab = grub_malloc (s->sh_size);
if (!mod->symtab)
return grub_errno;
memcpy (mod->symtab, (char *) e + s->sh_offset, s->sh_size);
grub_memcpy (mod->symtab, (char *) e + s->sh_offset, s->sh_size);
#else
mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset);
#endif

View file

@ -262,6 +262,7 @@ grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
grub_efi_boot_services_t *b;
grub_efi_uintn_t key;
grub_efi_uint32_t version;
grub_efi_uintn_t size;
if (grub_efi_is_finished)
{
@ -291,10 +292,14 @@ grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
map_key = &key;
if (! descriptor_version)
descriptor_version = &version;
if (! descriptor_size)
descriptor_size = &size;
b = grub_efi_system_table->boot_services;
status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key,
descriptor_size, descriptor_version);
if (*descriptor_size == 0)
*descriptor_size = sizeof (grub_efi_memory_descriptor_t);
if (status == GRUB_EFI_SUCCESS)
return 1;
else if (status == GRUB_EFI_BUFFER_TOO_SMALL)

View file

@ -8,7 +8,7 @@
#include "../ia64/cache.c"
#elif defined (__arm__) || defined (__aarch64__)
void __clear_cache (char *beg, char *end);
void __clear_cache (void *beg, void *end);
void
grub_arch_sync_caches (void *address, grub_size_t len)

View file

@ -99,7 +99,7 @@ find_free_slot (void)
{
unsigned int i;
for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
for (i = 0; i < ARRAY_SIZE (map); i++)
if (! map[i].drive)
return i;
@ -115,7 +115,7 @@ grub_util_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
if (pull != GRUB_DISK_PULL_NONE)
return 0;
for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
for (i = 0; i < ARRAY_SIZE (map); i++)
if (map[i].drive && hook (map[i].drive, hook_data))
return 1;
@ -184,7 +184,7 @@ grub_hostdisk_os_dev_to_grub_drive (const char *os_disk, int add)
unsigned int i;
char *canon;
canon = canonicalize_file_name (os_disk);
canon = grub_canonicalize_file_name (os_disk);
if (!canon)
canon = xstrdup (os_disk);
@ -535,7 +535,7 @@ read_device_map (const char *dev_map)
/* On Linux, the devfs uses symbolic links horribly, and that
confuses the interface very much, so use realpath to expand
symbolic links. */
map[drive].device = canonicalize_file_name (p);
map[drive].device = grub_canonicalize_file_name (p);
if (! map[drive].device)
map[drive].device = xstrdup (p);
@ -581,7 +581,7 @@ grub_util_biosdisk_fini (void)
{
unsigned i;
for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
for (i = 0; i < ARRAY_SIZE(map); i++)
{
if (map[i].drive)
free (map[i].drive);

View file

@ -19,11 +19,6 @@
#include <config-util.h>
/* Legacy feature macro.*/
#define _BSD_SOURCE
/* New feature macro that provides everything _BSD_SOURCE and
* _SVID_SOURCE provided and possibly more. */
#define _DEFAULT_SOURCE
#include <grub/fs.h>
#include <grub/file.h>
#include <grub/disk.h>

View file

@ -34,5 +34,5 @@ grub_rtc_get_time_ms (void)
1 s 1 T rtc ticks
*/
grub_uint64_t ticks_ms_per_sec = ((grub_uint64_t) 1000) * grub_get_rtc ();
return grub_divmod64 (ticks_ms_per_sec, GRUB_TICKS_PER_SECOND, 0);
return grub_divmod64 (ticks_ms_per_sec, GRUB_TICKS_PER_SECOND ? : 1000, 0);
}

View file

@ -61,8 +61,3 @@ multiboot_header:
/* checksum */
.long -0x1BADB002 - MULTIBOOT_MEMORY_INFO
/*
* prot_to_real and associated structures (but NOT real_to_prot, that is
* only needed for BIOS gates).
*/
#include "../realmode.S"

View file

@ -148,7 +148,7 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
while (1)
{
grub_memset (entry, 0, sizeof (entry));
grub_memset (entry, 0, sizeof (*entry));
cont = grub_get_mmap_entry (entry, cont);

View file

@ -135,7 +135,7 @@ LOCAL(prot_to_real_addr):
.macro REAL_TO_PROT
movl LOCAL(real_to_prot_addr), %eax
DATA32 call *%ax
calll *%eax
.endm
/*

View file

@ -28,7 +28,7 @@
_start:
jmp codestart
. = _start + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR
.org GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR
VARIABLE(grub_core_entry_addr)
.long 0
@ -73,5 +73,3 @@ codestart:
1:
hlt
jmp 1b
#include "../realmode.S"

View file

@ -54,7 +54,7 @@ protstack:
.endm
.macro REAL_TO_PROT
DATA32 call real_to_prot
calll real_to_prot
.endm
/*
@ -137,7 +137,22 @@ real_to_prot:
/* load the GDT register */
xorw %ax, %ax
movw %ax, %ds
DATA32 ADDR32 lgdt gdtdesc
#ifdef GRUB_MACHINE_QEMU
/*
qemu is special: gdtdesc is in ROM.
%cs = 0xf000
_start + GRUB_BOOT_MACHINE_SIZE = 0x100000
So
_start + GRUB_BOOT_MACHINE_SIZE - 0x10000 points to the same point
as %cs.
gdtdesc - (_start + GRUB_BOOT_MACHINE_SIZE - 0x10000)
= gdtdesc - _start - GRUB_BOOT_MACHINE_SIZE + 0x10000
but the later can be computed by assembly.
*/
lgdtl %cs:(gdtdesc - _start - GRUB_BOOT_MACHINE_SIZE + 0x10000)
#else
lgdtl gdtdesc
#endif
/* turn on protected mode */
movl %cr0, %eax
@ -145,7 +160,7 @@ real_to_prot:
movl %eax, %cr0
/* jump to relocation, flush prefetch queue, and reload %cs */
DATA32 ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
ljmpl $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
.code32
protcseg:
@ -178,6 +193,9 @@ protcseg:
/* return on the old (or initialized) stack! */
ret
/* prot_to_real assumes that this code is under 64K which is not
true for qemu. */
#ifndef GRUB_MACHINE_QEMU
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc.
@ -237,7 +255,7 @@ tmpcseg:
movl %eax, %cr0
/* flush prefetch queue, reload %cs */
DATA32 ljmp $0, $realcseg
ljmpl $0, $realcseg
realcseg:
/* we are in real mode now
@ -258,6 +276,6 @@ realcseg:
#endif
/* return on new stack! */
DATA32 ret
retl
#endif
.code32

View file

@ -57,6 +57,8 @@ grub_get_tsc (void)
return (((grub_uint64_t) hi) << 32) | lo;
}
#ifndef GRUB_MACHINE_XEN
static __inline int
grub_cpu_is_tsc_supported (void)
{
@ -69,8 +71,6 @@ grub_cpu_is_tsc_supported (void)
return (d & (1 << 4)) != 0;
}
#ifndef GRUB_MACHINE_XEN
static void
grub_pit_wait (grub_uint16_t tics)
{
@ -122,7 +122,11 @@ calibrate_tsc (void)
grub_pit_wait (0xffff);
end_tsc = grub_get_tsc ();
grub_tsc_rate = grub_divmod64 ((55ULL << 32), end_tsc - tsc_boot_time, 0);
grub_tsc_rate = 0;
if (end_tsc > tsc_boot_time)
grub_tsc_rate = grub_divmod64 ((55ULL << 32), end_tsc - tsc_boot_time, 0);
if (grub_tsc_rate == 0)
grub_tsc_rate = 5368;/* 800 MHz */
}
#endif

View file

@ -1,8 +1,10 @@
#include <grub/symbol.h>
#include <grub/cpu/kernel.h>
.set noreorder
.set nomacro
mips_attributes
FUNCTION (grub_arch_sync_caches)
#include "cache_flush.S"
@ -65,4 +67,4 @@ FUNCTION (grub_arch_sync_dma_caches)
#endif
sync_op
jr $ra
jr $ra

View file

@ -21,6 +21,7 @@
#include <grub/offsets.h>
#include <grub/machine/memory.h>
#include <grub/machine/kernel.h>
#include <grub/cpu/kernel.h>
#include <grub/offsets.h>
#define BASE_ADDR 8
@ -28,6 +29,7 @@
.globl __start, _start, start
.set noreorder
.set nomacro
mips_attributes
__start:
_start:
start:
@ -36,7 +38,7 @@ start:
bal cont
nop
. = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
.org GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
VARIABLE(grub_total_modules_size)
.long 0

View file

@ -95,25 +95,6 @@ grub_memmove (void *dest, const void *src, grub_size_t n)
return dest;
}
#ifndef __APPLE__
void *memmove (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memmove")));
/* GCC emits references to memcpy() for struct copies etc. */
void *memcpy (void *dest, const void *src, grub_size_t n)
__attribute__ ((alias ("grub_memmove")));
#else
void * GRUB_BUILTIN_ATTR
memcpy (void *dest, const void *src, grub_size_t n)
{
return grub_memmove (dest, src, n);
}
void * GRUB_BUILTIN_ATTR
memmove (void *dest, const void *src, grub_size_t n)
{
return grub_memmove (dest, src, n);
}
#endif
char *
grub_strcpy (char *dest, const char *src)
{
@ -253,16 +234,6 @@ grub_memcmp (const void *s1, const void *s2, grub_size_t n)
return 0;
}
#ifndef __APPLE__
int memcmp (const void *s1, const void *s2, grub_size_t n)
__attribute__ ((alias ("grub_memcmp")));
#else
int GRUB_BUILTIN_ATTR
memcmp (const void *s1, const void *s2, grub_size_t n)
{
return grub_memcmp (s1, s2, n);
}
#endif
int
grub_strcmp (const char *s1, const char *s2)
@ -532,26 +503,6 @@ grub_memset (void *s, int c, grub_size_t len)
return s;
}
#ifndef __APPLE__
void *memset (void *s, int c, grub_size_t n)
__attribute__ ((alias ("grub_memset")));
#else
void * GRUB_BUILTIN_ATTR
memset (void *s, int c, grub_size_t n)
{
return grub_memset (s, c, n);
}
#endif
#if !defined(GRUB_UTIL) && defined(__APPLE__)
void GRUB_BUILTIN_ATTR
__bzero (void *s, grub_size_t n)
{
grub_memset (s, 0, n);
}
#endif
grub_size_t
grub_strlen (const char *s)
@ -594,10 +545,10 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
grub_uint64_t m = 0;
/* ARM and IA64 don't have a fast 32-bit division.
Using that code would just make us use libgcc routines, calling
them twice (once for modulo and once for quotient.
Using that code would just make us use software division routines, calling
ourselves indirectly and hence getting infinite recursion.
*/
#if !defined (__arm__) && !defined (__ia64__)
#if !GRUB_DIVISION_IN_SOFTWARE
/* Skip the slow computation if 32-bit arithmetic is possible. */
if (n < 0xffffffff && d < 0xffffffff)
{
@ -631,132 +582,6 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
return q;
}
#if !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
#if defined (__arm__)
grub_uint32_t
__udivsi3 (grub_uint32_t a, grub_uint32_t b)
{
return grub_divmod64 (a, b, 0);
}
grub_uint32_t
__umodsi3 (grub_uint32_t a, grub_uint32_t b)
{
grub_uint64_t ret;
grub_divmod64 (a, b, &ret);
return ret;
}
#endif
#ifdef NEED_CTZDI2
unsigned
__ctzdi2 (grub_uint64_t x)
{
unsigned ret = 0;
if (!x)
return 64;
if (!(x & 0xffffffff))
{
x >>= 32;
ret |= 32;
}
if (!(x & 0xffff))
{
x >>= 16;
ret |= 16;
}
if (!(x & 0xff))
{
x >>= 8;
ret |= 8;
}
if (!(x & 0xf))
{
x >>= 4;
ret |= 4;
}
if (!(x & 0x3))
{
x >>= 2;
ret |= 2;
}
if (!(x & 0x1))
{
x >>= 1;
ret |= 1;
}
return ret;
}
#endif
#ifdef NEED_CTZSI2
unsigned
__ctzsi2 (grub_uint32_t x)
{
unsigned ret = 0;
if (!x)
return 32;
if (!(x & 0xffff))
{
x >>= 16;
ret |= 16;
}
if (!(x & 0xff))
{
x >>= 8;
ret |= 8;
}
if (!(x & 0xf))
{
x >>= 4;
ret |= 4;
}
if (!(x & 0x3))
{
x >>= 2;
ret |= 2;
}
if (!(x & 0x1))
{
x >>= 1;
ret |= 1;
}
return ret;
}
#endif
#ifdef __arm__
grub_uint32_t
__aeabi_uidiv (grub_uint32_t a, grub_uint32_t b)
__attribute__ ((alias ("__udivsi3")));
#endif
#if defined (__ia64__)
grub_uint64_t
__udivdi3 (grub_uint64_t a, grub_uint64_t b)
{
return grub_divmod64 (a, b, 0);
}
grub_uint64_t
__umoddi3 (grub_uint64_t a, grub_uint64_t b)
{
grub_uint64_t ret;
grub_divmod64 (a, b, &ret);
return ret;
}
#endif
#endif /* GRUB_UTIL */
/* Convert a long long value to a string. This function avoids 64-bit
modular arithmetic or divisions. */
static inline char *
@ -1265,15 +1090,6 @@ grub_abort (void)
grub_exit ();
}
#if defined (__clang__) && !defined (GRUB_UTIL)
/* clang emits references to abort(). */
void __attribute__ ((noreturn))
abort (void)
{
grub_abort ();
}
#endif
void
grub_fatal (const char *fmt, ...)
{
@ -1286,23 +1102,6 @@ grub_fatal (const char *fmt, ...)
grub_abort ();
}
#if (defined (__MINGW32__) || defined (__CYGWIN__)) && !defined(GRUB_UTIL)
void __register_frame_info (void)
{
}
void __deregister_frame_info (void)
{
}
void ___chkstk_ms (void)
{
}
void __chkstk_ms (void)
{
}
#endif
#if BOOT_TIME_STATS
#include <grub/time.h>

View file

@ -0,0 +1,130 @@
/*
* Special support for eabi and SVR4
*
* Copyright (C) 1995-2014 Free Software Foundation, Inc.
* Written By Michael Meissner
* 64-bit support written by David Edelsohn
*
* This file is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3, or (at your option) any
* later version.
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* Under Section 7 of GPL version 3, you are granted additional
* permissions described in the GCC Runtime Library Exception, version
* 3.1, as published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License and
* a copy of the GCC Runtime Library Exception along with this program;
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
* <http://www.gnu.org/licenses/>.
*/
/* Do any initializations needed for the eabi environment */
#include <grub/symbol.h>
#include <grub/dl.h>
.section ".text"
#define CFI_RESTORE(reg) .cfi_restore reg
#define CFI_OFFSET(reg, off) .cfi_offset reg, off
#define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
#define CFI_STARTPROC .cfi_startproc
#define CFI_ENDPROC .cfi_endproc
/* Routines for restoring integer registers, called by the compiler. */
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer restore area. */
CFI_STARTPROC
CFI_DEF_CFA_REGISTER (11)
CFI_OFFSET (65, 4)
CFI_OFFSET (14, -72)
CFI_OFFSET (15, -68)
CFI_OFFSET (16, -64)
CFI_OFFSET (17, -60)
CFI_OFFSET (18, -56)
CFI_OFFSET (19, -52)
CFI_OFFSET (20, -48)
CFI_OFFSET (21, -44)
CFI_OFFSET (22, -40)
CFI_OFFSET (23, -36)
CFI_OFFSET (24, -32)
CFI_OFFSET (25, -28)
CFI_OFFSET (26, -24)
CFI_OFFSET (27, -20)
CFI_OFFSET (28, -16)
CFI_OFFSET (29, -12)
CFI_OFFSET (30, -8)
CFI_OFFSET (31, -4)
FUNCTION(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */
CFI_RESTORE (14)
FUNCTION(_restgpr_15_x) lwz 15,-68(11)
CFI_RESTORE (15)
FUNCTION(_restgpr_16_x) lwz 16,-64(11)
CFI_RESTORE (16)
FUNCTION(_restgpr_17_x) lwz 17,-60(11)
CFI_RESTORE (17)
FUNCTION(_restgpr_18_x) lwz 18,-56(11)
CFI_RESTORE (18)
FUNCTION(_restgpr_19_x) lwz 19,-52(11)
CFI_RESTORE (19)
FUNCTION(_restgpr_20_x) lwz 20,-48(11)
CFI_RESTORE (20)
FUNCTION(_restgpr_21_x) lwz 21,-44(11)
CFI_RESTORE (21)
FUNCTION(_restgpr_22_x) lwz 22,-40(11)
CFI_RESTORE (22)
FUNCTION(_restgpr_23_x) lwz 23,-36(11)
CFI_RESTORE (23)
FUNCTION(_restgpr_24_x) lwz 24,-32(11)
CFI_RESTORE (24)
FUNCTION(_restgpr_25_x) lwz 25,-28(11)
CFI_RESTORE (25)
FUNCTION(_restgpr_26_x) lwz 26,-24(11)
CFI_RESTORE (26)
FUNCTION(_restgpr_27_x) lwz 27,-20(11)
CFI_RESTORE (27)
FUNCTION(_restgpr_28_x) lwz 28,-16(11)
CFI_RESTORE (28)
FUNCTION(_restgpr_29_x) lwz 29,-12(11)
CFI_RESTORE (29)
FUNCTION(_restgpr_30_x) lwz 30,-8(11)
CFI_RESTORE (30)
FUNCTION(_restgpr_31_x) lwz 0,4(11)
lwz 31,-4(11)
CFI_RESTORE (31)
mtlr 0
CFI_RESTORE (65)
mr 1,11
CFI_DEF_CFA_REGISTER (1)
blr
CFI_ENDPROC
CFI_STARTPROC
FUNCTION(_savegpr_14) stw 14,-72(11) /* save gp registers */
FUNCTION(_savegpr_15) stw 15,-68(11)
FUNCTION(_savegpr_16) stw 16,-64(11)
FUNCTION(_savegpr_17) stw 17,-60(11)
FUNCTION(_savegpr_18) stw 18,-56(11)
FUNCTION(_savegpr_19) stw 19,-52(11)
FUNCTION(_savegpr_20) stw 20,-48(11)
FUNCTION(_savegpr_21) stw 21,-44(11)
FUNCTION(_savegpr_22) stw 22,-40(11)
FUNCTION(_savegpr_23) stw 23,-36(11)
FUNCTION(_savegpr_24) stw 24,-32(11)
FUNCTION(_savegpr_25) stw 25,-28(11)
FUNCTION(_savegpr_26) stw 26,-24(11)
FUNCTION(_savegpr_27) stw 27,-20(11)
FUNCTION(_savegpr_28) stw 28,-16(11)
FUNCTION(_savegpr_29) stw 29,-12(11)
FUNCTION(_savegpr_30) stw 30,-8(11)
FUNCTION(_savegpr_31) stw 31,-4(11)
blr
CFI_ENDPROC

View file

@ -27,7 +27,7 @@ _start:
ba codestart
mov %o4, %o0
. = EXT_C(_start) + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
.org GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
VARIABLE(grub_total_module_size)
.word 0

View file

@ -205,13 +205,16 @@ grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
{
const grub_uint8_t *inptr, *end;
grub_uint8_t *outptr;
grub_size_t blocksize;
if (!cipher->cipher->decrypt)
return GPG_ERR_NOT_SUPPORTED;
if (size % cipher->cipher->blocksize != 0)
blocksize = cipher->cipher->blocksize;
if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
|| ((size & (blocksize - 1)) != 0))
return GPG_ERR_INV_ARG;
end = (const grub_uint8_t *) in + size;
for (inptr = in, outptr = out; inptr < end;
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
inptr += blocksize, outptr += blocksize)
cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
return GPG_ERR_NO_ERROR;
}
@ -222,13 +225,16 @@ grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
{
const grub_uint8_t *inptr, *end;
grub_uint8_t *outptr;
grub_size_t blocksize;
if (!cipher->cipher->encrypt)
return GPG_ERR_NOT_SUPPORTED;
if (size % cipher->cipher->blocksize != 0)
blocksize = cipher->cipher->blocksize;
if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
|| ((size & (blocksize - 1)) != 0))
return GPG_ERR_INV_ARG;
end = (const grub_uint8_t *) in + size;
for (inptr = in, outptr = out; inptr < end;
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
inptr += blocksize, outptr += blocksize)
cipher->cipher->encrypt (cipher->ctx, outptr, inptr);
return GPG_ERR_NO_ERROR;
}
@ -241,20 +247,23 @@ grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
grub_uint8_t *outptr;
const grub_uint8_t *inptr, *end;
void *iv;
if (!cipher->cipher->decrypt)
grub_size_t blocksize;
if (!cipher->cipher->encrypt)
return GPG_ERR_NOT_SUPPORTED;
if (size % cipher->cipher->blocksize != 0)
blocksize = cipher->cipher->blocksize;
if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
|| ((size & (blocksize - 1)) != 0))
return GPG_ERR_INV_ARG;
end = (const grub_uint8_t *) in + size;
iv = iv_in;
for (inptr = in, outptr = out; inptr < end;
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
inptr += blocksize, outptr += blocksize)
{
grub_crypto_xor (outptr, inptr, iv, cipher->cipher->blocksize);
grub_crypto_xor (outptr, inptr, iv, blocksize);
cipher->cipher->encrypt (cipher->ctx, outptr, outptr);
iv = outptr;
}
grub_memcpy (iv_in, iv, cipher->cipher->blocksize);
grub_memcpy (iv_in, iv, blocksize);
return GPG_ERR_NO_ERROR;
}
@ -266,20 +275,23 @@ grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
const grub_uint8_t *inptr, *end;
grub_uint8_t *outptr;
grub_uint8_t ivt[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
grub_size_t blocksize;
if (!cipher->cipher->decrypt)
return GPG_ERR_NOT_SUPPORTED;
if (size % cipher->cipher->blocksize != 0)
blocksize = cipher->cipher->blocksize;
if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
|| ((size & (blocksize - 1)) != 0))
return GPG_ERR_INV_ARG;
if (cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
return GPG_ERR_INV_ARG;
end = (const grub_uint8_t *) in + size;
for (inptr = in, outptr = out; inptr < end;
inptr += cipher->cipher->blocksize, outptr += cipher->cipher->blocksize)
inptr += blocksize, outptr += blocksize)
{
grub_memcpy (ivt, inptr, cipher->cipher->blocksize);
grub_memcpy (ivt, inptr, blocksize);
cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
grub_crypto_xor (outptr, outptr, iv, cipher->cipher->blocksize);
grub_memcpy (iv, ivt, cipher->cipher->blocksize);
grub_crypto_xor (outptr, outptr, iv, blocksize);
grub_memcpy (iv, ivt, blocksize);
}
return GPG_ERR_NO_ERROR;
}

Some files were not shown because too many files have changed in this diff Show more