github / github/codeql

Python: Why global dataflow not tracking `endpoints` in function `Service.start()`?

Aperta
#17,019 5 commenti 0 reazioni 0 assegnatari Vedi su GitHub
question
Lingua principale
CodeQL
Stelle
10.1k
Fork
2.1k
Merge medio
2g 15h
PR unite (30g)
141

Descrizione

## Python code from openstack
```python
from neutron_lib._i18n import _
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging
from oslo_messaging import serializer as om_serializer
from oslo_service import service

LOG = logging.getLogger(__name__)
TRANSPORT = None

class RequestContextSerializer(om_serializer.Serializer):
def __init__(self, base=None):
pass

pass

def get_server(target, endpoints, serializer=None):
"""Get a new RPC server reference.

:param target: The target for the new RPC server.
:param endpoints: The endpoints for the RPC server.
:param serializer: The optional serialize to use for the RPC server.
:returns: A new RPC server reference.
"""
if TRANSPORT is None:
raise AssertionError(_("'TRANSPORT' must not be None"))
serializer = RequestContextSerializer(serializer)
return oslo_messaging.get_rpc_server(TRANSPORT, target, endpoints,
'eventlet', serializer)

class Service(service.Service):
"""Service object for binaries running on hosts.

A service enables rpc by listening to queues based on topic and host.
"""
def __init__(self, host, topic, manager=None, serializer=None):
super().__init__()
self.host = host
self.topic = topic
self.serializer = serializer
if manager is None:
self.manager = self
else:
self.manager = manager

def start(self):
super().start()

self.conn = Connection()
LOG.debug("Creating Consumer connection for Service %s",
self.topic)

endpoints = [self.manager]

self.conn.create_consumer(self.topic, endpoints)

# Hook to allow the manager to do other initializations after
# the rpc connection is created.
if callable(getattr(self.manager, 'initialize_service_hook', None)):
self.manager.initialize_service_hook(self)

# Consume from all consumers in threads
self.conn.consume_in_threads()

def stop(self):
# Try to shut the connection down, but if we get any sort of
# errors, go ahead and ignore them.. as we're shutting down anyway
try:
self.conn.close()
except Exception: # nosec
pass
super().stop()

class Connection(object):
"""A utility class that manages a collection of RPC servers."""

def __init__(self):
super().__init__()
self.servers = []

def create_consumer(self, topic, endpoints, fanout=False):
target = oslo_messaging.Target(
topic=topic, server=cfg.CONF.host, fanout=fanout)
server = get_server(target, endpoints)
self.servers.append(server)

def consume_in_threads(self):
for server in self.servers:
server.start()
return self.servers

def close(self):
for server in self.servers:
server.stop()
for server in self.servers:
server.wait()
```
## CodeQL
```codeql
import python
import semmle.python.ApiGraphs
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking

module MyConf implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr().isConstant() or
source.asExpr() instanceof Name or
source.asExpr() instanceof Attribute
}
predicate isSink(DataFlow::Node sink) {
sink = API::moduleImport("oslo_messaging").getMember("get_rpc_server").getACall().getArg(2)
}
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo){
nodeTo.asCfgNode().(IterableNode).getAnElement() = nodeFrom.asCfgNode()
}
}

module MyFlow = DataFlow::Global;

from DataFlow::Node source, DataFlow::Node sink
where MyFlow::flow(source, sink)
select source, sink
```
## Output
|source|sink|
|-|-|
|`endpoints` in line 19|`endpoints` in line 30|
|`endpoints` in line 30|`endpoints` in line 30|
|`endpoints` in line 84|`endpoints` in line 30|
|`endpoints` in line 87|`endpoints` in line 30|

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia riproducendo lo snippet Python e la query CodeQL mostrati, quindi ispeziona MyConf.isAdditionalFlowStep e i risultati del flusso DataFlow::Global per le sorgenti degli endpoint e il sink elencati. Confronta i percorsi segnalati con il flusso previsto degli elementi iterabili e documenta se l’output è quello previsto o identifica un difetto nella modellazione del flusso di dati.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
security
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Da chiarire
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.