diff options
author | Yi Yang <yi.y.yang@intel.com> | 2008-06-14 00:52:06 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2008-07-16 17:27:01 -0400 |
commit | 6594d87ebd8371f4b67f7ab4b68f172b139b78d6 (patch) | |
tree | 324aba7fecae632e08e7b1182e3322423fe6092e /drivers/acpi/fan.c | |
parent | 74523c901342a773ddd9f14c14539ec3d4197ecf (diff) |
ACPI: fix acpi fan state set error
Under /proc/acpi, there is a fan control interface, a user can
set 0 or 3 to /proc/acpi/fan/*/state, 0 denotes D0 state, 3
denotes D3 state, but in current implementation, a user can
set a fan to D1 state by any char excluding '1', '2' and '3'.
For example:
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost acpi]# echo "3" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "xxxxx" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
Obviously, such inputs as "" and "xxxxx" are invalid for fan state.
This patch fixes this issue, it strictly limits fan state only to
accept 0, 1, 2 and 3, any other inputs are invalid.
Before applying this patch, the test result is:
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost acpi]# echo "3" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "xxxxx" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost acpi]# echo "3" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "3x" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost acpi]# echo "-1x" > /proc/acpi/fan/C31B/state
[root@localhost acpi]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost acpi]#
After applying this patch, the test result is:
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "" > /proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "3" > /proc/acpi/fan/C31B/state
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "xxxxx" > /proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "-1x" > /proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "0" > //proc/acpi/fan/C31B/state
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost ~]# echo "4" > //proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost ~]# echo "3" > //proc/acpi/fan/C31B/state
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: off
[root@localhost ~]# echo "0" > //proc/acpi/fan/C31B/state
[root@localhost ~]# cat /proc/acpi/fan/C31B/state
status: on
[root@localhost ~]# echo "3x" > //proc/acpi/fan/C31B/state
-bash: echo: write error: Invalid argument
[root@localhost ~]#
Signed-off-by: Yi Yang <yi.y.yang@intel.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/fan.c')
-rw-r--r-- | drivers/acpi/fan.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 6cf10cbc1eee..55c17afbe669 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -148,7 +148,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer, | |||
148 | int result = 0; | 148 | int result = 0; |
149 | struct seq_file *m = file->private_data; | 149 | struct seq_file *m = file->private_data; |
150 | struct acpi_device *device = m->private; | 150 | struct acpi_device *device = m->private; |
151 | char state_string[12] = { '\0' }; | 151 | char state_string[3] = { '\0' }; |
152 | 152 | ||
153 | if (count > sizeof(state_string) - 1) | 153 | if (count > sizeof(state_string) - 1) |
154 | return -EINVAL; | 154 | return -EINVAL; |
@@ -157,6 +157,12 @@ acpi_fan_write_state(struct file *file, const char __user * buffer, | |||
157 | return -EFAULT; | 157 | return -EFAULT; |
158 | 158 | ||
159 | state_string[count] = '\0'; | 159 | state_string[count] = '\0'; |
160 | if ((state_string[0] < '0') || (state_string[0] > '3')) | ||
161 | return -EINVAL; | ||
162 | if (state_string[1] == '\n') | ||
163 | state_string[1] = '\0'; | ||
164 | if (state_string[1] != '\0') | ||
165 | return -EINVAL; | ||
160 | 166 | ||
161 | result = acpi_bus_set_power(device->handle, | 167 | result = acpi_bus_set_power(device->handle, |
162 | simple_strtoul(state_string, NULL, 0)); | 168 | simple_strtoul(state_string, NULL, 0)); |