1 /* 2 * xentoolcore_internal.h 3 * 4 * Interfaces of xentoolcore directed internally at other Xen libraries 5 * 6 * Copyright (c) 2017 Citrix 7 * 8 * Common code used by all Xen tools libraries 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; 13 * version 2.1 of the License. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #ifndef XENTOOLCORE_INTERNAL_H 25 #define XENTOOLCORE_INTERNAL_H 26 27 #include <stddef.h> 28 29 #include "xentoolcore.h" 30 #include "_xentoolcore_list.h" 31 32 /*---------- active handle registration ----------*/ 33 34 /* 35 * This is all to support xentoolcore_restrict_all 36 * 37 * Any libxl library that opens a Xen control handle of any kind which 38 * might allow manipulation of dom0, of other domains, or of the whole 39 * machine, must: 40 * I. arrange that their own datastructure contains a 41 * Xentoolcore__Active_Handle 42 * 43 * II. during the "open handle" function 44 * 1. allocate the memory for the own datastructure and initialise it 45 * 2. set Xentoolcore__Active_Handle.restrict_callback 46 * 3. call xentoolcore__register_active_handle 47 * 3a. if the open fails, call xentoolcore__deregister_active_handle 48 * 4. ONLY THEN actually open the relevant fd or whatever 49 * 50 * III. during the "close handle" function 51 * 1. FIRST call xentoolcore__deregister_active_handle 52 * 2. close the relevant fd or whatever 53 * 54 * [ III(b). Do the same as III for error exit from the open function. ] 55 * 56 * IV. in the restrict_callback function 57 * * Arrange that the fd (or other handle) can no longer by used 58 * other than with respect to domain domid. 59 * * Future attempts to manipulate other domains (or the whole 60 * host) via this handle must cause an error return (and 61 * perhaps a log message), not a crash 62 * * If selective restriction is not possible, the handle must 63 * be completely invalidated so that it is not useable; 64 * subsequent manipulations may not crash 65 * * The restrict_callback function should not normally fail 66 * if this can be easily avoided - it is better to make the 67 * handle nonfunction instead. 68 * * NB that restrict_callback might be called again. That must 69 * work properly: if the domid is the same, it is idempotent. 70 * If the domid is different. then either the handle must be 71 * completely invalidated, or restrict_callback must fail.) 72 * 73 * Thread safety: 74 * xentoolcore__[de]register_active_handle are threadsafe 75 * but MUST NOT be called within restrict_callback 76 * 77 * Fork safety: 78 * Libraries which use these functions do not on that account 79 * need to take any special care over forks occurring in 80 * other threads, provided that they obey the rules above. 81 */ 82 83 typedef struct Xentoolcore__Active_Handle Xentoolcore__Active_Handle; 84 85 typedef int Xentoolcore__Restrict_Callback(Xentoolcore__Active_Handle*, 86 domid_t domid); 87 88 struct Xentoolcore__Active_Handle { 89 Xentoolcore__Restrict_Callback *restrict_callback; 90 XENTOOLCORE_LIST_ENTRY(Xentoolcore__Active_Handle) entry; 91 }; 92 93 void xentoolcore__register_active_handle(Xentoolcore__Active_Handle*); 94 void xentoolcore__deregister_active_handle(Xentoolcore__Active_Handle*); 95 96 /* 97 * Utility function for use in restrict_callback in libraries whose 98 * handles don't have a useful restrict function. We neuter the fd by 99 * dup'ing /dev/null onto it. This is better than closing it, because 100 * it does not involve locking against concurrent uses of in other 101 * threads. 102 * 103 * Returns the value that restrict_callback should return. 104 * fd may be < 0. 105 */ 106 int xentoolcore__restrict_by_dup2_null(int fd); 107 108 /* ---------- convenient stuff ---------- */ 109 110 /* 111 * This does not appear in xentoolcore.h because it is a bit 112 * namespace-unclean. 113 */ 114 115 /* 116 * Convenience macros. 117 */ 118 119 /* 120 * CONTAINER_OF work like this. Given: 121 * typedef struct { 122 * ... 123 * member_type member_name; 124 * ... 125 * } outer_type; 126 * outer_type outer, *outer_var; 127 * member_type *inner_ptr = &outer->member_name; 128 * 129 * Then, effectively: 130 * outer_type *CONTAINER_OF(member_type *inner_ptr, 131 * *outer_var, // or type name for outer_type 132 * member_name); 133 * 134 * So that: 135 * CONTAINER_OF(inner_ptr, *outer_var, member_name) == &outer 136 * CONTAINER_OF(inner_ptr, outer_type, member_name) == &outer 137 */ 138 #define CONTAINER_OF(inner_ptr, outer, member_name) \ 139 ({ \ 140 typeof(outer) *container_of_; \ 141 container_of_ = (void*)((char*)(inner_ptr) - \ 142 offsetof(typeof(outer), member_name)); \ 143 (void)(&container_of_->member_name == \ 144 (typeof(inner_ptr))0) /* type check */; \ 145 container_of_; \ 146 }) 147 148 #endif /* XENTOOLCORE_INTERNAL_H */ 149 150 /* 151 * Local variables: 152 * mode: C 153 * c-file-style: "BSD" 154 * c-basic-offset: 4 155 * tab-width: 4 156 * indent-tabs-mode: nil 157 * End: 158 */ 159