xref: /aosp_15_r20/external/toybox/tests/chattr.test (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
1*cf5a6c84SAndroid Build Coastguard Worker#!/bin/bash
2*cf5a6c84SAndroid Build Coastguard Worker
3*cf5a6c84SAndroid Build Coastguard Worker[ -f testing.sh ] && . testing.sh
4*cf5a6c84SAndroid Build Coastguard Worker
5*cf5a6c84SAndroid Build Coastguard Worker#testing "name" "command" "result" "infile" "stdin"
6*cf5a6c84SAndroid Build Coastguard Worker
7*cf5a6c84SAndroid Build Coastguard Workerif [ "$(id -u)" -ne 0 ]; then
8*cf5a6c84SAndroid Build Coastguard Worker  echo "$SHOWSKIP: chattr (not root)"
9*cf5a6c84SAndroid Build Coastguard Worker  return 2>/dev/null
10*cf5a6c84SAndroid Build Coastguard Worker  exit
11*cf5a6c84SAndroid Build Coastguard Workerfi
12*cf5a6c84SAndroid Build Coastguard Worker
13*cf5a6c84SAndroid Build Coastguard Workerfunction clean()
14*cf5a6c84SAndroid Build Coastguard Worker{
15*cf5a6c84SAndroid Build Coastguard Worker  # We don't know whether the fs will have extents (e, typically true on the
16*cf5a6c84SAndroid Build Coastguard Worker  # desktop) or be encrypted (E, typically true on Android), or have data
17*cf5a6c84SAndroid Build Coastguard Worker  # inlined in the inode (N), or use indexed directories, so strip those out.
18*cf5a6c84SAndroid Build Coastguard Worker  # We also don't want to rely on chattr(1) to set a known version number or
19*cf5a6c84SAndroid Build Coastguard Worker  # project number, so blank out any numbers.
20*cf5a6c84SAndroid Build Coastguard Worker  sed -E -e 's/, (Encrypted|Extents|Indexed_directory|Inline_Data)//g;' \
21*cf5a6c84SAndroid Build Coastguard Worker         -e 's/[EeIN]-/--/g; s/[0-9]+/_/g'
22*cf5a6c84SAndroid Build Coastguard Worker}
23*cf5a6c84SAndroid Build Coastguard Worker
24*cf5a6c84SAndroid Build Coastguard Workermkdir testattr
25*cf5a6c84SAndroid Build Coastguard WorkerIN="cd testattr"
26*cf5a6c84SAndroid Build Coastguard WorkerOUT="cd .."
27*cf5a6c84SAndroid Build Coastguard Worker_t="abcdefghijklmnopqrstuvwxyz"
28*cf5a6c84SAndroid Build Coastguard Worker
29*cf5a6c84SAndroid Build Coastguard Worker_empty="--------------------"
30*cf5a6c84SAndroid Build Coastguard Worker
31*cf5a6c84SAndroid Build Coastguard Worker# Check +i (immutable) works by trying to write to and remove the file.
32*cf5a6c84SAndroid Build Coastguard Worker_i="----i---------------"
33*cf5a6c84SAndroid Build Coastguard Workertesting "immutable" "$IN && echo "$_t" > testFile &&
34*cf5a6c84SAndroid Build Coastguard Worker         chattr +i testFile && lsattr testFile | clean &&
35*cf5a6c84SAndroid Build Coastguard Worker         date > testFile 2>/dev/null; rm testFile; chattr -i testFile;
36*cf5a6c84SAndroid Build Coastguard Worker         cat testFile; rm -rf testFile; $OUT " "$_i testFile\n$_t\n" "" ""
37*cf5a6c84SAndroid Build Coastguard Worker
38*cf5a6c84SAndroid Build Coastguard Worker# Check +a (append-only) works by failing to write and succeeding in appending.
39*cf5a6c84SAndroid Build Coastguard Worker_a="-----a--------------"
40*cf5a6c84SAndroid Build Coastguard Workertesting "append-only" "$IN && echo "$_t" > testFile &&
41*cf5a6c84SAndroid Build Coastguard Worker         chattr +a testFile &&
42*cf5a6c84SAndroid Build Coastguard Worker         echo $_t >> testFile &&
43*cf5a6c84SAndroid Build Coastguard Worker         date > testFile || lsattr testFile | clean &&
44*cf5a6c84SAndroid Build Coastguard Worker         chattr -a testFile; cat testFile; rm -rf testFile; $OUT" \
45*cf5a6c84SAndroid Build Coastguard Worker         "$_a testFile\n$_t\n$_t\n" "" ""
46*cf5a6c84SAndroid Build Coastguard Worker
47*cf5a6c84SAndroid Build Coastguard Worker# For the rest, just toggle the bits back and forth (where supported).
48*cf5a6c84SAndroid Build Coastguard Worker# Note that some file system/kernel combinations do return success but
49*cf5a6c84SAndroid Build Coastguard Worker# silently ignore your request: +T on 4.19 f2fs, or +F on 5.2 ext4,
50*cf5a6c84SAndroid Build Coastguard Worker# for example, so we're deliberately a bit selective here.
51*cf5a6c84SAndroid Build Coastguard Worker# f2fs in 5.6+ kernels supports compression, but you can only enable
52*cf5a6c84SAndroid Build Coastguard Worker# compression on a file while it's still empty, so we skip +c too.
53*cf5a6c84SAndroid Build Coastguard Workerfor attr in "A" "d" "e" "j" "P" "S" "s" "t" "u"; do
54*cf5a6c84SAndroid Build Coastguard Worker  echo "$_t" > testFile && chattr +$attr testFile 2>/dev/null || ((++SKIP))
55*cf5a6c84SAndroid Build Coastguard Worker  # Check that $attr is in the lsattr output, then that - turns it back off.
56*cf5a6c84SAndroid Build Coastguard Worker  testing "toggle $attr" "lsattr testFile | awk '{print \$1}' > attrs;
57*cf5a6c84SAndroid Build Coastguard Worker    grep -q $attr attrs || cat attrs; cat testFile && chattr -$attr testFile &&
58*cf5a6c84SAndroid Build Coastguard Worker    lsattr testFile | clean; rm -rf testFile" "$_t\n$_empty testFile\n" "" ""
59*cf5a6c84SAndroid Build Coastguard Workerdone
60*cf5a6c84SAndroid Build Coastguard Worker
61*cf5a6c84SAndroid Build Coastguard Worker_aA="-----a-A------------"
62*cf5a6c84SAndroid Build Coastguard Workertesting "multiple bits" "$IN && touch testFile &&
63*cf5a6c84SAndroid Build Coastguard Worker  chattr +Aa testFile && lsattr testFile | clean &&
64*cf5a6c84SAndroid Build Coastguard Worker  chattr -Aa testFile && lsattr testFile | clean;
65*cf5a6c84SAndroid Build Coastguard Worker  rm -rf testFile; $OUT" "$_aA testFile\n$_empty testFile\n" "" ""
66*cf5a6c84SAndroid Build Coastguard Worker
67*cf5a6c84SAndroid Build Coastguard Workertesting "multiple files" "$IN && touch fileA && touch fileB &&
68*cf5a6c84SAndroid Build Coastguard Worker  chattr +Aa fileA fileB && lsattr fileA fileB | clean &&
69*cf5a6c84SAndroid Build Coastguard Worker  chattr -Aa fileA fileB && lsattr fileA fileB | clean;
70*cf5a6c84SAndroid Build Coastguard Worker  rm -rf testFile*; $OUT" \
71*cf5a6c84SAndroid Build Coastguard Worker  "$_aA fileA\n$_aA fileB\n$_empty fileA\n$_empty fileB\n" "" ""
72*cf5a6c84SAndroid Build Coastguard Worker
73*cf5a6c84SAndroid Build Coastguard Workertouch testFile && chattr -v 1234 testFile 2>/dev/null || ((++SKIP))
74*cf5a6c84SAndroid Build Coastguard Workertesting "-v version" "lsattr -v testFile | awk '{print \$1}' &&
75*cf5a6c84SAndroid Build Coastguard Worker  chattr -v 4567 testFile && lsattr -v testFile | awk '{print \$1}';
76*cf5a6c84SAndroid Build Coastguard Worker  rm -rf testFile" "1234\n4567\n" "" ""
77*cf5a6c84SAndroid Build Coastguard Worker
78*cf5a6c84SAndroid Build Coastguard Workermkdir -p a/b/c && touch a/b/c/fA a/b/c/fB
79*cf5a6c84SAndroid Build Coastguard Workertesting "-R" "chattr -R +a a && lsattr a/b/c/fA a/b/c/fB | clean &&
80*cf5a6c84SAndroid Build Coastguard Worker  chattr -R -a a && rm -rf a" \
81*cf5a6c84SAndroid Build Coastguard Worker  "$_a a/b/c/fA\n$_a a/b/c/fB\n" "" ""
82*cf5a6c84SAndroid Build Coastguard Workerrm -rf a
83*cf5a6c84SAndroid Build Coastguard Worker
84*cf5a6c84SAndroid Build Coastguard Worker# Clean up
85*cf5a6c84SAndroid Build Coastguard Workerrm -rf testattr
86