summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb
diff options
context:
space:
mode:
authorOliver Endriss <o.endriss@gmx.de>2007-07-24 02:00:36 +0200
committerOliver Endriss <o.endriss@gmx.de>2007-07-24 02:00:36 +0200
commit1aae159fd7aa139ede4e5a41d211d6e1fc960159 (patch)
tree38a46a4d7f79c2a799b088847ebd21c3a224ead0 /linux/drivers/media/dvb
parentf3f02f5343b042a516acb67637a00ee26ca06d79 (diff)
downloadmediapointer-dvb-s2-1aae159fd7aa139ede4e5a41d211d6e1fc960159.tar.gz
mediapointer-dvb-s2-1aae159fd7aa139ede4e5a41d211d6e1fc960159.tar.bz2
dvb_frontend: Range check of frequency and symbol rate
From: Oliver Endriss <o.endriss@gmx.de> Add range check of frequency and symbol rate to the FE_SET_FRONTEND ioctl. This will also avoid a divide-by zero exception in the stv0297 driver, if symbol rate is set to 0. Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index 18c4997cf..08e92187d 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -702,6 +702,47 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
return 0;
}
+static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *parms)
+{
+ /* range check: frequency */
+ if ((fe->ops.info.frequency_min &&
+ parms->frequency < fe->ops.info.frequency_min) ||
+ (fe->ops.info.frequency_max &&
+ parms->frequency > fe->ops.info.frequency_max)) {
+ printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n",
+ fe->dvb->num, parms->frequency,
+ fe->ops.info.frequency_min, fe->ops.info.frequency_max);
+ return -EINVAL;
+ }
+
+ /* range check: symbol rate */
+ if (fe->ops.info.type == FE_QPSK) {
+ if ((fe->ops.info.symbol_rate_min &&
+ parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
+ (fe->ops.info.symbol_rate_max &&
+ parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) {
+ printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
+ fe->dvb->num, parms->u.qpsk.symbol_rate,
+ fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
+ return -EINVAL;
+ }
+
+ } else if (fe->ops.info.type == FE_QAM) {
+ if ((fe->ops.info.symbol_rate_min &&
+ parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) ||
+ (fe->ops.info.symbol_rate_max &&
+ parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) {
+ printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
+ fe->dvb->num, parms->u.qam.symbol_rate,
+ fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
@@ -888,6 +929,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
case FE_SET_FRONTEND: {
struct dvb_frontend_tune_settings fetunesettings;
+ if (dvb_frontend_check_parameters(fe, parg) < 0) {
+ err = -EINVAL;
+ break;
+ }
+
memcpy (&fepriv->parameters, parg,
sizeof (struct dvb_frontend_parameters));