Commit message: Bug 27494 — publicly exports dm key information

Change udisks-dm-export to only export UDISKS_DM_TARGETS_PARAMS for "linear"
types. It is the only one we care about for now and know how to interpret.
"crypto" types have information about the encryption key in the target
parameters, which we must not leak.

Also add appropriate comments to the two places which currently evaluate
UDISKS_DM_TARGETS_PARAMS.
CVE: CVE-2010-1149
CWE: CWE-200
Vulnerability description: probers/udisks-dm-export.c in udisks before 1.0.1 exports UDISKS_DM_TARGETS_PARAMS information to udev even for a crypt UDISKS_DM_TARGETS_TYPE, which allows local users to discover encryption keys by (1) running a certain udevadm command or (2) reading a certain file under /dev/.udev/db/.

Project: udisks
File: device.c

update_info_linux_md (Device *device)
{
  gboolean ret;
  guint n;
  gchar *s;
  gchar *p;

  ret = FALSE;

  if (sysfs_file_exists (device->priv->native_path, "md"))
    {
      gchar *uuid;
      gint num_raid_devices;
      gchar *raid_level;
      gchar *array_state;
      Device *slave;
      GPtrArray *md_slaves;
      const gchar *md_name;
      const gchar *md_home_host;

      device_set_device_is_linux_md (device, TRUE);

      /* figure out if the array is active */
      array_state = sysfs_get_string (device->priv->native_path, "md/array_state");
      if (array_state == NULL)
        {
          g_print ("**** NOTE: Linux MD array %s has no array_state file'; removing\n", device->priv->native_path);
          goto out;
        }
      g_strstrip (array_state);

      /* ignore clear arrays since these have no devices, no size, no level */
      if (strcmp (array_state, "clear") == 0)
        {
          g_print ("**** NOTE: Linux MD array %s is 'clear'; removing\n", device->priv->native_path);
          g_free (array_state);
          goto out;
        }

      device_set_linux_md_state (device, array_state);
      g_free (array_state);

      /* find a slave from the array */
      slave = NULL;
      for (n = 0; n < device->priv->slaves_objpath->len; n++)
        {
          const gchar *slave_objpath;

          slave_objpath = device->priv->slaves_objpath->pdata[n];
          slave = daemon_local_find_by_object_path (device->priv->daemon, slave_objpath);
          if (slave != NULL)
            break;
        }

      uuid = g_strdup (g_udev_device_get_property (device->priv->d, "MD_UUID"));
      num_raid_devices = sysfs_get_int (device->priv->native_path, "md/raid_disks");
      raid_level = g_strstrip (sysfs_get_string (device->priv->native_path, "md/level"));

      if (slave != NULL)
        {
          /* if the UUID isn't set by the udev rules (array may be inactive) get it from a slave */
          if (uuid == NULL || strlen (uuid) == 0)
            {
              g_free (uuid);
              uuid = g_strdup (slave->priv->linux_md_component_uuid);
            }

          /* ditto for raid level */
          if (raid_level == NULL || strlen (raid_level) == 0)
            {
              g_free (raid_level);
              raid_level = g_strdup (slave->priv->linux_md_component_level);
            }

          /* and num_raid_devices too */
          if (device->priv->linux_md_num_raid_devices == 0)
            {
              num_raid_devices = slave->priv->linux_md_component_num_raid_devices;
            }
        }

      device_set_linux_md_uuid (device, uuid);
      device_set_linux_md_num_raid_devices (device, num_raid_devices);
      device_set_linux_md_level (device, raid_level);
      g_free (raid_level);
      g_free (uuid);

      /* infer the array name and homehost */
      p = g_strdup (g_udev_device_get_property (device->priv->d, "MD_NAME"));
      s = NULL;
      if (p != NULL)
        s = strstr (p, ":");
      if (s != NULL)
        {
          *s = '\0';
          md_home_host = p;
          md_name = s + 1;
        }
      else
        {
          md_home_host = "";
          md_name = p;
        }
      device_set_linux_md_home_host (device, md_home_host);
      device_set_linux_md_name (device, md_name);
      g_free (p);

      s = g_strstrip (sysfs_get_string (device->priv->native_path, "md/metadata_version"));
      device_set_linux_md_version (device, s);
      g_free (s);

      /* Go through all block slaves and build up the linux_md_slaves property
       *
       * Also update the slaves since the slave state may have changed.
       */
      md_slaves = g_ptr_array_new ();
      for (n = 0; n < device->priv->slaves_objpath->len; n++)
        {
          Device *slave_device;
          const gchar *slave_objpath;

          slave_objpath = device->priv->slaves_objpath->pdata[n];
          g_ptr_array_add (md_slaves, (gpointer) slave_objpath);
          slave_device = daemon_local_find_by_object_path (device->priv->daemon, slave_objpath);
          if (slave_device != NULL)
            {
              update_info (slave_device);
            }
        }
      g_ptr_array_sort (md_slaves, (GCompareFunc) ptr_str_array_compare);
      g_ptr_array_add (md_slaves, NULL);
      device_set_linux_md_slaves (device, (GStrv) md_slaves->pdata);
      g_ptr_array_free (md_slaves, TRUE);

      /* TODO: may race */
      device_set_drive_vendor (device, "Linux");
      if (device->priv->linux_md_level != NULL)
        s = g_strdup_printf ("Software RAID %s", device->priv->linux_md_level);
      else
        s = g_strdup_printf ("Software RAID");
      device_set_drive_model (device, s);
      g_free (s);
      device_set_drive_revision (device, device->priv->linux_md_version);
      device_set_drive_connection_interface (device, "virtual");
      device_set_drive_serial (device, device->priv->linux_md_uuid);

      /* RAID-0 can never resync or run degraded */
      if (g_strcmp0 (device->priv->linux_md_level, "raid0") == 0 || g_strcmp0 (device->priv->linux_md_level, "linear")
          == 0)
        {
          device_set_linux_md_sync_action (device, "idle");
          device_set_linux_md_is_degraded (device, FALSE);
        }
      else
        {
          gchar *degraded_file;
          gint num_degraded_devices;

          degraded_file = sysfs_get_string (device->priv->native_path, "md/degraded");
          if (degraded_file == NULL)
            {
              num_degraded_devices = 0;
            }
          else
            {
              num_degraded_devices = strtol (degraded_file, NULL, 0);
            }
          g_free (degraded_file);

          device_set_linux_md_is_degraded (device, (num_degraded_devices > 0));

          s = g_strstrip (sysfs_get_string (device->priv->native_path, "md/sync_action"));
          device_set_linux_md_sync_action (device, s);
          g_free (s);

          if (device->priv->linux_md_sync_action == NULL || strlen (device->priv->linux_md_sync_action) == 0)
            {
              device_set_linux_md_sync_action (device, "idle");
            }

          /* if not idle; update percentage and speed */
          if (g_strcmp0 (device->priv->linux_md_sync_action, "idle") != 0)
            {
              char *s;
              guint64 done;
              guint64 remaining;

              s = g_strstrip (sysfs_get_string (device->priv->native_path, "md/sync_completed"));
              if (sscanf (s, "%" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "", &done, &remaining) == 2)
                {
                  device_set_linux_md_sync_percentage (device, 100.0 * ((double) done) / ((double) remaining));
                }
              else
                {
                  g_warning ("cannot parse md/sync_completed for %s: '%s'", device->priv->native_path, s);
                }
              g_free (s);

              device_set_linux_md_sync_speed (device, 1000L * sysfs_get_uint64 (device->priv->native_path,
                                                                                "md/sync_speed"));

              /* Since the kernel doesn't emit uevents while the job is pending, set up
               * a timeout for every two seconds to synthesize the change event so we can
               * refresh the completed/speed properties.
               */
              if (device->priv->linux_md_poll_timeout_id == 0)
                {
                  device->priv->linux_md_poll_timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
                                                                                       2,
                                                                                       poll_syncing_md_device,
                                                                                       g_object_ref (device),
                                                                                       g_object_unref);
                }
            }
          else
            {
              device_set_linux_md_sync_percentage (device, 0.0);
              device_set_linux_md_sync_speed (device, 0);
            }
        }

    }
  else
    {
      device_set_device_is_linux_md (device, FALSE);
      device_set_linux_md_state (device, NULL);
      device_set_linux_md_level (device, NULL);
      device_set_linux_md_num_raid_devices (device, 0);
      device_set_linux_md_uuid (device, NULL);
      device_set_linux_md_home_host (device, NULL);
      device_set_linux_md_name (device, NULL);
      device_set_linux_md_version (device, NULL);
      device_set_linux_md_slaves (device, NULL);
      device_set_linux_md_is_degraded (device, FALSE);
      device_set_linux_md_sync_action (device, NULL);
      device_set_linux_md_sync_percentage (device, 0.0);
      device_set_linux_md_sync_speed (device, 0);
    }

  ret = TRUE;

 out:
  return ret;
}

