[PATCH 1/2] Filesystem: Add and use rtems_filesystem_chmod()

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Sep 11 09:01:11 UTC 2013


Implement POSIX requirements in the high-level file system layer.
---
 cpukit/libcsupport/include/rtems/libio_.h |    5 +++
 cpukit/libcsupport/src/chmod.c            |    2 +-
 cpukit/libcsupport/src/fchmod.c           |   49 ++++++++++++++++++++++++-----
 cpukit/libfs/src/imfs/imfs_fchmod.c       |   20 +-----------
 cpukit/libfs/src/rfs/rtems-rfs-rtems.c    |   24 +-------------
 5 files changed, 49 insertions(+), 51 deletions(-)

diff --git a/cpukit/libcsupport/include/rtems/libio_.h b/cpukit/libcsupport/include/rtems/libio_.h
index 55156c0..4a0623e 100644
--- a/cpukit/libcsupport/include/rtems/libio_.h
+++ b/cpukit/libcsupport/include/rtems/libio_.h
@@ -566,6 +566,11 @@ int rtems_filesystem_mknod(
 
 int rtems_filesystem_chdir( rtems_filesystem_location_info_t *loc );
 
+int rtems_filesystem_chmod(
+  const rtems_filesystem_location_info_t *loc,
+  mode_t mode
+);
+
 int rtems_filesystem_chown(
   const char *path,
   uid_t owner,
diff --git a/cpukit/libcsupport/src/chmod.c b/cpukit/libcsupport/src/chmod.c
index 8b91b60..a8785d4 100644
--- a/cpukit/libcsupport/src/chmod.c
+++ b/cpukit/libcsupport/src/chmod.c
@@ -33,7 +33,7 @@ int chmod( const char *path, mode_t mode )
   const rtems_filesystem_location_info_t *currentloc =
     rtems_filesystem_eval_path_start( &ctx, path, eval_flags );
 
-  rv = (*currentloc->mt_entry->ops->fchmod_h)( currentloc, mode );
+  rv = rtems_filesystem_chmod( currentloc, mode );
 
   rtems_filesystem_eval_path_cleanup( &ctx );
 
diff --git a/cpukit/libcsupport/src/fchmod.c b/cpukit/libcsupport/src/fchmod.c
index 94e8264..b8f4d33 100644
--- a/cpukit/libcsupport/src/fchmod.c
+++ b/cpukit/libcsupport/src/fchmod.c
@@ -22,6 +22,42 @@
 
 #include <rtems/libio_.h>
 
+int rtems_filesystem_chmod(
+  const rtems_filesystem_location_info_t *loc,
+  mode_t mode
+)
+{
+  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
+  int rv;
+
+  if ( mt_entry->writeable || rtems_filesystem_location_is_null( loc ) ) {
+    struct stat st;
+
+    memset( &st, 0, sizeof(st) );
+
+    rv = (*loc->handlers->fstat_h)( loc, &st );
+    if ( rv == 0 ) {
+      uid_t uid = geteuid();
+
+      if ( uid == 0 || st.st_uid == uid ) {
+        mode_t mask = S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX;
+
+        mode = (st.st_mode & ~mask) | (mode & mask);
+
+        rv = (*mt_entry->ops->fchmod_h)( loc, mode );
+      } else {
+        errno = EPERM;
+        rv = -1;
+      }
+    }
+  } else {
+    errno = EROFS;
+    rv = -1;
+  }
+
+  return rv;
+}
+
 /**
  *  POSIX 1003.1b 5.6.4 - Change File Modes
  */
@@ -34,14 +70,11 @@ int fchmod( int fd, mode_t mode )
   iop = rtems_libio_iop( fd );
   rtems_libio_check_is_open(iop);
 
-  if (iop->pathinfo.mt_entry->writeable) {
-    rtems_filesystem_instance_lock( &iop->pathinfo );
-    rv = (*iop->pathinfo.mt_entry->ops->fchmod_h)( &iop->pathinfo, mode );
-    rtems_filesystem_instance_unlock( &iop->pathinfo );
-  } else {
-    errno = EROFS;
-    rv = -1;
-  }
+  rtems_filesystem_instance_lock( &iop->pathinfo );
+
+  rv = rtems_filesystem_chmod( &iop->pathinfo, mode );
+
+  rtems_filesystem_instance_unlock( &iop->pathinfo );
 
   return rv;
 }
diff --git a/cpukit/libfs/src/imfs/imfs_fchmod.c b/cpukit/libfs/src/imfs/imfs_fchmod.c
index ccb3446..5111944 100644
--- a/cpukit/libfs/src/imfs/imfs_fchmod.c
+++ b/cpukit/libfs/src/imfs/imfs_fchmod.c
@@ -26,28 +26,10 @@ int IMFS_fchmod(
 )
 {
   IMFS_jnode_t  *jnode;
-#if defined(RTEMS_POSIX_API)
-  uid_t          st_uid;
-#endif
 
   jnode = loc->node_access;
 
-  /*
-   *  Verify I am the owner of the node or the super user.
-   */
-#if defined(RTEMS_POSIX_API)
-  st_uid = geteuid();
-
-  if ( ( st_uid != jnode->st_uid ) && ( st_uid != 0 ) )
-    rtems_set_errno_and_return_minus_one( EPERM );
-#endif
-
-  /*
-   * Change only the RWX permissions on the jnode to mode.
-   */
-
-  jnode->st_mode &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
-  jnode->st_mode |= mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
+  jnode->st_mode = mode;
 
   IMFS_update_ctime( jnode );
 
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
index 37daeea..4e3370b 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
@@ -468,10 +468,6 @@ rtems_rfs_rtems_fchmod (const rtems_filesystem_location_info_t* pathloc,
   rtems_rfs_file_system*  fs = rtems_rfs_rtems_pathloc_dev (pathloc);
   rtems_rfs_ino           ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
   rtems_rfs_inode_handle  inode;
-  uint16_t                imode;
-#if defined (RTEMS_POSIX_API)
-  uid_t                   uid;
-#endif
   int                     rc;
 
   if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FCHMOD))
@@ -484,25 +480,7 @@ rtems_rfs_rtems_fchmod (const rtems_filesystem_location_info_t* pathloc,
     return rtems_rfs_rtems_error ("fchmod: opening inode", rc);
   }
 
-  imode = rtems_rfs_inode_get_mode (&inode);
-
-  /*
-   *  Verify I am the owner of the node or the super user.
-   */
-#if defined (RTEMS_POSIX_API)
-  uid = geteuid();
-
-  if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0))
-  {
-    rtems_rfs_inode_close (fs, &inode);
-    return rtems_rfs_rtems_error ("fchmod: checking uid", EPERM);
-  }
-#endif
-
-  imode &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
-  imode |= mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
-
-  rtems_rfs_inode_set_mode (&inode, imode);
+  rtems_rfs_inode_set_mode (&inode, mode);
 
   rc = rtems_rfs_inode_close (fs, &inode);
   if (rc > 0)
-- 
1.7.7




More information about the devel mailing list