diff options
author | Brian Rogers <brian@xyzw.org> | 2010-09-22 07:06:43 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-09-30 06:18:37 -0400 |
commit | a08c7c68f702e2a2797a4035b6c0a756c4886c26 (patch) | |
tree | 4761de745c2260d5832241f82d41d9985e79addb /drivers/media/IR/ir-sysfs.c | |
parent | ddc79e0fdc16c05c3ff7f9b6ae9052bda0506108 (diff) |
V4L/DVB: ir-core: Fix null dereferences in the protocols sysfs interface
For some cards, ir_dev->props and ir_dev->raw are both NULL. These cards are
using built-in IR decoding instead of raw, and can't easily be made to switch
protocols.
So upon reading /sys/class/rc/rc?/protocols on such a card, return 'builtin' as
the supported and enabled protocol. Return -EINVAL on any attempts to change
the protocol. And most important of all, don't crash.
Signed-off-by: Brian Rogers <brian@xyzw.org>
Acked-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/IR/ir-sysfs.c')
-rw-r--r-- | drivers/media/IR/ir-sysfs.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index 96dafc425c8e..46d42467f9b4 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c | |||
@@ -67,13 +67,14 @@ static ssize_t show_protocols(struct device *d, | |||
67 | char *tmp = buf; | 67 | char *tmp = buf; |
68 | int i; | 68 | int i; |
69 | 69 | ||
70 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { | 70 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { |
71 | enabled = ir_dev->rc_tab.ir_type; | 71 | enabled = ir_dev->rc_tab.ir_type; |
72 | allowed = ir_dev->props->allowed_protos; | 72 | allowed = ir_dev->props->allowed_protos; |
73 | } else { | 73 | } else if (ir_dev->raw) { |
74 | enabled = ir_dev->raw->enabled_protocols; | 74 | enabled = ir_dev->raw->enabled_protocols; |
75 | allowed = ir_raw_get_allowed_protocols(); | 75 | allowed = ir_raw_get_allowed_protocols(); |
76 | } | 76 | } else |
77 | return sprintf(tmp, "[builtin]\n"); | ||
77 | 78 | ||
78 | IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", | 79 | IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", |
79 | (long long)allowed, | 80 | (long long)allowed, |
@@ -121,10 +122,14 @@ static ssize_t store_protocols(struct device *d, | |||
121 | int rc, i, count = 0; | 122 | int rc, i, count = 0; |
122 | unsigned long flags; | 123 | unsigned long flags; |
123 | 124 | ||
124 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) | 125 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) |
125 | type = ir_dev->rc_tab.ir_type; | 126 | type = ir_dev->rc_tab.ir_type; |
126 | else | 127 | else if (ir_dev->raw) |
127 | type = ir_dev->raw->enabled_protocols; | 128 | type = ir_dev->raw->enabled_protocols; |
129 | else { | ||
130 | IR_dprintk(1, "Protocol switching not supported\n"); | ||
131 | return -EINVAL; | ||
132 | } | ||
128 | 133 | ||
129 | while ((tmp = strsep((char **) &data, " \n")) != NULL) { | 134 | while ((tmp = strsep((char **) &data, " \n")) != NULL) { |
130 | if (!*tmp) | 135 | if (!*tmp) |
@@ -185,7 +190,7 @@ static ssize_t store_protocols(struct device *d, | |||
185 | } | 190 | } |
186 | } | 191 | } |
187 | 192 | ||
188 | if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { | 193 | if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { |
189 | spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); | 194 | spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); |
190 | ir_dev->rc_tab.ir_type = type; | 195 | ir_dev->rc_tab.ir_type = type; |
191 | spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); | 196 | spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); |