/* * xentoolcore_internal.h * * Interfaces of xentoolcore directed internally at other Xen libraries * * Copyright (c) 2017 Citrix * * Common code used by all Xen tools libraries * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see . */ #ifndef XENTOOLCORE_INTERNAL_H #define XENTOOLCORE_INTERNAL_H #include #include "xentoolcore.h" #include "_xentoolcore_list.h" /*---------- active handle registration ----------*/ /* * This is all to support xentoolcore_restrict_all * * Any libxl library that opens a Xen control handle of any kind which * might allow manipulation of dom0, of other domains, or of the whole * machine, must: * I. arrange that their own datastructure contains a * Xentoolcore__Active_Handle * * II. during the "open handle" function * 1. allocate the memory for the own datastructure and initialise it * 2. set Xentoolcore__Active_Handle.restrict_callback * 3. call xentoolcore__register_active_handle * 3a. if the open fails, call xentoolcore__deregister_active_handle * 4. ONLY THEN actually open the relevant fd or whatever * * III. during the "close handle" function * 1. FIRST call xentoolcore__deregister_active_handle * 2. close the relevant fd or whatever * * [ III(b). Do the same as III for error exit from the open function. ] * * IV. in the restrict_callback function * * Arrange that the fd (or other handle) can no longer by used * other than with respect to domain domid. * * Future attempts to manipulate other domains (or the whole * host) via this handle must cause an error return (and * perhaps a log message), not a crash * * If selective restriction is not possible, the handle must * be completely invalidated so that it is not useable; * subsequent manipulations may not crash * * The restrict_callback function should not normally fail * if this can be easily avoided - it is better to make the * handle nonfunction instead. * * NB that restrict_callback might be called again. That must * work properly: if the domid is the same, it is idempotent. * If the domid is different. then either the handle must be * completely invalidated, or restrict_callback must fail.) * * Thread safety: * xentoolcore__[de]register_active_handle are threadsafe * but MUST NOT be called within restrict_callback * * Fork safety: * Libraries which use these functions do not on that account * need to take any special care over forks occurring in * other threads, provided that they obey the rules above. */ typedef struct Xentoolcore__Active_Handle Xentoolcore__Active_Handle; typedef int Xentoolcore__Restrict_Callback(Xentoolcore__Active_Handle*, domid_t domid); struct Xentoolcore__Active_Handle { Xentoolcore__Restrict_Callback *restrict_callback; XENTOOLCORE_LIST_ENTRY(Xentoolcore__Active_Handle) entry; }; void xentoolcore__register_active_handle(Xentoolcore__Active_Handle*); void xentoolcore__deregister_active_handle(Xentoolcore__Active_Handle*); /* * Utility function for use in restrict_callback in libraries whose * handles don't have a useful restrict function. We neuter the fd by * dup'ing /dev/null onto it. This is better than closing it, because * it does not involve locking against concurrent uses of in other * threads. * * Returns the value that restrict_callback should return. * fd may be < 0. */ int xentoolcore__restrict_by_dup2_null(int fd); /* ---------- convenient stuff ---------- */ /* * This does not appear in xentoolcore.h because it is a bit * namespace-unclean. */ /* * Convenience macros. */ /* * CONTAINER_OF work like this. Given: * typedef struct { * ... * member_type member_name; * ... * } outer_type; * outer_type outer, *outer_var; * member_type *inner_ptr = &outer->member_name; * * Then, effectively: * outer_type *CONTAINER_OF(member_type *inner_ptr, * *outer_var, // or type name for outer_type * member_name); * * So that: * CONTAINER_OF(inner_ptr, *outer_var, member_name) == &outer * CONTAINER_OF(inner_ptr, outer_type, member_name) == &outer */ #define CONTAINER_OF(inner_ptr, outer, member_name) \ ({ \ typeof(outer) *container_of_; \ container_of_ = (void*)((char*)(inner_ptr) - \ offsetof(typeof(outer), member_name)); \ (void)(&container_of_->member_name == \ (typeof(inner_ptr))0) /* type check */; \ container_of_; \ }) #endif /* XENTOOLCORE_INTERNAL_H */ /* * Local variables: * mode: C * c-file-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */