summaryrefslogtreecommitdiff
path: root/tools/include/xentoolcore_internal.h
blob: 1be014434d32f399de1ba3bcc9fcbb7f61c08749 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * 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 <http://www.gnu.org/licenses/>.
 */

#ifndef XENTOOLCORE_INTERNAL_H
#define XENTOOLCORE_INTERNAL_H

#include <stddef.h>

#include "xentoolcore.h"
#include "xen_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;
    XEN_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:
 */