Обрезка с LVM и dm-склепом

Одно место для взгляда является Общими Уязвимостями и Воздействием МИТРЫ. Страница результатов поиска здесь. Я сделал поиск на "ядре Linux" и нашел набор, но только один в 2012, который является, когда 3.2 вышел бы, правильно? Я не следую за разработкой Ядра Linux тесно, но мне дают, чтобы понять, что у разработчиков Ядра Linux есть отношение, которое рассматривает большинство "дыр в системе безопасности" как ошибки надежности или что-то как этот.

21
29.09.2013, 11:02
3 ответа

Я предлагаю использовать другой метод тестирования. hdparm является немного странным, поскольку это дает адреса устройства, а не адреса файловой системы, и это не говорит, какого устройства те адреса касаются (например, это разрешает разделы, но не devicemapper цели, и т.д.). Намного легче использовать что-то, что придерживается адресов файловой системы, тот способ, которым это последовательно (возможно, за исключением нетрадиционных файловых систем как zfs/btrfs).

Создайте тестовый файл: (не случайный нарочно)

# yes | dd iflag=fullblock bs=1M count=1 of=trim.test 

Получите адрес, длину и blocksize: (точная команда зависит от filefrag версия)

# filefrag -s -v trim.test
File size of trim.test is 1048576 (256 blocks, blocksize 4096)
 ext logical physical expected length flags
   0       0    34048             256 eof
trim.test: 1 extent found

Получите устройство и точку монтирования:

# df trim.test
/dev/mapper/something  32896880 11722824  20838512   37% /mount/point

С настроенным, у Вас есть файл trim.test заполненный yes- шаблон на /dev/mapper/something в адресе 34048 с длиной 256 блоки 4096 байты.

Чтение, который от устройства непосредственно должен произвести yes- шаблон:

# dd bs=4096 skip=34048 count=256 if=/dev/mapper/something | hexdump -C
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
*
00100000

Если ОБРЕЗКА включена, этот шаблон должен измениться при удалении файла. Обратите внимание, что кэши должны быть отброшены также, иначе dd не перечитает данные из диска.

# rm trim.test
# sync
# fstrim -v /mount/point/ # when not using 'discard' mount option
# echo 1 > /proc/sys/vm/drop_caches
# dd bs=4096 skip=34048 count=256 if=/dev/mapper/something | hexdump -C

На большей части SSD, который привел бы к нулевому шаблону:

00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000

Если шифрование будет включено, то Вы будете видеть случайный шаблон вместо этого:

00000000  1f c9 55 7d 07 15 00 d1  4a 1c 41 1a 43 84 15 c0  |..U}....J.A.C...|
00000010  24 35 37 fe 05 f7 43 93  1e f4 3c cc d8 83 44 ad  |$57...C...<...D.|
00000020  46 80 c2 26 13 06 dc 20  7e 22 e4 94 21 7c 8b 2c  |F..&... ~"..!|.,|

Поэтому физически обрезанный, crypto чтения слоя обнуляют и дешифруют, они обнуляют к "случайным" данным.

Если yes- шаблон сохраняется, скорее всего, никакая обрезка не была сделана.

23
27.01.2020, 19:43
  • 1
    @student: Я плохо себя чувствую для не замечать это ранее, отредактировал ответ для отбрасывания кэшей прежде hexdump. –  frostschutz 29.09.2013, 00:48
  • 2
    Спасибо, который был недостающей точкой. Теперь это, кажется, работает! –  student 29.09.2013, 11:00
  • 3
    я все еще не уверен, не должно ли ядро отбрасывать кэши отдельно каждый раз, когда это обрезает что-то на SSD. Кэши, как предполагается, не возвращают неправильные данные. Это - также отходы на кэш-памяти, если это заняло чем-то, что это больше не там..., о, хорошо. –  frostschutz 29.09.2013, 11:17
  • 4
    @frostschutz Спасибо за это отличное решение. Я сделал сценарий для автоматизации процесса, если некоторый ленивый человек приезжает сюда. –  desgua 29.04.2014, 19:42
  • 5
    , действительно обратите внимание, что команда TRIM будет не всегда "заполнять нулями" блоки сразу же. Посмотрите здесь, здесь и здесь. Хотя это должно, в случае OP, начиная с его hdparm -I результат указывает "На детерминированные НУЛИ чтения после ОБРЕЗКИ". –  Marc.2377 02.06.2017, 06:09

