xref: /aosp_15_r20/external/libcap-ng/src/lookup_table.c (revision 8dd5e09d5faf27a871e8654ddaa2d2af7c696578)
1*8dd5e09dSSadaf Ebrahimi /* lookup_table.c --
2*8dd5e09dSSadaf Ebrahimi  * Copyright 2009, 2013 Red Hat Inc.
3*8dd5e09dSSadaf Ebrahimi  * All Rights Reserved.
4*8dd5e09dSSadaf Ebrahimi  *
5*8dd5e09dSSadaf Ebrahimi  * This library is free software; you can redistribute it and/or
6*8dd5e09dSSadaf Ebrahimi  * modify it under the terms of the GNU Lesser General Public
7*8dd5e09dSSadaf Ebrahimi  * License as published by the Free Software Foundation; either
8*8dd5e09dSSadaf Ebrahimi  * version 2.1 of the License, or (at your option) any later version.
9*8dd5e09dSSadaf Ebrahimi  *
10*8dd5e09dSSadaf Ebrahimi  * This library is distributed in the hope that it will be useful,
11*8dd5e09dSSadaf Ebrahimi  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*8dd5e09dSSadaf Ebrahimi  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13*8dd5e09dSSadaf Ebrahimi  * Lesser General Public License for more details.
14*8dd5e09dSSadaf Ebrahimi  *
15*8dd5e09dSSadaf Ebrahimi  * You should have received a copy of the GNU Lesser General Public License
16*8dd5e09dSSadaf Ebrahimi  * along with this program; see the file COPYING.LIB. If not, write to the
17*8dd5e09dSSadaf Ebrahimi  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
18*8dd5e09dSSadaf Ebrahimi  * Boston, MA 02110-1335, USA.
19*8dd5e09dSSadaf Ebrahimi  *
20*8dd5e09dSSadaf Ebrahimi  * Authors:
21*8dd5e09dSSadaf Ebrahimi  *      Steve Grubb <[email protected]>
22*8dd5e09dSSadaf Ebrahimi  */
23*8dd5e09dSSadaf Ebrahimi 
24*8dd5e09dSSadaf Ebrahimi #include "config.h"
25*8dd5e09dSSadaf Ebrahimi #include <stddef.h>
26*8dd5e09dSSadaf Ebrahimi #include <linux/capability.h>
27*8dd5e09dSSadaf Ebrahimi #include <strings.h>
28*8dd5e09dSSadaf Ebrahimi #include <stdio.h>
29*8dd5e09dSSadaf Ebrahimi #include <stdlib.h>  // free
30*8dd5e09dSSadaf Ebrahimi 
31*8dd5e09dSSadaf Ebrahimi 
32*8dd5e09dSSadaf Ebrahimi #define hidden __attribute__ ((visibility ("hidden")))
33*8dd5e09dSSadaf Ebrahimi extern unsigned int last_cap hidden;
34*8dd5e09dSSadaf Ebrahimi 
35*8dd5e09dSSadaf Ebrahimi #undef cap_valid
36*8dd5e09dSSadaf Ebrahimi #define cap_valid(x) ((x) <= last_cap)
37*8dd5e09dSSadaf Ebrahimi 
38*8dd5e09dSSadaf Ebrahimi 
39*8dd5e09dSSadaf Ebrahimi struct transtab {
40*8dd5e09dSSadaf Ebrahimi     int   value;
41*8dd5e09dSSadaf Ebrahimi     int   offset;
42*8dd5e09dSSadaf Ebrahimi };
43*8dd5e09dSSadaf Ebrahimi 
44*8dd5e09dSSadaf Ebrahimi #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
45*8dd5e09dSSadaf Ebrahimi #define MSGSTRFIELD1(line) str##line
46*8dd5e09dSSadaf Ebrahimi 
47*8dd5e09dSSadaf Ebrahimi 
48*8dd5e09dSSadaf Ebrahimi /* To create the following tables in a DSO-friendly way we split them in
49*8dd5e09dSSadaf Ebrahimi    two separate variables: a long string which is created by concatenating
50*8dd5e09dSSadaf Ebrahimi    all strings referenced in the table and the table itself, which uses
51*8dd5e09dSSadaf Ebrahimi    offsets instead of string pointers.  To do this without increasing
52*8dd5e09dSSadaf Ebrahimi    the maintenance burden we use a lot of preprocessor magic.  All the
53*8dd5e09dSSadaf Ebrahimi    maintainer has to do is to add a new entry to the included file and
54*8dd5e09dSSadaf Ebrahimi    recompile.  */
55*8dd5e09dSSadaf Ebrahimi 
56*8dd5e09dSSadaf Ebrahimi static const union captab_msgstr_t {
57*8dd5e09dSSadaf Ebrahimi     struct {
58*8dd5e09dSSadaf Ebrahimi #define _S(n, s) char MSGSTRFIELD(__LINE__)[sizeof (s)];
59*8dd5e09dSSadaf Ebrahimi #include "captab.h"
60*8dd5e09dSSadaf Ebrahimi #undef _S
61*8dd5e09dSSadaf Ebrahimi     };
62*8dd5e09dSSadaf Ebrahimi     char str[0];
63*8dd5e09dSSadaf Ebrahimi } captab_msgstr = { {
64*8dd5e09dSSadaf Ebrahimi #define _S(n, s) s,
65*8dd5e09dSSadaf Ebrahimi #include "captab.h"
66*8dd5e09dSSadaf Ebrahimi #undef _S
67*8dd5e09dSSadaf Ebrahimi } };
68*8dd5e09dSSadaf Ebrahimi static const struct transtab captab[] = {
69*8dd5e09dSSadaf Ebrahimi #define _S(n, s) { n, offsetof(union captab_msgstr_t,  \
70*8dd5e09dSSadaf Ebrahimi                                MSGSTRFIELD(__LINE__)) },
71*8dd5e09dSSadaf Ebrahimi #include "captab.h"
72*8dd5e09dSSadaf Ebrahimi #undef _S
73*8dd5e09dSSadaf Ebrahimi };
74*8dd5e09dSSadaf Ebrahimi #define CAP_NG_CAPABILITY_NAMES (sizeof(captab)/sizeof(captab[0]))
75*8dd5e09dSSadaf Ebrahimi 
76*8dd5e09dSSadaf Ebrahimi 
77*8dd5e09dSSadaf Ebrahimi 
78*8dd5e09dSSadaf Ebrahimi 
capng_lookup_name(const struct transtab * table,const char * tabstr,size_t length,const char * name)79*8dd5e09dSSadaf Ebrahimi static int capng_lookup_name(const struct transtab *table,
80*8dd5e09dSSadaf Ebrahimi 		const char *tabstr, size_t length, const char *name)
81*8dd5e09dSSadaf Ebrahimi {
82*8dd5e09dSSadaf Ebrahimi 	size_t i;
83*8dd5e09dSSadaf Ebrahimi 
84*8dd5e09dSSadaf Ebrahimi 	for (i = 0; i < length; i++) {
85*8dd5e09dSSadaf Ebrahimi 		if (!strcasecmp(tabstr + table[i].offset, name))
86*8dd5e09dSSadaf Ebrahimi 			return table[i].value;
87*8dd5e09dSSadaf Ebrahimi 	}
88*8dd5e09dSSadaf Ebrahimi 	return -1;
89*8dd5e09dSSadaf Ebrahimi }
90*8dd5e09dSSadaf Ebrahimi 
capng_lookup_number(const struct transtab * table,const char * tabstr,size_t length,int number)91*8dd5e09dSSadaf Ebrahimi static const char *capng_lookup_number(const struct transtab *table,
92*8dd5e09dSSadaf Ebrahimi                                        const char *tabstr, size_t length,
93*8dd5e09dSSadaf Ebrahimi                                        int number)
94*8dd5e09dSSadaf Ebrahimi {
95*8dd5e09dSSadaf Ebrahimi 	size_t i;
96*8dd5e09dSSadaf Ebrahimi 
97*8dd5e09dSSadaf Ebrahimi 	for (i = 0; i < length; i++) {
98*8dd5e09dSSadaf Ebrahimi 		if (table[i].value == number)
99*8dd5e09dSSadaf Ebrahimi 			return tabstr + table[i].offset;
100*8dd5e09dSSadaf Ebrahimi 	}
101*8dd5e09dSSadaf Ebrahimi 	return NULL;
102*8dd5e09dSSadaf Ebrahimi }
103*8dd5e09dSSadaf Ebrahimi 
capng_name_to_capability(const char * name)104*8dd5e09dSSadaf Ebrahimi int capng_name_to_capability(const char *name)
105*8dd5e09dSSadaf Ebrahimi {
106*8dd5e09dSSadaf Ebrahimi 	return capng_lookup_name(captab, captab_msgstr.str,
107*8dd5e09dSSadaf Ebrahimi                                  CAP_NG_CAPABILITY_NAMES, name);
108*8dd5e09dSSadaf Ebrahimi }
109*8dd5e09dSSadaf Ebrahimi 
110*8dd5e09dSSadaf Ebrahimi static char *ptr2 = NULL;
capng_capability_to_name(unsigned int capability)111*8dd5e09dSSadaf Ebrahimi const char *capng_capability_to_name(unsigned int capability)
112*8dd5e09dSSadaf Ebrahimi {
113*8dd5e09dSSadaf Ebrahimi 	const char *ptr;
114*8dd5e09dSSadaf Ebrahimi 
115*8dd5e09dSSadaf Ebrahimi 	if (!cap_valid(capability))
116*8dd5e09dSSadaf Ebrahimi 		return NULL;
117*8dd5e09dSSadaf Ebrahimi 
118*8dd5e09dSSadaf Ebrahimi 	ptr = capng_lookup_number(captab, captab_msgstr.str,
119*8dd5e09dSSadaf Ebrahimi                                    CAP_NG_CAPABILITY_NAMES, capability);
120*8dd5e09dSSadaf Ebrahimi 	if (ptr == NULL) { // This leaks memory, but should almost never be used
121*8dd5e09dSSadaf Ebrahimi 		free(ptr2);
122*8dd5e09dSSadaf Ebrahimi 		if (asprintf(&ptr2, "cap_%u", capability) < 0)
123*8dd5e09dSSadaf Ebrahimi 			ptr = NULL;
124*8dd5e09dSSadaf Ebrahimi 		else
125*8dd5e09dSSadaf Ebrahimi 			ptr = ptr2;
126*8dd5e09dSSadaf Ebrahimi 	}
127*8dd5e09dSSadaf Ebrahimi 	return ptr;
128*8dd5e09dSSadaf Ebrahimi }
129*8dd5e09dSSadaf Ebrahimi 
130