]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
dvb network: fix possible wrong memory access in dvb_network_get_orbital_pos()
authorJaroslav Kysela <perex@perex.cz>
Wed, 4 Nov 2015 16:36:25 +0000 (17:36 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 4 Nov 2015 16:36:25 +0000 (17:36 +0100)
src/input/mpegts/mpegts_dvb.h
src/input/mpegts/mpegts_network_dvb.c
src/input/mpegts/mpegts_service.c

index a780a07309ea3707c800f96c50cdfa0bcffcdaf6..3362fe9b2716dd4571f8df74888b6953fcdaf987 100644 (file)
@@ -52,6 +52,7 @@ extern const idclass_t dvb_network_atsc_class;
 
 void dvb_network_init ( void );
 void dvb_network_done ( void );
+
 static inline dvb_network_t *dvb_network_find_by_uuid(const char *uuid)
   { return idnode_find(uuid, &dvb_network_class, NULL); }
 
@@ -61,6 +62,7 @@ dvb_network_t *dvb_network_create0
 dvb_mux_t *dvb_network_find_mux
   ( dvb_network_t *ln, dvb_mux_conf_t *dmc, uint16_t onid, uint16_t tsid );
 
+const idclass_t *dvb_network_mux_class(mpegts_network_t *mn);
 int dvb_network_get_orbital_pos(mpegts_network_t *mn);
 
 /*
index 8cd4e3f62d462d34afecc5a1f93db5471a9c35de..0902c9c4c7aa4030ba3030440616d9bde5adbd7f 100644 (file)
@@ -398,7 +398,7 @@ dvb_network_config_save ( mpegts_network_t *mn )
   htsmsg_destroy(c);
 }
 
-static const idclass_t *
+const idclass_t *
 dvb_network_mux_class
   ( mpegts_network_t *mn )
 {
@@ -449,6 +449,7 @@ dvb_network_create_mux
     satpos = dvb_network_get_orbital_pos(mn);
     if (dvb_network_check_orbital_pos(satpos, dmc->u.dmc_fe_qpsk.orbital_pos)) {
       LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) {
+        if (!idnode_is_instance(&mn->mn_id, &dvb_network_dvbs_class)) continue;
         satpos = dvb_network_get_orbital_pos(mn);
         if (satpos == INT_MAX) continue;
         if (!dvb_network_check_orbital_pos(satpos, dmc->u.dmc_fe_qpsk.orbital_pos))
@@ -724,6 +725,12 @@ int dvb_network_get_orbital_pos(mpegts_network_t *mn)
 
   if (!ln)
     return INT_MAX;
+  if (tvhtrace_enabled()) {
+    if (!idnode_is_instance(&mn->mn_id, &dvb_network_dvbs_class)) {
+      tvhinfo("mpegts", "wrong dvb_network_get_orbital_pos() call");
+      return INT_MAX;
+    }
+  }
   if (ln->mn_satpos != INT_MAX)
     return ln->mn_satpos;
   LIST_FOREACH(mm, &ln->mn_muxes, mm_network_link) {
index 7674968f3534f62d8f4e0c0b8bc0c82117b058a1..10469c4b64a05eaef8673251643a5ef90771a670 100644 (file)
@@ -547,17 +547,12 @@ mpegts_service_channel_icon ( service_t *s )
 
 #if ENABLE_MPEGTS_DVB
 static int
-mpegts_service_match_network(mpegts_network_t *mn, uint32_t hash, const idclass_t **idc)
+mpegts_service_match_network(mpegts_network_t *mn, uint32_t hash, const idclass_t *idc)
 {
-  int pos = hash >> 16, pos2;
+  int pos, pos2;
 
+  if (idc != &dvb_mux_dvbs_class) return 1;
   pos = hash >> 16;
-  switch (pos) {
-  case 0xFFFF: *idc = &dvb_mux_dvbc_class; return 1;
-  case 0xEEEE: *idc = &dvb_mux_dvbt_class; return 1;
-  case 0xDDDD: *idc = &dvb_mux_dvbt_class; return 1;
-  default:     *idc = &dvb_mux_dvbs_class; break;
-  }
   if (pos > 3600 || pos < 0) return 0;
   pos = pos <= 1800 ? pos : pos - 3600;
   if ((pos2 = dvb_network_get_orbital_pos(mn)) == INT_MAX) return 0;
@@ -595,9 +590,16 @@ mpegts_service_find_e2(uint32_t stype, uint32_t sid, uint32_t tsid,
 
   lock_assert(&global_lock);
 
+  switch (hash & 0xFFFF0000) {
+  case 0xFFFF0000: idc = &dvb_mux_dvbc_class; break;
+  case 0xEEEE0000: idc = &dvb_mux_dvbt_class; break;
+  case 0xDDDD0000: idc = &dvb_mux_dvbt_class; break;
+  default:         idc = &dvb_mux_dvbs_class; break;
+  }
   LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) {
     if (!idnode_is_instance(&mn->mn_id, &dvb_network_class)) continue;
-    if (!mpegts_service_match_network(mn, hash, &idc)) continue;
+    if (dvb_network_mux_class(mn) != idc) continue;
+    if (!mpegts_service_match_network(mn, hash, idc)) continue;
     LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) {
       if (!idnode_is_instance(&mm->mm_id, idc)) continue;
       if (mm->mm_tsid != tsid || mm->mm_onid != onid) continue;