about summary refs log tree commit diff homepage
path: root/runtime/POSIX/fd.c
diff options
context:
space:
mode:
authorCristian Cadar <c.cadar@imperial.ac.uk>2023-06-09 23:06:41 +0100
committerMartinNowack <2443641+MartinNowack@users.noreply.github.com>2023-06-11 19:23:24 +0100
commitc10e9e926700773e01f44fbb1917deac7be2aaea (patch)
tree7abfceec757330360ec5d4be383e4c7a5a8933b7 /runtime/POSIX/fd.c
parentdab1c0fa376771be1c3cdd5b8d564484755907dd (diff)
downloadklee-c10e9e926700773e01f44fbb1917deac7be2aaea.tar.gz
Rewrote has_permission in the POSIX runtime. We now only return with permission error a single time in symbolic execution mode.
The rewrite also fixes a bug reported in #1230.
Rewrote the FilePerm.c test accordingly.
Diffstat (limited to 'runtime/POSIX/fd.c')
-rw-r--r--runtime/POSIX/fd.c32
1 files changed, 9 insertions, 23 deletions
diff --git a/runtime/POSIX/fd.c b/runtime/POSIX/fd.c
index be13a40b..b41d4e32 100644
--- a/runtime/POSIX/fd.c
+++ b/runtime/POSIX/fd.c
@@ -106,32 +106,18 @@ mode_t umask(mode_t mask) {
 
 
 /* Returns 1 if the process has the access rights specified by 'flags'
-   to the file with stat 's'.  Returns 0 otherwise*/
+   to the file with stat 's', and returns 0 otherwise. 
+   We allow access if any user has access to the file, so we ignore 
+   s->st_uid / geteuid() and s->st_gid / getegid(). */
 static int has_permission(int flags, struct stat64 *s) {
-  int write_access, read_access;
   mode_t mode = s->st_mode;
-  
-  if (flags & O_RDONLY || flags & O_RDWR)
-    read_access = 1;
-  else read_access = 0;
-
-  if (flags & O_WRONLY || flags & O_RDWR)
-    write_access = 1;
-  else write_access = 0;
-
-  /* XXX: We don't worry about process uid and gid for now. 
-     We allow access if any user has access to the file. */
-#if 0
-  uid_t uid = s->st_uid;
-  uid_t euid = geteuid();
-  gid_t gid = s->st_gid;
-  gid_t egid = getegid();
-#endif  
-
-  if (read_access && ((mode & S_IRUSR) | (mode & S_IRGRP) | (mode & S_IROTH)))
-    return 0;
+  int read_request = ((flags & O_RDONLY) | (flags & O_RDWR)) ? 1 : 0;
+  int write_request = ((flags & O_WRONLY) | (flags & O_RDWR)) ? 1 : 0;
 
-  if (write_access && !((mode & S_IWUSR) | (mode & S_IWGRP) | (mode & S_IWOTH)))
+  /* It is important to do this check using only bitwise operators so that we 
+     return 0 a single time in symbolic execution mode. */
+  if ((read_request  & !((mode & S_IRUSR) | (mode & S_IRGRP) | (mode & S_IROTH))) |
+      (write_request & !((mode & S_IWUSR) | (mode & S_IWGRP) | (mode & S_IWOTH))))
     return 0;
 
   return 1;