Path: blob/main/lib/libcapsicum/capsicum_helpers.h
39475 views
/*-1* Copyright (c) 2016 Mariusz Zaborski <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#ifndef _CAPSICUM_HELPERS_H_27#define _CAPSICUM_HELPERS_H_2829#include <sys/param.h>30#include <sys/capsicum.h>31#include <sys/ioctl.h>3233#include <errno.h>34#include <nl_types.h>35#include <termios.h>36#include <time.h>37#include <unistd.h>3839#include <libcasper.h>4041#define CAPH_IGNORE_EBADF 0x000142#define CAPH_READ 0x000243#define CAPH_WRITE 0x000444#define CAPH_LOOKUP 0x00084546__BEGIN_DECLS4748static const unsigned long caph_stream_cmds[] =49{50#ifdef TIOCGETA51TIOCGETA,52#endif53#ifdef TIOCGWINSZ54TIOCGWINSZ,55#endif56#ifdef FIODTYPE57FIODTYPE,58#endif59};60static const uint32_t caph_stream_fcntls = CAP_FCNTL_GETFL;6162static __inline void63caph_stream_rights(cap_rights_t *rights, int flags)64{6566cap_rights_init(rights, CAP_EVENT, CAP_FCNTL, CAP_FSTAT,67CAP_IOCTL, CAP_SEEK);6869if ((flags & CAPH_READ) != 0)70cap_rights_set(rights, CAP_READ);71if ((flags & CAPH_WRITE) != 0)72cap_rights_set(rights, CAP_WRITE);73if ((flags & CAPH_LOOKUP) != 0)74cap_rights_set(rights, CAP_LOOKUP);75}7677static __inline int78caph_limit_stream(int fd, int flags)79{80cap_rights_t rights;8182caph_stream_rights(&rights, flags);83if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) {84if (errno == EBADF && (flags & CAPH_IGNORE_EBADF) != 0)85return (0);86return (-1);87}8889if (cap_ioctls_limit(fd, caph_stream_cmds,90nitems(caph_stream_cmds)) < 0 && errno != ENOSYS)91return (-1);9293if (cap_fcntls_limit(fd, caph_stream_fcntls) < 0 && errno != ENOSYS)94return (-1);9596return (0);97}9899static __inline int100caph_limit_stdin(void)101{102103return (caph_limit_stream(STDIN_FILENO, CAPH_READ));104}105106static __inline int107caph_limit_stderr(void)108{109110return (caph_limit_stream(STDERR_FILENO, CAPH_WRITE));111}112113static __inline int114caph_limit_stdout(void)115{116117return (caph_limit_stream(STDOUT_FILENO, CAPH_WRITE));118}119120static __inline int121caph_limit_stdio(void)122{123const int iebadf = CAPH_IGNORE_EBADF;124125if (caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1 ||126caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1 ||127caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1)128return (-1);129return (0);130}131132static __inline void133caph_cache_tzdata(void)134{135time_t delta;136137tzset();138139/*140* The tzset() function does not cache all time zones.141* Some functions, such as gmtime(), require a GMT time zone.142* The only way to cache them is to call the function directly.143*/144delta = 0;145(void)gmtime(&delta);146}147148static __inline void149caph_cache_catpages(void)150{151152(void)catopen("libc", NL_CAT_LOCALE);153}154155static __inline int156caph_enter(void)157{158159if (cap_enter() < 0 && errno != ENOSYS)160return (-1);161162return (0);163}164165static __inline int166caph_rights_limit(int fd, const cap_rights_t *rights)167{168169if (cap_rights_limit(fd, rights) < 0 && errno != ENOSYS)170return (-1);171172return (0);173}174175static __inline int176caph_ioctls_limit(int fd, const unsigned long *cmds, size_t ncmds)177{178179if (cap_ioctls_limit(fd, cmds, ncmds) < 0 && errno != ENOSYS)180return (-1);181182return (0);183}184185static __inline int186caph_fcntls_limit(int fd, uint32_t fcntlrights)187{188189if (cap_fcntls_limit(fd, fcntlrights) < 0 && errno != ENOSYS)190return (-1);191192return (0);193}194195static __inline int196caph_enter_casper(void)197{198199return (CASPER_SUPPORT == 0 ? 0 : caph_enter());200}201202__END_DECLS203204#endif /* _CAPSICUM_HELPERS_H_ */205206207