Ваша тестовая задача является неправильной — Вы получаете номера секторов относительно блочного устройства, которое файловая система находится на — который в этом случае, логический том. Логический том, конечно, не запускается в первом секторе физического тома (и даже может не быть непрерывным).

Даже если логический том запустился в секторе 0 физического тома (который он не делает), то физический том является на самом деле другой целью картопостроителя устройства, этим для шифрования. И вероятно впереди существует заголовок LUKS, таким образом, номера секторов не соответствуют там, также.

Если Вы хотите работать посредством отображения номера сектора к базовому диску, dmsetup tables даст Вам информацию, в которой Вы нуждаетесь. При вставке его здесь удостоверьтесь, что Ваш - версия, которая не показывает ключ в выводе (это должно показать весь 0 вместо этого)! (Нет никакого восстановления после раскрытия ключа — это не может быть изменено — это намного хуже, чем раскрытие пароля).

Я предлагаю, чтобы для отладки (после того как Вы разработали отображение секторов) Вы запустили на самом низком уровне и подтвердили, что это работает там. ОБРЕЖЬТЕ файловую систему непосредственно на/dev/sdaX и удостоверьтесь, что работы (ее довольно возможное, что устройство находится, и обрезка, не читает назад нули). Затем dm-склеп и обрезка, файловая система на этом, и удостоверяется, что это работает. Наконец, помещенный LVM на вершине и проверка, которая работает.

3
27.01.2020, 19:43
  • 1
    @student OK, это - неправильный сектор затем (первые два абзаца моего ответа). Я отредактирую свой ответ для удаления того предложения о секторе 6575104, поскольку это больше не релевантно. –  derobert 07.08.2013, 23:46
  • 2
    я не уверен, для какого устройства я должен взять dmsetup. Я просто сделал: sudo dmsetup table /dev/mapper/lubuntu--vg-root который дает 0 465903616 linear 252:0 2048 –  student 09.08.2013, 09:55
  • 3
    @student, Который означает сектор 0, в секторе 2048 на устройстве 252:0. Необходимо будет выяснить, какой 252:0, я предположил бы его dm crypto устройство (это - главное и незначительное число, обнаружится в/dev, например). И необходимо будет посмотреть на таблицу для того устройства, чтобы продолжить упорно искать его к блоку на базовом устройстве. –  derobert 09.08.2013, 18:48

Это просто сценарий, которым я хотел бы поделиться, если сюда придет какой-нибудь ленивый человек. Он был составлен из принятого ответа от frostschutz .


#!/bin/bash
#
# This script is provided "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement.
#
# License GPL2
#
# by desgua 2014/04/29

function CLEAN {
cd "$pasta"
[ -f test-trim-by-desgua ] && rm test-trim-by-desgua && echo "Temp file removed"
echo "Goodbye"
exit 0
}

trap 'echo ; echo "Aborted." ; CLEAN; echo ; exit 0' INT HUP

if [[ "$(echo $USER)" != "root" ]]; then

read -n 1 -p 'Become root? [Y/n]' a
    if [[ $a == "Y" || $a == "y" || $a == "" ]]; then
        sudo $0 $1
        exit 0
    else
        echo "
        This script needs root privilege.
        "
        exit 1

    fi

fi


