Beispiel #1
0
/* The command to add and remove loopback devices.  */
static grub_err_t
grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args)
{
  struct grub_arg_list *state = ctxt->state;
  grub_file_t file;
  struct grub_loopback *newdev;
  grub_err_t ret;

  if (argc < 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");

  /* Check if `-d' was used.  */
  if (state[0].set)
      return delete_loopback (args[0]);

  if (argc < 2)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  file = grub_file_open (args[1]);
  if (! file)
    return grub_errno;

  /* First try to replace the old device.  */
  for (newdev = loopback_list; newdev; newdev = newdev->next)
    if (grub_strcmp (newdev->devname, args[0]) == 0)
      break;

  if (newdev)
    {
      grub_file_close (newdev->file);
      newdev->file = file;

      return 0;
    }

  /* Unable to replace it, make a new entry.  */
  newdev = grub_malloc (sizeof (struct grub_loopback));
  if (! newdev)
    goto fail;

  newdev->devname = grub_strdup (args[0]);
  if (! newdev->devname)
    {
      grub_free (newdev);
      goto fail;
    }

  newdev->file = file;

  /* Add the new entry to the list.  */
  newdev->next = loopback_list;
  loopback_list = newdev;

  return 0;

fail:
  ret = grub_errno;
  grub_file_close (file);
  return ret;
}
Beispiel #2
0
static grub_err_t
grub_cmd_nthibr (grub_command_t cmd __attribute__ ((unused)),
                 int argc, char **args)
{
  grub_uint8_t hibr_file_magic[4];
  grub_file_t hibr_file = 0;

  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));

  hibr_file = grub_file_open (args[0]);
  if (!hibr_file)
    return grub_errno;

  /* Try to read magic number of 'hiberfil.sys' */
  if (grub_file_read (hibr_file, hibr_file_magic,
		      sizeof (hibr_file_magic))
      != (grub_ssize_t) sizeof (hibr_file_magic))
    {
      if (!grub_errno)
	grub_error (GRUB_ERR_TEST_FAILURE, "false");
      goto exit;
    }

  if (!(grub_memcmp ("hibr", hibr_file_magic, sizeof (hibr_file_magic)) == 0
	|| grub_memcmp ("HIBR", hibr_file_magic, sizeof (hibr_file_magic)) == 0))
    grub_error (GRUB_ERR_TEST_FAILURE, "false");

 exit:
  grub_file_close (hibr_file);

  return grub_errno;
}
Beispiel #3
0
/* Opens 'filename' with compression filters disabled. Optionally disables the
   PUBKEY filter (that insists upon properly signed files) as well.  PUBKEY
   filter is restored before the function returns. */
static grub_file_t
open_envblk_file (char *filename,
		  enum grub_file_type type)
{
  grub_file_t file;
  char *buf = 0;

  if (! filename)
    {
      const char *prefix;
      int len;

      prefix = grub_env_get ("prefix");
      if (! prefix)
        {
          grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
          return 0;
        }

      len = grub_strlen (prefix);
      buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG));
      if (! buf)
        return 0;
      filename = buf;

      grub_strcpy (filename, prefix);
      filename[len] = '/';
      grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
    }

  file = grub_file_open (filename, type);

  grub_free (buf);
  return file;
}
Beispiel #4
0
grub_uitree_t
grub_uitree_load_file (grub_uitree_t root, const char *name, int flags)
{
  grub_uitree_t result = 0;
  grub_file_t file;
  int size;
  const char *prefix;

  file = grub_file_open (name);
  if (! file)
    return 0;
  
  prefix = grub_strrchr (name, '/');
  if (! prefix)
    prefix = name;

  size = file->size;
  if (size)
    {
      char *buf;

      buf = grub_malloc (size);
      if (buf)
	{
	  grub_file_read (file, buf, size);
	  result = grub_uitree_load_buf (name, prefix - name, root,
					 buf, size, flags);
	}
      grub_free (buf);
    }

  grub_file_close (file);

  return result;
}
Beispiel #5
0
/* This is similar to grub_file_open. */
static grub_err_t
grub_mofile_open (struct grub_gettext_context *ctx,
		  const char *filename)
{
  struct header head;
  grub_err_t err;
  grub_file_t fd;

  /* Using fd_mo and not another variable because
     it's needed for grub_gettext_get_info.  */

  fd = grub_file_open (filename);

  if (!fd)
    return grub_errno;

  err = grub_gettext_pread (fd, &head, sizeof (head), 0);
  if (err)
    {
      grub_file_close (fd);
      return err;
    }

  if (head.magic != grub_cpu_to_le32_compile_time (MO_MAGIC_NUMBER))
    {
      grub_file_close (fd);
      return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			 "mo: invalid mo magic in file: %s", filename);
    }

  if (head.version != 0)
    {
      grub_file_close (fd);
      return grub_error (GRUB_ERR_BAD_FILE_TYPE,
			 "mo: invalid mo version in file: %s", filename);
    }

  ctx->grub_gettext_offset_original = grub_le_to_cpu32 (head.offset_original);
  ctx->grub_gettext_offset_translation = grub_le_to_cpu32 (head.offset_translation);
  ctx->grub_gettext_max = grub_le_to_cpu32 (head.number_of_strings);
  for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log;
       ctx->grub_gettext_max_log++);

  ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max
					    * sizeof (ctx->grub_gettext_msg_list[0]));
  if (!ctx->grub_gettext_msg_list)
    {
      grub_file_close (fd);
      return grub_errno;
    }
  ctx->fd_mo = fd;
  if (grub_gettext != grub_gettext_translate)
    {
      grub_gettext_original = grub_gettext;
      grub_gettext = grub_gettext_translate;
    }
  return 0;
}
Beispiel #6
0
Datei: compat.c Projekt: xk/bits
FILE *fopen(const char *path, const char *mode)
{
    grub_errno = GRUB_ERR_NONE;
    if (grub_strcmp(mode, "r") != 0 && grub_strcmp(mode, "rb") != 0) {
        grub_printf("Internal error: Python attempted to open a file with unsupported mode \"%s\"\n", mode);
        return NULL;
    }
    return grub_file_open(path);
}
Beispiel #7
0
static grub_err_t
grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args)
{
  struct grub_arg_list *state = ctxt->state;
  int dos = 0;
  grub_file_t file;
  char buf[GRUB_DISK_SECTOR_SIZE];
  grub_ssize_t size;
  int key = 0;

  if (state[0].set)
    dos = 1;

  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");

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

  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0
	 && key != GRUB_TERM_ESC)
    {
      int i;

      for (i = 0; i < size; i++)
	{
	  unsigned char c = buf[i];

	  if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
	    grub_printf ("%c", c);
	  else if (dos && c == '\r' && i + 1 < size && buf[i + 1] == '\n')
	    {
	      grub_printf ("\n");
	      i++;
	    }
	  else
	    {
	      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
	      grub_printf ("<%x>", (int) c);
	      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
	    }
	}

      while (grub_checkkey () >= 0 &&
	     (key = grub_getkey ()) != GRUB_TERM_ESC)
	;
    }

  grub_xputs ("\n");
  grub_refresh ();
  grub_file_close (file);

  return 0;
}
Beispiel #8
0
grub_autolist_t
grub_autolist_load (const char *name)
{
  grub_autolist_t result = 0;
  const char *prefix;

  prefix = grub_env_get ("prefix");
  if (prefix)
    {
      char *filename;

      filename = grub_xasprintf ("%s/%s", prefix, name);
      if (filename)
	{
	  grub_file_t file;

	  file = grub_file_open (filename);
	  if (file)
	    {
	      char *buf = NULL;
	      for (;; grub_free (buf))
		{
		  char *p;

		  buf = grub_getline (file);

		  if (! buf)
		    break;

		  if (! grub_isgraph (buf[0]))
		    continue;

		  p = grub_strchr (buf, ':');
		  if (! p)
		    continue;

		  *p = '\0';
		  while (*++p == ' ')
		    ;

		  insert_item (&result, buf, p);
		}
	      grub_file_close (file);
	    }
	  grub_free (filename);
	}
    }

  return result;
}
Beispiel #9
0
static grub_err_t
grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)),
		int argc, char *argv[])
{
  grub_err_t err;
  grub_file_t file;
  grub_elf_t elf;

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

  grub_loader_unset ();

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

  relocator = grub_relocator_new ();
  if (!relocator)
    {
      grub_file_close (file);
      return grub_errno;
    }

  elf = grub_elf_file (file, argv[0]);
  if (!elf)
    {
      grub_relocator_unload (relocator);
      relocator = 0;
      grub_file_close (file);
    }

  if (!grub_elf_is_elf32 (elf))
    {
      grub_relocator_unload (relocator);
      relocator = 0;
      grub_elf_close (elf);
    }

  entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF;
  
  err = grub_elf32_load (elf, argv[0], grub_chain_elf32_hook, 0, 0);

  grub_elf_close (elf);
  if (err)
    return err;

  grub_loader_set (grub_chain_boot, grub_chain_unload, 0);
  return GRUB_ERR_NONE;
}
Beispiel #10
0
grub_macho_t
grub_macho_open (const char *name, int is_64bit)
{
  grub_file_t file;
  grub_macho_t macho;

  file = grub_file_open (name);
  if (! file)
    return 0;

  macho = grub_macho_file (file, name, is_64bit);
  if (! macho)
    grub_file_close (file);

  return macho;
}
Beispiel #11
0
grub_elf_t
grub_elf_open (const char *name)
{
  grub_file_t file;
  grub_elf_t elf;

  file = grub_file_open (name);
  if (! file)
    return 0;

  elf = grub_elf_file (file, name);
  if (! elf)
    grub_file_close (file);

  return elf;
}
Beispiel #12
0
grub_file_t
grub_buffile_open (const char *name, int size)
{
  grub_file_t io, file;

  io = grub_file_open (name);
  if (! io)
    return 0;

  file = grub_bufio_open (io, size);
  if (! file)
    {
      grub_file_close (io);
      return 0;
    }

  return file;
}
Beispiel #13
0
Datei: compat.c Projekt: xk/bits
int stat(const char *path, struct stat *buf)
{
    FILE *file;
    grub_errno = GRUB_ERR_NONE;
    file = grub_file_open(path);
    if (file) {
        buf->st_size = grub_file_size(file);
        grub_file_close(file);
        buf->st_mode = S_IFREG | 0777;
    } else {
        if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && is_directory(path)) {
            grub_errno = GRUB_ERR_NONE;
            buf->st_size = 0;
            buf->st_mode = S_IFDIR | 0777;
        } else {
            return -1;
        }
    }
    buf->st_mtime = 0;
    return 0;
}
Beispiel #14
0
/* Opens 'filename' with compression filters disabled. Optionally disables the
   PUBKEY filter (that insists upon properly signed files) as well.  PUBKEY
   filter is restored before the function returns. */
