Skip to content

Commit 9512229

Browse files
warped-rudijnettlet
authored andcommitted
MXC-CEC: Fix message length while keeping compatibility with old client libs
The maximum CEC message length is 16, not 17 as defined before. However, since this number has been made visible to userland, ensure that older clients that specify slightly more than 16 bytes will not be rejected. Signed-off-by: Rudi <[email protected]>
1 parent 8a4c7b9 commit 9512229

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

drivers/mxc/hdmi-cec/mxc_hdmi-cec.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
#include "mxc_hdmi-cec.h"
4848

4949

50-
#define MAX_MESSAGE_LEN 17
50+
#define MAX_MESSAGE_LEN 16
5151

5252
#define MESSAGE_TYPE_RECEIVE_SUCCESS 1
5353
#define MESSAGE_TYPE_NOACK 2
@@ -92,6 +92,7 @@ struct hdmi_cec_event {
9292
int event_type;
9393
int msg_len;
9494
u8 msg[MAX_MESSAGE_LEN];
95+
u8 padding[4]; /* compatibility with old userland */
9596
struct list_head list;
9697
};
9798

@@ -342,15 +343,21 @@ static int hdmi_cec_open(struct inode *inode, struct file *file)
342343
static ssize_t hdmi_cec_read(struct file *file, char __user *buf, size_t count,
343344
loff_t *ppos)
344345
{
345-
ssize_t len;
346+
ssize_t len = 0;
346347
struct hdmi_cec_event *event;
347348

348349
pr_debug("function : %s\n", __func__);
349350

350351
mutex_lock(&hdmi_cec_data.lock);
351-
if (!hdmi_cec_data.is_started) {
352+
353+
if (!hdmi_cec_data.is_started)
354+
len = -EACCES;
355+
else if (count < offsetof(struct hdmi_cec_event, padding))
356+
len = -EINVAL;
357+
358+
if (len < 0) {
352359
mutex_unlock(&hdmi_cec_data.lock);
353-
return -EACCES;
360+
return len;
354361
}
355362

356363
if (list_empty(&ev_pending)) {
@@ -367,7 +374,8 @@ static ssize_t hdmi_cec_read(struct file *file, char __user *buf, size_t count,
367374
} while (list_empty(&ev_pending));
368375
}
369376

370-
len = offsetof(struct hdmi_cec_event, list);
377+
/* Hack: older versions of libcec attempt to read more bytes than we provide */
378+
len = min(count, offsetof(struct hdmi_cec_event, list));
371379
event = list_first_entry(&ev_pending, struct hdmi_cec_event, list);
372380
if (copy_to_user(buf, event, len))
373381
len = -EFAULT;

0 commit comments

Comments
 (0)