Numpy: Dados inválidos e segfault ao ler além do tamanho do arquivo com fromfile no Ubuntu 16.04

Criado em 31 out. 2018  ·  4Comentários  ·  Fonte: numpy/numpy


fromfile dados inválidos e às vezes falha de segurança se a leitura ultrapassar o final de um arquivo, ou seja, não verifica se a leitura irá além do final do arquivo. Esse problema leva a um segfault no Ubuntu 16.04, mas parece não ter um segfault no OSX.

Reproduzindo exemplo de código:

import numpy as np

def test_read_from_file():
    # create an empty file named `empty.bin`
    filename = 'empty.bin'
    open(filename, 'a').close()

    # read large chunk of data, past the end of the file
    dtype = [('data', '<f4', 500,)]
    count = 100000000

    with open(filename, 'rb') as fh:
        data = np.fromfile(fh, dtype, count)

    print(data.shape)

Mensagem de erro:


Processo concluído com o código de saída 139 (interrompido pelo sinal 11: SIGSEGV)

Informações sobre a versão Numpy / Python:

plataforma linux - Python 3.6.6, pytest-3.8.2, py-1.6.0, pluggy-0.7.1

00 - Bug numpy.core

Comentários muito úteis

Eu acredito que o problema aqui é que no ubuntu você está recebendo um MemoryError que está sendo manuseado incorretamente e causando o segfault.

Um PR com uma correção está aqui: https://github.com/numpy/numpy/pull/12354

Todos 4 comentários

Apenas para observar, reproduzível em 1.15.3. Acho que sabemos o tamanho, então isso deve apenas gerar um erro ou ler o arquivo inteiro. Se isso funcionar silenciosamente em alguns sistemas, talvez devêssemos colocar uma nota de lançamento para o caso (eu ainda diria que podemos apenas corrigi-lo).

EDIT: Eu tenderia a errar, só pensei que o arquivo inteiro pode ser uma opção por causa da indexação, mas a indexação é um pouco especial a esse respeito.

Concordo, apontar um erro parece uma boa ideia. Ainda há algo a ser dito sobre leituras parciais, que podem ser tratadas de duas maneiras:

  1. leia tantos registros de dados quanto possível até o final do arquivo ou o count em fromfile seja alcançado, mas então precisamos de um mecanismo para retornar explicitamente o número real de registros que foram lidos (implicitamente isso deve ser visível na forma da matriz resultante). Um erro ainda pode ser gerado porque não é o cenário de uso normal.
  2. não permite leituras parciais, ou seja, aumente se o tamanho a ser lido não couber no resto do arquivo.

Não sei quais cenários se encaixam melhor com a filosofia entorpecida, mas a primeira opção parece mais útil.

Acho que um erro é muito razoável. O que eu não tenho certeza agora é se fromfile suporta arquivos como objetos que não têm um tamanho conhecido, ou o que acontece atualmente no caso de sep kwarg não vazio.

@amuresan o código para fromfile está em C, mas se você tiver um pouco de tempo, ficaremos sempre muito felizes com as solicitações pull e parece uma dificuldade razoável mergulhar um pouco na API C (Python).

Eu acredito que o problema aqui é que no ubuntu você está recebendo um MemoryError que está sendo manuseado incorretamente e causando o segfault.

Um PR com uma correção está aqui: https://github.com/numpy/numpy/pull/12354

Esta página foi útil?
0 / 5 - 0 avaliações