static grub_file_t
open_envblk_file (char *filename, int untrusted)
{
  grub_file_t file;
  char *buf = 0;

  if (! filename)
    {
      const char *prefix;
      int len;

      prefix = grub_env_get ("prefix");
      if (! prefix)
        {
          grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
          return 0;
        }

      len = grub_strlen (prefix);
      buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG));
      if (! buf)
        return 0;
      filename = buf;

      grub_strcpy (filename, prefix);
      filename[len] = '/';
      grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
    }

  /* The filters that are disabled will be re-enabled by the call to
     grub_file_open() after this particular file is opened. */
  grub_file_filter_disable_compression ();
  if (untrusted)
    grub_file_filter_disable_pubkey ();

  file = grub_file_open (filename);

  grub_free (buf);
  return file;
}
Beispiel #15
0
LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
  LoadF lf;
  int status, readstatus;
  int c;
  int fnameindex = lua_gettop(L) + 1;  /* index of filename on the stack */
  lf.extraline = 0;
  if (filename == NULL) {
    lua_pushliteral(L, "=stdin");
    return errfile(L, "open", fnameindex);
  }
  else {
    lua_pushfstring(L, "@%s", filename);
    lf.f = grub_file_open(filename);
    if (lf.f == NULL) return errfile(L, "open", fnameindex);
  }

  c = grub_getc(lf.f);
  if (c == '#') {  /* Unix exec. file? */
    lf.extraline = 1;
    while ((c = grub_getc(lf.f)) != GRUB_EOF && c != '\n') ;  /* skip first line */
    if (c == '\n') c = grub_getc(lf.f);
  }
  if (c == LUA_SIGNATURE[0] && filename) {  /* binary file? */
    /* skip eventual `#!...' */
   while ((c = grub_getc(lf.f)) != GRUB_EOF && c != LUA_SIGNATURE[0]) ;
    lf.extraline = 0;
  }
  lf.ungetc = c;
  status = lua_load(L, getF, &lf, lua_tostring(L, -1));
  readstatus = grub_errno;
  grub_file_close(lf.f);  /* close file (even in case of errors) */
  if (readstatus) {
    lua_settop(L, fnameindex);  /* ignore results from `lua_load' */
    return errfile(L, "read", fnameindex);
  }
  lua_remove(L, fnameindex);
  return status;
}
Beispiel #16
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;
    }

  /* Begin TCG Extension */
  DEBUG_PRINT( ("measured multiboot module: %s \n", argv[0]) );
  grub_TPM_measure_buffer( module, size, TPM_LOADER_MEASUREMENT_PCR );
  /* End TCG Extension */

  grub_file_close (file);
  return GRUB_ERR_NONE;
}
Beispiel #17
0
static grub_err_t
grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)),
		    int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_err_t err;

  grub_loader_unset ();

  highest_load = 0;

