Add SDcard password confirm popup
[platform/core/security/ode.git] / server / ext4-tool.cpp
1 /*
2  *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 #include <fcntl.h>
17
18 #include <string>
19 #include <vector>
20
21 #include <klay/filesystem.h>
22 #include <klay/process.h>
23 #include <klay/exception.h>
24 #include <klay/audit/logger.h>
25
26 #include "ext4-tool.h"
27
28 namespace ode {
29
30 #define ODE_SUPERBLOCK_OFFSET           1024
31 #define ODE_SUPERBLOCK_SIZE                     1024
32 #define ODE_EXT2_MIN_DESC_SIZE          32
33 #define ODE_EXT2_MIN_BLOCK_LOG_SIZE     10      /* 1024 */
34 #define ODE_EXT2_MIN_BLOCK_SIZE         (1 << ODE_EXT2_MIN_BLOCK_LOG_SIZE)
35
36 static unsigned int divCeilSafely(unsigned int a, unsigned int b)
37 {
38         if (!a)
39                 return 0;
40
41         return ((a - 1) / b) + 1;
42 }
43
44 Ext4Tool::Ext4Tool(const std::string &src) :
45         source(src), blockSize(0), totalBlockCount(0)
46 {
47         unsigned int firstDataBlock = 0;
48         unsigned int blocksPerGroup = 0;
49         unsigned int clustersPerGroup = 0;
50         runtime::File device(source);
51
52         if (device.exists() == false)
53                 throw runtime::Exception("Source doesn't exist");
54
55         device.open(O_RDONLY);
56
57         // read totalBlockCount
58         device.lseek(ODE_SUPERBLOCK_OFFSET +  4, SEEK_SET);
59         device.read(&totalBlockCount, 4);
60
61         // read firstDataBlock
62         device.lseek(ODE_SUPERBLOCK_OFFSET + 20, SEEK_SET);
63         device.read(&firstDataBlock, 4);
64
65         // read blockSize
66         device.lseek(ODE_SUPERBLOCK_OFFSET + 24, SEEK_SET);
67         device.read(&blockSize, 4);
68         blockSize = (ODE_EXT2_MIN_BLOCK_SIZE << blockSize);
69
70         // read blocksPerGroup
71         device.lseek(ODE_SUPERBLOCK_OFFSET + 32, SEEK_SET);
72         device.read(&blocksPerGroup, 4);
73
74         // read clustersPerGroup
75         device.lseek(ODE_SUPERBLOCK_OFFSET + 36, SEEK_SET);
76         device.read(&clustersPerGroup, 4);
77
78         unsigned int groupDescCount = divCeilSafely(totalBlockCount - firstDataBlock, blocksPerGroup);
79         int blockNbytes = clustersPerGroup / 8;
80
81         // read group_desc
82         unsigned int descPerBlock = blockSize / ODE_EXT2_MIN_DESC_SIZE;
83         unsigned int descBlockCount = divCeilSafely(groupDescCount, descPerBlock);
84
85         // read first meta block
86         data group_desc(descBlockCount * blockSize);
87         device.lseek((firstDataBlock + 1) * blockSize, SEEK_SET);
88         device.read(group_desc.data(), (descBlockCount * blockSize));
89
90         unsigned int cnt = 0;
91         unsigned int blkItr = firstDataBlock;
92
93         // this structure just is used for easy type-casting.
94         struct odeExtGroupDesc {
95                 unsigned int    blockBitmap;    /* Blocks bitmap block */
96                 /* skip other member */
97         };
98
99         // read bitmap
100         {
101                 unsigned int start = firstDataBlock;
102                 unsigned int real_end = blocksPerGroup * groupDescCount - 1 + start;
103                 size_t size = (size_t) (((real_end - start) / 8) + 1);
104                 size = (size + 7) & ~3;
105                 bitmap.resize(size);
106         }
107
108         for (unsigned int i = 0; i < groupDescCount; i++) {
109                 data block_bitmap(blockSize);
110
111                 unsigned int blk = (((struct odeExtGroupDesc *)(((unsigned char *)(group_desc.data())) + i * ODE_EXT2_MIN_DESC_SIZE))->blockBitmap);
112                 device.lseek(blk * blockSize, SEEK_SET);
113                 device.read(block_bitmap.data(), blockSize);
114
115                 cnt = blockNbytes << 3;
116                 memcpy(bitmap.data() + (blkItr >> 3), block_bitmap.data(), (cnt + 7) >> 3);
117                 blkItr += blockNbytes << 3;
118         }
119
120         device.close();
121 }
122
123 Ext4Tool::~Ext4Tool()
124 {
125 }
126
127 unsigned int Ext4Tool::getBlockSize()
128 {
129         return blockSize;
130 }
131
132 unsigned int Ext4Tool::getTotalBlockCount()
133 {
134         return totalBlockCount;
135 }
136
137 bool Ext4Tool::isUsedBlock(unsigned int blockIndex)
138 {
139         unsigned char *addr = (bitmap.data() + (blockIndex >> 3));
140         int mask = 1 << (blockIndex & 0x07);
141
142         if (mask & *addr)
143                 return true;
144
145         return false;
146 }
147
148 void Ext4Tool::forceCleanUp()
149 {
150         std::vector<std::string> args = {
151                 "-f",
152                 "-y",
153                 source
154         };
155
156         runtime::Process proc("/sbin/e2fsck", args);
157         proc.execute();
158         proc.waitForFinished();
159 }
160
161 } // namespace ode