Issue 1:
After modifying the value of the indices attribute of a csr_matrix, several operations on the matrix produce segfaults. However, other sparse matrix types (lil_matrix and coo_matrix) do not. Therefore, I suspect this is because CSR matrix compresses the row indices.

I have not come across any legitimate use case for modifying indices directly. Although I have not dug into the source code, perhaps the easiest fix would be to make indices read-only from outside the _cs_matrix class.

I would be happy to open a PR if needed.

Reproducing code example:

from scipy.sparse import csr_matrix
import numpy as np

a = csr_matrix(np.arange(16).reshape((4, 4)))
b = csr_matrix(np.eye(4))

a.indices = [0] # This should not be allowed

# Each of these lines run individually produce segfaults

# print(a.toarray())
# print(np.sum(a))
# print(a @ b)

Note that this is not an exhaustive list of operations. There are likely other operations which segfault as well.

Error message:

This is the backtrace for the first line that segfaults (print(a.toarray()))

#0 0x00007fffe7a9373c in ?? ()
from /home/anag004/.local/lib/python3.6/site-packages/scipy/sparse/_sparsetools.cpython-36m-x86_64-linux-gnu.so
#1 0x00007fffe7a7e77e in ?? ()
from /home/anag004/.local/lib/python3.6/site-packages/scipy/sparse/_sparsetools.cpython-36m-x86_64-linux-gnu.so
#2 0x000000000050a2bf in ?? ()
#3 0x000000000050bfb4 in _PyEval_EvalFrameDefault ()
#4 0x0000000000507d64 in ?? ()
#5 0x0000000000509a90 in ?? ()
#6 0x000000000050a48d in ?? ()
#7 0x000000000050bfb4 in _PyEval_EvalFrameDefault ()
#8 0x0000000000507d64 in ?? ()
#9 0x000000000050ae13 in PyEval_EvalCode ()
#10 0x0000000000634c82 in ?? ()
#11 0x0000000000634d37 in PyRun_FileExFlags ()
#12 0x00000000006384ef in PyRun_SimpleFileExFlags ()
#13 0x0000000000639091 in Py_Main ()
#14 0x00000000004b0d00 in main ()

Scipy/Numpy/Python version information:

1.4.1 1.18.4 sys.version_info(major=3, minor=6, micro=9, releaselevel='final', serial=0)

Issue 2:
A csr_matrix can be constructed with malformed data (column indices that are out of bounds) without crashing. This can lead to later segfaults when (I guess) out of bounds memory is accessed. In my application, it didn't crash 100% of the time, but was more random, as is common with out-of-bounds memory accesses. I would expect the construction of the csr_matrix to fail, or at least the documentation should reflect that this can lead to undefined behavior if your parameters is incorrect.

Reproducing code example:

from scipy.sparse import csr_matrix

data = [1.0, 1.0]
indices = [1001, 555]
indptr = [0, 1, 2]
shape = (2, 1000)

mat = csr_matrix((data, indices, indptr), shape=shape)
print "constructed csr_matrix"
print mat * mat.T

The matrix has a width of 1000, but the column indices list places something in column 1001, which is out of bounds. The seg fault occurs on the print mat * mat.T line, not the construction of the matrix with the malformed parameters.

Error message:

$ python test.py
constructed csr_matrix
Segmentation fault (core dumped)

Scipy/Numpy/Python version information:

('1.0.0', '1.14.0', sys.version_info(major=2, minor=7, micro=6, releaselevel='final', serial=0))

I'm running on Ubuntu 14.04 on a 64-bit x86 processor.