#ifndef GRUB_USE_MULTIBOOT2
  grub_multiboot_quirks = GRUB_MULTIBOOT_QUIRKS_NONE;
  int option_found = 0;

  do
    {
      option_found = 0;
      if (argc != 0 && grub_strcmp (argv[0], "--quirk-bad-kludge") == 0)
	{
	  argc--;
	  argv++;
	  option_found = 1;
	  grub_multiboot_quirks |= GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE;
	}

      if (argc != 0 && grub_strcmp (argv[0], "--quirk-modules-after-kernel") == 0)
	{
	  argc--;
	  argv++;
	  option_found = 1;
	  grub_multiboot_quirks |= GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL;
	}
    } while (option_found);
#endif

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

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

  grub_dl_ref (my_mod);

  /* Skip filename.  */
  grub_multiboot_init_mbi (argc - 1, argv + 1);

  grub_relocator_unload (grub_multiboot_relocator);
  grub_multiboot_relocator = grub_relocator_new ();

  if (!grub_multiboot_relocator)
    goto fail;

  err = grub_multiboot_load (file, argv[0]);
  if (err)
    goto fail;

  grub_multiboot_set_bootdev ();

  grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0);

 fail:
  if (file)
    grub_file_close (file);

  if (grub_errno != GRUB_ERR_NONE)
    {
      grub_relocator_unload (grub_multiboot_relocator);
      grub_multiboot_relocator = NULL;
      grub_dl_unref (my_mod);
    } else {
    	/* Begin TCG Extension */
    	grub_TPM_measure_file( argv[0], TPM_LOADER_MEASUREMENT_PCR );
    	/* End TCG Extension */
    }

  return grub_errno;
}
Beispiel #18
0
static grub_err_t
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
                int argc, char *argv[])
{
    grub_file_t file = 0;
    struct linux_kernel_header lh;
    grub_ssize_t len, start, filelen;
    void *kernel = NULL;

    grub_dl_ref (my_mod);

    if (argc == 0)
    {
        grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
        goto fail;
    }

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

    filelen = grub_file_size (file);

    kernel = grub_malloc(filelen);

    if (!kernel)
    {
        grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
        goto fail;
    }

    if (grub_file_read (file, kernel, filelen) != filelen)
    {
        grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]);
        goto fail;
    }

    grub_tpm_measure (kernel, filelen, GRUB_KERNEL_PCR);

    if (! grub_linuxefi_secure_validate (kernel, filelen))
    {
        grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
        grub_free (kernel);
        goto fail;
    }

    params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384));

    if (! params)
    {
        grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
        goto fail;
    }

    grub_memset (params, 0, 16384);

    grub_memcpy (&lh, kernel, sizeof (lh));

    if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
    {
        grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
        goto fail;
    }

    if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
    {
        grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
        goto fail;
    }

    if (lh.version < grub_cpu_to_le16 (0x020b))
    {
        grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
        goto fail;
    }

    if (!lh.handover_offset)
    {
        grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
        goto fail;
    }

    linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
                    BYTES_TO_PAGES(lh.cmdline_size + 1));

    if (!linux_cmdline)
    {
        grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
        goto fail;
    }

    grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
    grub_create_loader_cmdline (argc, argv,
                                linux_cmdline + sizeof (LINUX_IMAGE) - 1,
                                lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1));

    grub_pass_verity_hash(&lh, linux_cmdline);
    lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline;

    handover_offset = lh.handover_offset;

    start = (lh.setup_sects + 1) * 512;
    len = grub_file_size(file) - start;

    kernel_mem = grub_efi_allocate_pages(lh.pref_address,
                                         BYTES_TO_PAGES(lh.init_size));

    if (!kernel_mem)
        kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
                     BYTES_TO_PAGES(lh.init_size));

    if (!kernel_mem)
    {
        grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
        goto fail;
    }

    grub_memcpy (kernel_mem, (char *)kernel + start, len);
    grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
    loaded=1;

    lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem;
    grub_memcpy (params, &lh, 2 * 512);

    params->type_of_loader = 0x21;

