Driver core: change add_uevent_var to use a struct
This changes the uevent buffer functions to use a struct instead of a long list of parameters. It does no longer require the caller to do the proper buffer termination and size accounting, which is currently wrong in some places. It fixes a known bug where parts of the uevent environment are overwritten because of wrong index calculations. Many thanks to Mathieu Desnoyers for finding bugs and improving the error handling. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Cc: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
8380770c84
commit
7eff2e7a8b
@@ -66,8 +66,7 @@ struct bus_type {
|
||||
struct driver_attribute * drv_attrs;
|
||||
|
||||
int (*match)(struct device * dev, struct device_driver * drv);
|
||||
int (*uevent)(struct device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size);
|
||||
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
int (*probe)(struct device * dev);
|
||||
int (*remove)(struct device * dev);
|
||||
void (*shutdown)(struct device * dev);
|
||||
@@ -187,10 +186,8 @@ struct class {
|
||||
struct class_device_attribute * class_dev_attrs;
|
||||
struct device_attribute * dev_attrs;
|
||||
|
||||
int (*uevent)(struct class_device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size);
|
||||
int (*dev_uevent)(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size);
|
||||
int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);
|
||||
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
|
||||
void (*release)(struct class_device *dev);
|
||||
void (*class_release)(struct class *class);
|
||||
@@ -266,8 +263,7 @@ struct class_device {
|
||||
struct attribute_group ** groups; /* optional groups */
|
||||
|
||||
void (*release)(struct class_device *dev);
|
||||
int (*uevent)(struct class_device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size);
|
||||
int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);
|
||||
char class_id[BUS_ID_SIZE]; /* unique to this class */
|
||||
};
|
||||
|
||||
@@ -335,8 +331,7 @@ extern void class_device_destroy(struct class *cls, dev_t devt);
|
||||
struct device_type {
|
||||
const char *name;
|
||||
struct attribute_group **groups;
|
||||
int (*uevent)(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size);
|
||||
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
||||
void (*release)(struct device *dev);
|
||||
int (*suspend)(struct device * dev, pm_message_t state);
|
||||
int (*resume)(struct device * dev);
|
||||
|
@@ -29,6 +29,8 @@
|
||||
|
||||
#define KOBJ_NAME_LEN 20
|
||||
#define UEVENT_HELPER_PATH_LEN 256
|
||||
#define UEVENT_NUM_ENVP 32 /* number of env pointers */
|
||||
#define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */
|
||||
|
||||
/* path to the userspace helper executed on an event */
|
||||
extern char uevent_helper[];
|
||||
@@ -111,11 +113,18 @@ struct kobj_type {
|
||||
struct attribute ** default_attrs;
|
||||
};
|
||||
|
||||
struct kobj_uevent_env {
|
||||
char *envp[UEVENT_NUM_ENVP];
|
||||
int envp_idx;
|
||||
char buf[UEVENT_BUFFER_SIZE];
|
||||
int buflen;
|
||||
};
|
||||
|
||||
struct kset_uevent_ops {
|
||||
int (*filter)(struct kset *kset, struct kobject *kobj);
|
||||
const char *(*name)(struct kset *kset, struct kobject *kobj);
|
||||
int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size);
|
||||
int (*uevent)(struct kset *kset, struct kobject *kobj,
|
||||
struct kobj_uevent_env *env);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -275,10 +284,8 @@ int kobject_uevent(struct kobject *kobj, enum kobject_action action);
|
||||
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
||||
char *envp[]);
|
||||
|
||||
int add_uevent_var(char **envp, int num_envp, int *cur_index,
|
||||
char *buffer, int buffer_size, int *cur_len,
|
||||
const char *format, ...)
|
||||
__attribute__((format (printf, 7, 8)));
|
||||
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
#else
|
||||
static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action)
|
||||
{ return 0; }
|
||||
@@ -287,9 +294,7 @@ static inline int kobject_uevent_env(struct kobject *kobj,
|
||||
char *envp[])
|
||||
{ return 0; }
|
||||
|
||||
static inline int add_uevent_var(char **envp, int num_envp, int *cur_index,
|
||||
char *buffer, int buffer_size, int *cur_len,
|
||||
const char *format, ...)
|
||||
static inline int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user