diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2007-08-14 09:15:12 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:51:01 -0400 |
commit | 7eff2e7a8b65c25920207324e56611150eb1cd9a (patch) | |
tree | 02a0eeba9d25d996233e30c18f258dfae0ae2139 /drivers/input | |
parent | 8380770c842faef3001e44662953d64ad9a93663 (diff) |
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>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/input.c | 62 | ||||
-rw-r--r-- | drivers/input/serio/serio.c | 11 |
2 files changed, 23 insertions, 50 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 5fe755586623..5dc361c954e2 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -859,87 +859,66 @@ static void input_dev_release(struct device *device) | |||
859 | * Input uevent interface - loading event handlers based on | 859 | * Input uevent interface - loading event handlers based on |
860 | * device bitfields. | 860 | * device bitfields. |
861 | */ | 861 | */ |
862 | static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, | 862 | static int input_add_uevent_bm_var(struct kobj_uevent_env *env, |
863 | char *buffer, int buffer_size, int *cur_len, | ||
864 | const char *name, unsigned long *bitmap, int max) | 863 | const char *name, unsigned long *bitmap, int max) |
865 | { | 864 | { |
866 | if (*cur_index >= num_envp - 1) | 865 | int len; |
867 | return -ENOMEM; | ||
868 | |||
869 | envp[*cur_index] = buffer + *cur_len; | ||
870 | 866 | ||
871 | *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name); | 867 | if (add_uevent_var(env, "%s=", name)) |
872 | if (*cur_len >= buffer_size) | ||
873 | return -ENOMEM; | 868 | return -ENOMEM; |
874 | 869 | ||
875 | *cur_len += input_print_bitmap(buffer + *cur_len, | 870 | len = input_print_bitmap(&env->buf[env->buflen - 1], |
876 | max(buffer_size - *cur_len, 0), | 871 | sizeof(env->buf) - env->buflen, |
877 | bitmap, max, 0) + 1; | 872 | bitmap, max, 0); |
878 | if (*cur_len > buffer_size) | 873 | if (len >= (sizeof(env->buf) - env->buflen)) |
879 | return -ENOMEM; | 874 | return -ENOMEM; |
880 | 875 | ||
881 | (*cur_index)++; | 876 | env->buflen += len; |
882 | return 0; | 877 | return 0; |
883 | } | 878 | } |
884 | 879 | ||
885 | static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_index, | 880 | static int input_add_uevent_modalias_var(struct kobj_uevent_env *env, |
886 | char *buffer, int buffer_size, int *cur_len, | ||
887 | struct input_dev *dev) | 881 | struct input_dev *dev) |
888 | { | 882 | { |
889 | if (*cur_index >= num_envp - 1) | 883 | int len; |
890 | return -ENOMEM; | ||
891 | |||
892 | envp[*cur_index] = buffer + *cur_len; | ||
893 | 884 | ||
894 | *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), | 885 | if (add_uevent_var(env, "MODALIAS=")) |
895 | "MODALIAS="); | ||
896 | if (*cur_len >= buffer_size) | ||
897 | return -ENOMEM; | 886 | return -ENOMEM; |
898 | 887 | ||
899 | *cur_len += input_print_modalias(buffer + *cur_len, | 888 | len = input_print_modalias(&env->buf[env->buflen - 1], |
900 | max(buffer_size - *cur_len, 0), | 889 | sizeof(env->buf) - env->buflen, |
901 | dev, 0) + 1; | 890 | dev, 0); |
902 | if (*cur_len > buffer_size) | 891 | if (len >= (sizeof(env->buf) - env->buflen)) |
903 | return -ENOMEM; | 892 | return -ENOMEM; |
904 | 893 | ||
905 | (*cur_index)++; | 894 | env->buflen += len; |
906 | return 0; | 895 | return 0; |
907 | } | 896 | } |
908 | 897 | ||
909 | #define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ | 898 | #define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ |
910 | do { \ | 899 | do { \ |
911 | int err = add_uevent_var(envp, num_envp, &i, \ | 900 | int err = add_uevent_var(env, fmt, val); \ |
912 | buffer, buffer_size, &len, \ | ||
913 | fmt, val); \ | ||
914 | if (err) \ | 901 | if (err) \ |
915 | return err; \ | 902 | return err; \ |
916 | } while (0) | 903 | } while (0) |
917 | 904 | ||
918 | #define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \ | 905 | #define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \ |
919 | do { \ | 906 | do { \ |
920 | int err = input_add_uevent_bm_var(envp, num_envp, &i, \ | 907 | int err = input_add_uevent_bm_var(env, name, bm, max); \ |
921 | buffer, buffer_size, &len, \ | ||
922 | name, bm, max); \ | ||
923 | if (err) \ | 908 | if (err) \ |
924 | return err; \ | 909 | return err; \ |
925 | } while (0) | 910 | } while (0) |
926 | 911 | ||
927 | #define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \ | 912 | #define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \ |
928 | do { \ | 913 | do { \ |
929 | int err = input_add_uevent_modalias_var(envp, \ | 914 | int err = input_add_uevent_modalias_var(env, dev); \ |
930 | num_envp, &i, \ | ||
931 | buffer, buffer_size, &len, \ | ||
932 | dev); \ | ||
933 | if (err) \ | 915 | if (err) \ |
934 | return err; \ | 916 | return err; \ |
935 | } while (0) | 917 | } while (0) |
936 | 918 | ||
937 | static int input_dev_uevent(struct device *device, char **envp, | 919 | static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env) |
938 | int num_envp, char *buffer, int buffer_size) | ||
939 | { | 920 | { |
940 | struct input_dev *dev = to_input_dev(device); | 921 | struct input_dev *dev = to_input_dev(device); |
941 | int i = 0; | ||
942 | int len = 0; | ||
943 | 922 | ||
944 | INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x", | 923 | INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x", |
945 | dev->id.bustype, dev->id.vendor, | 924 | dev->id.bustype, dev->id.vendor, |
@@ -971,7 +950,6 @@ static int input_dev_uevent(struct device *device, char **envp, | |||
971 | 950 | ||
972 | INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev); | 951 | INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev); |
973 | 952 | ||
974 | envp[i] = NULL; | ||
975 | return 0; | 953 | return 0; |
976 | } | 954 | } |
977 | 955 | ||
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 372ca4931194..b3bc15acd3f5 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -876,18 +876,14 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv) | |||
876 | 876 | ||
877 | #define SERIO_ADD_UEVENT_VAR(fmt, val...) \ | 877 | #define SERIO_ADD_UEVENT_VAR(fmt, val...) \ |
878 | do { \ | 878 | do { \ |
879 | int err = add_uevent_var(envp, num_envp, &i, \ | 879 | int err = add_uevent_var(env, fmt, val); \ |
880 | buffer, buffer_size, &len, \ | ||
881 | fmt, val); \ | ||
882 | if (err) \ | 880 | if (err) \ |
883 | return err; \ | 881 | return err; \ |
884 | } while (0) | 882 | } while (0) |
885 | 883 | ||
886 | static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) | 884 | static int serio_uevent(struct device *dev, struct kobj_uevent_env *env) |
887 | { | 885 | { |
888 | struct serio *serio; | 886 | struct serio *serio; |
889 | int i = 0; | ||
890 | int len = 0; | ||
891 | 887 | ||
892 | if (!dev) | 888 | if (!dev) |
893 | return -ENODEV; | 889 | return -ENODEV; |
@@ -900,7 +896,6 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf | |||
900 | SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); | 896 | SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); |
901 | SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", | 897 | SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", |
902 | serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); | 898 | serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); |
903 | envp[i] = NULL; | ||
904 | 899 | ||
905 | return 0; | 900 | return 0; |
906 | } | 901 | } |
@@ -908,7 +903,7 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf | |||
908 | 903 | ||
909 | #else | 904 | #else |
910 | 905 | ||
911 | static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) | 906 | static int serio_uevent(struct device *dev, struct kobj_uevent_env *env) |
912 | { | 907 | { |
913 | return -ENODEV; | 908 | return -ENODEV; |
914 | } | 909 | } |