fail:

    if (file)
        grub_file_close (file);

    if (kernel)
        grub_free (kernel);

    if (grub_errno != GRUB_ERR_NONE)
    {
        grub_dl_unref (my_mod);
        loaded = 0;
    }

    if (linux_cmdline && !loaded)
        grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1));

    if (kernel_mem && !loaded)
        grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size));

    if (params && !loaded)
        grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384));

    return grub_errno;
}
Beispiel #19
0
static void
read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
{
  static char buf[BUF_SIZE];
  grub_file_t file;
  grub_off_t ofs, len;

  if ((pathname[0] == '-') && (pathname[1] == 0))
    {
      grub_device_t dev;

      dev = grub_device_open (0);
      if ((! dev) || (! dev->disk))
        grub_util_error (_("can\'t open device"));

      grub_util_info ("total sectors : %lld",
                      (unsigned long long) dev->disk->total_sectors);

      if (! leng)
        leng = (dev->disk->total_sectors << GRUB_DISK_SECTOR_BITS) - skip;

      while (leng)
        {
          grub_size_t len;

          len = (leng > BUF_SIZE) ? BUF_SIZE : leng;

          if (grub_disk_read (dev->disk, 0, skip, len, buf))
            grub_util_error (_("disk read fails at offset %lld, length %d"),
                             skip, len);

          if (hook (skip, buf, len))
            break;

          skip += len;
          leng -= len;
        }

      grub_device_close (dev);
      return;
    }

  grub_file_filter_disable_compression ();
  file = grub_file_open (pathname);
  if (!file)
    {
      grub_util_error (_("cannot open file %s:%s"), pathname,
		       grub_errmsg);
      return;
    }

  grub_util_info ("file size : %lld", (unsigned long long) file->size);

  if (skip > file->size)
    {
      grub_util_error (_("invalid skip value %lld"), (unsigned long long) skip);
      return;
    }

  ofs = skip;
  len = file->size - skip;
  if ((leng) && (leng < len))
    len = leng;

  file->offset = skip;

  while (len)
    {
      grub_ssize_t sz;

      sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len);
      if (sz < 0)
	{
	  grub_util_error (_("read error at offset %llu: %s"), ofs,
			   grub_errmsg);
	  break;
	}

      if ((sz == 0) || (hook (ofs, buf, sz)))
	break;

      ofs += sz;
      len -= sz;
    }

  grub_file_close (file);
}
Beispiel #20
0
/* Helper for grub_ls_list_files.  */
static int
print_files_long (const char *filename, const struct grub_dirhook_info *info,
		  void *data)
{
  struct grub_ls_list_files_ctx *ctx = data;

  if ((! ctx->all) && (filename[0] == '.'))
    return 0;

  if (! info->dir)
    {
      grub_file_t file;
      char *pathname;

      if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/')
	pathname = grub_xasprintf ("%s%s", ctx->dirname, filename);
      else
	pathname = grub_xasprintf ("%s/%s", ctx->dirname, filename);

      if (!pathname)
	return 1;

      /* XXX: For ext2fs symlinks are detected as files while they
	 should be reported as directories.  */
      grub_file_filter_disable_compression ();
      file = grub_file_open (pathname);
      if (! file)
	{
	  grub_errno = 0;
	  grub_free (pathname);
	  return 0;
	}

      if (! ctx->human)
	grub_printf ("%-12llu", (unsigned long long) file->size);
      else
	{
	  grub_uint64_t fsize = file->size * 100ULL;
	  grub_uint64_t fsz = file->size;
	  int units = 0;
	  char buf[20];

	  while (fsz / 1024)
	    {
	      fsize = (fsize + 512) / 1024;
	      fsz /= 1024;
	      units++;
	    }

	  if (units)
	    {
	      grub_uint64_t whole, fraction;

	      whole = grub_divmod64 (fsize, 100, &fraction);
	      grub_snprintf (buf, sizeof (buf),
			     "%" PRIuGRUB_UINT64_T
			     ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction,
			     grub_human_sizes[units]);
	      grub_printf ("%-12s", buf);
	    }
	  else
	    grub_printf ("%-12llu", (unsigned long long) file->size);

	}
      grub_file_close (file);
      grub_free (pathname);
    }
  else
    grub_printf ("%-12s", _("DIR"));

  if (info->mtimeset)
    {
      struct grub_datetime datetime;
      grub_unixtime2datetime (info->mtime, &datetime);
      if (ctx->human)
	grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ",
		     datetime.year, datetime.month, datetime.day,
		     datetime.hour, datetime.minute,
		     datetime.second,
		     grub_get_weekday_name (&datetime));
      else
	grub_printf (" %04d%02d%02d%02d%02d%02d ",
		     datetime.year, datetime.month,
		     datetime.day, datetime.hour,
		     datetime.minute, datetime.second);
    }
  grub_printf ("%s%s\n", filename, info->dir ? "/" : "");

  return 0;
}
Beispiel #21
0
static grub_err_t
grub_ls_list_files (char *dirname, int longlist, int all, int human)
{
  char *device_name;
  grub_fs_t fs;
  const char *path;
  grub_device_t dev;

  device_name = grub_file_get_device_name (dirname);
  dev = grub_device_open (device_name);
  if (! dev)
    goto fail;

  fs = grub_fs_probe (dev);
  path = grub_strchr (dirname, ')');
  if (! path)
    path = dirname;
  else
    path++;

  if (! path && ! device_name)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
      goto fail;
    }

  if (! *path)
    {
      if (grub_errno == GRUB_ERR_UNKNOWN_FS)
	grub_errno = GRUB_ERR_NONE;

      grub_normal_print_device_info (device_name);
    }
  else if (fs)
    {
      struct grub_ls_list_files_ctx ctx = {
	.dirname = dirname,
	.all = all,
	.human = human
      };

      if (longlist)
	(fs->dir) (dev, path, print_files_long, &ctx);
      else
	(fs->dir) (dev, path, print_files, &ctx);

      if (grub_errno == GRUB_ERR_BAD_FILE_TYPE
	  && path[grub_strlen (path) - 1] != '/')
	{
	  /* PATH might be a regular file.  */
	  char *p;
	  grub_file_t file;
	  struct grub_dirhook_info info;
	  grub_errno = 0;

	  grub_file_filter_disable_compression ();
	  file = grub_file_open (dirname);
	  if (! file)
	    goto fail;

	  grub_file_close (file);

	  p = grub_strrchr (dirname, '/') + 1;
	  dirname = grub_strndup (dirname, p - dirname);
	  if (! dirname)
	    goto fail;

	  all = 1;
	  grub_memset (&info, 0, sizeof (info));
	  if (longlist)
	    print_files_long (p, &info, &ctx);
	  else
	    print_files (p, &info, &ctx);

	  grub_free (dirname);
	}

      if (grub_errno == GRUB_ERR_NONE)
	grub_xputs ("\n");

      grub_refresh ();
    }

 fail:
  if (dev)
    grub_device_close (dev);

  grub_free (device_name);

  return 0;
}
Beispiel #22
0
static void
grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
{
  grub_file_t file = 0;
  grub_uint16_t signature;
  grub_device_t dev;
  int drive = -1;
  void *part_addr = 0;

  grub_dl_ref (my_mod);

  file = grub_file_open (filename);
  if (! file)
    goto fail;

  /* Read the first block.  */
  if (grub_file_read (file, (void *) 0x7C00, GRUB_DISK_SECTOR_SIZE)
      != GRUB_DISK_SECTOR_SIZE)
    {
      if (grub_errno == GRUB_ERR_NONE)
	grub_error (GRUB_ERR_BAD_OS, "too small");

      goto fail;
    }

  /* Check the signature.  */
  signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2));
  if (signature != grub_le_to_cpu16 (0xaa55)
      && ! (flags & GRUB_CHAINLOADER_FORCE))
    {
      grub_error (GRUB_ERR_BAD_OS, "invalid signature");
      goto fail;
    }

  grub_file_close (file);

  /* Obtain the partition table from the root device.  */
  drive = grub_get_root_biosnumber ();
  dev = grub_device_open (0);
  if (dev && dev->disk && dev->disk->partition)
    {
      grub_disk_t disk = dev->disk;

      if (disk)
	{
	  grub_partition_t p = disk->partition;

	  if (p && grub_strcmp (p->partmap->name, "msdos") == 0)
	    {
	      disk->partition = p->parent;
	      grub_disk_read (disk, p->offset, 446, 64,
			      (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
	      part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
				    + (p->index << 4));
	      disk->partition = p;
	    }
	}
    }

  if (dev)
    grub_device_close (dev);

  /* Ignore errors. Perhaps it's not fatal.  */
  grub_errno = GRUB_ERR_NONE;

  boot_drive = drive;
  boot_part_addr = part_addr;

  grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1);
  return;

 fail:

  if (file)
    grub_file_close (file);

  grub_dl_unref (my_mod);
}
Beispiel #23
0
/* Set properties on the view based on settings from the specified
   theme file.  */