Project: udisks
File: device.c

update_info_linux_md_component (Device *device)
{
  if (g_strcmp0 (device->priv->id_type, "linux_raid_member") == 0)
    {
      const gchar *md_comp_level;
      gint md_comp_num_raid_devices;
      const gchar *md_comp_uuid;
      const gchar *md_comp_home_host;
      const gchar *md_comp_name;
      const gchar *md_comp_version;
      gchar *md_name;
      gchar *s;
      int md_comp_position;

      md_comp_position = -1;

      device_set_device_is_linux_md_component (device, TRUE);

      /* linux_md_component_holder and linux_md_component_state */
      if (device->priv->holders_objpath->len == 1)
        {
          Device *holder;
          gchar **state_tokens;

          device_set_linux_md_component_holder (device, device->priv->holders_objpath->pdata[0]);
          state_tokens = NULL;
          holder = daemon_local_find_by_object_path (device->priv->daemon, device->priv->holders_objpath->pdata[0]);
          if (holder != NULL && holder->priv->device_is_linux_md)
            {
              gchar *dev_name;
              gchar *md_dev_path;
              gchar *state_contents;
              gchar *slot_contents;
              gint slot_number;
              gchar *endp;

              dev_name = g_path_get_basename (device->priv->native_path);
              md_dev_path = g_strdup_printf ("%s/md/dev-%s", holder->priv->native_path, dev_name);
              state_contents = sysfs_get_string (md_dev_path, "state");
              g_strstrip (state_contents);
              state_tokens = g_strsplit (state_contents, ",", 0);

              slot_contents = sysfs_get_string (md_dev_path, "slot");
              g_strstrip (slot_contents);
              slot_number = strtol (slot_contents, &endp, 0);
              if (endp != NULL && *endp == '\0')
                {
                  md_comp_position = slot_number;
                }

              g_free (slot_contents);
              g_free (state_contents);
              g_free (md_dev_path);
              g_free (dev_name);
            }

          device_set_linux_md_component_state (device, state_tokens);
          g_strfreev (state_tokens);

        }
      else
        {
          /* no holder, nullify properties */
          device_set_linux_md_component_holder (device, NULL);
          device_set_linux_md_component_state (device, NULL);
        }

      md_comp_level = g_udev_device_get_property (device->priv->d, "MD_LEVEL");
      md_comp_num_raid_devices = g_udev_device_get_property_as_int (device->priv->d, "MD_DEVICES");
      md_comp_uuid = g_udev_device_get_property (device->priv->d, "MD_UUID");
      md_name = g_strdup (g_udev_device_get_property (device->priv->d, "MD_NAME"));
      s = NULL;
      if (md_name != NULL)
        s = strstr (md_name, ":");
      if (s != NULL)
        {
          *s = '\0';
          md_comp_home_host = md_name;
          md_comp_name = s + 1;
        }
      else
        {
          md_comp_home_host = "";
          md_comp_name = md_name;
        }
      md_comp_version = device->priv->id_version;

      device_set_linux_md_component_level (device, md_comp_level);
      device_set_linux_md_component_position (device, md_comp_position);
      device_set_linux_md_component_num_raid_devices (device, md_comp_num_raid_devices);
      device_set_linux_md_component_uuid (device, md_comp_uuid);
      device_set_linux_md_component_home_host (device, md_comp_home_host);
      device_set_linux_md_component_name (device, md_comp_name);
      device_set_linux_md_component_version (device, md_comp_version);

      g_free (md_name);
    }
  else
    {
      device_set_device_is_linux_md_component (device, FALSE);
      device_set_linux_md_component_level (device, NULL);
      device_set_linux_md_component_position (device, -1);
      device_set_linux_md_component_num_raid_devices (device, 0);
      device_set_linux_md_component_uuid (device, NULL);
      device_set_linux_md_component_home_host (device, NULL);
      device_set_linux_md_component_name (device, NULL);
      device_set_linux_md_component_version (device, NULL);
      device_set_linux_md_component_holder (device, NULL);
      device_set_linux_md_component_state (device, NULL);
    }

  return TRUE;
}

