From 4ecd63d7869922dab94d88e6e0a4fa4c9f0d0c66 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 16 Jul 2015 14:21:22 -0400 Subject: [PATCH] e2fsck: check for an encrypted lost+found directory The /lost+found directory must not be encrypted, since e2fsck won't have any keys. If we find an encrypted lost+found directory, we should delete the directory and recreate it. Signed-off-by: Theodore Ts'o --- e2fsck/pass3.c | 18 +++++++++++++++++- e2fsck/problem.c | 5 +++++ e2fsck/problem.h | 3 +++ tests/f_encrypted_lpf/expect.1 | 27 +++++++++++++++++++++++++++ tests/f_encrypted_lpf/expect.2 | 7 +++++++ tests/f_encrypted_lpf/image.gz | Bin 0 -> 1123 bytes tests/f_encrypted_lpf/name | 1 + 7 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 tests/f_encrypted_lpf/expect.1 create mode 100644 tests/f_encrypted_lpf/expect.2 create mode 100644 tests/f_encrypted_lpf/image.gz create mode 100644 tests/f_encrypted_lpf/name diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index 1d5255f6..d7b88029 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -100,7 +100,8 @@ void e2fsck_pass3(e2fsck_t ctx) iter = e2fsck_dir_info_iter_begin(ctx); while ((dir = e2fsck_dir_info_iter(ctx, iter)) != 0) { - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) + if (ctx->flags & E2F_FLAG_SIGNAL_MASK || + ctx->flags & E2F_FLAG_RESTART) goto abort_exit; if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs)) goto abort_exit; @@ -415,6 +416,12 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix) goto unlink; } + if (fix && (inode.i_flags & EXT4_ENCRYPT_FL)) { + if (!fix_problem(ctx, PR_3_LPF_ENCRYPTED, &pctx)) + return 0; + goto unlink; + } + if (ext2fs_check_directory(fs, ino) == 0) { ctx->lost_and_found = ino; return ino; @@ -437,6 +444,15 @@ unlink: } (void) e2fsck_dir_info_set_parent(ctx, ino, 0); e2fsck_adjust_inode_count(ctx, ino, -1); + /* + * If the old lost+found was a directory, we've just + * disconnected it from the directory tree, which + * means we need to restart the directory tree scan. + * The simplest way to do this is restart the whole + * e2fsck operation. + */ + if (LINUX_S_ISDIR(inode.i_mode)) + ctx->flags |= E2F_FLAG_RESTART; } else if (retval != EXT2_ET_FILE_NOT_FOUND) { pctx.errcode = retval; fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx); diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 23d21835..084131ab 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -1750,6 +1750,11 @@ static struct e2fsck_problem problem_table[] = { N_("Insufficient space to recover lost files!\nMove data off the @f and re-run e2fsck.\n\n"), PROMPT_NONE, 0 }, + /* Lost+found is encrypted */ + { PR_3_LPF_ENCRYPTED, + N_("/@l is encrypted\n"), + PROMPT_CLEAR, 0 }, + /* Pass 3A Directory Optimization */ /* Pass 3A: Optimizing directories */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index e0b5d14d..5af3edf0 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -1048,6 +1048,9 @@ struct problem_context { /* Insufficient space to recover lost files */ #define PR_3_NO_SPACE_TO_RECOVER 0x03001A +/* Lost+found is encrypted */ +#define PR_3_LPF_ENCRYPTED 0x03001B + /* * Pass 3a --- rehashing diretories */ diff --git a/tests/f_encrypted_lpf/expect.1 b/tests/f_encrypted_lpf/expect.1 new file mode 100644 index 00000000..7e215b7d --- /dev/null +++ b/tests/f_encrypted_lpf/expect.1 @@ -0,0 +1,27 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Unconnected directory inode 12 (/???) +Connect to /lost+found? yes + +/lost+found is encrypted +Clear? yes + +/lost+found not found. Create? yes + +Restarting e2fsck from the beginning... +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Unconnected directory inode 11 (/???) +Connect to /lost+found? yes + +Pass 3A: Optimizing directories +Pass 4: Checking reference counts +Inode 12 ref count is 3, should be 2. Fix? yes + +Pass 5: Checking group summary information + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 13/64 files (0.0% non-contiguous), 13/100 blocks +Exit status is 1 diff --git a/tests/f_encrypted_lpf/expect.2 b/tests/f_encrypted_lpf/expect.2 new file mode 100644 index 00000000..6a59947a --- /dev/null +++ b/tests/f_encrypted_lpf/expect.2 @@ -0,0 +1,7 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information +test_filesys: 13/64 files (0.0% non-contiguous), 13/100 blocks +Exit status is 0 diff --git a/tests/f_encrypted_lpf/image.gz b/tests/f_encrypted_lpf/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..7c89e07a5d96ecaef3d7ba57a5bb627760f0580f GIT binary patch literal 1123 zcmb2|=3pp!y*!kO`RyJ544F^~h7aG>q9S^v8n!oevFEBTV2QpgYT7H_x-P$5-K<4d zOgHb&zq${pY4>j5?5{MQ`R03>xgvx3>VG26nzMp=mb^H9d$Y|U7t>SyyI)*(1U(c0Sy)ImH zH+ub@tm4=?tAE5S9jvgy24)TWQej~$bjytVK08&06cH90G%&A<8Q_`K)gx~u>D zmxa8p2Z}B*eD(j$yoKVYUvtYIV+IOHZT+X;7xQo8FL@y6%6}l?kPM*?pJ)E@AEf8P zj?({Uc<=Yt%w6?w=ZtNqFaCZxdHeeRMIWXv?eAW@d1^lUn$y48d1Zl0*LWC;9f~Nt z-+1rmv%i;@FQ510?X{E7^Q!k-+!dYGCk0Z13;d{F+E)W|xXBuUO*?12`d?IIU}62| z+Opiu-p|>SUgxB?CB)vd&o~7Nm9Qle+=**;ymxqC^ZB1|`I+*68-8!iwU@hN`|I7A zhueGkaM?mYTs-Lc%Dv3pALF0e6e+dLH(NIKs$z~u8-vv z&3De;|5s1#w>n?H?sxp_%4hci-&oxYTm1KXX8m^po){6*Qg`P!H=N67aA0Eq03~Ok AqyPW_ literal 0 HcmV?d00001 diff --git a/tests/f_encrypted_lpf/name b/tests/f_encrypted_lpf/name new file mode 100644 index 00000000..b74259ce --- /dev/null +++ b/tests/f_encrypted_lpf/name @@ -0,0 +1 @@ +encrypted lost+found directory