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
@@ -57,26 +57,21 @@ ssize_t of_device_get_modalias(struct of_device *ofdev,
|
||||
return tsize;
|
||||
}
|
||||
|
||||
int of_device_uevent(struct device *dev,
|
||||
char **envp, int num_envp, char *buffer, int buffer_size)
|
||||
int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
const char *compat;
|
||||
int i = 0, length = 0, seen = 0, cplen, sl;
|
||||
int seen = 0, cplen, sl;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_NAME=%s", ofdev->node->name))
|
||||
if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_TYPE=%s", ofdev->node->type))
|
||||
if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Since the compatible field can contain pretty much anything
|
||||
@@ -85,9 +80,7 @@ int of_device_uevent(struct device *dev,
|
||||
|
||||
compat = of_get_property(ofdev->node, "compatible", &cplen);
|
||||
while (compat && *compat && cplen > 0) {
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_COMPATIBLE_%d=%s", seen, compat))
|
||||
if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
|
||||
return -ENOMEM;
|
||||
|
||||
sl = strlen (compat) + 1;
|
||||
@@ -96,25 +89,17 @@ int of_device_uevent(struct device *dev,
|
||||
seen++;
|
||||
}
|
||||
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"OF_COMPATIBLE_N=%d", seen))
|
||||
if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
|
||||
return -ENOMEM;
|
||||
|
||||
/* modalias is trickier, we add it in 2 steps */
|
||||
if (add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"MODALIAS="))
|
||||
if (add_uevent_var(env, "MODALIAS="))
|
||||
return -ENOMEM;
|
||||
|
||||
sl = of_device_get_modalias(ofdev, &buffer[length-1],
|
||||
buffer_size-length);
|
||||
if (sl >= (buffer_size-length))
|
||||
sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
|
||||
sizeof(env->buf) - env->buflen);
|
||||
if (sl >= (sizeof(env->buf) - env->buflen))
|
||||
return -ENOMEM;
|
||||
|
||||
length += sl;
|
||||
|
||||
envp[i] = NULL;
|
||||
env->buflen += sl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user