Refactor test for smack_*getlabel and smack_*setlabel.
[platform/core/test/security-tests.git] / tests / common / fs_label_manager.cpp
1 #include <fs_label_manager.h>
2
3 #include <tests_common.h>
4 #include <memory.h>
5
6 #include <unistd.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <sys/mount.h>
12 #include <sys/xattr.h>
13 #include <linux/xattr.h>
14
15
16 namespace
17 {
18 static const char* get_xattr_name(enum smack_label_type type)
19 {
20     switch (type) {
21         case SMACK_LABEL_ACCESS:
22             return XATTR_NAME_SMACK;
23         case SMACK_LABEL_EXEC:
24             return XATTR_NAME_SMACKEXEC;
25         case SMACK_LABEL_MMAP:
26             return XATTR_NAME_SMACKMMAP;
27         case SMACK_LABEL_TRANSMUTE:
28             return XATTR_NAME_SMACKTRANSMUTE;
29         case SMACK_LABEL_IPIN:
30             return XATTR_NAME_SMACKIPIN;
31         case SMACK_LABEL_IPOUT:
32             return XATTR_NAME_SMACKIPOUT;
33         default:
34             /*  Should not reach this point */
35             return NULL;
36     }
37 }
38 }
39
40 FsLabelManager::FsLabelManager(const std::string &path, const std::string &label)
41     : m_path(path)
42     , m_label(label)
43 {
44     umount(m_path.c_str());
45     rmdir(m_path.c_str());
46
47     std::string data = std::string("mode=0777,uid=0,smackfsdef=") + label;
48
49     int ret = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
50     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to make directory");
51
52     ret = mount("none", path.c_str(), "tmpfs", 0, data.c_str());
53     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to mount filesystem");
54
55     if (m_path[m_path.length()-1] != '/')
56         m_path += '/';
57 }
58
59 FsLabelManager::~FsLabelManager()
60 {
61     umount(m_path.c_str());
62     rmdir(m_path.c_str());
63 }
64
65 void FsLabelManager::createFile(const std::string &relativePath)
66 {
67     std::string path = m_path + relativePath;
68
69     mode_t systemMask = umask(0000);
70     int fd = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
71     umask(systemMask);
72     RUNNER_ASSERT_MSG_BT(fd > -1, "Unable to create file for tests: " << strerror(errno));
73
74     close(fd);
75
76     int ret = chown(path.c_str(), APP_UID, APP_GID);
77     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to change file owner: " << strerror(errno));
78 }
79
80 void FsLabelManager::createLink(const std::string &relativeLinkPath, const std::string &relativeRealPath)
81 {
82     std::string linkPath = m_path + relativeLinkPath;
83     std::string realPath = m_path + relativeRealPath;
84
85     int ret = unlink(linkPath.c_str());
86     RUNNER_ASSERT_MSG_BT(ret == 0 || errno == ENOENT, "Unable to unlink file." << strerror(errno));
87
88     ret = symlink(realPath.c_str(), linkPath.c_str());
89     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to create symlink." << strerror(errno));
90
91     ret = lchown(linkPath.c_str(), APP_UID, APP_GID);
92     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to change file owner: " << strerror(errno));
93 }
94
95 void FsLabelManager::testSmackSetLabel(const std::string &relativePath,
96                                        const char *label,
97                                        enum smack_label_type labelType)
98 {
99     std::string path = m_path + relativePath;
100
101     int ret = smack_setlabel(path.c_str(), label, labelType);
102     RUNNER_ASSERT_MSG_BT(ret == 0, "Error in normal setting label " << label);
103
104     checkLabel(path, label, labelType);
105 }
106
107 void FsLabelManager::testSmackLSetLabel(const std::string &relativePath,
108                                         const char *label,
109                                         enum smack_label_type labelType)
110 {
111     std::string path = m_path + relativePath;
112
113     int ret = smack_lsetlabel(path.c_str(), label, labelType);
114     RUNNER_ASSERT_MSG_BT(ret == 0, "Error in link setting label " << label);
115
116     checkLinkLabel(path, label, labelType);
117 }
118
119 void FsLabelManager::testSmackFSetLabel(const std::string &relativePath,
120                                         const char *label,
121                                         enum smack_label_type labelType)
122 {
123     std::string path = m_path + relativePath;
124
125     int fd = open(path.c_str(), O_WRONLY);
126     RUNNER_ASSERT_MSG_BT(fd > -1, "Unable to open file: " << strerror(errno));
127
128     int ret = smack_fsetlabel(fd, label, labelType);
129     close(fd);
130     RUNNER_ASSERT_MSG_BT(ret == 0, "Error in fd setting " << label);
131
132     checkLabel(path, label, labelType);
133 }
134
135 void FsLabelManager::testSmackGetLabel(const std::string &relativePath,
136                                        const char *label,
137                                        enum smack_label_type labelType)
138 {
139     std::string path = m_path + relativePath;
140
141     char *tmpLabel;
142     int ret = smack_getlabel(path.c_str(), &tmpLabel, labelType);
143     RUNNER_ASSERT_MSG_BT(ret == 0, "Error in normal getting label");
144     SmackLabelPtr labelPtr(tmpLabel);
145
146     if (label == NULL && !m_label.compare(tmpLabel))
147         return;
148     RUNNER_ASSERT_MSG_BT(label != NULL, "Path should be related with file system default label. "
149                                         << tmpLabel << " != " << m_label);
150
151     ret = strcmp(tmpLabel, label);
152     RUNNER_ASSERT_MSG_BT(ret == 0, "Wrong label. " << tmpLabel << " != " << label);
153
154     checkLabel(path, tmpLabel, labelType);
155 }
156
157 void FsLabelManager::testSmackLGetLabel(const std::string &relativePath,
158                                         const char *label,
159                                         enum smack_label_type labelType)
160 {
161     std::string path = m_path + relativePath;
162
163     char *tmpLabel;
164     int ret = smack_lgetlabel(path.c_str(), &tmpLabel, labelType);
165     RUNNER_ASSERT_MSG_BT(ret == 0, "Error in link getting label");
166     SmackLabelPtr labelPtr(tmpLabel);
167
168     if (label == NULL && !m_label.compare(tmpLabel))
169         return;
170     RUNNER_ASSERT_MSG_BT(label != NULL, "Path should be related with file system default label. "
171                                         << tmpLabel << " != " << m_label);
172
173     ret = strcmp(tmpLabel, label);
174     RUNNER_ASSERT_MSG_BT(ret == 0, "Wrong label. " << tmpLabel << " != " << label);
175
176     checkLinkLabel(path, tmpLabel, labelType);
177 }
178
179 void FsLabelManager::testSmackFGetLabel(const std::string &relativePath,
180                                         const char *label,
181                                         enum smack_label_type labelType)
182 {
183     std::string path = m_path + relativePath;
184     int fd = open(path.c_str(), O_WRONLY);
185     RUNNER_ASSERT_MSG_BT(fd > -1, "Unable to open file: " << strerror(errno));
186
187     char *tmpLabel;
188     int ret = smack_fgetlabel(fd, &tmpLabel, labelType);
189     close(fd);
190     RUNNER_ASSERT_MSG_BT(ret == 0, "Error in fd getting label");
191     SmackLabelPtr labelPtr(tmpLabel);
192
193     if (label == NULL && !m_label.compare(tmpLabel))
194         return;
195     RUNNER_ASSERT_MSG_BT(label != NULL, "Fd should be related with file system default label. "
196                                         << tmpLabel << " != " << m_label);
197
198     ret = strcmp(tmpLabel, label);
199     RUNNER_ASSERT_MSG_BT(ret == 0, "Wrong label. " << tmpLabel << " != " << label);
200
201     checkLabel(path, tmpLabel, labelType);
202 }
203
204 void FsLabelManager::testSmackClearLabels(const std::string &relativePath)
205 {
206     testSmackSetLabel(relativePath, NULL, SMACK_LABEL_ACCESS);
207     testSmackGetLabel(relativePath, NULL, SMACK_LABEL_ACCESS);
208     testSmackSetLabel(relativePath, NULL, SMACK_LABEL_EXEC);
209     testSmackGetLabel(relativePath, NULL, SMACK_LABEL_EXEC);
210 }
211
212 void FsLabelManager::checkLabel(const std::string &path,
213                                 const char *label,
214                                 enum smack_label_type labelType)
215 {
216     char buf[SMACK_LABEL_LEN+2] = { 0, };
217     int ret = getxattr(path.c_str(), get_xattr_name(labelType), buf, SMACK_LABEL_LEN+1);
218     RUNNER_ASSERT_MSG_BT(ret > 0, "Error in getting xattr. " << strerror(errno));
219
220     const char *tmpLabel;
221     if (label == NULL)
222         tmpLabel = m_label.c_str();
223     else
224         tmpLabel = label;
225
226     ret = strncmp(tmpLabel, buf, SMACK_LABEL_LEN+1);
227     RUNNER_ASSERT_MSG_BT(ret == 0, "Wrong label. " << tmpLabel << " != " << buf);
228 }
229
230 void FsLabelManager::checkLinkLabel(const std::string &path,
231                                     const char *label,
232                                     enum smack_label_type labelType)
233 {
234     char buf[SMACK_LABEL_LEN+2] = { 0, };
235     int ret = lgetxattr(path.c_str(), get_xattr_name(labelType), buf, SMACK_LABEL_LEN+1);
236     RUNNER_ASSERT_MSG_BT(ret > 0, "Error in getting xattr. " << strerror(errno));
237
238     const char *tmpLabel;
239     if (label == NULL)
240         tmpLabel = m_label.c_str();
241     else
242         tmpLabel = label;
243
244     ret = strncmp(tmpLabel, buf, SMACK_LABEL_LEN+1);
245     RUNNER_ASSERT_MSG_BT(ret == 0, "Wrong label. " << tmpLabel << " != " << buf);
246 }