grub_err_t
grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path)
{
  grub_file_t file;
  struct parsebuf p;

  p.view = view;
  p.theme_dir = grub_get_dirname (theme_path);

  file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME);
  if (! file)
    {
      grub_free (p.theme_dir);
      return grub_errno;
    }

  p.len = grub_file_size (file);
  p.buf = grub_malloc (p.len);
  p.pos = 0;
  p.line_num = 1;
  p.col_num = 1;
  p.filename = theme_path;
  if (! p.buf)
    {
      grub_file_close (file);
      grub_free (p.theme_dir);
      return grub_errno;
    }
  if (grub_file_read (file, p.buf, p.len) != p.len)
    {
      grub_free (p.buf);
      grub_file_close (file);
      grub_free (p.theme_dir);
      return grub_errno;
    }

  if (view->canvas)
    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);

  while (has_more (&p))
    {
      /* Skip comments (lines beginning with #).  */
      if (peek_char (&p) == '#')
        {
          advance_to_next_line (&p);
          continue;
        }

      /* Find the first non-whitespace character.  */
      skip_whitespace (&p);

      /* Handle the content.  */
      if (peek_char (&p) == '+')
        {
          /* Skip the '+'.  */
          read_char (&p);
          read_object (&p, view->canvas);
        }
      else
        {
          read_property (&p);
        }

      if (grub_errno != GRUB_ERR_NONE)
        goto fail;
    }

  /* Set the new theme path.  */
  grub_free (view->theme_path);
  view->theme_path = grub_strdup (theme_path);
  goto cleanup;

fail:
  if (view->canvas)
    {
      view->canvas->component.ops->destroy (view->canvas);
      view->canvas = 0;
    }

cleanup:
  grub_free (p.buf);
  grub_file_close (file);
  grub_free (p.theme_dir);
  return grub_errno;
}
Beispiel #24
0
/* Helper for FUNC_NAME.  */
static int
iterate_device (const char *name, void *data)
{
  struct search_ctx *ctx = data;
  int found = 0;

  /* Skip floppy drives when requested.  */
  if (ctx->no_floppy &&
      name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
    return 0;

#ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp
#else
#define compare_fn grub_strcmp
#endif

#ifdef DO_SEARCH_FILE
    {
      char *buf;
      grub_file_t file;

      buf = grub_xasprintf ("(%s)%s", name, ctx->key);
      if (! buf)
	return 1;

      grub_file_filter_disable_compression ();
      file = grub_file_open (buf);
      if (file)
	{
	  found = 1;
	  grub_file_close (file);
	}
      grub_free (buf);
    }
#elif defined(DO_SEARCH_PART_UUID)
    {
      grub_device_t dev;
      char *quid;

      dev = grub_device_open (name);
      if (dev)
	{
	  if (grub_gpt_part_uuid (dev, &quid) == GRUB_ERR_NONE)
	    {
	      if (grub_strcasecmp (quid, ctx->key) == 0)
		    found = 1;

	      grub_free (quid);
	    }

	  grub_device_close (dev);
	}
    }
#elif defined(DO_SEARCH_PART_LABEL)
    {
      grub_device_t dev;
      char *quid;

      dev = grub_device_open (name);
      if (dev)
	{
	  if (grub_gpt_part_label (dev, &quid) == GRUB_ERR_NONE)
	    {
	      if (grub_strcmp (quid, ctx->key) == 0)
		    found = 1;

	      grub_free (quid);
	    }

	  grub_device_close (dev);
	}
    }
#else
    {
      /* SEARCH_FS_UUID or SEARCH_LABEL */
      grub_device_t dev;
      grub_fs_t fs;
      char *quid;

      dev = grub_device_open (name);
      if (dev)
	{
	  fs = grub_fs_probe (dev);

#ifdef DO_SEARCH_FS_UUID
#define read_fn uuid
#else
#define read_fn label
#endif

	  if (fs && fs->read_fn)
	    {
	      fs->read_fn (dev, &quid);

	      if (grub_errno == GRUB_ERR_NONE && quid)
		{
		  if (compare_fn (quid, ctx->key) == 0)
		    found = 1;

		  grub_free (quid);
		}
	    }

	  grub_device_close (dev);
	}
    }
#endif

  if (!ctx->is_cache && found && ctx->count == 0)
    {
      struct cache_entry *cache_ent;
      cache_ent = grub_malloc (sizeof (*cache_ent));
      if (cache_ent)
	{
	  cache_ent->key = grub_strdup (ctx->key);
	  cache_ent->value = grub_strdup (name);
	  if (cache_ent->value && cache_ent->key)
	    {
	      cache_ent->next = cache;
	      cache = cache_ent;
	    }
	  else
	    {
	      grub_free (cache_ent->value);
	      grub_free (cache_ent->key);
	      grub_free (cache_ent);
	      grub_errno = GRUB_ERR_NONE;
	    }
	}
      else
	grub_errno = GRUB_ERR_NONE;
    }

  if (found)
    {
      ctx->count++;
      if (ctx->var)
	grub_env_set (ctx->var, name);
      else
	grub_printf (" %s", name);
    }

  grub_errno = GRUB_ERR_NONE;
  return (found && ctx->var);
}
Beispiel #25
0
static grub_err_t
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
                 int argc, char *argv[])
{
    grub_file_t *files = 0;
    int i, nfiles = 0;
    grub_size_t size = 0;
    grub_uint8_t *ptr;

    if (argc == 0)
    {
        grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
        goto fail;
    }

    if (!loaded)
    {
        grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
        goto fail;
    }

    files = grub_zalloc (argc * sizeof (files[0]));
    if (!files)
        goto fail;

    for (i = 0; i < argc; i++)
    {
        grub_file_filter_disable_compression ();
        files[i] = grub_file_open (argv[i]);
        if (! files[i])
            goto fail;
        nfiles++;
        size += ALIGN_UP (grub_file_size (files[i]), 4);
    }

    initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));

    if (!initrd_mem)
    {
        grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
        goto fail;
    }

    params->ramdisk_size = size;
    params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem;

    ptr = initrd_mem;

    for (i = 0; i < nfiles; i++)
    {
        grub_ssize_t cursize = grub_file_size (files[i]);
        if (grub_file_read (files[i], ptr, cursize) != cursize)
        {
            if (!grub_errno)
                grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
                            argv[i]);
            goto fail;
        }
        grub_tpm_measure (ptr, cursize, GRUB_INITRD_PCR);
        ptr += cursize;
        grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
        ptr += ALIGN_UP_OVERHEAD (cursize, 4);
    }

    params->ramdisk_size = size;

