Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:15

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup libcsupport
0007  *
0008  * @brief Change Root Directory
0009  */
0010 
0011 /*
0012  * Copyright (c) 2001 Fernando Ruiz Casas <fruizcasas@gmail.com>
0013  *
0014  * COPYRIGHT (c) 1989-2008.
0015  * On-Line Applications Research Corporation (OAR).
0016  *
0017  * Modifications to support reference counting in the file system are
0018  * Copyright (c) 2012 embedded brains GmbH & Co. KG
0019  *
0020  * Redistribution and use in source and binary forms, with or without
0021  * modification, are permitted provided that the following conditions
0022  * are met:
0023  * 1. Redistributions of source code must retain the above copyright
0024  *    notice, this list of conditions and the following disclaimer.
0025  * 2. Redistributions in binary form must reproduce the above copyright
0026  *    notice, this list of conditions and the following disclaimer in the
0027  *    documentation and/or other materials provided with the distribution.
0028  *
0029  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0030  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0031  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0032  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0033  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0034  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0035  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0036  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0037  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0038  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0039  * POSSIBILITY OF SUCH DAMAGE.
0040  */
0041 
0042 #ifdef HAVE_CONFIG_H
0043 #include "config.h"
0044 #endif
0045 
0046 #include <string.h>
0047 #include <unistd.h>
0048 
0049 #include <rtems/libio_.h>
0050 
0051 int chroot( const char *path )
0052 {
0053   int rv = 0;
0054   rtems_status_code sc = RTEMS_SUCCESSFUL;
0055   rtems_filesystem_eval_path_context_t ctx;
0056   int eval_flags = RTEMS_FS_PERMS_EXEC
0057     | RTEMS_FS_FOLLOW_LINK;
0058   rtems_filesystem_location_info_t loc;
0059   rtems_filesystem_global_location_t *new_current_loc;
0060 
0061   /*
0062    * We use the global environment for path evaluation.  This makes it possible
0063    * to escape from a chroot environment referencing an unmounted file system.
0064    */
0065   rtems_filesystem_eval_path_start_with_root_and_current(
0066     &ctx,
0067     path,
0068     strlen( path ),
0069     eval_flags,
0070     &rtems_global_user_env.root_directory,
0071     &rtems_global_user_env.current_directory
0072   );
0073 
0074   rtems_filesystem_eval_path_extract_currentloc( &ctx, &loc );
0075   new_current_loc = rtems_filesystem_location_transform_to_global( &loc );
0076   if ( !rtems_filesystem_global_location_is_null( new_current_loc ) ) {
0077     rtems_filesystem_global_location_t *new_root_loc =
0078       rtems_filesystem_global_location_obtain( &new_current_loc );
0079     mode_t type = rtems_filesystem_location_type( &new_root_loc->location );
0080 
0081     if ( S_ISDIR( type ) ) {
0082       sc = rtems_libio_set_private_env();
0083       if (sc == RTEMS_SUCCESSFUL) {
0084         rtems_filesystem_global_location_assign(
0085           &rtems_filesystem_root,
0086           new_root_loc
0087         );
0088         rtems_filesystem_global_location_assign(
0089           &rtems_filesystem_current,
0090           new_current_loc
0091         );
0092       } else {
0093         if (sc != RTEMS_UNSATISFIED) {
0094           errno = ENOMEM;
0095         }
0096         rv = -1;
0097       }
0098     } else {
0099       rtems_filesystem_location_error( &new_root_loc->location, ENOTDIR );
0100       rv = -1;
0101     }
0102 
0103     if ( rv != 0 ) {
0104       rtems_filesystem_global_location_release( new_root_loc, true );
0105     }
0106   } else {
0107     rv = -1;
0108   }
0109 
0110   rtems_filesystem_eval_path_cleanup( &ctx );
0111 
0112   if ( rv != 0 ) {
0113     rtems_filesystem_global_location_release( new_current_loc, false );
0114   }
0115 
0116   return rv;
0117 }