Example #1
0
static grub_err_t
grub_ext2_uuid (grub_device_t device, char **uuid)
{
  struct grub_ext2_data *data;
  grub_disk_t disk = device->disk;

  grub_dl_ref (my_mod);

  data = grub_ext2_mount (disk);
  if (data)
    {
      *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
			     grub_be_to_cpu16 (data->sblock.uuid[0]),
			     grub_be_to_cpu16 (data->sblock.uuid[1]),
			     grub_be_to_cpu16 (data->sblock.uuid[2]),
			     grub_be_to_cpu16 (data->sblock.uuid[3]),
			     grub_be_to_cpu16 (data->sblock.uuid[4]),
			     grub_be_to_cpu16 (data->sblock.uuid[5]),
			     grub_be_to_cpu16 (data->sblock.uuid[6]),
			     grub_be_to_cpu16 (data->sblock.uuid[7]));
    }
  else
    *uuid = NULL;

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}
Example #2
0
static grub_err_t
grub_dyncmd_dispatcher (struct grub_command *cmd,
			int argc, char **args)
{
  char *modname = cmd->data;
  grub_dl_t mod;
  grub_err_t ret;

  mod = grub_dl_load (modname);
  if (mod)
    {
      char *name;

      grub_free (modname);
      grub_dl_ref (mod);

      name = (char *) cmd->name;
      grub_unregister_command (cmd);

      cmd = grub_command_find (name);
      if (cmd)
	ret = (cmd->func) (cmd, argc, args);
      else
	ret = grub_errno;

      grub_free (name);
    }
  else
    ret = grub_errno;

  return ret;
}
Example #3
0
static grub_err_t
grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
		   int argc, char **args)
{
  grub_err_t err;
  char *pass;
  int copylen;

  if (argc != 2)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected");

  pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN);
  if (!pass)
    return grub_errno;
  copylen = grub_strlen (args[1]);
  if (copylen >= GRUB_AUTH_MAX_PASSLEN)
    copylen = GRUB_AUTH_MAX_PASSLEN - 1;
  grub_memcpy (pass, args[1], copylen);

  err = grub_auth_register_authentication (args[0], check_password, pass);
  if (err)
    {
      grub_free (pass);
      return err;
    }
  grub_dl_ref (my_mod);
  return GRUB_ERR_NONE;
}
Example #4
0
File: ext2.c Project: TemmeR/grub2
static grub_err_t
grub_ext2_dir (grub_device_t device, const char *path,
	       int (*hook) (const char *filename,
			    const struct grub_dirhook_info *info))
{
  struct grub_ext2_data *data = 0;
  struct grub_fshelp_node *fdiro = 0;

  auto int NESTED_FUNC_ATTR iterate (const char *filename,
				     enum grub_fshelp_filetype filetype,
				     grub_fshelp_node_t node);

  int NESTED_FUNC_ATTR iterate (const char *filename,
				enum grub_fshelp_filetype filetype,
				grub_fshelp_node_t node)
    {
      struct grub_dirhook_info info;
      grub_memset (&info, 0, sizeof (info));
      if (! node->inode_read)
	{
	  grub_ext2_read_inode (data, node->ino, &node->inode);
	  if (!grub_errno)
	    node->inode_read = 1;
	  grub_errno = GRUB_ERR_NONE;
	}
      if (node->inode_read)
	{
	  info.mtimeset = 1;
	  info.mtime = grub_le_to_cpu32 (node->inode.mtime);
	}

      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
      grub_free (node);
      return hook (filename, &info);
    }

  grub_dl_ref (my_mod);

  data = grub_ext2_mount (device->disk);
  if (! data)
    goto fail;

  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_ext2_iterate_dir,
			 grub_ext2_read_symlink, GRUB_FSHELP_DIR);
  if (grub_errno)
    goto fail;

  grub_ext2_iterate_dir (fdiro, iterate);

 fail:
  if (fdiro != &data->diropen)
    grub_free (fdiro);
  grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Example #5