fail:
    for (i = 0; i < nfiles; i++)
        grub_file_close (files[i]);
    grub_free (files);

    if (initrd_mem && grub_errno)
        grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size));

    return grub_errno;
}
Beispiel #26
0
static grub_err_t
grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args)
{
  grub_file_t file = 0;
  grub_elf_t elf = 0;
  grub_err_t err;
  int type = -1, i;
  int ret = 0;
  grub_macho_t macho = 0;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
  for (i = OPT_TYPE_MIN; i <= OPT_TYPE_MAX; i++)
    if (ctxt->state[i].set)
      {
	if (type == -1)
	  {
	    type = i;
	    continue;
	  }
	return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple types specified");
      }
  if (type == -1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no type specified");

  file = grub_file_open (args[0]);
  if (!file)
    return grub_errno;
  switch (type)
    {
    case IS_BIOS_BOOTSECTOR:
      {
	grub_uint16_t sig;
	if (grub_file_size (file) != 512)
	  break;
	if (grub_file_seek (file, 510) == (grub_size_t) -1)
	  break;
	if (grub_file_read (file, &sig, 2) != 2)
	  break;
	if (sig != grub_cpu_to_le16_compile_time (0xaa55))
	  break;
	ret = 1;
	break;
      }
    case IS_IA64_LINUX:
      {
	Elf64_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_ident[EI_CLASS] != ELFCLASS64
	    || ehdr.e_ident[EI_DATA] != ELFDATA2LSB
	    || ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_IA_64))
	  break;

	ret = 1;

	break;
      }

    case IS_SPARC64_LINUX:
      {
	Elf64_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_ident[EI_CLASS] != ELFCLASS64
	    || ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
	  break;

	if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_SPARCV9)
	    || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC))
	  break;

	ret = 1;

	break;
      }

    case IS_POWERPC_LINUX:
      {
	Elf32_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB
	    || (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_PPC)
		&& ehdr.e_machine !=
		grub_cpu_to_le16_compile_time (EM_PPC64)))
	  break;

	if (ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC)
	    && ehdr.e_type != grub_cpu_to_be16_compile_time (ET_DYN))
	  break;

	ret = 1;

	break;
      }

    case IS_MIPS_LINUX:
      {
	Elf32_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB
	    || ehdr.e_machine != grub_cpu_to_be16_compile_time (EM_MIPS)
	    || ehdr.e_type != grub_cpu_to_be16_compile_time (ET_EXEC))
	  break;

	ret = 1;

	break;
      }

    case IS_X86_KNETBSD:
    case IS_X86_KNETBSD32:
    case IS_X86_KNETBSD64:
      {
	int is32, is64;

	elf = grub_elf_file (file, file->name);

	if (elf->ehdr.ehdr32.e_type != grub_cpu_to_le16_compile_time (ET_EXEC)
	    || elf->ehdr.ehdr32.e_ident[EI_DATA] != ELFDATA2LSB)
	  break;

	is32 = grub_elf_is_elf32 (elf);
	is64 = grub_elf_is_elf64 (elf);
	if (!is32 && !is64)
	  break;
	if (!is32 && type == IS_X86_KNETBSD32)
	  break;
	if (!is64 && type == IS_X86_KNETBSD64)
	  break;
	if (is64)
	  ret = grub_file_check_netbsd64 (elf);
	if (is32)
	  ret = grub_file_check_netbsd32 (elf);
	break;
      }

    case IS_X86_KFREEBSD:
    case IS_X86_KFREEBSD32:
    case IS_X86_KFREEBSD64:
      {
	Elf32_Ehdr ehdr;
	int is32, is64;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC)
	    || ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
	  break;

	if (ehdr.e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
	  break;

	is32 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_386)
		&& ehdr.e_ident[EI_CLASS] == ELFCLASS32);
	is64 = (ehdr.e_machine == grub_cpu_to_le16_compile_time (EM_X86_64)
		&& ehdr.e_ident[EI_CLASS] == ELFCLASS64);
	if (!is32 && !is64)
	  break;
	if (!is32 && (type == IS_X86_KFREEBSD32 || type == IS_X86_KNETBSD32))
	  break;
	if (!is64 && (type == IS_X86_KFREEBSD64 || type == IS_X86_KNETBSD64))
	  break;
	ret = 1;

	break;
      }


    case IS_MIPSEL_LINUX:
      {
	Elf32_Ehdr ehdr;

	if (grub_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
	  break;

	if (ehdr.e_ident[EI_MAG0] != ELFMAG0
	    || ehdr.e_ident[EI_MAG1] != ELFMAG1
	    || ehdr.e_ident[EI_MAG2] != ELFMAG2
	    || ehdr.e_ident[EI_MAG3] != ELFMAG3
	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT
	    || ehdr.e_version != EV_CURRENT)
	  break;

	if (ehdr.e_machine != grub_cpu_to_le16_compile_time (EM_MIPS)
	    || ehdr.e_type != grub_cpu_to_le16_compile_time (ET_EXEC))
	  break;

	ret = 1;

	break;
      }
    case IS_ARM_LINUX:
      {
	grub_uint32_t sig, sig_pi;
	if (grub_file_read (file, &sig_pi, 4) != 4)
	  break;
	/* Raspberry pi.  */
	if (sig_pi == grub_cpu_to_le32_compile_time (0xea000006))
	  {
	    ret = 1;
	    break;
	  }

	if (grub_file_seek (file, 0x24) == (grub_size_t) -1)
	  break;
	if (grub_file_read (file, &sig, 4) != 4)
	  break;
	if (sig == grub_cpu_to_le32_compile_time (0x016f2818))
	  {
	    ret = 1;
	    break;
	  }
	break;
      }
    case IS_ARM64_LINUX:
      {
	grub_uint32_t sig;

	if (grub_file_seek (file, 0x38) == (grub_size_t) -1)
	  break;
	if (grub_file_read (file, &sig, 4) != 4)
	  break;
	if (sig == grub_cpu_to_le32_compile_time (0x644d5241))
	  {
	    ret = 1;
	    break;
	  }
	break;
      }
    case IS_PAE_DOMU ... IS_DOM0:
      {
	struct grub_xen_file_info xen_inf;
	elf = grub_xen_file (file);
	if (!elf)
	  break;
	err = grub_xen_get_info (elf, &xen_inf);
	if (err)
	  break;
	/* Unfortuntely no way to check if kernel supports dom0.  */
	if (type == IS_DOM0)
	  ret = 1;
	if (type == IS_PAE_DOMU)
	  ret = (xen_inf.arch == GRUB_XEN_FILE_I386_PAE
		 || xen_inf.arch == GRUB_XEN_FILE_I386_PAE_BIMODE);
	if (type == IS_64_DOMU)
	  ret = (xen_inf.arch == GRUB_XEN_FILE_X86_64);
	break;
      }
    case IS_MULTIBOOT:
    case IS_MULTIBOOT2:
      {
	grub_uint32_t *buffer;
	grub_ssize_t len;
	grub_size_t search_size;
	grub_uint32_t *header;
	grub_uint32_t magic;
	grub_size_t step;

	if (type == IS_MULTIBOOT2)
	  {
	    search_size = 32768;
	    magic = grub_cpu_to_le32_compile_time (0xe85250d6);
	    step = 2;
	  }
	else
	  {
	    search_size = 8192;
	    magic = grub_cpu_to_le32_compile_time (0x1BADB002);
	    step = 1;
	  }

	buffer = grub_malloc (search_size);
	if (!buffer)
	  break;

	len = grub_file_read (file, buffer, search_size);
	if (len < 32)
	  {
	    grub_free (buffer);
	    break;
	  }

	/* Look for the multiboot header in the buffer.  The header should
	   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)
	  {
	    if (header[0] == magic
		&& !(grub_le_to_cpu32 (header[0])
		     + grub_le_to_cpu32 (header[1])
		     + grub_le_to_cpu32 (header[2])
		     + (type == IS_MULTIBOOT2
			? grub_le_to_cpu32 (header[3]) : 0)))
	      break;
	  }

	if (header != 0)
	  ret = 1;
	grub_free (buffer);
	break;
      }
    case IS_X86_LINUX32:
    case IS_X86_LINUX:
      {
	struct linux_kernel_header lh;
	if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
	  break;
	if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
	  break;

	if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
	  break;

	/* FIXME: some really old kernels (< 1.3.73) will fail this.  */
	if (lh.header !=
	    grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE)
	    || grub_le_to_cpu16 (lh.version) < 0x0200)
	  break;

	if (type == IS_X86_LINUX)
	  {
	    ret = 1;
	    break;
	  }

	/* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and
	   still not support 32-bit boot.  */
	if (lh.header !=
	    grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE)
	    || grub_le_to_cpu16 (lh.version) < 0x0203)
	  break;

	if (!(lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
	  break;
	ret = 1;
	break;
      }
    case IS_HIBERNATED:
      {
	grub_uint8_t hibr_file_magic[4];
	if (grub_file_read (file, &hibr_file_magic, sizeof (hibr_file_magic))
	    != sizeof (hibr_file_magic))
	  break;
	if (grub_memcmp ("hibr", hibr_file_magic, sizeof (hibr_file_magic)) ==
	    0
	    || grub_memcmp ("HIBR", hibr_file_magic,
			    sizeof (hibr_file_magic)) == 0)
	  ret = 1;
	break;
      }
    case IS_XNU64:
    case IS_XNU32:
      {
	macho = grub_macho_open (args[0], (type == IS_XNU64));
	if (!macho)
	  break;
	/* FIXME: more checks?  */
	ret = 1;
	break;
      }
    case IS_XNU_HIBR:
      {
	struct grub_xnu_hibernate_header hibhead;
	if (grub_file_read (file, &hibhead, sizeof (hibhead))
	    != sizeof (hibhead))
	  break;
	if (hibhead.magic !=
	    grub_cpu_to_le32_compile_time (GRUB_XNU_HIBERNATE_MAGIC))
	  break;
	ret = 1;
	break;
      }
    case IS_32_EFI:
    case IS_64_EFI:
    case IS_IA_EFI:
    case IS_ARM64_EFI:
    case IS_ARM_EFI:
      {
	char signature[4];
	grub_uint32_t pe_offset;
	struct grub_pe32_coff_header coff_head;

	if (grub_file_read (file, signature, 2) != 2)
	  break;
	if (signature[0] != 'M' || signature[1] != 'Z')
	  break;
	if ((grub_ssize_t) grub_file_seek (file, 0x3c) == -1)
	  break;
	if (grub_file_read (file, &pe_offset, 4) != 4)
	  break;
	if ((grub_ssize_t) grub_file_seek (file, grub_le_to_cpu32 (pe_offset))
	    == -1)
	  break;
	if (grub_file_read (file, signature, 4) != 4)
	  break;
	if (signature[0] != 'P' || signature[1] != 'E'
	    || signature[2] != '\0' || signature[3] != '\0')
	  break;

	if (grub_file_read (file, &coff_head, sizeof (coff_head))
	    != sizeof (coff_head))
	  break;
	if (type == IS_32_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_I386))
	  break;
	if (type == IS_64_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_X86_64))
	  break;
	if (type == IS_IA_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_IA64))
	  break;
	if (type == IS_ARM64_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARM64))
	  break;
	if (type == IS_ARM_EFI
	    && coff_head.machine !=
	    grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARMTHUMB_MIXED))
	  break;
	if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI)
	  {
	    struct grub_pe64_optional_header o64;
	    if (grub_file_read (file, &o64, sizeof (o64)) != sizeof (o64))
	      break;
	    if (o64.magic !=
		grub_cpu_to_le16_compile_time (GRUB_PE32_PE64_MAGIC))
	      break;
	    if (o64.subsystem !=
		grub_cpu_to_le16_compile_time
		(GRUB_PE32_SUBSYSTEM_EFI_APPLICATION))
	      break;
	    ret = 1;
	    break;
	  }
	if (type == IS_32_EFI || type == IS_ARM_EFI)
	  {
	    struct grub_pe32_optional_header o32;
	    if (grub_file_read (file, &o32, sizeof (o32)) != sizeof (o32))
	      break;
	    if (o32.magic !=
		grub_cpu_to_le16_compile_time (GRUB_PE32_PE32_MAGIC))
	      break;
	    if (o32.subsystem !=
		grub_cpu_to_le16_compile_time
		(GRUB_PE32_SUBSYSTEM_EFI_APPLICATION))
	      break;
	    ret = 1;
	    break;
	  }
	break;
      }
    }

  if (elf)
    grub_elf_close (elf);
  else if (macho)
    grub_macho_close (macho);
  else if (file)
    grub_file_close (file);

  if (!ret && (grub_errno == GRUB_ERR_BAD_OS || grub_errno == GRUB_ERR_NONE))
    /* TRANSLATORS: it's a standalone boolean value,
       opposite of "true".  */
    grub_error (GRUB_ERR_TEST_FAILURE, N_("false"));
  return grub_errno;
}
Beispiel #27
0
/* Read the file fs.lst for auto-loading.  */
void
read_fs_list (const char *prefix)
{
  if (prefix)
    {
      char *filename;

      filename = grub_xasprintf ("%s/fs.lst", prefix);
      if (filename)
	{
	  grub_file_t file;
	  grub_fs_autoload_hook_t tmp_autoload_hook;

	  /* This rules out the possibility that read_fs_list() is invoked
	     recursively when we call grub_file_open() below.  */
	  tmp_autoload_hook = grub_fs_autoload_hook;
	  grub_fs_autoload_hook = NULL;

	  file = grub_file_open (filename);
	  if (file)
	    {
	      /* Override previous fs.lst.  */
	      while (fs_module_list)
		{
		  grub_named_list_t tmp;
		  tmp = fs_module_list->next;
		  grub_free (fs_module_list);
		  fs_module_list = tmp;
		}

	      while (1)
		{
		  char *buf;
		  char *p;
		  char *q;
		  grub_named_list_t fs_mod;

		  buf = grub_getline (file);
		  if (! buf)
		    break;

		  p = buf;
		  q = buf + grub_strlen (buf) - 1;

		  /* Ignore space.  */
		  while (grub_isspace (*p))
		    p++;

		  while (p < q && grub_isspace (*q))
		    *q-- = '\0';

		  /* If the line is empty, skip it.  */
		  if (p >= q)
		    continue;

		  fs_mod = grub_malloc (sizeof (*fs_mod));
		  if (! fs_mod)
		    continue;

		  fs_mod->name = grub_strdup (p);
		  if (! fs_mod->name)
		    {
		      grub_free (fs_mod);
		      continue;
		    }

		  fs_mod->next = fs_module_list;
		  fs_module_list = fs_mod;
		}

	      grub_file_close (file);
	      grub_fs_autoload_hook = tmp_autoload_hook;
	    }

	  grub_free (filename);
	}
    }

  /* Ignore errors.  */
  grub_errno = GRUB_ERR_NONE;

  /* Set the hook.  */
  grub_fs_autoload_hook = autoload_fs_module;
}
Beispiel #28
0
static grub_err_t
grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
		     int argc, char **args_in)
{
  char *uuid_root = 0, *uuid_prefix, *prefdev = 0;
  const char *prefix = 0;
  const char *path_prefix = 0;
  int mods_loaded = 0;
  grub_dl_t *mods;
  const char **args;
  int i;

  if (argc == 0)
    {
      argc = ARRAY_SIZE (modnames_def);
      args = modnames_def;
    }
  else
    args = (const char **) args_in;

  prefix = grub_env_get ("prefix");

  if (! prefix)
    return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");

  if (prefix)
    path_prefix = (prefix[0] == '(') ? grub_strchr (prefix, ')') : NULL;
  if (path_prefix)
    path_prefix++;
  else
    path_prefix = prefix;

  mods = grub_malloc (argc * sizeof (mods[0]));
  if (!mods)
    return grub_errno;

  if (get_uuid (NULL, &uuid_root, 0))
    return grub_errno;

  prefdev = grub_file_get_device_name (prefix);
  if (grub_errno)
    {
      grub_print_error ();
      prefdev = 0;
    }

  if (get_uuid (prefdev, &uuid_prefix, 0))
    {
      grub_free (uuid_root);
      return grub_errno;
    }

  grub_dprintf ("nativedisk", "uuid_prefix = %s, uuid_root = %s\n",
		uuid_prefix, uuid_root);

  for (mods_loaded = 0; mods_loaded < argc; mods_loaded++)
    {
      char *filename;
      grub_dl_t mod;
      grub_file_t file = NULL;
      grub_ssize_t size;
      void *core = 0;

      mod = grub_dl_get (args[mods_loaded]);
      if (mod)
	{
	  mods[mods_loaded] = 0;
	  continue;
	}

      filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod",
				 prefix, args[mods_loaded]);
      if (! filename)
	goto fail;

      file = grub_file_open (filename);
      grub_free (filename);
      if (! file)
	goto fail;

      size = grub_file_size (file);
      core = grub_malloc (size);
      if (! core)
	{
	  grub_file_close (file);
	  goto fail;
	}

      if (grub_file_read (file, core, size) != (grub_ssize_t) size)
	{
	  grub_file_close (file);
	  grub_free (core);
	  goto fail;
	}

      grub_file_close (file);

      mods[mods_loaded] = grub_dl_load_core_noinit (core, size);
      if (! mods[mods_loaded])
	goto fail;
    }

  for (i = 0; i < argc; i++)
    if (mods[i])
      grub_dl_init (mods[i]);

  if (uuid_prefix || uuid_root)
    {
      struct search_ctx ctx;
      grub_fs_autoload_hook_t saved_autoload;

      /* No need to autoload FS since obviously we already have the necessary fs modules.  */
      saved_autoload = grub_fs_autoload_hook;
      grub_fs_autoload_hook = 0;

      ctx.root_uuid = uuid_root;
      ctx.prefix_uuid = uuid_prefix;
      ctx.prefix_path = path_prefix;
      ctx.prefix_found = !uuid_prefix;
      ctx.root_found = !uuid_root;

      /* FIXME: try to guess the correct values.  */
      grub_device_iterate (iterate_device, &ctx);

      grub_fs_autoload_hook = saved_autoload;
    }
  grub_free (uuid_root);
  grub_free (uuid_prefix);

  return GRUB_ERR_NONE;

 fail:
  grub_free (uuid_root);
  grub_free (uuid_prefix);

  for (i = 0; i < mods_loaded; i++)
    if (mods[i])
      {
	mods[i]->fini = 0;
	grub_dl_unload (mods[i]);
      }
  return grub_errno;
}
Beispiel #29
0
static grub_menu_t
read_config_file (const char *config)
{
  grub_file_t file;

  auto grub_err_t getline (char **line, int cont);
  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
    {
      while (1)
	{
	  char *buf;

	  *line = buf = grub_file_getline (file);
	  if (! buf)
	    return grub_errno;

	  if (buf[0] == '#')
	    grub_free (*line);
	  else
	    break;
	}

      return GRUB_ERR_NONE;
    }

  grub_menu_t newmenu;

  newmenu = grub_env_get_menu ();
  if (! newmenu)
    {
      newmenu = grub_zalloc (sizeof (*newmenu));
      if (! newmenu)
	return 0;

      grub_env_set_menu (newmenu);
    }

  /* Try to open the config file.  */
  file = grub_file_open (config);
  if (! file)
    return 0;

  while (1)
    {
      char *line;

      /* Print an error, if any.  */
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;

      if ((getline (&line, 0)) || (! line))
	break;

      grub_normal_parse_line (line, getline);
      grub_free (line);
    }

  grub_file_close (file);

  return newmenu;
}
Beispiel #30
0
/* Read the file crypto.lst for auto-loading.  */
void
read_crypto_list (const char *prefix)
{
  char *filename;
  grub_file_t file;
  char *buf = NULL;

  if (!prefix)
    {
      grub_errno = GRUB_ERR_NONE;
      return;
    }
  
  filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM
			     "/crypto.lst", prefix);
  if (!filename)
    {
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  file = grub_file_open (filename);
  grub_free (filename);
  if (!file)
    {
      grub_errno = GRUB_ERR_NONE;
      return;
    }

  /* Override previous crypto.lst.  */
  grub_crypto_spec_free ();

  for (;; grub_free (buf))
    {
      char *p, *name;
      struct load_spec *cur;
      
      buf = grub_file_getline (file);
	
      if (! buf)
	break;
      
      name = buf;
      while (grub_isspace (name[0]))
	name++;

      p = grub_strchr (name, ':');
      if (! p)
	continue;
      
      *p = '\0';
      p++;
      while (*p == ' ' || *p == '\t')
	p++;

      cur = grub_malloc (sizeof (*cur));
      if (!cur)
	{
	  grub_errno = GRUB_ERR_NONE;
	  continue;
	}
      
      cur->name = grub_strdup (name);
      if (! name)
	{
	  grub_errno = GRUB_ERR_NONE;
	  grub_free (cur);
	  continue;
	}
	
      cur->modname = grub_strdup (p);
      if (! cur->modname)
	{
	  grub_errno = GRUB_ERR_NONE;
	  grub_free (cur);
	  grub_free (cur->name);
	  continue;
	}
      cur->next = crypto_specs;
      crypto_specs = cur;
    }
  
  grub_file_close (file);

  grub_errno = GRUB_ERR_NONE;

  grub_crypto_autoload_hook = grub_crypto_autoload;
}