mount.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. /*
  2. * AppArmor security module
  3. *
  4. * This file contains AppArmor mediation of files
  5. *
  6. * Copyright (C) 1998-2008 Novell/SUSE
  7. * Copyright 2009-2017 Canonical Ltd.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation, version 2 of the
  12. * License.
  13. */
  14. #include <linux/fs.h>
  15. #include <linux/mount.h>
  16. #include <linux/namei.h>
  17. #include "include/apparmor.h"
  18. #include "include/audit.h"
  19. #include "include/context.h"
  20. #include "include/domain.h"
  21. #include "include/file.h"
  22. #include "include/match.h"
  23. #include "include/mount.h"
  24. #include "include/path.h"
  25. #include "include/policy.h"
  26. static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags)
  27. {
  28. if (flags & MS_RDONLY)
  29. audit_log_format(ab, "ro");
  30. else
  31. audit_log_format(ab, "rw");
  32. if (flags & MS_NOSUID)
  33. audit_log_format(ab, ", nosuid");
  34. if (flags & MS_NODEV)
  35. audit_log_format(ab, ", nodev");
  36. if (flags & MS_NOEXEC)
  37. audit_log_format(ab, ", noexec");
  38. if (flags & MS_SYNCHRONOUS)
  39. audit_log_format(ab, ", sync");
  40. if (flags & MS_REMOUNT)
  41. audit_log_format(ab, ", remount");
  42. if (flags & MS_MANDLOCK)
  43. audit_log_format(ab, ", mand");
  44. if (flags & MS_DIRSYNC)
  45. audit_log_format(ab, ", dirsync");
  46. if (flags & MS_NOATIME)
  47. audit_log_format(ab, ", noatime");
  48. if (flags & MS_NODIRATIME)
  49. audit_log_format(ab, ", nodiratime");
  50. if (flags & MS_BIND)
  51. audit_log_format(ab, flags & MS_REC ? ", rbind" : ", bind");
  52. if (flags & MS_MOVE)
  53. audit_log_format(ab, ", move");
  54. if (flags & MS_SILENT)
  55. audit_log_format(ab, ", silent");
  56. if (flags & MS_POSIXACL)
  57. audit_log_format(ab, ", acl");
  58. if (flags & MS_UNBINDABLE)
  59. audit_log_format(ab, flags & MS_REC ? ", runbindable" :
  60. ", unbindable");
  61. if (flags & MS_PRIVATE)
  62. audit_log_format(ab, flags & MS_REC ? ", rprivate" :
  63. ", private");
  64. if (flags & MS_SLAVE)
  65. audit_log_format(ab, flags & MS_REC ? ", rslave" :
  66. ", slave");
  67. if (flags & MS_SHARED)
  68. audit_log_format(ab, flags & MS_REC ? ", rshared" :
  69. ", shared");
  70. if (flags & MS_RELATIME)
  71. audit_log_format(ab, ", relatime");
  72. if (flags & MS_I_VERSION)
  73. audit_log_format(ab, ", iversion");
  74. if (flags & MS_STRICTATIME)
  75. audit_log_format(ab, ", strictatime");
  76. if (flags & MS_NOUSER)
  77. audit_log_format(ab, ", nouser");
  78. }
  79. /**
  80. * audit_cb - call back for mount specific audit fields
  81. * @ab: audit_buffer (NOT NULL)
  82. * @va: audit struct to audit values of (NOT NULL)
  83. */
  84. static void audit_cb(struct audit_buffer *ab, void *va)
  85. {
  86. struct common_audit_data *sa = va;
  87. if (aad(sa)->mnt.type) {
  88. audit_log_format(ab, " fstype=");
  89. audit_log_untrustedstring(ab, aad(sa)->mnt.type);
  90. }
  91. if (aad(sa)->mnt.src_name) {
  92. audit_log_format(ab, " srcname=");
  93. audit_log_untrustedstring(ab, aad(sa)->mnt.src_name);
  94. }
  95. if (aad(sa)->mnt.trans) {
  96. audit_log_format(ab, " trans=");
  97. audit_log_untrustedstring(ab, aad(sa)->mnt.trans);
  98. }
  99. if (aad(sa)->mnt.flags) {
  100. audit_log_format(ab, " flags=\"");
  101. audit_mnt_flags(ab, aad(sa)->mnt.flags);
  102. audit_log_format(ab, "\"");
  103. }
  104. if (aad(sa)->mnt.data) {
  105. audit_log_format(ab, " options=");
  106. audit_log_untrustedstring(ab, aad(sa)->mnt.data);
  107. }
  108. }
  109. /**
  110. * audit_mount - handle the auditing of mount operations
  111. * @profile: the profile being enforced (NOT NULL)
  112. * @op: operation being mediated (NOT NULL)
  113. * @name: name of object being mediated (MAYBE NULL)
  114. * @src_name: src_name of object being mediated (MAYBE_NULL)
  115. * @type: type of filesystem (MAYBE_NULL)
  116. * @trans: name of trans (MAYBE NULL)
  117. * @flags: filesystem idependent mount flags
  118. * @data: filesystem mount flags
  119. * @request: permissions requested
  120. * @perms: the permissions computed for the request (NOT NULL)
  121. * @info: extra information message (MAYBE NULL)
  122. * @error: 0 if operation allowed else failure error code
  123. *
  124. * Returns: %0 or error on failure
  125. */
  126. static int audit_mount(struct aa_profile *profile, const char *op,
  127. const char *name, const char *src_name,
  128. const char *type, const char *trans,
  129. unsigned long flags, const void *data, u32 request,
  130. struct aa_perms *perms, const char *info, int error)
  131. {
  132. int audit_type = AUDIT_APPARMOR_AUTO;
  133. DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);
  134. if (likely(!error)) {
  135. u32 mask = perms->audit;
  136. if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
  137. mask = 0xffff;
  138. /* mask off perms that are not being force audited */
  139. request &= mask;
  140. if (likely(!request))
  141. return 0;
  142. audit_type = AUDIT_APPARMOR_AUDIT;
  143. } else {
  144. /* only report permissions that were denied */
  145. request = request & ~perms->allow;
  146. if (request & perms->kill)
  147. audit_type = AUDIT_APPARMOR_KILL;
  148. /* quiet known rejects, assumes quiet and kill do not overlap */
  149. if ((request & perms->quiet) &&
  150. AUDIT_MODE(profile) != AUDIT_NOQUIET &&
  151. AUDIT_MODE(profile) != AUDIT_ALL)
  152. request &= ~perms->quiet;
  153. if (!request)
  154. return error;
  155. }
  156. aad(&sa)->name = name;
  157. aad(&sa)->mnt.src_name = src_name;
  158. aad(&sa)->mnt.type = type;
  159. aad(&sa)->mnt.trans = trans;
  160. aad(&sa)->mnt.flags = flags;
  161. if (data && (perms->audit & AA_AUDIT_DATA))
  162. aad(&sa)->mnt.data = data;
  163. aad(&sa)->info = info;
  164. aad(&sa)->error = error;
  165. return aa_audit(audit_type, profile, &sa, audit_cb);
  166. }
  167. /**
  168. * match_mnt_flags - Do an ordered match on mount flags
  169. * @dfa: dfa to match against
  170. * @state: state to start in
  171. * @flags: mount flags to match against
  172. *
  173. * Mount flags are encoded as an ordered match. This is done instead of
  174. * checking against a simple bitmask, to allow for logical operations
  175. * on the flags.
  176. *
  177. * Returns: next state after flags match
  178. */
  179. static unsigned int match_mnt_flags(struct aa_dfa *dfa, unsigned int state,
  180. unsigned long flags)
  181. {
  182. unsigned int i;
  183. for (i = 0; i <= 31 ; ++i) {
  184. if ((1 << i) & flags)
  185. state = aa_dfa_next(dfa, state, i + 1);
  186. }
  187. return state;
  188. }
  189. /**
  190. * compute_mnt_perms - compute mount permission associated with @state
  191. * @dfa: dfa to match against (NOT NULL)
  192. * @state: state match finished in
  193. *
  194. * Returns: mount permissions
  195. */
  196. static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa,
  197. unsigned int state)
  198. {
  199. struct aa_perms perms;
  200. perms.kill = 0;
  201. perms.allow = dfa_user_allow(dfa, state);
  202. perms.audit = dfa_user_audit(dfa, state);
  203. perms.quiet = dfa_user_quiet(dfa, state);
  204. perms.xindex = dfa_user_xindex(dfa, state);
  205. return perms;
  206. }
  207. static const char * const mnt_info_table[] = {
  208. "match succeeded",
  209. "failed mntpnt match",
  210. "failed srcname match",
  211. "failed type match",
  212. "failed flags match",
  213. "failed data match"
  214. };
  215. /*
  216. * Returns 0 on success else element that match failed in, this is the
  217. * index into the mnt_info_table above
  218. */
  219. static int do_match_mnt(struct aa_dfa *dfa, unsigned int start,
  220. const char *mntpnt, const char *devname,
  221. const char *type, unsigned long flags,
  222. void *data, bool binary, struct aa_perms *perms)
  223. {
  224. unsigned int state;
  225. AA_BUG(!dfa);
  226. AA_BUG(!perms);
  227. state = aa_dfa_match(dfa, start, mntpnt);
  228. state = aa_dfa_null_transition(dfa, state);
  229. if (!state)
  230. return 1;
  231. if (devname)
  232. state = aa_dfa_match(dfa, state, devname);
  233. state = aa_dfa_null_transition(dfa, state);
  234. if (!state)
  235. return 2;
  236. if (type)
  237. state = aa_dfa_match(dfa, state, type);
  238. state = aa_dfa_null_transition(dfa, state);
  239. if (!state)
  240. return 3;
  241. state = match_mnt_flags(dfa, state, flags);
  242. if (!state)
  243. return 4;
  244. *perms = compute_mnt_perms(dfa, state);
  245. if (perms->allow & AA_MAY_MOUNT)
  246. return 0;
  247. /* only match data if not binary and the DFA flags data is expected */
  248. if (data && !binary && (perms->allow & AA_MNT_CONT_MATCH)) {
  249. state = aa_dfa_null_transition(dfa, state);
  250. if (!state)
  251. return 4;
  252. state = aa_dfa_match(dfa, state, data);
  253. if (!state)
  254. return 5;
  255. *perms = compute_mnt_perms(dfa, state);
  256. if (perms->allow & AA_MAY_MOUNT)
  257. return 0;
  258. }
  259. /* failed at end of flags match */
  260. return 4;
  261. }
  262. static int path_flags(struct aa_profile *profile, const struct path *path)
  263. {
  264. AA_BUG(!profile);
  265. AA_BUG(!path);
  266. return profile->path_flags |
  267. (S_ISDIR(path->dentry->d_inode->i_mode) ? PATH_IS_DIR : 0);
  268. }
  269. /**
  270. * match_mnt_path_str - handle path matching for mount
  271. * @profile: the confining profile
  272. * @mntpath: for the mntpnt (NOT NULL)
  273. * @buffer: buffer to be used to lookup mntpath
  274. * @devnme: string for the devname/src_name (MAY BE NULL OR ERRPTR)
  275. * @type: string for the dev type (MAYBE NULL)
  276. * @flags: mount flags to match
  277. * @data: fs mount data (MAYBE NULL)
  278. * @binary: whether @data is binary
  279. * @devinfo: error str if (IS_ERR(@devname))
  280. *
  281. * Returns: 0 on success else error
  282. */
  283. static int match_mnt_path_str(struct aa_profile *profile,
  284. const struct path *mntpath, char *buffer,
  285. const char *devname, const char *type,
  286. unsigned long flags, void *data, bool binary,
  287. const char *devinfo)
  288. {
  289. struct aa_perms perms = { };
  290. const char *mntpnt = NULL, *info = NULL;
  291. int pos, error;
  292. AA_BUG(!profile);
  293. AA_BUG(!mntpath);
  294. AA_BUG(!buffer);
  295. if (!PROFILE_MEDIATES(profile, AA_CLASS_MOUNT))
  296. return 0;
  297. error = aa_path_name(mntpath, path_flags(profile, mntpath), buffer,
  298. &mntpnt, &info, profile->disconnected);
  299. if (error)
  300. goto audit;
  301. if (IS_ERR(devname)) {
  302. error = PTR_ERR(devname);
  303. devname = NULL;
  304. info = devinfo;
  305. goto audit;
  306. }
  307. error = -EACCES;
  308. pos = do_match_mnt(profile->policy.dfa,
  309. profile->policy.start[AA_CLASS_MOUNT],
  310. mntpnt, devname, type, flags, data, binary, &perms);
  311. if (pos) {
  312. info = mnt_info_table[pos];
  313. goto audit;
  314. }
  315. error = 0;
  316. audit:
  317. return audit_mount(profile, OP_MOUNT, mntpnt, devname, type, NULL,
  318. flags, data, AA_MAY_MOUNT, &perms, info, error);
  319. }
  320. /**
  321. * match_mnt - handle path matching for mount
  322. * @profile: the confining profile
  323. * @mntpath: for the mntpnt (NOT NULL)
  324. * @buffer: buffer to be used to lookup mntpath
  325. * @devpath: path devname/src_name (MAYBE NULL)
  326. * @devbuffer: buffer to be used to lookup devname/src_name
  327. * @type: string for the dev type (MAYBE NULL)
  328. * @flags: mount flags to match
  329. * @data: fs mount data (MAYBE NULL)
  330. * @binary: whether @data is binary
  331. *
  332. * Returns: 0 on success else error
  333. */
  334. static int match_mnt(struct aa_profile *profile, const struct path *path,
  335. char *buffer, struct path *devpath, char *devbuffer,
  336. const char *type, unsigned long flags, void *data,
  337. bool binary)
  338. {
  339. const char *devname = NULL, *info = NULL;
  340. int error = -EACCES;
  341. AA_BUG(!profile);
  342. AA_BUG(devpath && !devbuffer);
  343. if (!PROFILE_MEDIATES(profile, AA_CLASS_MOUNT))
  344. return 0;
  345. if (devpath) {
  346. error = aa_path_name(devpath, path_flags(profile, devpath),
  347. devbuffer, &devname, &info,
  348. profile->disconnected);
  349. if (error)
  350. devname = ERR_PTR(error);
  351. }
  352. return match_mnt_path_str(profile, path, buffer, devname, type, flags,
  353. data, binary, info);
  354. }
  355. int aa_remount(struct aa_label *label, const struct path *path,
  356. unsigned long flags, void *data)
  357. {
  358. struct aa_profile *profile;
  359. char *buffer = NULL;
  360. bool binary;
  361. int error;
  362. AA_BUG(!label);
  363. AA_BUG(!path);
  364. binary = path->dentry->d_sb->s_type->fs_flags & FS_BINARY_MOUNTDATA;
  365. get_buffers(buffer);
  366. error = fn_for_each_confined(label, profile,
  367. match_mnt(profile, path, buffer, NULL, NULL, NULL,
  368. flags, data, binary));
  369. put_buffers(buffer);
  370. return error;
  371. }
  372. int aa_bind_mount(struct aa_label *label, const struct path *path,
  373. const char *dev_name, unsigned long flags)
  374. {
  375. struct aa_profile *profile;
  376. char *buffer = NULL, *old_buffer = NULL;
  377. struct path old_path;
  378. int error;
  379. AA_BUG(!label);
  380. AA_BUG(!path);
  381. if (!dev_name || !*dev_name)
  382. return -EINVAL;
  383. flags &= MS_REC | MS_BIND;
  384. error = kern_path(dev_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
  385. if (error)
  386. return error;
  387. get_buffers(buffer, old_buffer);
  388. error = fn_for_each_confined(label, profile,
  389. match_mnt(profile, path, buffer, &old_path, old_buffer,
  390. NULL, flags, NULL, false));
  391. put_buffers(buffer, old_buffer);
  392. path_put(&old_path);
  393. return error;
  394. }
  395. int aa_mount_change_type(struct aa_label *label, const struct path *path,
  396. unsigned long flags)
  397. {
  398. struct aa_profile *profile;
  399. char *buffer = NULL;
  400. int error;
  401. AA_BUG(!label);
  402. AA_BUG(!path);
  403. /* These are the flags allowed by do_change_type() */
  404. flags &= (MS_REC | MS_SILENT | MS_SHARED | MS_PRIVATE | MS_SLAVE |
  405. MS_UNBINDABLE);
  406. get_buffers(buffer);
  407. error = fn_for_each_confined(label, profile,
  408. match_mnt(profile, path, buffer, NULL, NULL, NULL,
  409. flags, NULL, false));
  410. put_buffers(buffer);
  411. return error;
  412. }
  413. int aa_move_mount(struct aa_label *label, const struct path *path,
  414. const char *orig_name)
  415. {
  416. struct aa_profile *profile;
  417. char *buffer = NULL, *old_buffer = NULL;
  418. struct path old_path;
  419. int error;
  420. AA_BUG(!label);
  421. AA_BUG(!path);
  422. if (!orig_name || !*orig_name)
  423. return -EINVAL;
  424. error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path);
  425. if (error)
  426. return error;
  427. get_buffers(buffer, old_buffer);
  428. error = fn_for_each_confined(label, profile,
  429. match_mnt(profile, path, buffer, &old_path, old_buffer,
  430. NULL, MS_MOVE, NULL, false));
  431. put_buffers(buffer, old_buffer);
  432. path_put(&old_path);
  433. return error;
  434. }
  435. int aa_new_mount(struct aa_label *label, const char *dev_name,
  436. const struct path *path, const char *type, unsigned long flags,
  437. void *data)
  438. {
  439. struct aa_profile *profile;
  440. char *buffer = NULL, *dev_buffer = NULL;
  441. bool binary = true;
  442. int error;
  443. int requires_dev = 0;
  444. struct path tmp_path, *dev_path = NULL;
  445. AA_BUG(!label);
  446. AA_BUG(!path);
  447. if (type) {
  448. struct file_system_type *fstype;
  449. fstype = get_fs_type(type);
  450. if (!fstype)
  451. return -ENODEV;
  452. binary = fstype->fs_flags & FS_BINARY_MOUNTDATA;
  453. requires_dev = fstype->fs_flags & FS_REQUIRES_DEV;
  454. put_filesystem(fstype);
  455. if (requires_dev) {
  456. if (!dev_name || !*dev_name)
  457. return -ENOENT;
  458. error = kern_path(dev_name, LOOKUP_FOLLOW, &tmp_path);
  459. if (error)
  460. return error;
  461. dev_path = &tmp_path;
  462. }
  463. }
  464. get_buffers(buffer, dev_buffer);
  465. if (dev_path) {
  466. error = fn_for_each_confined(label, profile,
  467. match_mnt(profile, path, buffer, dev_path, dev_buffer,
  468. type, flags, data, binary));
  469. } else {
  470. error = fn_for_each_confined(label, profile,
  471. match_mnt_path_str(profile, path, buffer, dev_name,
  472. type, flags, data, binary, NULL));
  473. }
  474. put_buffers(buffer, dev_buffer);
  475. if (dev_path)
  476. path_put(dev_path);
  477. return error;
  478. }
  479. static int profile_umount(struct aa_profile *profile, struct path *path,
  480. char *buffer)
  481. {
  482. struct aa_perms perms = { };
  483. const char *name = NULL, *info = NULL;
  484. unsigned int state;
  485. int error;
  486. AA_BUG(!profile);
  487. AA_BUG(!path);
  488. if (!PROFILE_MEDIATES(profile, AA_CLASS_MOUNT))
  489. return 0;
  490. error = aa_path_name(path, path_flags(profile, path), buffer, &name,
  491. &info, profile->disconnected);
  492. if (error)
  493. goto audit;
  494. state = aa_dfa_match(profile->policy.dfa,
  495. profile->policy.start[AA_CLASS_MOUNT],
  496. name);
  497. perms = compute_mnt_perms(profile->policy.dfa, state);
  498. if (AA_MAY_UMOUNT & ~perms.allow)
  499. error = -EACCES;
  500. audit:
  501. return audit_mount(profile, OP_UMOUNT, name, NULL, NULL, NULL, 0, NULL,
  502. AA_MAY_UMOUNT, &perms, info, error);
  503. }
  504. int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags)
  505. {
  506. struct aa_profile *profile;
  507. char *buffer = NULL;
  508. int error;
  509. struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
  510. AA_BUG(!label);
  511. AA_BUG(!mnt);
  512. get_buffers(buffer);
  513. error = fn_for_each_confined(label, profile,
  514. profile_umount(profile, &path, buffer));
  515. put_buffers(buffer);
  516. return error;
  517. }
  518. /* helper fn for transition on pivotroot
  519. *
  520. * Returns: label for transition or ERR_PTR. Does not return NULL
  521. */
  522. static struct aa_label *build_pivotroot(struct aa_profile *profile,
  523. const struct path *new_path,
  524. char *new_buffer,
  525. const struct path *old_path,
  526. char *old_buffer)
  527. {
  528. const char *old_name, *new_name = NULL, *info = NULL;
  529. const char *trans_name = NULL;
  530. struct aa_perms perms = { };
  531. unsigned int state;
  532. int error;
  533. AA_BUG(!profile);
  534. AA_BUG(!new_path);
  535. AA_BUG(!old_path);
  536. if (profile_unconfined(profile) ||
  537. !PROFILE_MEDIATES(profile, AA_CLASS_MOUNT))
  538. return aa_get_newest_label(&profile->label);
  539. error = aa_path_name(old_path, path_flags(profile, old_path),
  540. old_buffer, &old_name, &info,
  541. profile->disconnected);
  542. if (error)
  543. goto audit;
  544. error = aa_path_name(new_path, path_flags(profile, new_path),
  545. new_buffer, &new_name, &info,
  546. profile->disconnected);
  547. if (error)
  548. goto audit;
  549. error = -EACCES;
  550. state = aa_dfa_match(profile->policy.dfa,
  551. profile->policy.start[AA_CLASS_MOUNT],
  552. new_name);
  553. state = aa_dfa_null_transition(profile->policy.dfa, state);
  554. state = aa_dfa_match(profile->policy.dfa, state, old_name);
  555. perms = compute_mnt_perms(profile->policy.dfa, state);
  556. if (AA_MAY_PIVOTROOT & perms.allow)
  557. error = 0;
  558. audit:
  559. error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name,
  560. NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT,
  561. &perms, info, error);
  562. if (error)
  563. return ERR_PTR(error);
  564. return aa_get_newest_label(&profile->label);
  565. }
  566. int aa_pivotroot(struct aa_label *label, const struct path *old_path,
  567. const struct path *new_path)
  568. {
  569. struct aa_profile *profile;
  570. struct aa_label *target = NULL;
  571. char *old_buffer = NULL, *new_buffer = NULL, *info = NULL;
  572. int error;
  573. AA_BUG(!label);
  574. AA_BUG(!old_path);
  575. AA_BUG(!new_path);
  576. get_buffers(old_buffer, new_buffer);
  577. target = fn_label_build(label, profile, GFP_ATOMIC,
  578. build_pivotroot(profile, new_path, new_buffer,
  579. old_path, old_buffer));
  580. if (!target) {
  581. info = "label build failed";
  582. error = -ENOMEM;
  583. goto fail;
  584. } else if (!IS_ERR(target)) {
  585. error = aa_replace_current_label(target);
  586. if (error) {
  587. /* TODO: audit target */
  588. aa_put_label(target);
  589. goto out;
  590. }
  591. } else
  592. /* already audited error */
  593. error = PTR_ERR(target);
  594. out:
  595. put_buffers(old_buffer, new_buffer);
  596. return error;
  597. fail:
  598. /* TODO: add back in auditing of new_name and old_name */
  599. error = fn_for_each(label, profile,
  600. audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */,
  601. NULL /* old_name */,
  602. NULL, NULL,
  603. 0, NULL, AA_MAY_PIVOTROOT, &nullperms, info,
  604. error));
  605. goto out;
  606. }