0
grub_command_t
grub_command_find (char *cmdline)
{
  char *first_space;
  grub_command_t cmd;
  int count = 0;
  
  first_space = grub_strchr (cmdline, ' ');
  if (first_space)
    *first_space = '\0';

 again:
  
  for (cmd = grub_command_list; cmd; cmd = cmd->next)
    if (grub_strcmp (cmdline, cmd->name) == 0)
      break;

  if (! cmd)
    grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", cmdline);
  else if (cmd->flags & GRUB_COMMAND_FLAG_NOT_LOADED)
    {
      /* Automatically load the command.  */
      if (count == 0)
	{
	  grub_dl_t mod;
	  char *module_name;

	  module_name = grub_strdup (cmd->module_name);
	  if (module_name)
	    {
	      mod = grub_dl_load (module_name);
	      if (mod)
		{
		  grub_dl_ref (mod);
		  count++;
		  grub_free (module_name);
  		  goto again;
		}

	      grub_free (module_name);
	    }
	}

      /* This module seems broken.  */
      grub_unregister_command (cmdline);
      grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", cmdline);
      cmd = 0;
    }
  
  if (first_space)
    *first_space = ' ';

  return cmd;
}
Example #6
0
static void
grub_crypto_autoload (const char *name)
{
    struct load_spec *cur;
    grub_dl_t mod;

    for (cur = crypto_specs; cur; cur = cur->next)
        if (grub_strcasecmp (name, cur->name) == 0)
        {
            mod = grub_dl_load (cur->modname);
            if (mod)
                grub_dl_ref (mod);
            grub_errno = GRUB_ERR_NONE;
        }
}
Example #7
0
File: ext2.c Project: TemmeR/grub2
/* Open a file named NAME and initialize FILE.  */
static grub_err_t
grub_ext2_open (struct grub_file *file, const char *name)
{
  struct grub_ext2_data *data;
  struct grub_fshelp_node *fdiro = 0;
  grub_err_t err;

  grub_dl_ref (my_mod);

  data = grub_ext2_mount (file->device->disk);
  if (! data)
    {
      err = grub_errno;
      goto fail;
    }

  err = grub_fshelp_find_file (name, &data->diropen, &fdiro,
			       grub_ext2_iterate_dir,
			       grub_ext2_read_symlink, GRUB_FSHELP_REG);
  if (err)
    goto fail;

  if (! fdiro->inode_read)
    {
      err = grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
      if (err)
	goto fail;
    }

  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode));
  grub_free (fdiro);

  file->size = grub_le_to_cpu32 (data->inode->size);
  file->data = data;
  file->offset = 0;

  return 0;

 fail:
  if (fdiro != &data->diropen)
    grub_free (fdiro);
  grub_free (data);

  grub_dl_unref (my_mod);

  return err;
}
Example #8
0
File: ext2.c Project: TemmeR/grub2
static grub_err_t
grub_ext2_label (grub_device_t device, char **label)
{
  struct grub_ext2_data *data;
  grub_disk_t disk = device->disk;

  grub_dl_ref (my_mod);

  data = grub_ext2_mount (disk);
  if (data)
    *label = grub_strndup (data->sblock.volume_name, 14);
  else
    *label = NULL;

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;
}
Example #9
0
File: ext2.c Project: TemmeR/grub2
/* Get mtime.  */
static grub_err_t
grub_ext2_mtime (grub_device_t device, grub_int32_t *tm)
{
  struct grub_ext2_data *data;
  grub_disk_t disk = device->disk;

  grub_dl_ref (my_mod);

  data = grub_ext2_mount (disk);
  if (!data)
    *tm = 0;
  else
    *tm = grub_le_to_cpu32 (data->sblock.utime);

  grub_dl_unref (my_mod);

  grub_free (data);

  return grub_errno;

}
Example #10
0
static void 
grub_crypto_autoload (const char *name)
{
  struct load_spec *cur;
  grub_dl_t mod;
  static int depth = 0;

  /* Some bufio of filesystems may want some crypto modules.
     It may result in infinite recursion. Hence this check.  */
  if (depth)
    return;
  depth++;

  for (cur = crypto_specs; cur; cur = cur->next)
    if (grub_strcasecmp (name, cur->name) == 0)
      {
	mod = grub_dl_load (cur->modname);
	if (mod)
	  grub_dl_ref (mod);
	grub_errno = GRUB_ERR_NONE;
      }
  depth--;
}
Example #11
0
static grub_err_t
grub_ext2_dir (grub_device_t device, const char *path,
	       int (*hook) (const char *filename,
			    const struct grub_dirhook_info *info,
			    void *closure),
	       void *closure)
{
  struct grub_ext2_data *data = 0;
  struct grub_fshelp_node *fdiro = 0;
  struct grub_ext2_dir_closure c;

  grub_dl_ref (my_mod);

  data = grub_ext2_mount (device->disk);
  if (! data)
    goto fail;

  grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_ext2_iterate_dir,
			 0, grub_ext2_read_symlink, GRUB_FSHELP_DIR);
  if (grub_errno)
    goto fail;

  c.hook = hook;
  c.closure = closure;
  c.data = data;
  grub_ext2_iterate_dir (fdiro, iterate, &c);

 fail:
  if (fdiro != &data->diropen)
    grub_free (fdiro);
  grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Example #12
