Commit 59444fad authored by J. R. Okajima's avatar J. R. Okajima
Browse files

aufs: mount option, warning about the permissions



While most people (especially who use tmpfs as top writable branch)
doesn't care, I care and think it can be a security problem.
For example, when the lower readonly branch may contain
/etc/{passwd,shadow} and the permission bits of the upper empty
branch is world-writable, then a malicious user can make these files
manually with by-passing aufs.
Aufs can do nothing but produce a warning.

For details, see aufs manual in aufs-util.git.
Signed-off-by: default avatarJ. R. Okajima <hooanon05g@gmail.com>
parent 852c25f7
...@@ -187,8 +187,8 @@ static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) ...@@ -187,8 +187,8 @@ static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
{ {
int err; int err;
aufs_bindex_t bbot, bindex; aufs_bindex_t bbot, bindex;
struct dentry *root; struct dentry *root, *h_dentry;
struct inode *inode; struct inode *inode, *h_inode;
root = sb->s_root; root = sb->s_root;
bbot = au_sbbot(sb); bbot = au_sbbot(sb);
...@@ -256,6 +256,19 @@ static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) ...@@ -256,6 +256,19 @@ static int test_add(struct super_block *sb, struct au_opt_add *add, int remount)
} }
err = 0; err = 0;
if (au_opt_test(au_mntflags(sb), WARN_PERM)) {
h_dentry = au_h_dptr(root, 0);
h_inode = d_inode(h_dentry);
if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO)
|| !uid_eq(h_inode->i_uid, inode->i_uid)
|| !gid_eq(h_inode->i_gid, inode->i_gid))
pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n",
add->pathname,
i_uid_read(inode), i_gid_read(inode),
(inode->i_mode & S_IALLUGO),
i_uid_read(h_inode), i_gid_read(h_inode),
(h_inode->i_mode & S_IALLUGO));
}
out: out:
return err; return err;
......
...@@ -27,6 +27,7 @@ enum { ...@@ -27,6 +27,7 @@ enum {
Opt_plink, Opt_noplink, Opt_list_plink, Opt_plink, Opt_noplink, Opt_list_plink,
Opt_udba, Opt_udba,
Opt_dio, Opt_nodio, Opt_dio, Opt_nodio,
Opt_warn_perm, Opt_nowarn_perm,
Opt_wbr_copyup, Opt_wbr_create, Opt_wbr_copyup, Opt_wbr_create,
Opt_verbose, Opt_noverbose, Opt_verbose, Opt_noverbose,
Opt_sum, Opt_nosum, Opt_wsum, Opt_sum, Opt_nosum, Opt_wsum,
...@@ -94,6 +95,9 @@ static match_table_t options = { ...@@ -94,6 +95,9 @@ static match_table_t options = {
{Opt_ignore_silent, "nodirren"}, {Opt_ignore_silent, "nodirren"},
#endif #endif
{Opt_warn_perm, "warn_perm"},
{Opt_nowarn_perm, "nowarn_perm"},
{Opt_dirperm1, "dirperm1"}, {Opt_dirperm1, "dirperm1"},
{Opt_nodirperm1, "nodirperm1"}, {Opt_nodirperm1, "nodirperm1"},
...@@ -601,6 +605,12 @@ static void dump_opts(struct au_opts *opts) ...@@ -601,6 +605,12 @@ static void dump_opts(struct au_opts *opts)
case Opt_nodio: case Opt_nodio:
AuLabel(nodio); AuLabel(nodio);
break; break;
case Opt_warn_perm:
AuLabel(warn_perm);
break;
case Opt_nowarn_perm:
AuLabel(nowarn_perm);
break;
case Opt_verbose: case Opt_verbose:
AuLabel(verbose); AuLabel(verbose);
break; break;
...@@ -1086,6 +1096,8 @@ int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts) ...@@ -1086,6 +1096,8 @@ int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts)
case Opt_list_plink: case Opt_list_plink:
case Opt_dio: case Opt_dio:
case Opt_nodio: case Opt_nodio:
case Opt_warn_perm:
case Opt_nowarn_perm:
case Opt_verbose: case Opt_verbose:
case Opt_noverbose: case Opt_noverbose:
case Opt_sum: case Opt_sum:
...@@ -1247,6 +1259,13 @@ static int au_opt_simple(struct super_block *sb, struct au_opt *opt, ...@@ -1247,6 +1259,13 @@ static int au_opt_simple(struct super_block *sb, struct au_opt *opt,
au_fset_opts(opts->flags, REFRESH_DYAOP); au_fset_opts(opts->flags, REFRESH_DYAOP);
break; break;
case Opt_warn_perm:
au_opt_set(sbinfo->si_mntflags, WARN_PERM);
break;
case Opt_nowarn_perm:
au_opt_clr(sbinfo->si_mntflags, WARN_PERM);
break;
case Opt_verbose: case Opt_verbose:
au_opt_set(sbinfo->si_mntflags, VERBOSE); au_opt_set(sbinfo->si_mntflags, VERBOSE);
break; break;
......
...@@ -30,6 +30,7 @@ struct file; ...@@ -30,6 +30,7 @@ struct file;
bits */ bits */
#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */ #define AuOpt_SUM (1 << 10) /* summation for statfs(2) */
#define AuOpt_SUM_W (1 << 11) /* unimplemented */ #define AuOpt_SUM_W (1 << 11) /* unimplemented */
#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */
#define AuOpt_VERBOSE (1 << 13) /* print the cause of error */ #define AuOpt_VERBOSE (1 << 13) /* print the cause of error */
#define AuOpt_DIO (1 << 14) /* direct io */ #define AuOpt_DIO (1 << 14) /* direct io */
#define AuOpt_DIRREN (1 << 15) /* directory rename */ #define AuOpt_DIRREN (1 << 15) /* directory rename */
...@@ -47,7 +48,7 @@ struct file; ...@@ -47,7 +48,7 @@ struct file;
| AuOpt_UDBA_REVAL \ | AuOpt_UDBA_REVAL \
| AuOpt_PLINK \ | AuOpt_PLINK \
/* | AuOpt_DIRPERM1 */ \ /* | AuOpt_DIRPERM1 */ \
) | AuOpt_WARN_PERM)
#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ #define AuOptMask_UDBA (AuOpt_UDBA_NONE \
| AuOpt_UDBA_REVAL \ | AuOpt_UDBA_REVAL \
| AuOpt_UDBA_HNOTIFY) | AuOpt_UDBA_HNOTIFY)
......
...@@ -279,6 +279,7 @@ static int aufs_show_options(struct seq_file *m, struct dentry *dentry) ...@@ -279,6 +279,7 @@ static int aufs_show_options(struct seq_file *m, struct dentry *dentry)
AuBool(DIRREN, dirren); AuBool(DIRREN, dirren);
AuBool(SUM, sum); AuBool(SUM, sum);
/* AuBool(SUM_W, wsum); */ /* AuBool(SUM_W, wsum); */
AuBool(WARN_PERM, warn_perm);
AuBool(VERBOSE, verbose); AuBool(VERBOSE, verbose);
out: out:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment