2 * This file is part of MSM security plugin
3 * Greatly based on the code of MSSF security plugin
5 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
7 * Contact: Tero Aho <ext-tero.aho@nokia.com>
9 * Copyright (C) 2011 - 2013 Intel Corporation.
11 * Contact: Elena Reshetova <elena.reshetova@intel.com>
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
32 #define SMACK64 "security.SMACK64"
33 #define SMACK64EXEC "security.SMACK64EXEC"
34 #define SMACK64TRANSMUTE "security.SMACK64TRANSMUTE"
36 #define SMACK_RULES_PATH "/etc/smack/accesses.d/"
37 #define DEVICE_SECURITY_POLICY "/etc/device-sec-policy"
39 #define SMACK_ISOLATED_LABEL "Isolated"
41 #define SMACK_LABEL_LENGTH 255
42 #define SMACK_ACCESS_TYPE_LENGTH 6
43 #define SMACK_UNINSTALL 1
44 #define RANK_LIMIT 10000
46 #define DBUS_SERVICE 1
48 #define DBUS_INTERFACE 3
56 #include <sys/capability.h>
57 #include <sys/smack.h>
59 #include "rpmio/rpmio.h"
63 * All lists are doubly-linked, the last element is stored to list pointer,
64 * which means that lists must be looped using the prev pointer, or by
65 * calling LISTHEAD first to go to start in order to use the next pointer.
67 #define LISTADD(list, node) \
69 (node)->prev = (list); \
70 if (list) (node)->next = (list)->next; \
71 else (node)->next = NULL; \
72 if (list) (list)->next = (node); \
76 #define NODEADD(node1, node2) \
78 (node2)->prev = (node1); \
79 (node2)->next = (node1)->next; \
80 if ((node1)->next) (node1)->next->prev = (node2); \
81 (node1)->next = (node2); \
84 #define LISTCAT(list, first, last) \
85 if ((first) && (last)) { \
86 (first)->prev = (list); \
90 #define LISTDEL(list, node) \
92 if ((node)->prev) (node)->prev->next = (node)->next; \
93 if ((node)->next) (node)->next->prev = (node)->prev; \
94 if (!((node)->prev) && !((node)->next)) (list) = NULL; \
97 #define LISTHEAD(list, node) \
98 for ((node) = (list); (node)->prev; (node) = (node)->prev);
100 #define LISTTAIL(list, node) \
101 for ((node) = (list); (node)->next; (node) = (node)->next);
104 * Structure definitions.
105 * These structures represent the parsed security manifest of a package.
108 typedef struct file_x {
109 const char *path; /* file path */
110 ino_t ino; /* file inode */
115 typedef struct filesystem_x {
116 const char *path; /* filesystem object absolute path */
117 const char *label; /* SMACK64 xattr */
118 const char *exec_label; /* SMACK64EXEC xattr */
119 const char *type; /* can be set as TRANSMUTABLE for directory */
120 struct filesystem_x *prev;
121 struct filesystem_x *next;
124 typedef struct ac_domain_x { /* structure for storing ac domain */
125 const char *name; /* ac domain name */
127 const char *type; /* ac domain policy type: "shared" or "restricted" or "NULL" (private) */
128 const char *plist; /* list of packages that allowed to request domain, if policy is "restricted" */
129 const char *pkg_name; /* package that defined ac domain */
130 struct ac_domain_x *prev;
131 struct ac_domain_x *next;
132 struct sw_source_x *sw_source; /* sw source of the package that defined the domain */
136 struct ac_domain_x *older; /* previous version in upgrades */
137 struct ac_domain_x *newer; /* the newer upgraded version */
140 typedef struct annotation_x {
145 typedef struct member_x {
148 struct annotation_x *annotation;
149 struct member_x *prev;
150 struct member_x *next;
153 typedef struct interface_x {
155 struct annotation_x *annotation;
156 struct member_x *members;
157 struct interface_x *prev;
158 struct interface_x *next;
161 typedef struct node_x {
163 struct annotation_x *annotation;
164 struct member_x *members;
165 struct interface_x *interfaces;
170 typedef struct dbus_x {
174 struct annotation_x *annotation;
175 struct node_x *nodes;
180 typedef struct provide_x {
181 const char *name; /* _system_ or NULL */
182 struct ac_domain_x *ac_domains;
183 struct filesystem_x *filesystems;
184 struct dbus_x *dbuss;
186 struct provide_x *prev;
187 struct provide_x *next;
190 typedef struct request_x {
191 const char *ac_domain;
194 typedef struct keyinfo_x {
195 const unsigned char *keydata;
197 struct keyinfo_x *prev;
198 struct keyinfo_x *next;
201 typedef struct access_x {
204 struct access_x *prev;
205 struct access_x *next;
208 typedef struct origin_x {
210 struct keyinfo_x *keyinfos;
211 struct access_x *accesses;
212 struct origin_x *prev;
213 struct origin_x *next;
216 typedef struct constraint_x {
219 struct constraint_x *prev;
220 struct constraint_x *next;
223 typedef struct d_request_x {
224 const char *label_name;
226 struct d_request_x *prev;
227 struct d_request_x *next;
230 typedef struct d_permit_x {
231 const char *label_name;
232 const char *to_label_name;
234 struct d_permit_x *prev;
235 struct d_permit_x *next;
238 typedef struct d_provide_x {
239 const char *label_name;
240 struct d_provide_x *prev;
241 struct d_provide_x *next;
244 typedef struct define_x {
245 const char *name; /* ac domain name */
247 const char *plist; /* list of packages that are allowed to request the ac domain */
248 struct d_request_x *d_requests;
249 struct d_permit_x *d_permits;
250 struct d_provide_x *d_provides;
251 struct define_x *prev;
252 struct define_x *next;
255 typedef struct package_x {
256 const char *name; /* package name */
257 struct sw_source_x *sw_source; /* package sw source */
258 struct provide_x *provides;
259 const char *modified; /* internal packages */
260 struct package_x *prev;
261 struct package_x *next;
263 struct package_x *older; /* previous version in upgrades */
264 struct package_x *newer; /* the newer upgraded version */
267 typedef struct sw_source_x {
270 struct package_x *packages; /* config processing */
271 struct ac_domain_x *allowmatches; /* list of allow wildcards */
272 struct ac_domain_x *allows; /* hash of allowed ac domains */
273 struct ac_domain_x *denymatches; /* list of deny wildcards */
274 struct ac_domain_x *denys; /* hash of denied ac domains */
275 struct origin_x *origins;
276 struct sw_source_x *prev;
277 struct sw_source_x *next;
278 struct sw_source_x *parent;
279 struct sw_source_x *older; /* previous version in upgrades */
280 struct sw_source_x *newer; /* the newer upgraded version */
283 typedef struct manifest_x { /*package manifest */
284 struct sw_source_x *sw_source; /* package sw source */
285 const char *name; /* package name */
286 const char *package_type; /* package type: system or application */
287 struct provide_x *provides; /* assign section */
288 struct request_x *request; /* request section */
289 struct sw_source_x *sw_sources; /*defined software sources(non-NULL only for configuration manifests)*/
290 struct define_x *defines; /* define section(s) */
291 struct file_x *files; /* installed files */
295 * Frees the given pointer and sets it to NULL
296 * @param ptr address of pointer to be freed
299 void msmFreePointer(void **ptr);
302 * Process package security manifest.
303 * @param buffer xml data buffer
304 * @param size buffer length
305 * @param current sw source for package
306 * @param packagename name of the package
307 * @return pointer to structure on success
309 manifest_x *msmProcessManifestXml(const char *buffer, int size, sw_source_x *current, const char *packagename);
312 * Loads device security policy.
313 * @param rootDir --root rpm optional prefix
314 * @param dsp pointer to the loaded policy
315 * @return RPMRC_OK or RPMRC_FAIL
317 rpmRC msmLoadDeviceSecurityPolicy(const char* rootDir, manifest_x **dsp);
320 * Process device security policy file.
321 * @param filename file name
322 * @return pointer to structure on success
324 manifest_x *msmProcessDevSecPolicyXml(const char *filename);
327 * Creates a directory for the smack rules.
328 * @param rootDir --root rpm optional prefix
329 * @return RPMRC_OK or RPMRC_FAIL
331 rpmRC msmSetupSmackRulesDir(const char* rootDir);
334 * Free all structures reserved during manifest processing.
335 * @param mfx pointer to structure
337 manifest_x* msmFreeManifestXml(manifest_x * mfx);
340 * Go through all sw sources in manifest, import keys to RPM keyring.
341 * @param smack_accesses smack_accesses handle for setting smack rules
342 * @param mfx package manifest
343 * @param ts rpm transaction set
344 * @return 0 on success, else -1
346 int msmSetupSWSources(struct smack_accesses *smack_accesses, manifest_x *mfx, rpmts ts);
349 * Create package structure for package being installed.
350 * @param name package name
351 * @param sw_source package sw source
352 * @param provides provided ac domains
353 * @param modified for internal packages
354 * @return allocated and initialized package struct
356 package_x *msmCreatePackage(const char *name, sw_source_x *sw_source, provide_x *provides, const char *modified);
359 * Go through all provides in manifest, add provided ac domains to hash.
360 * @param packages pointer to packages list
361 * @param sw_source link to sw source in device security policy
362 * @param rule_set rule set for setting smack rules
363 * @return 0 on success, else -1
365 int msmSetupPackages(struct smack_accesses *smack_accesses, package_x *packages, sw_source_x *sw_source);
368 * Setup define section of manifest
369 * @param smack_accesses smack_accesses handle for setting smack rules
370 * @param mfx package manifest
371 * @return 0 on success, else -1
373 int msmSetupDefines(struct smack_accesses *smack_accesses, manifest_x *mfx);
376 * Setup smack rules according to the manifest
377 * @param smack_accesses smack_accesses handle for setting smack rules
378 * @param package_name package name
379 * @param flag flag to indicate installation or uninstallation
380 * @param SmackEnabled flag to indicate Smack presence in the kernel
381 * @return 0 on success, else -1
383 int msmSetupSmackRules(struct smack_accesses *smack_accesses, const char* package_name, int flag, int SmackEnabled);
386 * Check previous installation of package.
387 * @param name package name
388 * @return package or NULL
390 package_x *msmCheckPackage(const char *name);
393 * Cancel the installation of package (rules and config data).
394 * @param name package name
396 void msmCancelPackage(const char *name);
399 * Free package structure.
400 * @param package package
401 * @return next package in list or NULL
403 package_x *msmFreePackage(package_x *package);
406 * Set extended attributes of the file based on manifest.
407 * @param mfx package manifest
408 * @param filepath path of the file
409 * @param cookie magic cookie
410 * @return 0 on success, else -1
412 int msmSetFileXAttributes(manifest_x *mfx, const char* filepath, magic_t cookie);
415 * Set setup the request section of manifest.
416 * @param mfx package manifest
417 * @return 0 on success, else -1
419 int msmSetupRequests(manifest_x *mfx);
422 * Package is removed, remove all related Smack rules.
423 * @param mfx package manifest
424 * @param smack_accesses smack_accesses handle for setting smack rules
425 * @param SmackEnabled flag to indicate Smack presence in the kernel
427 void msmRemoveRules(struct smack_accesses *smack_accesses, manifest_x *mfx, int SmackEnabled);
430 * Setup DBus policies for package
431 * @param package package
432 * @param mfx package manifest
434 int msmSetupDBusPolicies(package_x *package, manifest_x *mfx);
437 * Package is removed, remove related data in device security policy.
438 * @param mfx package manifest
440 void msmRemoveConfig(manifest_x *mfx);
443 * String compare which allows wildcards (* and ?) in s2.
444 * @param s1 string to compare
445 * @param s2 string to compare
446 * @return 0 if s1 matches s2
448 int strwcmp(const char *s1, const char *s2);
451 * Saves configuration into /etc/dev-sec-policy.
452 * @param mfx data to serialize
453 * @param rooDir ts->rootDir prefix
454 * @return RPMRC_OK or RPMRC_FAIL
456 rpmRC msmSaveDeviceSecPolicyXml(manifest_x *root, const char *rootDir);
459 * Depth first tree traversal for sw source tree.
460 * @param sw_sources sw source tree
461 * @param func function to call for each sw source until 0 is returned
462 * @param param parameter for the function
463 * @param param2 second parameter for the function
464 * @return matching sw source or NULL
466 sw_source_x *msmSWSourceTreeTraversal(sw_source_x *sw_sources, int (func)(sw_source_x *, void *, void *), void *param, void* param2);
469 * Free internal hashes.
471 void msmFreeInternalHashes(void);
474 * Finds a sw source by key info.
475 * @param sw_source sw source
476 * @param param searched param
479 int msmFindSWSourceByKey(sw_source_x *sw_source, void *param);
482 * Finds a sw source by sw source name.
483 * @param sw_source sw source
484 * @param param searched param
487 int msmFindSWSourceByName(sw_source_x *sw_source, void *param);
490 * Finds a sw source by sw source signature.
491 * @param sw_source sw source
492 * @param param searched param
493 * @param param2 searched param2
496 int msmFindSWSourceBySignature(sw_source_x *sw_source, void *param, void* param2);