name=$(echo $0 | sed 's/.*\///')
if [ $# -ne 1 ]; then

echo "
Usage: $name /folder/to/test/

"
exit 1
fi

pasta=$1

read -n 1 -p 'Use fstrim? [y/N]' a
if [[ $a == "Y" || $a == "y" ]]; then
    fs=1
fi

method=
while [[ "$method" != "1" && "$method" != "2" ]]; do
read -n 1 -s -p 'Choose a method:
[1] hdparm (will fail in LUKS on LVM)
[2] filefrag (warning: you may have to force quit - close the terminal - in some cases of success trim if you see an output that never ends) 
' method
done

function SDATEST {
disk=$(fdisk -l | grep /dev/sda)
if [ "$disk" == "" ]; then
echo "
fdisk did not found /dev/sda 
"
exit 1
fi
}

function TEST {
echo "Entrying /" ; echo
cd $pasta
echo "Creating the file test-trim-by-desgua at $pasta" ; echo
dd if=/dev/urandom of=test-trim-by-desgua count=10 bs=512k
echo "Syncing and sleeping 2 seconds." ; echo
sync
sleep 2

hdparm --fibmap test-trim-by-desgua
lbab=$(hdparm --fibmap test-trim-by-desgua | tail -n1 | awk '{ print $2 }')

echo "As you can see, the file was created and its LBA begins at $lbab" ; echo

echo "Syncing and sleeping 2 seconds." ; echo
sync
sleep 2

echo "Removing file test-trim-by-desgua" ; echo 
rm test-trim-by-desgua

trap 'echo ; echo ; echo "Aborted." ; echo ; exit 0' INT
echo "Syncing and sleeping 2 seconds." ; echo
sync
sleep 2

if [[ "$fs" == "1" ]]; then 
    echo "fstrim $pasta && sleep 2" ; echo
    fstrim $pasta
    sleep 2
fi

echo "This is readed from sector $lbab: "
hdparm --read-sector $lbab /dev/sda

pass=$(hdparm --read-sector $lbab /dev/sda | grep "0000 0000 0000 0000")

if [[ $pass == "" ]]; then
    echo "
Trim failed... 
You should see only 0000 0000 0000 0000 ...
"
else
    echo "Success!!!"
fi
exit 0

}

function LUKSTEST {
# Reference: https://unix.stackexchange.com/questions/85865/trim-with-lvm-and-dm-crypt#
echo 1 > /proc/sys/vm/drop_caches
cd $pasta
echo "Creating a \"yes\" file."
yes | dd iflag=fullblock bs=1M count=1 of=test-trim-by-desgua

#position=`filefrag -s -v test-trim-by-desgua | grep "eof" | awk '{ print $3 }'`
position=`filefrag -s -v test-trim-by-desgua | grep "eof" | sed 's| ||g ; s|.*255:|| ; s|\.\..*||'`
[[ "$position" == "" ]] && echo "Could not find the position of the file. Are you on a LUKS on LVM?" && CLEAN;

device=`df test-trim-by-desgua | grep "dev/" | awk '{ print $1 }'`

yes=`dd bs=4096 skip=$position count=256 if=$device | hexdump -C`

echo "In the next line you should see a pattern like: 
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
$yes
"

if [[ "`echo "$yes" | grep "y.y.y"`" == "" ]]; then 
    echo "The pattern could not be checked. Something went wrong. Exiting."
    CLEAN;
else
    echo "Pattern confirmed."
fi

echo "Removing the temp file." 
rm test-trim-by-desgua

echo "Syncing."
sync
sleep 1

if [[ "$fs" == "1" ]]; then 
    echo "fstrim -v $pasta && sleep 2" ; echo
    fstrim -v $pasta
    sleep 2
fi

# Drop cache
echo 1 > /proc/sys/vm/drop_caches

echo "In the next line you should **NOT** see a yes pattern like: 
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.| 
If you see, then trim is not working:
`dd bs=4096 skip=$position count=256 if=$device | hexdump -C`"

yes=`dd bs=4096 skip=$position count=256 if=$device | hexdump -C`
if [[ "`echo "$yes" | grep "y.y.y"`" != "" ]]; then 
    echo "TRIM not working."
else
    echo "TRIM is working!"
fi
CLEAN;
}

if [[ "$method" == "1" ]]; then
    SDATEST;
    TEST;
elif [[ "$method" == "2" ]]; then
    LUKSTEST;
fi
exit 0

3
27.01.2020, 19:43

Теги

Похожие вопросы