summaryrefslogtreecommitdiff
path: root/util/nvmutil/include/common.h
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-20 04:02:51 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-22 13:50:44 +0000
commit6838db4647b600bf5b356429f54850bf801e7ba4 (patch)
treecc98541897703d2949af27dc050cad8cba5061a0 /util/nvmutil/include/common.h
parentf50ffd6bb13c04cb185fb6311f8875582bf18388 (diff)
WIP: hardened mktemp
i'm pretty much nearly there. still no dir support, only files. i won't keep amending now - will do more, then squash later. Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/nvmutil/include/common.h')
-rw-r--r--util/nvmutil/include/common.h176
1 files changed, 118 insertions, 58 deletions
diff --git a/util/nvmutil/include/common.h b/util/nvmutil/include/common.h
index 46fbcb38..6cdeba18 100644
--- a/util/nvmutil/include/common.h
+++ b/util/nvmutil/include/common.h
@@ -35,11 +35,20 @@
int fchmod(int fd, mode_t mode);
-/* analog of SSIZE_MAX
+/* if 1: on operations that
+ * check ownership, always
+ * permit root to access even
+ * if not the file/dir owner
*/
+#ifndef ALLOW_ROOT_OVERRIDE
+#define ALLOW_ROOT_OVERRIDE 0
+#endif
-#ifndef X_LONG_MAX
-#define X_LONG_MAX ((long)(~((long)1 << (sizeof(long)*CHAR_BIT-1))))
+/*
+ */
+
+#ifndef SSIZE_MAX
+#define SSIZE_MAX ((ssize_t)(~((ssize_t)1 << (sizeof(ssize_t)*CHAR_BIT-1))))
#endif
@@ -60,6 +69,13 @@ int fchmod(int fd, mode_t mode);
#define OFF_RESET 1
#endif
+/* by default: allow use
+ of openat in hardened mkstemp
+ */
+#ifndef DISABLE_OPENAT
+#define DISABLE_OPENAT 0 /* change to 1 if you don't have openat (old unix) */
+#endif
+
#ifndef S_ISVTX
#define S_ISVTX 01000
#endif
@@ -72,8 +88,8 @@ int fchmod(int fd, mode_t mode);
#define MAX_ZERO_RW_RETRY 5
#endif
-#ifndef HAVE_REAL_PREAD_PWRITE
-#define HAVE_REAL_PREAD_PWRITE 0
+#ifndef REAL_POS_IO
+#define REAL_POS_IO 0
#endif
#ifndef LOOP_EAGAIN
@@ -95,6 +111,10 @@ int fchmod(int fd, mode_t mode);
#define EXIT_SUCCESS 0
#endif
+#ifndef O_NOCTTY
+#define O_NOCTTY 0
+#endif
+
#ifndef O_ACCMODE
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
@@ -208,14 +228,14 @@ int fchmod(int fd, mode_t mode);
*/
struct commands {
- unsigned long chk;
+ size_t chk;
char *str;
void (*run)(void);
int argc;
unsigned char arg_part;
unsigned char chksum_read;
unsigned char chksum_write;
- unsigned long rw_size; /* within the 4KB GbE part */
+ size_t rw_size; /* within the 4KB GbE part */
int flags; /* e.g. O_RDWR or O_RDONLY */
};
@@ -254,7 +274,7 @@ struct xfile {
off_t gbe_file_size;
off_t gbe_tmp_size;
- unsigned long part;
+ size_t part;
unsigned char part_modified[2];
unsigned char part_valid[2];
@@ -278,7 +298,7 @@ struct xstate {
char *argv0;
- unsigned long i; /* index to cmd[] for current command */
+ size_t i; /* index to cmd[] for current command */
int no_cmd;
/* Cat commands set this.
@@ -286,28 +306,33 @@ struct xstate {
int cat;
};
+struct path_split {
+ int dirfd;
+ char *buf;
+ const char *base;
+};
-
-struct xstate *xstatus(int argc, char *argv[]);
+struct xstate *xstart(int argc, char *argv[]);
+struct xstate *xstatus(void);
/* Sanitize command tables.
*/
void sanitize_command_list(void);
-void sanitize_command_index(unsigned long c);
+void sanitize_command_index(size_t c);
/* Argument handling (user input)
*/
void set_cmd(int argc, char *argv[]);
void set_cmd_args(int argc, char *argv[]);
-unsigned long conv_argv_part_num(const char *part_str);
-int xstrxcmp(const char *a, const char *b, unsigned long maxlen);
+size_t conv_argv_part_num(const char *part_str);
/* Prep files for reading
*/
void open_gbe_file(void);
+int is_owner(struct stat *st);
int lock_file(int fd, int flags);
int same_file(int fd, struct stat *st_old, int check_size);
void xopen(int *fd, const char *path, int flags, struct stat *st);
@@ -318,25 +343,37 @@ void xopen(int *fd, const char *path, int flags, struct stat *st);
void copy_gbe(void);
void read_file(void);
void read_checksums(void);
-int good_checksum(unsigned long partnum);
+int good_checksum(size_t partnum);
/* validate commands
*/
-void check_command_num(unsigned long c);
-unsigned char valid_command(unsigned long c);
+void check_command_num(size_t c);
+unsigned char valid_command(size_t c);
/* Helper functions for command: setmac
*/
void cmd_helper_setmac(void);
void parse_mac_string(void);
-unsigned long xstrxlen(const char *scmp, unsigned long maxlen);
-void set_mac_byte(unsigned long mac_byte_pos);
-void set_mac_nib(unsigned long mac_str_pos,
- unsigned long mac_byte_pos, unsigned long mac_nib_pos);
+void set_mac_byte(size_t mac_byte_pos);
+void set_mac_nib(size_t mac_str_pos,
+ size_t mac_byte_pos, size_t mac_nib_pos);
+void write_mac_part(size_t partnum);
+
+/* string functions
+ */
+
+int slen(const char *scmp, size_t maxlen,
+ size_t *rval);
+int scmp(const char *a, const char *b,
+ size_t maxlen, int *rval);
+
+/* numerical functions
+ */
+
unsigned short hextonum(char ch_s);
-unsigned long rlong(void);
+size_t rlong(void);
#if !(defined(FALLBACK_RAND_1989) && \
((FALLBACK_RAND_1989) > 0))
#if defined(__linux__)
@@ -346,17 +383,16 @@ int fallback_rand_getrandom(void *buf, size_t len);
#endif
#endif
#else
-unsigned long fallback_rand_1989(void);
-unsigned long entropy_jitter(void);
+size_t fallback_rand_1989(void);
+size_t entropy_jitter(void);
#endif
-void write_mac_part(unsigned long partnum);
/* Helper functions for command: dump
*/
void cmd_helper_dump(void);
-void print_mac_from_nvm(unsigned long partnum);
-void hexdump(unsigned long partnum);
+void print_mac_from_nvm(size_t partnum);
+void hexdump(size_t partnum);
/* Helper functions for command: swap
*/
@@ -375,7 +411,7 @@ void cmd_helper_copy(void);
void cmd_helper_cat(void);
void cmd_helper_cat16(void);
void cmd_helper_cat128(void);
-void cat(unsigned long nff);
+void cat(size_t nff);
void cat_buf(unsigned char *b);
/* Command verification/control
@@ -388,51 +424,51 @@ void cmd_helper_err(void);
*/
void write_gbe_file(void);
-void set_checksum(unsigned long part);
-unsigned short calculated_checksum(unsigned long p);
+void set_checksum(size_t part);
+unsigned short calculated_checksum(size_t p);
/* NVM read/write
*/
-unsigned short nvm_word(unsigned long pos16, unsigned long part);
-void set_nvm_word(unsigned long pos16,
- unsigned long part, unsigned short val16);
-void set_part_modified(unsigned long p);
-void check_nvm_bound(unsigned long pos16, unsigned long part);
-void check_bin(unsigned long a, const char *a_name);
+unsigned short nvm_word(size_t pos16, size_t part);
+void set_nvm_word(size_t pos16,
+ size_t part, unsigned short val16);
+void set_part_modified(size_t p);
+void check_nvm_bound(size_t pos16, size_t part);
+void check_bin(size_t a, const char *a_name);
/* GbE file read/write
*/
-void rw_gbe_file_part(unsigned long p, int rw_type,
+void rw_gbe_file_part(size_t p, int rw_type,
const char *rw_type_str);
void write_to_gbe_bin(void);
int gbe_mv(void);
-void check_written_part(unsigned long p);
+void check_written_part(size_t p);
void report_io_err_rw(void);
-unsigned char *gbe_mem_offset(unsigned long part, const char *f_op);
-off_t gbe_file_offset(unsigned long part, const char *f_op);
-off_t gbe_x_offset(unsigned long part, const char *f_op,
+unsigned char *gbe_mem_offset(size_t part, const char *f_op);
+off_t gbe_file_offset(size_t part, const char *f_op);
+off_t gbe_x_offset(size_t part, const char *f_op,
const char *d_type, off_t nsize, off_t ncmp);
-long rw_gbe_file_exact(int fd, unsigned char *mem, unsigned long nrw,
+ssize_t rw_gbe_file_exact(int fd, unsigned char *mem, size_t nrw,
off_t off, int rw_type);
/* Generic read/write
*/
int fsync_dir(const char *path);
-long rw_file_exact(int fd, unsigned char *mem, unsigned long len,
+ssize_t rw_file_exact(int fd, unsigned char *mem, size_t len,
off_t off, int rw_type, int loop_eagain, int loop_eintr,
- unsigned long max_retries, int off_reset);
-long prw(int fd, void *mem, unsigned long nrw,
+ size_t max_retries, int off_reset);
+ssize_t prw(int fd, void *mem, size_t nrw,
off_t off, int rw_type, int loop_eagain, int loop_eintr,
int off_reset);
-int io_args(int fd, void *mem, unsigned long nrw,
+int io_args(int fd, void *mem, size_t nrw,
off_t off, int rw_type);
int check_file(int fd, struct stat *st);
-long rw_over_nrw(long r, unsigned long nrw);
-#if !defined(HAVE_REAL_PREAD_PWRITE) || \
- HAVE_REAL_PREAD_PWRITE < 1
+ssize_t rw_over_nrw(ssize_t r, size_t nrw);
+#if !defined(REAL_POS_IO) || \
+ REAL_POS_IO < 1
off_t lseek_on_eintr(int fd, off_t off,
int whence, int loop_eagain, int loop_eintr);
#endif
@@ -442,16 +478,40 @@ int try_err(int loop_err, int errval);
*/
void usage(void);
+void err_no_cleanup(int nvm_errval, const char *msg, ...);
void err(int nvm_errval, const char *msg, ...);
int exit_cleanup(void);
const char *getnvmprogname(void);
-/* Portable libc functions
+/* libc hardening
*/
char *new_tmpfile(int *fd, int local, const char *path);
-int mkstemp_n(char *template);
-char *get_tmpdir(void);
+char *new_tmplate(int *fd, int local, const char *path);
+#if !(defined(DISABLE_OPENAT) && \
+ ((DISABLE_OPENAT) > 0)) /* for openat dir replacement mitigation
+ in mkhtemp()
+ */
+int mkhtemp(int *fd, struct stat *st,
+ char *template, int dirfd, const char *fname,
+ struct stat *st_dir_initial);
+#else
+int mkhtemp(int *fd, struct stat *st,
+ char *template);
+#endif
+int world_writeable_and_sticky(const char *s,
+ int sticky_allowed, int always_sticky);
+int same_dir(const char *a, const char *b);
+int tmpdir_policy(const char *path,
+ int *allow_noworld_unsticky);
+char *env_tmpdir(int always_sticky);
+int split_path(const char *path,
+ struct path_split *ps);
+int open_verified_dir(const char *path);
+int check_dirfd(int dirfd, const char *path);
+int secure_file(int *fd, struct stat *st,
+ int bad_flags, int check_seek,
+ int do_lock, mode_t mode);
int close_on_eintr(int fd);
int fsync_on_eintr(int fd);
@@ -467,16 +527,16 @@ typedef char static_assert_unsigned_short_is_2[
typedef char static_assert_short_is_2[(sizeof(short) >= 2) ? 1 : -1];
typedef char static_assert_unsigned_int_is_4[
(sizeof(unsigned int) >= 4) ? 1 : -1];
-typedef char static_assert_unsigned_long_is_4[
- (sizeof(unsigned long) >= 4) ? 1 : -1];
-typedef char static_assert_long_ulong[
- (sizeof(unsigned long) == sizeof(long)) ? 1 : -1];
+typedef char static_assert_unsigned_ssize_t_is_4[
+ (sizeof(size_t) >= 4) ? 1 : -1];
+typedef char static_assert_ssize_t_ussize_t[
+ (sizeof(size_t) == sizeof(ssize_t)) ? 1 : -1];
typedef char static_assert_int_ge_32[(sizeof(int) >= 4) ? 1 : -1];
typedef char static_assert_twos_complement[
((-1 & 3) == 3) ? 1 : -1
];
-typedef char assert_unsigned_long_ptr[
- (sizeof(unsigned long) >= sizeof(void *)) ? 1 : -1
+typedef char assert_unsigned_ssize_t_ptr[
+ (sizeof(size_t) >= sizeof(void *)) ? 1 : -1
];
/*