python / python/cpython

Python pickle `load_reduce` function doesn't check if `args` is a tuple

Aperta
#144,412 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

extension-modules type-bug
Lingua principale
Python
Stelle
77.2k
Fork
35.9k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Bug report

Bug description:

When load_reduce() is called in Python pickle, the args variable is pulled off the stack and passed into the functions using the * operator. This syntax is type-permissive, meaning the type can be any iterable that will return the needed arguments.

https://github.com/python/cpython/blob/29acc08c8dad664cd5713cb392e5beba65724c10/Lib/pickle.py#L1723-L1727

However, in C _pickle, argtup is pulled off the stack and passed into PyObject_CallObject(), which checks if the args parameter is specifically a PyTuple().

https://github.com/python/cpython/blob/29acc08c8dad664cd5713cb392e5beba65724c10/Modules/_pickle.c#L6964

https://github.com/python/cpython/blob/29acc08c8dad664cd5713cb392e5beba65724c10/Objects/call.c#L460-L473

This means that any non-tuple iterator being used as the arguments passed into the function will cause C _pickle to throw an error, but Python pickle deserialization to unfold just fine.

payload:      b'cbuiltins\nprint\n}R.'

pickle:
None
_pickle.c:    FAILURE argument list must be a tuple
pickletools:
    0: c    GLOBAL     'builtins print'
   16: }    EMPTY_DICT
   17: R    REDUCE
   18: .    STOP
highest protocol among opcodes = 1

I think the easiest way to remedy the discrepancy is to explicitly type check the args parameter in pickle.py's load_reduce() function.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs
  • gh-144419

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia da load_reduce() in Lib/pickle.py e confronta la gestione dei suoi argomenti con Modules/_pickle.c e il comportamento di PyObject_CallObject() a cui si fa riferimento in Objects/call.c. Controlla la PR collegata gh-144419 e i test pickle esistenti; il lavoro è completato quando pickle e _pickle di Python gestiscono in modo coerente il caso segnalato di un argomento non tuple.

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

Valutazione

Stack tecnologico
python
Ambito
backend
Tipo di issue
Bug
Difficoltà
2/5
Tempo stimato
1-3 ore
Stato di attività
Ferma
Chiarezza
Specificata chiaramente
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.