Project: udisks
File: device.c

update_info_luks (Device *device)
{
  if (g_strcmp0 (device->priv->id_type, "crypto_LUKS") == 0 && device->priv->holders_objpath->len == 1)
    {
      device_set_device_is_luks (device, TRUE);
      device_set_luks_holder (device, device->priv->holders_objpath->pdata[0]);
    }
  else
    {
      device_set_device_is_luks (device, FALSE);
      device_set_luks_holder (device, NULL);
    }

  return TRUE;
}

Project: udisks
File: device.c

update_info_luks_cleartext (Device *device)
{
  uid_t unlocked_by_uid;
  const gchar *dkd_dm_name;
  const gchar *dkd_dm_target_types;
  gboolean ret;

  ret = FALSE;

  dkd_dm_name = g_udev_device_get_property (device->priv->d, "DM_NAME");
  dkd_dm_target_types = g_udev_device_get_property (device->priv->d, "UDISKS_DM_TARGETS_TYPE");
  if (dkd_dm_name != NULL && g_strcmp0 (dkd_dm_target_types, "crypt") == 0 && device->priv->slaves_objpath->len == 1)
    {

      /* TODO: might be racing with setting is_drive earlier */
      device_set_device_is_drive (device, FALSE);

      if (g_str_has_prefix (dkd_dm_name, "temporary-cryptsetup-"))
        {
          /* ignore temporary devices created by /sbin/cryptsetup */
          goto out;
        }

      device_set_device_is_luks_cleartext (device, TRUE);

      device_set_luks_cleartext_slave (device, ((gchar **) device->priv->slaves_objpath->pdata)[0]);

      if (luks_get_uid_from_dm_name (dkd_dm_name, &unlocked_by_uid))
        {
          device_set_luks_cleartext_unlocked_by_uid (device, unlocked_by_uid);
        }

      /* TODO: export this at some point */
      device_set_dm_name (device, dkd_dm_name);
    }
  else
    {
      device_set_device_is_luks_cleartext (device, FALSE);
      device_set_luks_cleartext_slave (device, NULL);
    }

  ret = TRUE;

 out:
  return ret;
}

