]> granicus.if.org Git - strace/blob - netlink_crypto.c
mmap_cache: add function to enable mmap_cache
[strace] / netlink_crypto.c
1 /*
2  * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
3  * Copyright (c) 2017 The strace developers.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "defs.h"
30
31 #ifdef HAVE_LINUX_CRYPTOUSER_H
32
33 # include "netlink.h"
34 # include "nlattr.h"
35 # include "print_fields.h"
36
37 # include <linux/cryptouser.h>
38
39 # include "xlat/crypto_nl_attrs.h"
40
41 static bool
42 decode_crypto_report_generic(struct tcb *const tcp,
43                              const kernel_ulong_t addr,
44                              const unsigned int len,
45                              const void *const opaque_data)
46 {
47         tprints("{type=");
48         printstr_ex(tcp, addr, len, QUOTE_0_TERMINATED);
49         tprints("}");
50
51         return true;
52 }
53
54 static bool
55 decode_crypto_report_hash(struct tcb *const tcp,
56                           const kernel_ulong_t addr,
57                           const unsigned int len,
58                           const void *const opaque_data)
59 {
60 # ifdef HAVE_STRUCT_CRYPTO_REPORT_HASH
61         struct crypto_report_hash rhash;
62
63         if (len < sizeof(rhash))
64                 printstrn(tcp, addr, len);
65         else if (!umove_or_printaddr(tcp, addr, &rhash)) {
66                 PRINT_FIELD_CSTRING("{", rhash, type);
67                 PRINT_FIELD_U(", ", rhash, blocksize);
68                 PRINT_FIELD_U(", ", rhash, digestsize);
69                 tprints("}");
70         }
71 # else
72         printstrn(tcp, addr, len);
73 # endif
74
75         return true;
76 }
77
78 static bool
79 decode_crypto_report_blkcipher(struct tcb *const tcp,
80                                const kernel_ulong_t addr,
81                                const unsigned int len,
82                                const void *const opaque_data)
83 {
84 # ifdef HAVE_STRUCT_CRYPTO_REPORT_BLKCIPHER
85         struct crypto_report_blkcipher rblkcipher;
86
87         if (len < sizeof(rblkcipher))
88                 printstrn(tcp, addr, len);
89         else if (!umove_or_printaddr(tcp, addr, &rblkcipher)) {
90                 PRINT_FIELD_CSTRING("{", rblkcipher, type);
91                 PRINT_FIELD_CSTRING(", ", rblkcipher, geniv);
92                 PRINT_FIELD_U(", ", rblkcipher, blocksize);
93                 PRINT_FIELD_U(", ", rblkcipher, min_keysize);
94                 PRINT_FIELD_U(", ", rblkcipher, max_keysize);
95                 PRINT_FIELD_U(", ", rblkcipher, ivsize);
96                 tprints("}");
97         }
98 # else
99         printstrn(tcp, addr, len);
100 # endif
101
102         return true;
103 }
104
105 static bool
106 decode_crypto_report_aead(struct tcb *const tcp,
107                           const kernel_ulong_t addr,
108                           const unsigned int len,
109                           const void *const opaque_data)
110 {
111 # ifdef HAVE_STRUCT_CRYPTO_REPORT_AEAD
112         struct crypto_report_aead raead;
113
114         if (len < sizeof(raead))
115                 printstrn(tcp, addr, len);
116         else if (!umove_or_printaddr(tcp, addr, &raead)) {
117                 PRINT_FIELD_CSTRING("{", raead, type);
118                 PRINT_FIELD_CSTRING(", ", raead, geniv);
119                 PRINT_FIELD_U(", ", raead, blocksize);
120                 PRINT_FIELD_U(", ", raead, maxauthsize);
121                 PRINT_FIELD_U(", ", raead, ivsize);
122                 tprints("}");
123         }
124 # else
125         printstrn(tcp, addr, len);
126 # endif
127
128         return true;
129 }
130
131 static bool
132 decode_crypto_report_rng(struct tcb *const tcp,
133                          const kernel_ulong_t addr,
134                          const unsigned int len,
135                          const void *const opaque_data)
136 {
137 # ifdef HAVE_STRUCT_CRYPTO_REPORT_RNG
138         struct crypto_report_rng rrng;
139
140         if (len < sizeof(rrng))
141                 printstrn(tcp, addr, len);
142         else if (!umove_or_printaddr(tcp, addr, &rrng)) {
143                 PRINT_FIELD_CSTRING("{", rrng, type);
144                 PRINT_FIELD_U(", ", rrng, seedsize);
145                 tprints("}");
146         }
147 # else
148         printstrn(tcp, addr, len);
149 # endif
150
151         return true;
152 }
153
154 static bool
155 decode_crypto_report_cipher(struct tcb *const tcp,
156                             const kernel_ulong_t addr,
157                             const unsigned int len,
158                             const void *const opaque_data)
159 {
160 # ifdef HAVE_STRUCT_CRYPTO_REPORT_CIPHER
161         struct crypto_report_cipher rcipher;
162
163         if (len < sizeof(rcipher))
164                 printstrn(tcp, addr, len);
165         else if (!umove_or_printaddr(tcp, addr, &rcipher)) {
166                 PRINT_FIELD_CSTRING("{", rcipher, type);
167                 PRINT_FIELD_U(", ", rcipher, blocksize);
168                 PRINT_FIELD_U(", ", rcipher, min_keysize);
169                 PRINT_FIELD_U(", ", rcipher, max_keysize);
170                 tprints("}");
171         }
172 # else
173         printstrn(tcp, addr, len);
174 # endif
175
176         return true;
177 }
178
179 static const nla_decoder_t crypto_user_alg_nla_decoders[] = {
180         [CRYPTOCFGA_PRIORITY_VAL]       = decode_nla_u32,
181         [CRYPTOCFGA_REPORT_LARVAL]      = decode_crypto_report_generic,
182         [CRYPTOCFGA_REPORT_HASH]        = decode_crypto_report_hash,
183         [CRYPTOCFGA_REPORT_BLKCIPHER]   = decode_crypto_report_blkcipher,
184         [CRYPTOCFGA_REPORT_AEAD]        = decode_crypto_report_aead,
185         [CRYPTOCFGA_REPORT_COMPRESS]    = decode_crypto_report_generic,
186         [CRYPTOCFGA_REPORT_RNG]         = decode_crypto_report_rng,
187         [CRYPTOCFGA_REPORT_CIPHER]      = decode_crypto_report_cipher,
188         [CRYPTOCFGA_REPORT_AKCIPHER]    = decode_crypto_report_generic,
189         [CRYPTOCFGA_REPORT_KPP]         = decode_crypto_report_generic,
190         [CRYPTOCFGA_REPORT_ACOMP]       = decode_crypto_report_generic
191 };
192
193 static void
194 decode_crypto_user_alg(struct tcb *const tcp,
195                        const kernel_ulong_t addr,
196                        const unsigned int len)
197 {
198         struct crypto_user_alg alg;
199
200         if (len < sizeof(alg))
201                 printstrn(tcp, addr, len);
202         else if (!umove_or_printaddr(tcp, addr, &alg)) {
203                 PRINT_FIELD_CSTRING("{", alg, cru_name);
204                 PRINT_FIELD_CSTRING(", ", alg, cru_driver_name);
205                 PRINT_FIELD_CSTRING(", ", alg, cru_module_name);
206                 PRINT_FIELD_X(", ", alg, cru_type);
207                 PRINT_FIELD_X(", ", alg, cru_mask);
208                 PRINT_FIELD_U(", ", alg, cru_refcnt);
209                 PRINT_FIELD_X(", ", alg, cru_flags);
210                 tprints("}");
211
212                 const size_t offset = NLMSG_ALIGN(sizeof(alg));
213                 if (len > offset) {
214                         tprints(", ");
215                         decode_nlattr(tcp, addr + offset, len - offset,
216                                       crypto_nl_attrs, "CRYPTOCFGA_???",
217                                       crypto_user_alg_nla_decoders,
218                                       ARRAY_SIZE(crypto_user_alg_nla_decoders),
219                                       NULL);
220                 }
221         }
222 }
223
224 bool
225 decode_netlink_crypto(struct tcb *const tcp,
226                       const struct nlmsghdr *const nlmsghdr,
227                       const kernel_ulong_t addr,
228                       const unsigned int len)
229 {
230         switch (nlmsghdr->nlmsg_type) {
231         case CRYPTO_MSG_NEWALG:
232         case CRYPTO_MSG_DELALG:
233         case CRYPTO_MSG_UPDATEALG:
234         case CRYPTO_MSG_GETALG:
235                 decode_crypto_user_alg(tcp, addr, len);
236                 break;
237         default:
238                 return false;
239         }
240
241         return true;
242 }
243
244 #endif /* HAVE_LINUX_CRYPTOUSER_H */