Ejemplo n.º 1
0
static grub_err_t
grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
		 int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_ssize_t size;
  void *module = NULL;
  grub_addr_t target;
  grub_err_t err;
  int nounzip = 0;
  grub_uint64_t lowest_addr = 0;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  if (grub_strcmp (argv[0], "--nounzip") == 0)
    {
      argv++;
      argc--;
      nounzip = 1;
    }

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  if (!grub_multiboot_relocator)
    return grub_error (GRUB_ERR_BAD_ARGUMENT,
		       N_("you need to load the kernel first"));

  if (nounzip)
    grub_file_filter_disable_compression ();

  file = grub_file_open (argv[0]);
  if (! file)
    return grub_errno;

#ifndef GRUB_USE_MULTIBOOT2
  lowest_addr = 0x100000;
  if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL)
    lowest_addr = ALIGN_UP (highest_load + 1048576, 4096);
#endif

  size = grub_file_size (file);
  if (size)
  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
					    lowest_addr, (0xffffffff - size) + 1,
					    size, MULTIBOOT_MOD_ALIGN,
					    GRUB_RELOCATOR_PREFERENCE_NONE, 1);
    if (err)
      {
	grub_file_close (file);
	return err;
      }
    module = get_virtual_current_address (ch);
    target = get_physical_target_address (ch);
  }
  else
    {
      module = 0;
      target = 0;
    }

  err = grub_multiboot_add_module (target, size, argc - 1, argv + 1);
  if (err)
    {
      grub_file_close (file);
      return err;
    }

  if (size && grub_file_read (file, module, size) != size)
    {
      grub_file_close (file);
      if (!grub_errno)
	grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
		    argv[0]);
      return grub_errno;
    }

  grub_file_close (file);
  return GRUB_ERR_NONE;
}
Ejemplo n.º 2
0
/* Read block header from file, after successful exit file points to
 * beginning of block data.  */
static int
read_block_header (struct grub_lzopio *lzopio)
{
  lzopio->saved_off += lzopio->block.usize;

  /* Free cached block data if any.  */
  grub_free (lzopio->block.udata);
  grub_free (lzopio->block.cdata);
  lzopio->block.udata = NULL;
  lzopio->block.cdata = NULL;

  if (grub_file_read (lzopio->file, &lzopio->block.usize,
		      sizeof (lzopio->block.usize)) !=
      sizeof (lzopio->block.usize))
    return -1;

  lzopio->block.usize = grub_be_to_cpu32 (lzopio->block.usize);

  /* Last block has uncompressed data size == 0 and no other fields.  */
  if (lzopio->block.usize == 0)
    {
      if (grub_file_tell (lzopio->file) == grub_file_size (lzopio->file))
	return 0;
      else
	return -1;
    }

  /* Read compressed data block size.  */
  if (grub_file_read (lzopio->file, &lzopio->block.csize,
		      sizeof (lzopio->block.csize)) !=
      sizeof (lzopio->block.csize))
    return -1;

  lzopio->block.csize = grub_be_to_cpu32 (lzopio->block.csize);

  /* Corrupted.  */
  if (lzopio->block.csize > lzopio->block.usize)
    return -1;

  /* Read checksum of uncompressed data.  */
  if (lzopio->has_ucheck)
    {
      if (grub_file_read (lzopio->file, &lzopio->block.ucheck,
			  sizeof (lzopio->block.ucheck)) !=
	  sizeof (lzopio->block.ucheck))
	return -1;

      lzopio->block.ucheck = lzopio->block.ucheck;
    }

  /* Read checksum of compressed data.  */
  if (lzopio->has_ccheck)
    {
      /* Incompressible data block.  */
      if (lzopio->block.csize == lzopio->block.usize)
	{
	  lzopio->block.ccheck = lzopio->block.ucheck;
	}
      else
	{
	  if (grub_file_read (lzopio->file, &lzopio->block.ccheck,
			      sizeof (lzopio->block.ccheck)) !=
	      sizeof (lzopio->block.ccheck))
	    return -1;

	  lzopio->block.ccheck = lzopio->block.ccheck;
	}
    }

  return 0;
}
Ejemplo n.º 3
0
static grub_err_t
grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
		int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_err_t err;
  void *bs, *ntldr;
  grub_size_t ntldrsize;
  grub_device_t dev;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  grub_dl_ref (my_mod);

  rel = grub_relocator_new ();
  if (!rel)
    goto fail;

  file = grub_file_open (argv[0]);
  if (! file)
    goto fail;

  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
					   GRUB_DISK_SECTOR_SIZE);
    if (err)
      goto fail;
    bs = get_virtual_current_address (ch);
  }

  edx = grub_get_root_biosnumber ();
  dev = grub_device_open (0);

  if (dev && dev->disk)
    {
      err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs);
      if (err)
	{
	  grub_device_close (dev);
	  goto fail;
	}
      grub_chainloader_patch_bpb (bs, dev, edx);
    }

  if (dev)
    grub_device_close (dev);

  ntldrsize = grub_file_size (file);
  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4,
					   ntldrsize);
    if (err)
      goto fail;
    ntldr = get_virtual_current_address (ch);
  }

  if (grub_file_read (file, ntldr, ntldrsize)
      != (grub_ssize_t) ntldrsize)
    goto fail;
 
  grub_loader_set (grub_ntldr_boot, grub_ntldr_unload, 1);

  /* Begin TCG Extension */
  if (grub_TPM_isAvailable())
    grub_TPM_measureFile( argv[0], TPM_LOADED_FILES_PCR );
  /* End TCG Extension */

  return GRUB_ERR_NONE;

 fail:

  if (file)
    grub_file_close (file);

  grub_ntldr_unload ();

  return grub_errno;
}
Ejemplo n.º 4
0
void
grub_module2 (int argc, char *argv[])
{
  grub_file_t file;
  grub_addr_t modaddr = 0;
  grub_ssize_t modsize = 0;
  grub_err_t err;

  if (argc == 0)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
      return;
    }

  if (argc == 1)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "No module type specified");
      return;
    }

  if (entry == 0)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT,
		  "You need to load the multiboot kernel first");
      return;
    }

  /* Load module data.  */
  file = grub_gzfile_open (argv[0], 1);
  if (! file)
    goto out;

  modsize = grub_file_size (file);
  err = grub_mb2_arch_module_alloc (modsize, &modaddr);
  if (err)
    goto out;

  grub_dprintf ("loader", "Loading module at 0x%x - 0x%x\n", modaddr,
		modaddr + modsize);
  if (grub_file_read (file, (char *) modaddr, modsize) != modsize)
    {
      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
      goto out;
    }

  /* Create the module tag.  */
  err = grub_mb2_tag_module_create (modaddr, modsize,
				   argv[1], MULTIBOOT2_TAG_MODULE,
				   argc-2, &argv[2]);
  if (err)
    goto out;