0
grub_err_t
grub_normal_set_password (const char *user, const char *password)
{
  grub_err_t err;
  char *pass;
  int copylen;

  pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN);
  if (!pass)
    return grub_errno;
  copylen = grub_strlen (password);
  if (copylen >= GRUB_AUTH_MAX_PASSLEN)
    copylen = GRUB_AUTH_MAX_PASSLEN - 1;
  grub_memcpy (pass, password, copylen);

  err = grub_auth_register_authentication (user, check_password, pass);
  if (err)
    {
      grub_free (pass);
      return err;
    }
  grub_dl_ref (my_mod);
  return GRUB_ERR_NONE;
}
Example #13
0
static grub_err_t
grub_cmd_pxechain (grub_command_t cmd __attribute__ ((unused)),
		int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_err_t err;
  void *image;
  grub_size_t imagesize;
  char *fname;

  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;

  if (file->device->net && file->device->net->name)
    fname = file->device->net->name;
  else
    {
      fname = argv[0];
      if (fname[0] == '(')
	{
	  fname = grub_strchr (fname, ')');
	  if (fname)
	    fname++;
	  else
	    fname = argv[0];
	}
    }

  grub_memset (boot_file, 0, sizeof (boot_file));
  grub_strncpy (boot_file, fname, sizeof (boot_file));

  grub_memset (server_name, 0, sizeof (server_name));
  if (file->device->net && file->device->net->server)
    grub_strncpy (server_name, file->device->net->server, sizeof (server_name));

  edx = grub_get_root_biosnumber ();

  imagesize = grub_file_size (file);
  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7c00, imagesize);
    if (err)
      goto fail;
    image = get_virtual_current_address (ch);
  }

  if (grub_file_read (file, image, imagesize) != (grub_ssize_t) imagesize)
    goto fail;
 
  grub_loader_set (grub_pxechain_boot, grub_pxechain_unload,
		   GRUB_LOADER_FLAG_NORETURN | GRUB_LOADER_FLAG_PXE_NOT_UNLOAD);
  return GRUB_ERR_NONE;

 fail:

  if (file)
    grub_file_close (file);

  grub_pxechain_unload ();

  return grub_errno;
}
Example #14
0
static grub_err_t
grub_cmd_appleloader (grub_command_t cmd __attribute__ ((unused)),
                      int argc, char *argv[])
{
  grub_efi_boot_services_t *b;
  grub_efi_loaded_image_t *loaded_image;
  struct devdata *pdev;

  grub_dl_ref (my_mod);

  /* Initialize some global variables.  */
  image_handle = 0;

  b = grub_efi_system_table->boot_services;

  for (pdev = devs ; pdev->devpath ; pdev++)
    if (efi_call_6 (b->load_image, 0, grub_efi_image_handle, pdev->devpath,
                    NULL, 0, &image_handle) == GRUB_EFI_SUCCESS)
      break;

  if (! pdev->devpath)
    {
      grub_error (GRUB_ERR_BAD_OS, "can't find model");
      goto fail;
    }

  grub_dprintf ("appleload", "Model: %s\n", pdev->model);

  loaded_image = grub_efi_get_loaded_image (image_handle);
  if (! loaded_image)
    {
      grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
      goto fail;
    }

  if (argc > 0)
    {
      int i, len;
      grub_efi_char16_t *p16;

      for (i = 0, len = 0; i < argc; i++)
        len += grub_strlen (argv[i]) + 1;

      len *= sizeof (grub_efi_char16_t);
      cmdline = p16 = grub_malloc (len);
      if (! cmdline)
        goto fail;

      for (i = 0; i < argc; i++)
        {
          char *p8;

          p8 = argv[i];
          while (*p8)
            *(p16++) = *(p8++);

          *(p16++) = ' ';
        }
      *(--p16) = 0;

      loaded_image->load_options = cmdline;
      loaded_image->load_options_size = len;
    }

  grub_loader_set (grub_appleloader_boot, grub_appleloader_unload, 0);

  return 0;

 fail:

  grub_dl_unref (my_mod);
  return grub_errno;
}
Example #15
0
static grub_err_t
grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
		   int argc, char **args)
{
  grub_err_t err;
  char *ptr, *ptr2;
  grub_uint8_t *ptro;
  struct pbkdf2_password *pass;

  if (argc != 2)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected.");

  if (grub_memcmp (args[1], "grub.pbkdf2.sha512.",
		   sizeof ("grub.pbkdf2.sha512.") - 1) != 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");

  ptr = args[1] + sizeof ("grub.pbkdf2.sha512.") - 1;

  pass = grub_malloc (sizeof (*pass));
  if (!pass)
    return grub_errno;

  pass->c = grub_strtoul (ptr, &ptr, 0);
  if (*ptr != '.')
    {
      grub_free (pass);
      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
    }
  ptr++;

  ptr2 = grub_strchr (ptr, '.');
  if (!ptr2 || ((ptr2 - ptr) & 1) || grub_strlen (ptr2 + 1) & 1)
    {
      grub_free (pass);
      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Incorrect PBKDF2 password.");
    }

  pass->saltlen = (ptr2 - ptr) >> 1;
  pass->buflen = grub_strlen (ptr2 + 1) >> 1;
  ptro = pass->salt = grub_malloc (pass->saltlen);
  if (!ptro)
    {
      grub_free (pass);
      return grub_errno;
    }
  while (ptr < ptr2)
    {
      int hex1, hex2;
      hex1 = hex2val (*ptr);
      ptr++;
      hex2 = hex2val (*ptr);
      ptr++;
      if (hex1 < 0 || hex2 < 0)
	{
	  grub_free (pass->salt);
	  grub_free (pass);
	  return grub_error (GRUB_ERR_BAD_ARGUMENT,
			     "Incorrect PBKDF2 password.");
	}

      *ptro = (hex1 << 4) | hex2;
      ptro++;
    }

  ptro = pass->expected = grub_malloc (pass->buflen);
  if (!ptro)
    {
      grub_free (pass->salt);
      grub_free (pass);
      return grub_errno;
    }
  ptr = ptr2 + 1;
  ptr2 += grub_strlen (ptr2); 
  while (ptr < ptr2)
    {
      int hex1, hex2;
      hex1 = hex2val (*ptr);
      ptr++;
      hex2 = hex2val (*ptr);
      ptr++;
      if (hex1 < 0 || hex2 < 0)
	{
	  grub_free (pass->expected);
	  grub_free (pass->salt);
	  grub_free (pass);
	  return grub_error (GRUB_ERR_BAD_ARGUMENT,
			     "Incorrect PBKDF2 password.");
	}

      *ptro = (hex1 << 4) | hex2;
      ptro++;
    }

  err = grub_auth_register_authentication (args[0], check_password, pass);
  if (err)
    {
      grub_free (pass);
      return err;
    }
  grub_dl_ref (my_mod);
  return GRUB_ERR_NONE;
}
Example #16
0
static grub_err_t
grub_cpio_dir (grub_device_t device, const char *path_in,
	       int (*hook) (const char *filename,
			    const struct grub_dirhook_info *info))
{
  struct grub_cpio_data *data;
  grub_disk_addr_t ofs;
  char *prev, *name, *path, *ptr;
  grub_size_t len;
  int symlinknest = 0;

  path = grub_strdup (path_in + 1);
  if (!path)
    return grub_errno;
  canonicalize (path);
  for (ptr = path + grub_strlen (path) - 1; ptr >= path && *ptr == '/'; ptr--)
    *ptr = 0;

  grub_dl_ref (my_mod);

  prev = 0;

  data = grub_cpio_mount (device->disk);
  if (!data)
    {
      grub_free (path);
      return grub_errno;
    }

  len = grub_strlen (path);
  data->hofs = 0;
  while (1)
    {
      grub_int32_t mtime;
      grub_uint32_t mode;
      grub_err_t err;

      if (grub_cpio_find_file (data, &name, &mtime, &ofs, &mode))
	goto fail;

      if (!ofs)
	break;

      if (grub_memcmp (path, name, len) == 0
	  && (name[len] == 0 || name[len] == '/' || len == 0))
	{
	  char *p, *n;

	  n = name + len;
	  while (*n == '/')
	    n++;

	  p = grub_strchr (n, '/');
	  if (p)
	    *p = 0;

	  if (((!prev) || (grub_strcmp (prev, name) != 0)) && *n != 0)
	    {
	      struct grub_dirhook_info info;
	      grub_memset (&info, 0, sizeof (info));
	      info.dir = (p != NULL) || ((mode & ATTR_TYPE) == ATTR_DIR);
	      info.mtime = mtime;
	      info.mtimeset = 1;

	      if (hook (n, &info))
		{
		  grub_free (name);
		  goto fail;
		}
	      grub_free (prev);
	      prev = name;
	    }
	  else
	    {
	      int restart = 0;
	      err = handle_symlink (data, name, &path, mode, &restart);
	      grub_free (name);
	      if (err)
		goto fail;
	      if (restart)
		{
		  len = grub_strlen (path);
		  if (++symlinknest == 8)
		    {
		      grub_error (GRUB_ERR_SYMLINK_LOOP,
				  N_("too deep nesting of symlinks"));
		      goto fail;
		    }
		  ofs = 0;
		}
	    }
	}
      else
	grub_free (name);
      data->hofs = ofs;
    }

fail:

  grub_free (path);
  grub_free (prev);
#ifdef MODE_USTAR
  grub_free (data->linkname);
#endif
  grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Example #17
0
static grub_err_t
grub_cpio_open (grub_file_t file, const char *name_in)
{
  struct grub_cpio_data *data;
  grub_disk_addr_t ofs;
  char *fn;
  char *name = grub_strdup (name_in + 1);
  int symlinknest = 0;

  if (!name)
    return grub_errno;

  canonicalize (name);

  grub_dl_ref (my_mod);

  data = grub_cpio_mount (file->device->disk);
  if (!data)
    {
      grub_free (name);
      return grub_errno;
    }

  data->hofs = 0;
  while (1)
    {
      grub_uint32_t mode;
      int restart;
      
      if (grub_cpio_find_file (data, &fn, NULL, &ofs, &mode))
	goto fail;

      if (!ofs)
	{
	  grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), name_in);
	  break;
	}

      if (handle_symlink (data, fn, &name, mode, &restart))
	{
	  grub_free (fn);
	  goto fail;
	}

      if (restart)
	{
	  ofs = 0;
	  if (++symlinknest == 8)
	    {
	      grub_error (GRUB_ERR_SYMLINK_LOOP,
			  N_("too deep nesting of symlinks"));
	      goto fail;
	    }
	  goto no_match;
	}

      if (grub_strcmp (name, fn) != 0)
	goto no_match;

      file->data = data;
      file->size = data->size;
      grub_free (fn);
      grub_free (name);

      return GRUB_ERR_NONE;

    no_match:

      grub_free (fn);
      data->hofs = ofs;
    }

fail:
#ifdef MODE_USTAR
  grub_free (data->linkname);
#endif
  grub_free (data);
  grub_free (name);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Example #18
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;
}
Example #19
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;
}
Example #20
0
static grub_err_t
grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)),
		int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_err_t err;
  void *bs, *kernelsys;
  grub_size_t kernelsyssize;
  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, GRUB_FREEDOS_BPB_ADDR,
					   GRUB_DISK_SECTOR_SIZE);
    if (err)
      goto fail;
    bs = get_virtual_current_address (ch);
  }

  ebx = 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, ebx);
    }

  if (dev)
    grub_device_close (dev);

  kernelsyssize = grub_file_size (file);

  if (kernelsyssize > GRUB_FREEDOS_MAX_SIZE)
    {
      grub_error (GRUB_ERR_BAD_OS,
		  N_("the size of `%s' is too large"), argv[0]);
      goto fail;
    }

  {
    grub_relocator_chunk_t ch;
    err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_ADDR,
					   kernelsyssize);
    if (err)
      goto fail;
    kernelsys = get_virtual_current_address (ch);
  }

  if (grub_file_read (file, kernelsys, kernelsyssize)
      != (grub_ssize_t) kernelsyssize)
    goto fail;
 
  grub_loader_set (grub_freedos_boot, grub_freedos_unload, 1);
  return GRUB_ERR_NONE;

 fail:

  if (file)
    grub_file_close (file);

  grub_freedos_unload ();

  return grub_errno;
}
Example #21
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;
}
Example #22
0
static grub_err_t
grub_cpio_dir (grub_device_t device, const char *path,
	       int (*hook) (const char *filename,
			    const struct grub_dirhook_info *info))
{
  struct grub_cpio_data *data;
  grub_uint32_t ofs;
  char *prev, *name;
  const char *np;
  int len;

  grub_dl_ref (my_mod);

  prev = 0;

  data = grub_cpio_mount (device->disk);
  if (!data)
    goto fail;

  np = path + 1;
  len = grub_strlen (path) - 1;

  data->hofs = 0;
  while (1)
    {
      if (grub_cpio_find_file (data, &name, &ofs))
	goto fail;

      if (!ofs)
	break;

      if (grub_memcmp (np, name, len) == 0)
	{
	  char *p, *n;

	  n = name + len;
	  if (*n == '/')
	    n++;

	  p = grub_strchr (name + len, '/');
	  if (p)
	    *p = 0;

	  if ((!prev) || (grub_strcmp (prev, name) != 0))
	    {
	      struct grub_dirhook_info info;
	      grub_memset (&info, 0, sizeof (info));
	      info.dir = (p != NULL);

	      hook (name + len, &info);
	      if (prev)
		grub_free (prev);
	      prev = name;
	    }
	  else
	    grub_free (name);
	}
      data->hofs = ofs;
    }

fail:

  if (prev)
    grub_free (prev);

  if (data)
    grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Example #23
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);
}
Example #24
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, "no file specified");

  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;
	}
    }

  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);
  return GRUB_ERR_NONE;

 fail:

  if (file)
    grub_file_close (file);

  grub_ntldr_unload ();

  return grub_errno;
}
Example #25
0
static grub_err_t
grub_cpio_open (grub_file_t file, const char *name)
{
  struct grub_cpio_data *data;
  grub_uint32_t ofs;
  char *fn;
  int i, j;

  grub_dl_ref (my_mod);

  data = grub_cpio_mount (file->device->disk);
  if (!data)
    goto fail;

  data->hofs = 0;
  while (1)
    {
      if (grub_cpio_find_file (data, &fn, &ofs))
	goto fail;

      if (!ofs)
	{
	  grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
	  break;
	}

      /* Compare NAME and FN by hand in order to cope with duplicate
	 slashes.  */
      i = 0;
      j = 0;
      while (name[i] == '/')
	i++;
      while (1)
	{
	  if (name[i] != fn[j])
	    goto no_match;

	  if (name[i] == '\0')
	    break;

	  while (name[i] == '/' && name[i+1] == '/')
	    i++;

	  i++;
	  j++;
	}

      if (name[i] != fn[j])
	goto no_match;

      file->data = data;
      file->size = data->size;
      grub_free (fn);

      return GRUB_ERR_NONE;

    no_match:

      grub_free (fn);
      data->hofs = ofs;
    }

fail:

  if (data)
    grub_free (data);

  grub_dl_unref (my_mod);

  return grub_errno;
}
Example #26
0
static grub_err_t
handle_command (int argc, char **args, struct abstract_terminal **enabled,
                struct abstract_terminal **disabled,
                struct grub_term_autoload *autoloads,
                const char *active_str,
                const char *available_str)
{
    int i;
    struct abstract_terminal *term;
    struct grub_term_autoload *aut;

    if (argc == 0)
    {
        grub_puts_ (active_str);
        for (term = *enabled; term; term = term->next)
            grub_printf ("%s ", term->name);
        grub_printf ("\n");
        grub_puts_ (available_str);
        for (term = *disabled; term; term = term->next)
            grub_printf ("%s ", term->name);
        /* This is quadratic but we don't expect mode than 30 terminal
          modules ever.  */
        for (aut = autoloads; aut; aut = aut->next)
        {
            for (term = *disabled; term; term = term->next)
                if (grub_strcmp (term->name, aut->name) == 0
                        || (aut->name[0] && aut->name[grub_strlen (aut->name) - 1] == '*'
                            && grub_memcmp (term->name, aut->name,
                                            grub_strlen (aut->name) - 1) == 0))
                    break;
            if (!term)
                for (term = *enabled; term; term = term->next)
                    if (grub_strcmp (term->name, aut->name) == 0
                            || (aut->name[0] && aut->name[grub_strlen (aut->name) - 1] == '*'
                                && grub_memcmp (term->name, aut->name,
                                                grub_strlen (aut->name) - 1) == 0))
                        break;
            if (!term)
                grub_printf ("%s ", aut->name);
        }
        grub_printf ("\n");
        return GRUB_ERR_NONE;
    }
    i = 0;

    if (grub_strcmp (args[0], "--append") == 0
            || grub_strcmp (args[0], "--remove") == 0)
        i++;

    if (i == argc)
        return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));

    for (; i < argc; i++)
    {
        int again = 0;
        while (1)
        {
            for (term = *disabled; term; term = term->next)
                if (grub_strcmp (args[i], term->name) == 0)
                    break;
            if (term == 0)
                for (term = *enabled; term; term = term->next)
                    if (grub_strcmp (args[i], term->name) == 0)
                        break;
            if (term)
                break;
            if (again)
                return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
                                   args[i]);
            for (aut = autoloads; aut; aut = aut->next)
                if (grub_strcmp (args[i], aut->name) == 0
                        || (aut->name[0] && aut->name[grub_strlen (aut->name) - 1] == '*'
                            && grub_memcmp (args[i], aut->name,
                                            grub_strlen (aut->name) - 1) == 0))
                {
                    grub_dl_t mod;
                    mod = grub_dl_load (aut->modname);
                    if (mod)
                        grub_dl_ref (mod);
                    grub_errno = GRUB_ERR_NONE;
                    break;
                }
            if (!aut)
                return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
                                   args[i]);
            again = 1;
        }
    }

    if (grub_strcmp (args[0], "--append") == 0)
    {
        for (i = 1; i < argc; i++)
        {
            for (term = *disabled; term; term = term->next)
                if (grub_strcmp (args[i], term->name) == 0)
                    break;
            if (term)
            {
                if (term->init && term->init (term) != GRUB_ERR_NONE)
                    return grub_errno;

                grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
                grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
            }
        }
        return GRUB_ERR_NONE;
    }

    if (grub_strcmp (args[0], "--remove") == 0)
    {
        for (i = 1; i < argc; i++)
        {
            for (term = *enabled; term; term = term->next)
                if (grub_strcmp (args[i], term->name) == 0)
                    break;
            if (term)
            {
                if (!term->next && term == *enabled)
                    return grub_error (GRUB_ERR_BAD_ARGUMENT,
                                       "can't remove the last terminal");
                grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
                if (term->fini)
                    term->fini (term);
                grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
            }
        }
        return GRUB_ERR_NONE;
    }
    for (i = 0; i < argc; i++)
    {
        for (term = *disabled; term; term = term->next)
            if (grub_strcmp (args[i], term->name) == 0)
                break;
        if (term)
        {
            if (term->init && term->init (term) != GRUB_ERR_NONE)
                return grub_errno;

            grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
            grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
        }
    }

    {
        struct abstract_terminal *next;
        for (term = *enabled; term; term = next)
        {
            next = term->next;
            for (i = 0; i < argc; i++)
                if (grub_strcmp (args[i], term->name) == 0)
                    break;
            if (i == argc)
            {
                if (!term->next && term == *enabled)
                    return grub_error (GRUB_ERR_BAD_ARGUMENT,
                                       "can't remove the last terminal");
                grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term));
                if (term->fini)
                    term->fini (term);
                grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term));
            }
        }
    }

    return GRUB_ERR_NONE;
}