Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed09dcc8 authored by Dan Williams's avatar Dan Williams Committed by Christoph Hellwig
Browse files

ses: close potential registration race



The slot and address fields have a small window of instability when
userspace can read them before initialization. Separate
enclosure_component
allocation from registration.

Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarSong Liu <songliubraving@fb.com>
Reviewed-by: default avatarJens Axboe <axboe@fb.com>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent acd6d738
Loading
Loading
Loading
Loading
+26 −11
Original line number Diff line number Diff line
@@ -273,27 +273,26 @@ enclosure_component_find_by_name(struct enclosure_device *edev,
static const struct attribute_group *enclosure_component_groups[];

/**
 * enclosure_component_register - add a particular component to an enclosure
 * enclosure_component_alloc - prepare a new enclosure component
 * @edev:	the enclosure to add the component
 * @num:	the device number
 * @type:	the type of component being added
 * @name:	an optional name to appear in sysfs (leave NULL if none)
 *
 * Registers the component.  The name is optional for enclosures that
 * give their components a unique name.  If not, leave the field NULL
 * and a name will be assigned.
 * The name is optional for enclosures that give their components a unique
 * name.  If not, leave the field NULL and a name will be assigned.
 *
 * Returns a pointer to the enclosure component or an error.
 */
struct enclosure_component *
enclosure_component_register(struct enclosure_device *edev,
enclosure_component_alloc(struct enclosure_device *edev,
			  unsigned int number,
			  enum enclosure_component_type type,
			  const char *name)
{
	struct enclosure_component *ecomp;
	struct device *cdev;
	int err, i;
	int i;
	char newname[COMPONENT_NAME_SIZE];

	if (number >= edev->components)
@@ -327,14 +326,30 @@ enclosure_component_register(struct enclosure_device *edev,
	cdev->release = enclosure_component_release;
	cdev->groups = enclosure_component_groups;

	return ecomp;
}
EXPORT_SYMBOL_GPL(enclosure_component_alloc);

/**
 * enclosure_component_register - publishes an initialized enclosure component
 * @ecomp:	component to add
 *
 * Returns 0 on successful registration, releases the component otherwise
 */
int enclosure_component_register(struct enclosure_component *ecomp)
{
	struct device *cdev;
	int err;

	cdev = &ecomp->cdev;
	err = device_register(cdev);
	if (err) {
		ecomp->number = -1;
		put_device(cdev);
		return ERR_PTR(err);
		return err;
	}

	return ecomp;
	return 0;
}
EXPORT_SYMBOL_GPL(enclosure_component_register);

+14 −7
Original line number Diff line number Diff line
@@ -423,16 +423,23 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
			    type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {

				if (create)
					ecomp =	enclosure_component_register(edev,
					ecomp =	enclosure_component_alloc(
						edev,
						components++,
						type_ptr[0],
						name);
				else
					ecomp = &edev->component[components++];

				if (!IS_ERR(ecomp) && addl_desc_ptr)
					ses_process_descriptor(ecomp,
				if (!IS_ERR(ecomp)) {
					if (addl_desc_ptr)
						ses_process_descriptor(
							ecomp,
							addl_desc_ptr);
					if (create)
						enclosure_component_register(
							ecomp);
				}
			}
			if (desc_ptr)
				desc_ptr += len;
+3 −2
Original line number Diff line number Diff line
@@ -120,8 +120,9 @@ enclosure_register(struct device *, const char *, int,
		   struct enclosure_component_callbacks *);
void enclosure_unregister(struct enclosure_device *);
struct enclosure_component *
enclosure_component_register(struct enclosure_device *, unsigned int,
enclosure_component_alloc(struct enclosure_device *, unsigned int,
			  enum enclosure_component_type, const char *);
int enclosure_component_register(struct enclosure_component *);
int enclosure_add_device(struct enclosure_device *enclosure, int component,
			 struct device *dev);
int enclosure_remove_device(struct enclosure_device *, struct device *);