1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * CDDL HEADER START
4 *
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or https://opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
25 */
26 #include "../../libzfs_impl.h"
27 #include <libzfs.h>
28 #include <libzutil.h>
29 #include <sys/sysctl.h>
30 #include <libintl.h>
31 #include <sys/linker.h>
32 #include <sys/module.h>
33 #include <sys/stat.h>
34 #include <sys/param.h>
35
36 #ifdef IN_BASE
37 #define ZFS_KMOD "zfs"
38 #else
39 #define ZFS_KMOD "openzfs"
40 #endif
41
42 #ifndef HAVE_EXECVPE
43 /* FreeBSD prior to 15 lacks execvpe */
44 static int
execvPe(const char * name,const char * path,char * const * argv,char * const * envp)45 execvPe(const char *name, const char *path, char * const *argv,
46 char * const *envp)
47 {
48 const char **memp;
49 size_t cnt, lp, ln;
50 int eacces, save_errno;
51 char buf[MAXPATHLEN];
52 const char *bp, *np, *op, *p;
53 struct stat sb;
54
55 eacces = 0;
56
57 /* If it's an absolute or relative path name, it's easy. */
58 if (strchr(name, '/')) {
59 bp = name;
60 op = NULL;
61 goto retry;
62 }
63 bp = buf;
64
65 /* If it's an empty path name, fail in the usual POSIX way. */
66 if (*name == '\0') {
67 errno = ENOENT;
68 return (-1);
69 }
70
71 op = path;
72 ln = strlen(name);
73 while (op != NULL) {
74 np = strchrnul(op, ':');
75
76 /*
77 * It's a SHELL path -- double, leading and trailing colons
78 * mean the current directory.
79 */
80 if (np == op) {
81 /* Empty component. */
82 p = ".";
83 lp = 1;
84 } else {
85 /* Non-empty component. */
86 p = op;
87 lp = np - op;
88 }
89
90 /* Advance to the next component or terminate after this. */
91 if (*np == '\0')
92 op = NULL;
93 else
94 op = np + 1;
95
96 /*
97 * If the path is too long complain. This is a possible
98 * security issue; given a way to make the path too long
99 * the user may execute the wrong program.
100 */
101 if (lp + ln + 2 > sizeof (buf)) {
102 (void) write(STDERR_FILENO, "execvP: ", 8);
103 (void) write(STDERR_FILENO, p, lp);
104 (void) write(STDERR_FILENO, ": path too long\n",
105 16);
106 continue;
107 }
108 memcpy(buf, p, lp);
109 buf[lp] = '/';
110 memcpy(buf + lp + 1, name, ln);
111 buf[lp + ln + 1] = '\0';
112
113 retry: (void) execve(bp, argv, envp);
114 switch (errno) {
115 case E2BIG:
116 goto done;
117 case ELOOP:
118 case ENAMETOOLONG:
119 case ENOENT:
120 break;
121 case ENOEXEC:
122 for (cnt = 0; argv[cnt]; ++cnt)
123 ;
124
125 /*
126 * cnt may be 0 above; always allocate at least
127 * 3 entries so that we can at least fit "sh", bp, and
128 * the NULL terminator. We can rely on cnt to take into
129 * account the NULL terminator in all other scenarios,
130 * as we drop argv[0].
131 */
132 memp = alloca(MAX(3, cnt + 2) * sizeof (char *));
133 if (memp == NULL) {
134 /* errno = ENOMEM; XXX override ENOEXEC? */
135 goto done;
136 }
137 if (cnt > 0) {
138 memp[0] = argv[0];
139 memp[1] = bp;
140 memcpy(memp + 2, argv + 1,
141 cnt * sizeof (char *));
142 } else {
143 memp[0] = "sh";
144 memp[1] = bp;
145 memp[2] = NULL;
146 }
147 (void) execve(_PATH_BSHELL,
148 __DECONST(char **, memp), envp);
149 goto done;
150 case ENOMEM:
151 goto done;
152 case ENOTDIR:
153 break;
154 case ETXTBSY:
155 /*
156 * We used to retry here, but sh(1) doesn't.
157 */
158 goto done;
159 default:
160 /*
161 * EACCES may be for an inaccessible directory or
162 * a non-executable file. Call stat() to decide
163 * which. This also handles ambiguities for EFAULT
164 * and EIO, and undocumented errors like ESTALE.
165 * We hope that the race for a stat() is unimportant.
166 */
167 save_errno = errno;
168 if (stat(bp, &sb) != 0)
169 break;
170 if (save_errno == EACCES) {
171 eacces = 1;
172 continue;
173 }
174 errno = save_errno;
175 goto done;
176 }
177 }
178 if (eacces)
179 errno = EACCES;
180 else
181 errno = ENOENT;
182 done:
183 return (-1);
184 }
185
186 int
execvpe(const char * name,char * const argv[],char * const envp[])187 execvpe(const char *name, char * const argv[], char * const envp[])
188 {
189 const char *path;
190
191 /* Get the path we're searching. */
192 if ((path = getenv("PATH")) == NULL)
193 path = _PATH_DEFPATH;
194
195 return (execvPe(name, path, argv, envp));
196 }
197 #endif /* !HAVE_EXECVPE */
198
199 static __thread char errbuf[ERRBUFLEN];
200
201 const char *
libzfs_error_init(int error)202 libzfs_error_init(int error)
203 {
204 char *msg = errbuf;
205 size_t msglen = sizeof (errbuf);
206
207 if (modfind("zfs") < 0) {
208 size_t len = snprintf(msg, msglen, dgettext(TEXT_DOMAIN,
209 "Failed to load %s module: "), ZFS_KMOD);
210 if (len >= msglen)
211 len = msglen - 1;
212 msg += len;
213 msglen -= len;
214 }
215
216 (void) snprintf(msg, msglen, "%s", zfs_strerror(error));
217
218 return (errbuf);
219 }
220
221 /*
222 * Verify the required ZFS_DEV device is available and optionally attempt
223 * to load the ZFS modules. Under normal circumstances the modules
224 * should already have been loaded by some external mechanism.
225 */
226 int
libzfs_load_module(void)227 libzfs_load_module(void)
228 {
229 /*
230 * XXX: kldfind(ZFS_KMOD) would be nice here, but we retain
231 * modfind("zfs") so out-of-base openzfs userland works with the
232 * in-base module.
233 */
234 if (modfind("zfs") < 0) {
235 /* Not present in kernel, try loading it. */
236 if (kldload(ZFS_KMOD) < 0 && errno != EEXIST) {
237 return (errno);
238 }
239 }
240 return (0);
241 }
242
243 int
zpool_relabel_disk(libzfs_handle_t * hdl,const char * path,const char * msg)244 zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg)
245 {
246 (void) hdl, (void) path, (void) msg;
247 return (0);
248 }
249
250 int
zpool_label_disk(libzfs_handle_t * hdl,zpool_handle_t * zhp,const char * name)251 zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
252 {
253 (void) hdl, (void) zhp, (void) name;
254 return (0);
255 }
256
257 int
find_shares_object(differ_info_t * di)258 find_shares_object(differ_info_t *di)
259 {
260 (void) di;
261 return (0);
262 }
263
264 int
zfs_destroy_snaps_nvl_os(libzfs_handle_t * hdl,nvlist_t * snaps)265 zfs_destroy_snaps_nvl_os(libzfs_handle_t *hdl, nvlist_t *snaps)
266 {
267 (void) hdl, (void) snaps;
268 return (0);
269 }
270
271 /*
272 * Attach/detach the given filesystem to/from the given jail.
273 */
274 int
zfs_jail(zfs_handle_t * zhp,int jailid,int attach)275 zfs_jail(zfs_handle_t *zhp, int jailid, int attach)
276 {
277 libzfs_handle_t *hdl = zhp->zfs_hdl;
278 zfs_cmd_t zc = {"\0"};
279 unsigned long cmd;
280 int ret;
281
282 if (attach) {
283 (void) snprintf(errbuf, sizeof (errbuf),
284 dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
285 } else {
286 (void) snprintf(errbuf, sizeof (errbuf),
287 dgettext(TEXT_DOMAIN, "cannot unjail '%s'"), zhp->zfs_name);
288 }
289
290 switch (zhp->zfs_type) {
291 case ZFS_TYPE_VOLUME:
292 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
293 "volumes can not be jailed"));
294 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
295 case ZFS_TYPE_SNAPSHOT:
296 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
297 "snapshots can not be jailed"));
298 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
299 case ZFS_TYPE_BOOKMARK:
300 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
301 "bookmarks can not be jailed"));
302 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
303 case ZFS_TYPE_VDEV:
304 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
305 "vdevs can not be jailed"));
306 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
307 case ZFS_TYPE_INVALID:
308 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
309 "invalid zfs_type_t: ZFS_TYPE_INVALID"));
310 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
311 case ZFS_TYPE_POOL:
312 case ZFS_TYPE_FILESYSTEM:
313 /* OK */
314 ;
315 }
316 assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
317
318 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
319 zc.zc_objset_type = DMU_OST_ZFS;
320 zc.zc_zoneid = jailid;
321
322 cmd = attach ? ZFS_IOC_JAIL : ZFS_IOC_UNJAIL;
323 if ((ret = zfs_ioctl(hdl, cmd, &zc)) != 0)
324 zfs_standard_error(hdl, errno, errbuf);
325
326 return (ret);
327 }
328
329 /*
330 * Set loader options for next boot.
331 */
332 int
zpool_nextboot(libzfs_handle_t * hdl,uint64_t pool_guid,uint64_t dev_guid,const char * command)333 zpool_nextboot(libzfs_handle_t *hdl, uint64_t pool_guid, uint64_t dev_guid,
334 const char *command)
335 {
336 zfs_cmd_t zc = {"\0"};
337 nvlist_t *args;
338
339 args = fnvlist_alloc();
340 fnvlist_add_uint64(args, ZPOOL_CONFIG_POOL_GUID, pool_guid);
341 fnvlist_add_uint64(args, ZPOOL_CONFIG_GUID, dev_guid);
342 fnvlist_add_string(args, "command", command);
343 zcmd_write_src_nvlist(hdl, &zc, args);
344 int error = zfs_ioctl(hdl, ZFS_IOC_NEXTBOOT, &zc);
345 zcmd_free_nvlists(&zc);
346 nvlist_free(args);
347 return (error);
348 }
349
350 /*
351 * Return allocated loaded module version, or NULL on error (with errno set)
352 */
353 char *
zfs_version_kernel(void)354 zfs_version_kernel(void)
355 {
356 size_t l;
357 if (sysctlbyname("vfs.zfs.version.module",
358 NULL, &l, NULL, 0) == -1)
359 return (NULL);
360 char *version = malloc(l);
361 if (version == NULL)
362 return (NULL);
363 if (sysctlbyname("vfs.zfs.version.module",
364 version, &l, NULL, 0) == -1) {
365 free(version);
366 return (NULL);
367 }
368 return (version);
369 }
370