summaryrefslogtreecommitdiff
path: root/debian/patches/0005-libdiskfs-add-permission-check-to-file_chflags.patch
blob: 3542a2770dfee427066a98ed3f3a3a7b513227d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
From ee535833540e536c88696966ed13c8e5150e2a78 Mon Sep 17 00:00:00 2001
From: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Tue, 10 Jun 2014 14:22:31 +0200
Subject: [PATCH 5/5] 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.
---
 TODO                     | 2 --
 libdiskfs/file-chflags.c | 8 ++++++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/TODO b/TODO
index d2500dc..0387e9f 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 01dc495..84da59c 100644
--- a/libdiskfs/file-chflags.c
+++ b/libdiskfs/file-chflags.c
@@ -25,6 +25,14 @@ diskfs_S_file_chflags (struct protid *cred,
 {
   CHANGE_NODE_FIELD (cred,
 		   ({
+                     /* Only root is allowed to change the high 16
+                        bits.  */
+#define HI(X)	((X) & 0xffff0000u)
+                     if ((HI (flags) != HI (np->dn_stat.st_flags))
+                         && ! idvec_contains (cred->user->uids, 0))
+                       return EPERM;
+#undef HI
+
 		     err = fshelp_isowner (&np->dn_stat, cred->user);
 		     if (!err)
 		       err = diskfs_validate_flags_change (np, flags);
-- 
2.0.0