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: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Song Liu <songliubraving@fb.com> Reviewed-by: Jens Axboe <axboe@fb.com> Cc: Hannes Reinecke <hare@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
acd6d73826
commit
ed09dcc8bd
|
@ -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,
|
||||
unsigned int number,
|
||||
enum enclosure_component_type type,
|
||||
const char *name)
|
||||
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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
components++,
|
||||
type_ptr[0],
|
||||
name);
|
||||
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,
|
||||
addl_desc_ptr);
|
||||
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;
|
||||
|
|
|
@ -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,
|
||||
enum enclosure_component_type, const char *);
|
||||
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 *);
|
||||
|
|
Loading…
Reference in a new issue