]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[image] Add concept of trusted images
authorMichael Brown <mcb30@ipxe.org>
Thu, 22 Mar 2012 13:39:45 +0000 (13:39 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 22 Mar 2012 16:16:02 +0000 (16:16 +0000)
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>
src/core/image.c
src/include/ipxe/image.h
src/usr/imgmgmt.c

index b1eba4ad4da1d7e2c409394b9ab3405ed8ad4a1b..ae09a0727387df0c3c48aeda0a1b93ec9a9497c8 100644 (file)
@@ -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
  *
@@ -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 );
@@ -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;
+}
index dbcd6d64226e487d530794dc793ee26c0a35dbbc..500b216eda26c89de4ccfed96fd5b3df5161795d 100644 (file)
@@ -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 */
@@ -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
@@ -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 */
index e323dd0c56bcb8c5e48a380577efe72aacdf4629..59011415bf3d8ae1b949d729cdacb9d2807d7ceb 100644 (file)
@@ -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 )