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>
This commit is contained in:
Brian Rogers 2010-09-22 08:06:43 -03:00 committed by Mauro Carvalho Chehab
parent ddc79e0fdc
commit a08c7c68f7
1 changed files with 11 additions and 6 deletions

View File

@ -67,13 +67,14 @@ static ssize_t show_protocols(struct device *d,
char *tmp = buf; char *tmp = buf;
int i; int i;
if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
enabled = ir_dev->rc_tab.ir_type; enabled = ir_dev->rc_tab.ir_type;
allowed = ir_dev->props->allowed_protos; allowed = ir_dev->props->allowed_protos;
} else { } else if (ir_dev->raw) {
enabled = ir_dev->raw->enabled_protocols; enabled = ir_dev->raw->enabled_protocols;
allowed = ir_raw_get_allowed_protocols(); allowed = ir_raw_get_allowed_protocols();
} } else
return sprintf(tmp, "[builtin]\n");
IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
(long long)allowed, (long long)allowed,
@ -121,10 +122,14 @@ static ssize_t store_protocols(struct device *d,
int rc, i, count = 0; int rc, i, count = 0;
unsigned long flags; unsigned long flags;
if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
type = ir_dev->rc_tab.ir_type; type = ir_dev->rc_tab.ir_type;
else else if (ir_dev->raw)
type = ir_dev->raw->enabled_protocols; type = ir_dev->raw->enabled_protocols;
else {
IR_dprintk(1, "Protocol switching not supported\n");
return -EINVAL;
}
while ((tmp = strsep((char **) &data, " \n")) != NULL) { while ((tmp = strsep((char **) &data, " \n")) != NULL) {
if (!*tmp) if (!*tmp)
@ -185,7 +190,7 @@ static ssize_t store_protocols(struct device *d,
} }
} }
if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
ir_dev->rc_tab.ir_type = type; ir_dev->rc_tab.ir_type = type;
spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);