diff options
author | Oliver Endriss <o.endriss@gmx.de> | 2007-07-23 20:00:36 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 21:03:28 -0400 |
commit | 1fab46f0decd226fcbae73b23d7f8ed478416fbb (patch) | |
tree | ab0d9d23cffcde41073554092ca42b11aacc7d19 /drivers/media/dvb | |
parent | 36c15f8ee41fbc3d8eaf88bba95be3d50268d5d2 (diff) |
V4L/DVB (5935): dvb_frontend: Range check of frequency and symbol rate
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>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index b6c7f6610ec5..384b5b8959c1 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -697,6 +697,47 @@ static int dvb_frontend_start(struct dvb_frontend *fe) | |||
697 | return 0; | 697 | return 0; |
698 | } | 698 | } |
699 | 699 | ||
700 | static int dvb_frontend_check_parameters(struct dvb_frontend *fe, | ||
701 | struct dvb_frontend_parameters *parms) | ||
702 | { | ||
703 | /* range check: frequency */ | ||
704 | if ((fe->ops.info.frequency_min && | ||
705 | parms->frequency < fe->ops.info.frequency_min) || | ||
706 | (fe->ops.info.frequency_max && | ||
707 | parms->frequency > fe->ops.info.frequency_max)) { | ||
708 | printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n", | ||
709 | fe->dvb->num, parms->frequency, | ||
710 | fe->ops.info.frequency_min, fe->ops.info.frequency_max); | ||
711 | return -EINVAL; | ||
712 | } | ||
713 | |||
714 | /* range check: symbol rate */ | ||
715 | if (fe->ops.info.type == FE_QPSK) { | ||
716 | if ((fe->ops.info.symbol_rate_min && | ||
717 | parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) || | ||
718 | (fe->ops.info.symbol_rate_max && | ||
719 | parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) { | ||
720 | printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", | ||
721 | fe->dvb->num, parms->u.qpsk.symbol_rate, | ||
722 | fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); | ||
723 | return -EINVAL; | ||
724 | } | ||
725 | |||
726 | } else if (fe->ops.info.type == FE_QAM) { | ||
727 | if ((fe->ops.info.symbol_rate_min && | ||
728 | parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) || | ||
729 | (fe->ops.info.symbol_rate_max && | ||
730 | parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) { | ||
731 | printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", | ||
732 | fe->dvb->num, parms->u.qam.symbol_rate, | ||
733 | fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); | ||
734 | return -EINVAL; | ||
735 | } | ||
736 | } | ||
737 | |||
738 | return 0; | ||
739 | } | ||
740 | |||
700 | static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | 741 | static int dvb_frontend_ioctl(struct inode *inode, struct file *file, |
701 | unsigned int cmd, void *parg) | 742 | unsigned int cmd, void *parg) |
702 | { | 743 | { |
@@ -883,6 +924,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
883 | case FE_SET_FRONTEND: { | 924 | case FE_SET_FRONTEND: { |
884 | struct dvb_frontend_tune_settings fetunesettings; | 925 | struct dvb_frontend_tune_settings fetunesettings; |
885 | 926 | ||
927 | if (dvb_frontend_check_parameters(fe, parg) < 0) { | ||
928 | err = -EINVAL; | ||
929 | break; | ||
930 | } | ||
931 | |||
886 | memcpy (&fepriv->parameters, parg, | 932 | memcpy (&fepriv->parameters, parg, |
887 | sizeof (struct dvb_frontend_parameters)); | 933 | sizeof (struct dvb_frontend_parameters)); |
888 | 934 | ||