Project: udisks
File: device.c

update_info_media_detection (Device *device)
{
  gboolean detected;
  gboolean polling;
  gboolean inhibitable;
  gboolean inhibited;

  detected = FALSE;
  polling = FALSE;
  inhibitable = FALSE;
  inhibited = FALSE;

  if (device->priv->device_is_removable)
    {
      guint64 evt_media_change;
      GUdevDevice *parent;

      evt_media_change = sysfs_get_uint64 (device->priv->native_path, "../../evt_media_change");
      if (evt_media_change & 1)
        {
          /* SATA AN capabable drive */

          polling = FALSE;
          detected = TRUE;
          goto determined;
        }

      parent = g_udev_device_get_parent_with_subsystem (device->priv->d, "platform", NULL);
      if (parent != NULL)
        {
          /* never poll PC floppy drives, they are noisy (fdo #22149) */
          if (g_str_has_prefix (g_udev_device_get_name (parent), "floppy."))
            {
              g_object_unref (parent);
              goto determined;
            }
          g_object_unref (parent);
        }

      /* assume the device needs polling */
      polling = TRUE;
      inhibitable = TRUE;

      /* custom udev rules might want to disable polling for known-broken
       * devices (fdo #26508) */
      if (g_udev_device_has_property (device->priv->d, "UDISKS_DISABLE_POLLING") &&
	  g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_DISABLE_POLLING"))
	polling = FALSE;

      if (device->priv->polling_inhibitors != NULL || daemon_local_has_polling_inhibitors (device->priv->daemon))
        {

          detected = FALSE;
          inhibited = TRUE;
        }
      else
        {
          detected = TRUE;
          inhibited = FALSE;
        }
    }

 determined:
  device_set_device_is_media_change_detected (device, detected);
  device_set_device_is_media_change_detection_polling (device, polling);
  device_set_device_is_media_change_detection_inhibitable (device, inhibitable);
  device_set_device_is_media_change_detection_inhibited (device, inhibited);

  return TRUE;
}

Project: udisks
File: device.c

update_info_mount_state (Device *device)
{
  MountMonitor *monitor;
  GList *mounts;
  gboolean was_mounted;

  mounts = NULL;

  /* defer setting the mount point until FilesystemMount returns and
   * the mounts file is written
   */
  if (device->priv->job_in_progress && g_strcmp0 (device->priv->job_id, "FilesystemMount") == 0)
    goto out;

  monitor = daemon_local_get_mount_monitor (device->priv->daemon);

  mounts = mount_monitor_get_mounts_for_dev (monitor, device->priv->dev);

  was_mounted = device->priv->device_is_mounted;

  if (mounts != NULL)
    {
      GList *l;
      guint n;
      gchar **mount_paths;

      mount_paths = g_new0 (gchar *, g_list_length (mounts) + 1);
      for (l = mounts, n = 0; l != NULL; l = l->next, n++)
        {
          mount_paths[n] = g_strdup (mount_get_mount_path (MOUNT (l->data)));
        }

      device_set_device_is_mounted (device, TRUE);
      device_set_device_mount_paths (device, mount_paths);
      if (!was_mounted)
        {
          uid_t mounted_by_uid;

          if (!mount_file_has_device (device->priv->device_file, &mounted_by_uid, NULL))
            mounted_by_uid = 0;
          device_set_device_mounted_by_uid (device, mounted_by_uid);
        }

      g_strfreev (mount_paths);

    }
  else
    {
      gboolean remove_dir_on_unmount;
      gchar *old_mount_path;

      old_mount_path = NULL;
      if (device->priv->device_mount_paths->len > 0)
        old_mount_path = g_strdup (((gchar **) device->priv->device_mount_paths->pdata)[0]);

      device_set_device_is_mounted (device, FALSE);
      device_set_device_mount_paths (device, NULL);
      device_set_device_mounted_by_uid (device, 0);

      /* clean up stale mount directory */
      remove_dir_on_unmount = FALSE;
      if (was_mounted && mount_file_has_device (device->priv->device_file, NULL, &remove_dir_on_unmount))
        {
          mount_file_remove (device->priv->device_file, old_mount_path);
          if (remove_dir_on_unmount)
            {
              if (g_rmdir (old_mount_path) != 0)
                {
                  g_warning ("Error removing dir '%s' on unmount: %m", old_mount_path);
                }
            }
        }

      g_free (old_mount_path);

    }

 out:
  g_list_foreach (mounts, (GFunc) g_object_unref, NULL);
  g_list_free (mounts);

  return TRUE;
}

Project: udisks
File: device.c

update_info_optical_disc (Device *device)
{
  const gchar *cdrom_disc_state;
  gint cdrom_track_count;
  gint cdrom_track_count_audio;
  gint cdrom_session_count;

  /* device_is_optical_disc and optical_disc_* */
  if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA"))
    {
      device_set_device_is_optical_disc (device, TRUE);

      cdrom_track_count = 0;
      cdrom_track_count_audio = 0;
      cdrom_session_count = 0;

      if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT"))
        cdrom_track_count = g_udev_device_get_property_as_int (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT");
      if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"))
        cdrom_track_count_audio = g_udev_device_get_property_as_int (device->priv->d,
                                                                     "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO");
      if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_SESSION_COUNT"))
        cdrom_session_count = g_udev_device_get_property_as_int (device->priv->d, "ID_CDROM_MEDIA_SESSION_COUNT");
      device_set_optical_disc_num_tracks (device, cdrom_track_count);
      device_set_optical_disc_num_audio_tracks (device, cdrom_track_count_audio);
      device_set_optical_disc_num_sessions (device, cdrom_session_count);
      cdrom_disc_state = g_udev_device_get_property (device->priv->d, "ID_CDROM_MEDIA_STATE");
      device_set_optical_disc_is_blank (device, g_strcmp0 (cdrom_disc_state, "blank") == 0);
      device_set_optical_disc_is_appendable (device, g_strcmp0 (cdrom_disc_state, "appendable") == 0);
      device_set_optical_disc_is_closed (device, g_strcmp0 (cdrom_disc_state, "complete") == 0);
    }
  else
    {
      device_set_device_is_optical_disc (device, FALSE);

      device_set_optical_disc_num_tracks (device, 0);
      device_set_optical_disc_num_audio_tracks (device, 0);
      device_set_optical_disc_num_sessions (device, 0);
      device_set_optical_disc_is_blank (device, FALSE);
      device_set_optical_disc_is_appendable (device, FALSE);
      device_set_optical_disc_is_closed (device, FALSE);
    }

  return TRUE;
}

Project: udisks
File: device.c

update_info_partition (Device *device)
{
  gboolean is_partition;

  is_partition = FALSE;

  /* Check if udisks-part-id identified the device as a partition.. this includes
   * identifying partitions set up by kpartx for multipath
   */
  if (g_udev_device_has_property (device->priv->d, "UDISKS_PARTITION"))
    {
      guint64 size;
      const gchar *scheme;
      const gchar *type;
      const gchar *label;
      const gchar *uuid;
      const gchar* const *flags;
      guint64 offset;
      guint64 alignment_offset;
      const gchar *slave_sysfs_path;
      gint number;

      scheme = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_SCHEME");
      size = g_udev_device_get_property_as_uint64 (device->priv->d, "UDISKS_PARTITION_SIZE");
      type = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_TYPE");
      label = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_LABEL");
      uuid = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_UUID");
      flags = g_udev_device_get_property_as_strv (device->priv->d, "UDISKS_PARTITION_FLAGS");
      offset = g_udev_device_get_property_as_uint64 (device->priv->d, "UDISKS_PARTITION_OFFSET");
      alignment_offset = g_udev_device_get_property_as_uint64 (device->priv->d, "UDISKS_PARTITION_ALIGNMENT_OFFSET");
      number = g_udev_device_get_property_as_int (device->priv->d, "UDISKS_PARTITION_NUMBER");
      slave_sysfs_path = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_SLAVE");

      if (slave_sysfs_path != NULL && scheme != NULL && number > 0)
        {
          gchar *s;

          device_set_partition_scheme (device, scheme);
          device_set_partition_size (device, size);
          device_set_partition_type (device, type);
          device_set_partition_label (device, label);
          device_set_partition_uuid (device, uuid);
          device_set_partition_flags (device, (gchar **) flags);
          device_set_partition_offset (device, offset);
          device_set_partition_alignment_offset (device, alignment_offset);
          device_set_partition_number (device, number);

          s = compute_object_path (slave_sysfs_path);
          device_set_partition_slave (device, s);
          g_free (s);

          is_partition = TRUE;
        }
    }

  /* Also handle the case where we are partitioned by the kernel and don't have
   * any UDISKS_PARTITION_* properties.
   *
   * This works without any udev UDISKS_PARTITION_* properties and is
   * there for maximum compatibility since udisks-part-id only knows a
   * limited set of partition table formats.
   */
  if (!is_partition && sysfs_file_exists (device->priv->native_path, "start"))
    {
      guint64 start;
      guint64 size;
      guint64 offset;
      guint64 alignment_offset;
      gchar *s;
      guint n;

      device_set_device_is_partition (device, TRUE);
      start = sysfs_get_uint64 (device->priv->native_path, "start");
      size = sysfs_get_uint64 (device->priv->native_path, "size");
      alignment_offset = sysfs_get_uint64 (device->priv->native_path, "alignment_offset");

      device_set_partition_size (device, size * 512); /* device->priv->device_block_size; */
      device_set_partition_alignment_offset (device, alignment_offset);

      offset = sysfs_get_uint64 (device->priv->native_path, "start") * device->priv->device_block_size;
      device_set_partition_offset (device, offset);

      s = device->priv->native_path;
      for (n = strlen (s) - 1; n >= 0 && g_ascii_isdigit (s[n]); n--)
        ;
      device_set_partition_number (device, strtol (s + n + 1, NULL, 0));

      s = g_strdup (device->priv->native_path);
      for (n = strlen (s) - 1; n >= 0 && s[n] != '/'; n--)
        s[n] = '\0';
      s[n] = '\0';
      device_set_partition_slave (device, compute_object_path (s));
      g_free (s);

      is_partition = TRUE;
    }

  device_set_device_is_partition (device, is_partition);
  if (!is_partition)
    {
      /* otherwise, clear all the data */
      device_set_partition_scheme (device, NULL);
      device_set_partition_size (device, device->priv->device_size);
      device_set_partition_type (device, NULL);
      device_set_partition_label (device, NULL);
      device_set_partition_uuid (device, NULL);
      device_set_partition_flags (device, NULL);
    }
  else
    {
      device_set_device_is_drive (device, FALSE);
    }

  return TRUE;
}

Project: udisks
File: device.c

update_info_partition_table (Device *device)
{
  gboolean is_partition_table;

  is_partition_table = FALSE;

  /* Check if udisks-part-id identified the device as a partition table.. this includes
   * identifying partition tables set up by kpartx for multipath etc.
   */
  if (g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_PARTITION_TABLE"))
    {
      device_set_partition_table_scheme (device,
                                         g_udev_device_get_property (device->priv->d,
                                                                     "UDISKS_PARTITION_TABLE_SCHEME"));
      device_set_partition_table_count (device,
                                        g_udev_device_get_property_as_int (device->priv->d,
                                                                           "UDISKS_PARTITION_TABLE_COUNT"));
      is_partition_table = TRUE;
    }

  /* Note that udisks-part-id might not detect all partition table
   * formats.. so in the negative case, also double check with
   * information in sysfs.
   *
   * The kernel guarantees that all childs are created before the
   * uevent for the parent is created. So if we have childs, we must
   * be a partition table.
   *
   * To detect a child we check for the existance of a subdir that has
   * the parents name as a prefix (e.g. for parent sda then sda1,
   * sda2, sda3 ditto md0, md0p1 etc. etc. will work).
   */
  if (!is_partition_table)
    {
      gchar *s;
      GDir *dir;

      s = g_path_get_basename (device->priv->native_path);
      if ((dir = g_dir_open (device->priv->native_path, 0, NULL)) != NULL)
        {
          guint partition_count;
          const gchar *name;

          partition_count = 0;
          while ((name = g_dir_read_name (dir)) != NULL)
            {
              if (g_str_has_prefix (name, s))
                {
                  partition_count++;
                }
            }
          g_dir_close (dir);

          if (partition_count > 0)
            {
              device_set_partition_table_scheme (device, "");
              device_set_partition_table_count (device, partition_count);
              is_partition_table = TRUE;
            }
        }
      g_free (s);
    }

  device_set_device_is_partition_table (device, is_partition_table);
  if (!is_partition_table)
    {
      /* otherwise, clear all the data */
      device_set_partition_table_scheme (device, NULL);
      device_set_partition_table_count (device, 0);
    }

  return TRUE;
}

Project: udisks
File: device.c

update_info_presentation (Device *device)
{
  gboolean hide;
  gboolean nopolicy;

  hide = FALSE;
  if (g_udev_device_has_property (device->priv->d, "UDISKS_PRESENTATION_HIDE"))
    hide = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_PRESENTATION_HIDE");
  device_set_device_presentation_hide (device, hide);

  nopolicy = FALSE;
  if (g_udev_device_has_property (device->priv->d, "UDISKS_PRESENTATION_NOPOLICY"))
    nopolicy = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_PRESENTATION_NOPOLICY");
  device_set_device_presentation_nopolicy (device, nopolicy);

  device_set_device_presentation_name (device, g_udev_device_get_property (device->priv->d, "UDISKS_PRESENTATION_NAME"));

  device_set_device_presentation_icon_name (device, g_udev_device_get_property (device->priv->d,
                                                                                "UDISKS_PRESENTATION_ICON_NAME"));

  return TRUE;
}

Project: udisks
File: part-id.c

count_entries (PartitionTable *pt)
{
  guint ret;
  guint num_top_level;
  guint n;

  ret = 0;

  num_top_level = part_table_get_num_entries (pt);
  for (n = 0; n < num_top_level; n++)
    {
      PartitionTable *nested;

      if (part_table_entry_is_in_use (pt, n))
        ret++;

      nested = part_table_entry_get_nested (pt, n);
      if (nested != NULL)
        {
          ret += part_table_get_num_entries (nested);
        }
    }

  return ret;
}

Project: udisks
File: part-id.c

get_udev_device_from_device_file (struct udev *udev,
             const gchar *device_file)
{
  struct udev_device *device;
  struct stat statbuf;

  device = NULL;

  if (stat (device_file, &statbuf) != 0)
    {
      g_printerr ("Error statting %s: %m\n", device_file);
      goto out;
    }

  device = udev_device_new_from_devnum (udev, 'b', statbuf.st_rdev);
  if (device == NULL)
    {
      g_printerr ("Error getting udev device for %s: %m\n", device_file);
      goto out;
    }

 out:
  return device;
}

Project: udisks
File: part-id.c

usage (int argc,
       char *argv[])
{
  execlp ("man", "man", "part_id", NULL);
  g_printerr ("Cannot show man page: %m\n");
  exit (1);
}

Project: udisks
File: udisks-dm-export.c

_udev_util_encode_string(const char *str, char *str_enc, size_t len)
{
        size_t i, j;

        if (str == NULL || str_enc == NULL)
                return -1;

        for (i = 0, j = 0; str[i] != '\0'; i++) {
                int seqlen;

                seqlen = utf8_encoded_valid_unichar(&str[i]);
                if (seqlen > 1) {
                        if (len-j < (size_t)seqlen)
                                goto err;
                        memcpy(&str_enc[j], &str[i], seqlen);
                        j += seqlen;
                        i += (seqlen-1);
                } else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) {
                        if (len-j < 4)
                                goto err;
                        sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]);
                        j += 4;
                } else {
                        if (len-j < 1)
                                goto err;
                        str_enc[j] = str[i];
                        j++;
                }
        }
        if (len-j < 1)
                goto err;
        str_enc[j] = '\0';
        return 0;
err:
        return -1;
}