out:
  grub_error_push ();

  if (file)
    grub_file_close (file);

  if (modaddr)
    grub_mb2_arch_module_free (modaddr, modsize);

  grub_error_pop ();
}
Ejemplo n.º 5
0
static int
test_gzip_header (grub_file_t file)
{
    struct {
        grub_uint16_t magic;
        grub_uint8_t method;
        grub_uint8_t flags;
        grub_uint32_t timestamp;
        grub_uint8_t extra_flags;
        grub_uint8_t os_type;
    } hdr;
    grub_uint16_t extra_len;
    grub_uint32_t orig_len;
    grub_gzio_t gzio = file->data;

    if (grub_file_tell (gzio->file) != 0)
        grub_file_seek (gzio->file, 0);

    /*
     *  This checks if the file is gzipped.  If a problem occurs here
     *  (other than a real error with the disk) then we don't think it
     *  is a compressed file, and simply mark it as such.
     */
    if (grub_file_read (gzio->file, &hdr, 10) != 10
            || ((hdr.magic != GZIP_MAGIC)
                && (hdr.magic != OLD_GZIP_MAGIC)))
    {
        grub_error (GRUB_ERR_BAD_FILE_TYPE, "no gzip magic found");
        return 0;
    }

    /*
     *  This does consistency checking on the header data.  If a
     *  problem occurs from here on, then we have corrupt or otherwise
     *  bad data, and the error should be reported to the user.
     */
    if (hdr.method != DEFLATED
            || (hdr.flags & UNSUPPORTED_FLAGS)
            || ((hdr.flags & EXTRA_FIELD)
                && (grub_file_read (gzio->file, &extra_len, 2) != 2
                    || eat_field (gzio->file,
                                  grub_le_to_cpu16 (extra_len))))
            || ((hdr.flags & ORIG_NAME) && eat_field (gzio->file, -1))
            || ((hdr.flags & COMMENT) && eat_field (gzio->file, -1)))
    {
        grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "unsupported gzip format");
        return 0;
    }

    gzio->data_offset = grub_file_tell (gzio->file);

    /* FIXME: don't do this on not easily seekable files.  */
    {
        grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4);
        if (grub_file_read (gzio->file, &orig_len, 4) != 4)
        {
            grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format");
            return 0;
        }
        /* FIXME: this does not handle files whose original size is over 4GB.
           But how can we know the real original size?  */
        file->size = grub_le_to_cpu32 (orig_len);
    }

    initialize_tables (gzio);

    return 1;
}
Ejemplo n.º 6
0
grub_macho_t
grub_macho_file (grub_file_t file, const char *filename, int is_64bit)
{
  grub_macho_t macho;
  union grub_macho_filestart filestart;

  macho = grub_malloc (sizeof (*macho));
  if (! macho)
    return 0;

  macho->file = file;
  macho->offset32 = -1;
  macho->offset64 = -1;
  macho->end32 = -1;
  macho->end64 = -1;
  macho->cmds32 = 0;
  macho->cmds64 = 0;
  macho->uncompressed32 = 0;
  macho->uncompressed64 = 0;
  macho->compressed32 = 0;
  macho->compressed64 = 0;

  if (grub_file_seek (macho->file, 0) == (grub_off_t) -1)
    goto fail;

  if (grub_file_read (macho->file, &filestart, sizeof (filestart))
      != sizeof (filestart))
    {
      if (!grub_errno)
	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
		    filename);
      goto fail;
    }

  /* Is it a fat file? */
  if (filestart.fat.magic == grub_cpu_to_be32_compile_time (GRUB_MACHO_FAT_MAGIC))
    {
      struct grub_macho_fat_arch *archs;
      int i, narchs;

      /* Load architecture description. */
      narchs = grub_be_to_cpu32 (filestart.fat.nfat_arch);
      if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header))
	  == (grub_off_t) -1)
	goto fail;
      archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
      if (!archs)
	goto fail;
      if (grub_file_read (macho->file, archs,
			  sizeof (struct grub_macho_fat_arch) * narchs)
	  != (grub_ssize_t) sizeof(struct grub_macho_fat_arch) * narchs)
	{
	  grub_free (archs);
	  if (!grub_errno)
	    grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
			filename);
	  goto fail;
	}

      for (i = 0; i < narchs; i++)
	{
	  if ((archs[i].cputype
	       == grub_cpu_to_be32_compile_time (GRUB_MACHO_CPUTYPE_IA32))
	      && !is_64bit)
	    {
	      macho->offset32 = grub_be_to_cpu32 (archs[i].offset);
	      macho->end32 = grub_be_to_cpu32 (archs[i].offset)
		+ grub_be_to_cpu32 (archs[i].size);
	    }
	  if ((archs[i].cputype
	       == grub_cpu_to_be32_compile_time (GRUB_MACHO_CPUTYPE_AMD64))
	      && is_64bit)
	    {
	      macho->offset64 = grub_be_to_cpu32 (archs[i].offset);
	      macho->end64 = grub_be_to_cpu32 (archs[i].offset)
		+ grub_be_to_cpu32 (archs[i].size);
	    }
	}
      grub_free (archs);
    }

  /* Is it a thin 32-bit file? */
  if (filestart.thin32.magic == GRUB_MACHO_MAGIC32 && !is_64bit)
    {
      macho->offset32 = 0;
      macho->end32 = grub_file_size (file);
    }

  /* Is it a thin 64-bit file? */
  if (filestart.thin64.magic == GRUB_MACHO_MAGIC64 && is_64bit)
    {
      macho->offset64 = 0;
      macho->end64 = grub_file_size (file);
    }

  if (grub_memcmp (filestart.lzss.magic, GRUB_MACHO_LZSS_MAGIC,
		   sizeof (filestart.lzss.magic)) == 0 && !is_64bit)
    {
      macho->offset32 = 0;
      macho->end32 = grub_file_size (file);
    }

  /* Is it a thin 64-bit file? */
  if (grub_memcmp (filestart.lzss.magic, GRUB_MACHO_LZSS_MAGIC,
		   sizeof (filestart.lzss.magic)) == 0 && is_64bit)
    {
      macho->offset64 = 0;
      macho->end64 = grub_file_size (file);
    }

  grub_macho_parse32 (macho, filename);
  grub_macho_parse64 (macho, filename);

  if (macho->offset32 == -1 && !is_64bit)
    {
      grub_error (GRUB_ERR_BAD_OS,
		  "Mach-O doesn't contain suitable 32-bit architecture");
      goto fail;
    }

  if (macho->offset64 == -1 && is_64bit)
    {
      grub_error (GRUB_ERR_BAD_OS,
		  "Mach-O doesn't contain suitable 64-bit architecture");
      goto fail;
    }

  return macho;

fail:
  macho->file = 0;
  grub_macho_close (macho);
  return 0;
}