Skip to content

Commit

Permalink
[image] Add concept of trusted images
Browse files Browse the repository at this point in the history
Trusted images may always be executed.  Untrusted images may be
executed only if the current image trust requirement allows untrusted
images.

Images can be marked as trusted using image_trust(), and marked as
untrusted using image_untrust().

The current image trust requirement can be changed using
image_set_trust().  It is possible to make the change permanent, in
which case any future attempts to change the image trust requirement
will fail.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Mar 22, 2012
1 parent efb0c7f commit 97dcc82
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/core/image.c
Expand Up @@ -36,12 +36,28 @@ FILE_LICENCE ( GPL2_OR_LATER );
*
*/

/* Disambiguate the various error causes */
#define EACCES_UNTRUSTED \
__einfo_error ( EINFO_EACCES_UNTRUSTED )
#define EINFO_EACCES_UNTRUSTED \
__einfo_uniqify ( EINFO_EACCES, 0x01, "Untrusted image" )
#define EACCES_PERMANENT \
__einfo_error ( EINFO_EACCES_PERMANENT )
#define EINFO_EACCES_PERMANENT \
__einfo_uniqify ( EINFO_EACCES, 0x02, "Trust requirement is permanent" )

/** List of registered images */
struct list_head images = LIST_HEAD_INIT ( images );

/** Currently-executing image */
struct image *current_image;

/** Current image trust requirement */
static int require_trusted_images = 0;

/** Prevent changes to image trust requirement */
static int require_trusted_images_permanent = 0;

/**
* Free executable image
*
Expand Down Expand Up @@ -228,6 +244,12 @@ int image_exec ( struct image *image ) {
if ( ( rc = image_select ( image ) ) != 0 )
return rc;

/* Check that image is trusted (if applicable) */
if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
DBGC ( image, "IMAGE %s is not trusted\n", image->name );
return -EACCES_UNTRUSTED;
}

/* Switch current working directory to be that of the image itself */
old_cwuri = uri_get ( cwuri );
churi ( image->uri );
Expand Down Expand Up @@ -355,3 +377,27 @@ struct image * image_find_selected ( void ) {
}
return NULL;
}

/**
* Change image trust requirement
*
* @v require_trusted Require trusted images
* @v permanent Make trust requirement permanent
* @ret rc Return status code
*/
int image_set_trust ( int require_trusted, int permanent ) {

/* Update trust requirement, if permitted to do so */
if ( ! require_trusted_images_permanent ) {
require_trusted_images = require_trusted;
require_trusted_images_permanent = permanent;
}

/* Fail if we attempted to change the trust requirement but
* were not permitted to do so.
*/
if ( require_trusted_images != require_trusted )
return -EACCES_PERMANENT;

return 0;
}
22 changes: 22 additions & 0 deletions src/include/ipxe/image.h
Expand Up @@ -64,6 +64,9 @@ struct image {
/** Image is selected for execution */
#define IMAGE_SELECTED 0x0002

/** Image is trusted */
#define IMAGE_TRUSTED 0x0004

/** An executable image type */
struct image_type {
/** Name of this image type */
Expand Down Expand Up @@ -148,6 +151,7 @@ extern int image_exec ( struct image *image );
extern int image_replace ( struct image *replacement );
extern int image_select ( struct image *image );
extern struct image * image_find_selected ( void );
extern int image_set_trust ( int require_trusted, int permanent );

/**
* Increment reference count on an image
Expand Down Expand Up @@ -181,4 +185,22 @@ static inline int image_set_name ( struct image *image, const char *name ) {
return 0;
}

/**
* Set image as trusted
*
* @v image Image
*/
static inline void image_trust ( struct image *image ) {
image->flags |= IMAGE_TRUSTED;
}

/**
* Set image as untrusted
*
* @v image Image
*/
static inline void image_untrust ( struct image *image ) {
image->flags &= ~IMAGE_TRUSTED;
}

#endif /* _IPXE_IMAGE_H */
2 changes: 2 additions & 0 deletions src/usr/imgmgmt.c
Expand Up @@ -140,6 +140,8 @@ void imgstat ( struct image *image ) {
printf ( "%s : %zd bytes", image->name, image->len );
if ( image->type )
printf ( " [%s]", image->type->name );
if ( image->flags & IMAGE_TRUSTED )
printf ( " [TRUSTED]" );
if ( image->flags & IMAGE_SELECTED )
printf ( " [SELECTED]" );
if ( image->cmdline )
Expand Down

0 comments on commit 97dcc82

Please sign in to comment.