summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-06-10 14:22:31 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2014-06-18 15:57:00 +0200
commit944cfdbe6cff4e8025a730228b48c1a21b4a2e33 (patch)
tree32accaee79c274514ead2fadd1a9975b2000fe8b
parent8821d8a213008eb723414c6c70de384830ea10d7 (diff)
libdiskfs: add permission check to file_chflags
Only root is allowed to change the high 16 bits. The TODO entry says otherwise, but that must be a mistake. For reference, see the glibc sources, sysdeps/mach/hurd/bits/stat.h. * libdiskfs/file-chflags.c (diskfs_S_file_chflags): Add permission check. * TODO (libdiskfs): Remove entry.
-rw-r--r--TODO2
-rw-r--r--libdiskfs/file-chflags.c8
2 files changed, 8 insertions, 2 deletions
diff --git a/TODO b/TODO
index d2500dc3..0387e9f3 100644
--- a/TODO
+++ b/TODO
@@ -108,8 +108,6 @@ See `tasks', the exported task list.
Rename the rest to libhurdutil or somesuch.
** libdiskfs
-*** file_chflags does not do proper permission checking (non-root isn't
- supposed to be able to change the low bits)
*** Add the short-circuited-but-not-builtin translator startup code from
dir-lookup to fsys_getroot. Compare and match carefully these two
routines and then share common code.
diff --git a/libdiskfs/file-chflags.c b/libdiskfs/file-chflags.c
index 01dc495c..a29ff07c 100644
--- a/libdiskfs/file-chflags.c
+++ b/libdiskfs/file-chflags.c
@@ -23,8 +23,15 @@ kern_return_t
diskfs_S_file_chflags (struct protid *cred,
int flags)
{
+#define HI(X) ((X) & 0xffff0000u)
CHANGE_NODE_FIELD (cred,
({
+ /* Only root is allowed to change the high 16
+ bits. */
+ if ((HI (flags) != HI (np->dn_stat.st_flags))
+ && ! idvec_contains (cred->user->uids, 0))
+ return EPERM;
+
err = fshelp_isowner (&np->dn_stat, cred->user);
if (!err)
err = diskfs_validate_flags_change (np, flags);
@@ -37,4 +44,5 @@ diskfs_S_file_chflags (struct protid *cred,
diskfs_notice_filechange(np, FILE_CHANGED_META,
0, 0);
}));
+#undef HI
}