diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 07019a2912eb..95a7f5470ec5 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -273,6 +273,12 @@ OLD_DIRS+=usr/lib/clang/9.0.1/lib/freebsd OLD_DIRS+=usr/lib/clang/9.0.1/lib OLD_DIRS+=usr/lib/clang/9.0.1 +# 20200220: Upgrade of ncurses, shlib bumped to version 9 +OLD_LIBS+=lib/libncurses.so.8 +OLD_LIBS+=lib/libncursesw.so.8 +OLD_LIBS+=usr/lib32/libncurses.so.8 +OLD_LIBS+=usr/lib32/libncursesw.so.8 + # 20200206: Remove elf2aout OLD_FILES+=usr/bin/elf2aout OLD_FILES+=usr/share/man/man1/elf2aout.1.gz diff --git a/UPDATING b/UPDATING index cc689a57f483..bbf3e7718d7e 100644 --- a/UPDATING +++ b/UPDATING @@ -32,10 +32,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW: information about prerequisites and upgrading, if you are not already using clang 3.5.0 or higher. -20200218: - ncurses has been updated to a newer version (6.1-20200118). After an - update some applications using ncurses may results have some rendering - problems and would need to be rebuilt. +20200220: + ncurses has been updated to a newer version (6.1-20200118). Given the ABI + has changed, users will have to rebuild all the ports that are linked to + ncurses. 20200217: The size of struct vnet and the magic cookie have changed. diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c index b7619650233b..ad3d862fb6ef 100644 --- a/bin/sh/miscbltin.c +++ b/bin/sh/miscbltin.c @@ -66,10 +66,79 @@ __FBSDID("$FreeBSD$"); #undef eflag +#define READ_BUFLEN 1024 +struct fdctx { + int fd; + size_t off; /* offset in buf */ + size_t buflen; + char *ep; /* tail pointer */ + char buf[READ_BUFLEN]; +}; + +static void fdctx_init(int, struct fdctx *); +static void fdctx_destroy(struct fdctx *); +static ssize_t fdgetc(struct fdctx *, char *); int readcmd(int, char **); int umaskcmd(int, char **); int ulimitcmd(int, char **); +static void +fdctx_init(int fd, struct fdctx *fdc) +{ + off_t cur; + + /* Check if fd is seekable. */ + cur = lseek(fd, 0, SEEK_CUR); + *fdc = (struct fdctx){ + .fd = fd, + .buflen = (cur != -1) ? READ_BUFLEN : 1, + .ep = &fdc->buf[0], /* No data */ + }; +} + +static ssize_t +fdgetc(struct fdctx *fdc, char *c) +{ + ssize_t nread; + + if (&fdc->buf[fdc->off] == fdc->ep) { + nread = read(fdc->fd, fdc->buf, fdc->buflen); + if (nread > 0) { + fdc->off = 0; + fdc->ep = fdc->buf + nread; + } else + return (nread); + } + *c = fdc->buf[fdc->off++]; + + return (1); +} + +static void +fdctx_destroy(struct fdctx *fdc) +{ + size_t residue; + + if (fdc->buflen > 1) { + /* + * Reposition the file offset. Here is the layout of buf: + * + * | off + * v + * |*****************|-------| + * buf ep buf+buflen + * |<- residue ->| + * + * off: current character + * ep: offset just after read(2) + * residue: length for reposition + */ + residue = (fdc->ep - fdc->buf) - fdc->off; + if (residue > 0) + (void) lseek(fdc->fd, -residue, SEEK_CUR); + } +} + /* * The read builtin. The -r option causes backslashes to be treated like * ordinary characters. @@ -108,6 +177,7 @@ readcmd(int argc __unused, char **argv __unused) fd_set ifds; ssize_t nread; int sig; + struct fdctx fdctx; rflag = 0; prompt = NULL; @@ -173,8 +243,9 @@ readcmd(int argc __unused, char **argv __unused) backslash = 0; STARTSTACKSTR(p); lastnonifs = lastnonifsws = -1; + fdctx_init(STDIN_FILENO, &fdctx); for (;;) { - nread = read(STDIN_FILENO, &c, 1); + nread = fdgetc(&fdctx, &c); if (nread == -1) { if (errno == EINTR) { sig = pendingsig; @@ -260,6 +331,7 @@ readcmd(int argc __unused, char **argv __unused) STARTSTACKSTR(p); lastnonifs = lastnonifsws = -1; } + fdctx_destroy(&fdctx); STACKSTRNUL(p); /* diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c index 99dc388c4db6..220910a3c610 100644 --- a/lib/libc/stdlib/realpath.c +++ b/lib/libc/stdlib/realpath.c @@ -42,14 +42,19 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "un-namespace.h" +#include "libc_private.h" + +extern int __realpathat(int fd, const char *path, char *buf, size_t size, + int flags); /* * Find the real name of path, by removing all ".", ".." and symlink * components. Returns (resolved) on success, or (NULL) on failure, * in which case the path which caused trouble is left in (resolved). */ -static char * +static char * __noinline realpath1(const char *path, char *resolved) { struct stat sb; @@ -223,6 +228,10 @@ realpath(const char * __restrict path, char * __restrict resolved) if (resolved == NULL) return (NULL); } + if (__getosreldate() >= 1300080) { + if (__realpathat(AT_FDCWD, path, resolved, PATH_MAX, 0) == 0) + return (resolved); + } res = realpath1(path, resolved); if (res == NULL) free(m); diff --git a/lib/ncurses/ncurses/Makefile b/lib/ncurses/ncurses/Makefile index c069233eb3ed..5b61df983ce9 100644 --- a/lib/ncurses/ncurses/Makefile +++ b/lib/ncurses/ncurses/Makefile @@ -13,7 +13,7 @@ MK_MAN=no .include "${.CURDIR:H}/config.mk" LIB= ncurses${LIB_SUFFIX} -SHLIB_MAJOR= 8 +SHLIB_MAJOR= 9 NO_LINT= @@ -292,7 +292,6 @@ CLEANFILES= ${GENSRCS} ${GENHDRS} keys.list make_hash term.h.new \ make_keys MKterm.h.awk comp_captab.c curses.head CFLAGS+= -DFREEBSD_NATIVE -DTERMIOS -CFLAGS.lib_freeall.c+= -Wno-missing-prototypes # Installed HEADERS= curses.h term.h termcap.h unctrl.h diff --git a/libexec/rtld-elf/rtld-libc/Makefile.inc b/libexec/rtld-elf/rtld-libc/Makefile.inc index 90e9f97251a3..9d56e58dfc8e 100644 --- a/libexec/rtld-elf/rtld-libc/Makefile.inc +++ b/libexec/rtld-elf/rtld-libc/Makefile.inc @@ -49,7 +49,7 @@ _libc_other_objects= sigsetjmp lstat stat fstat fstatat fstatfs syscall \ sysarch __sysctl issetugid __getcwd utrace \ thr_self thr_kill pread mmap lseek _exit _fstat _fstatat _fstatfs \ getdirentries _getdirentries _close _fcntl _open _openat _read \ - _sigprocmask _write readlink _setjmp setjmp setjmperr + _sigprocmask _write readlink __realpathat _setjmp setjmp setjmperr # Finally add additional architecture-dependent libc dependencies diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 1adfff6434ae..91ca0346b050 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -192,6 +192,7 @@ MAN= aac.4 \ ${_hv_vmbus.4} \ ${_hv_vss.4} \ hwpmc.4 \ + ${_hwpstate_intel.4} \ iavf.4 \ ichsmb.4 \ ${_ichwd.4} \ @@ -787,6 +788,7 @@ _hv_storvsc.4= hv_storvsc.4 _hv_utils.4= hv_utils.4 _hv_vmbus.4= hv_vmbus.4 _hv_vss.4= hv_vss.4 +_hwpstate_intel.4= hwpstate_intel.4 _i8254.4= i8254.4 _ichwd.4= ichwd.4 _if_bxe.4= if_bxe.4 diff --git a/stand/efi/libefi/efi_driver_utils.c b/stand/efi/libefi/efi_driver_utils.c index 0edea5c1e0d8..e5034c2e34d6 100644 --- a/stand/efi/libefi/efi_driver_utils.c +++ b/stand/efi/libefi/efi_driver_utils.c @@ -52,6 +52,8 @@ connect_controllers(EFI_GUID *filter) } handles = malloc(hsize); + if (handles == NULL) + return (EFI_OUT_OF_RESOURCES); nhandles = hsize / sizeof(EFI_HANDLE); status = BS->LocateHandle(ByProtocol, filter, NULL, diff --git a/stand/efi/libefi/efihttp.c b/stand/efi/libefi/efihttp.c index e637da23a088..2894709ca03c 100644 --- a/stand/efi/libefi/efihttp.c +++ b/stand/efi/libefi/efihttp.c @@ -701,6 +701,8 @@ efihttp_fs_seek(struct open_file *f, off_t offset, int where) return (0); if (where == SEEK_SET && fh->offset < offset) { buf = malloc(1500); + if (buf == NULL) + return (ENOMEM); res = offset - fh->offset; while (res > 0) { err = _efihttp_fs_read(f, buf, min(1500, res), &res2); diff --git a/stand/efi/libefi/efinet.c b/stand/efi/libefi/efinet.c index 418790524e4a..c52b11d32ec8 100644 --- a/stand/efi/libefi/efinet.c +++ b/stand/efi/libefi/efinet.c @@ -371,6 +371,8 @@ efinet_dev_init() status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, NULL); if (status == EFI_BUFFER_TOO_SMALL) { handles = (EFI_HANDLE *)malloc(sz); + if (handles == NULL) + return (ENOMEM); status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, handles); if (EFI_ERROR(status)) diff --git a/stand/efi/libefi/efipart.c b/stand/efi/libefi/efipart.c index 0710a33fdf93..424df7d2e423 100644 --- a/stand/efi/libefi/efipart.c +++ b/stand/efi/libefi/efipart.c @@ -363,6 +363,8 @@ efipart_inithandles(void) status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, hin); if (status == EFI_BUFFER_TOO_SMALL) { hin = malloc(sz); + if (hin == NULL) + return (ENOMEM); status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, hin); if (EFI_ERROR(status)) diff --git a/stand/efi/libefi/efizfs.c b/stand/efi/libefi/efizfs.c index 8b28250f109b..aedb9c2294cd 100644 --- a/stand/efi/libefi/efizfs.c +++ b/stand/efi/libefi/efizfs.c @@ -86,9 +86,11 @@ insert_zfs(EFI_HANDLE handle, uint64_t guid) zfsinfo_t *zi; zi = malloc(sizeof(zfsinfo_t)); - zi->zi_handle = handle; - zi->zi_pool_guid = guid; - STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link); + if (zi != NULL) { + zi->zi_handle = handle; + zi->zi_pool_guid = guid; + STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link); + } } void diff --git a/stand/efi/libefi/handles.c b/stand/efi/libefi/handles.c index 1e4ef6ffbd50..a55239dbec8c 100644 --- a/stand/efi/libefi/handles.c +++ b/stand/efi/libefi/handles.c @@ -52,6 +52,8 @@ efi_register_handles(struct devsw *sw, EFI_HANDLE *handles, nentries += count; sz = nentries * sizeof(struct entry); entry = (entry == NULL) ? malloc(sz) : realloc(entry, sz); + if (entry == NULL) + return (ENOMEM); for (unit = 0; idx < nentries; idx++, unit++) { entry[idx].handle = handles[unit]; if (aliases != NULL) diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile index d290cae5d4c8..6ee613e7bfea 100644 --- a/stand/efi/loader/Makefile +++ b/stand/efi/loader/Makefile @@ -22,7 +22,6 @@ SRCS= autoload.c \ framebuffer.c \ main.c \ self_reloc.c \ - smbios.c \ vers.c CFLAGS+= -I${.CURDIR}/../loader @@ -45,8 +44,6 @@ CWARNFLAGS.main.c+= -Wno-format .PATH: ${.CURDIR}/../loader .PATH: ${.CURDIR}/../loader/arch/${MACHINE} -# For smbios.c XXX need to abstract properly -.PATH: ${BOOTSRC}/i386/libi386 .include "${.CURDIR}/../loader/arch/${MACHINE}/Makefile.inc" CFLAGS+= -I${.CURDIR} @@ -57,18 +54,6 @@ CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include CFLAGS+= -I${BOOTSRC}/i386/libi386 CFLAGS+= -DEFI -.if !defined(BOOT_HIDE_SERIAL_NUMBERS) -# Export serial numbers, UUID, and asset tag from loader. -CFLAGS+= -DSMBIOS_SERIAL_NUMBERS -.if defined(BOOT_LITTLE_ENDIAN_UUID) -# Use little-endian UUID format as defined in SMBIOS 2.6. -CFLAGS+= -DSMBIOS_LITTLE_ENDIAN_UUID -.elif defined(BOOT_NETWORK_ENDIAN_UUID) -# Use network-endian UUID format for backward compatibility. -CFLAGS+= -DSMBIOS_NETWORK_ENDIAN_UUID -.endif -.endif - .if defined(HAVE_FDT) && ${MK_FDT} != "no" .include "${BOOTSRC}/fdt.mk" LIBEFI_FDT= ${BOOTOBJ}/efi/fdt/libefi_fdt.a diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c index 700ad6bec5a4..143c003adbb1 100644 --- a/stand/efi/loader/main.c +++ b/stand/efi/loader/main.c @@ -852,7 +852,11 @@ read_loader_env(const char *name, char *def_fn, bool once) } } - +caddr_t +ptov(uintptr_t x) +{ + return ((caddr_t)x); +} EFI_STATUS main(int argc, CHAR16 *argv[]) diff --git a/stand/i386/libi386/Makefile b/stand/i386/libi386/Makefile index d6667a548ccf..a4485b60a28e 100644 --- a/stand/i386/libi386/Makefile +++ b/stand/i386/libi386/Makefile @@ -9,7 +9,7 @@ SRCS= bio.c biosacpi.c biosdisk.c biosmem.c biospnp.c \ comconsole.c devicename.c elf32_freebsd.c \ elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.S \ i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.S \ - smbios.c time.c vidconsole.c amd64_tramp.S spinconsole.c + time.c vidconsole.c amd64_tramp.S spinconsole.c .PATH: ${ZFSSRC} SRCS+= devicename_stubs.c CFLAGS+= -I${ZFSSRC} @@ -28,18 +28,6 @@ CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED} CFLAGS+= -DDISK_DEBUG .endif -.if !defined(BOOT_HIDE_SERIAL_NUMBERS) -# Export serial numbers, UUID, and asset tag from loader. -CFLAGS+= -DSMBIOS_SERIAL_NUMBERS -.if defined(BOOT_LITTLE_ENDIAN_UUID) -# Use little-endian UUID format as defined in SMBIOS 2.6. -CFLAGS+= -DSMBIOS_LITTLE_ENDIAN_UUID -.elif defined(BOOT_NETWORK_ENDIAN_UUID) -# Use network-endian UUID format for backward compatibility. -CFLAGS+= -DSMBIOS_NETWORK_ENDIAN_UUID -.endif -.endif - # terminal emulation CFLAGS.vidconsole.c+= -I${SRCTOP}/sys/teken CFLAGS.teken.c+= -I${SRCTOP}/sys/teken diff --git a/stand/i386/loader/main.c b/stand/i386/loader/main.c index 2d0d63a12b37..0087ec757353 100644 --- a/stand/i386/loader/main.c +++ b/stand/i386/loader/main.c @@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "common/bootargs.h" #include "libi386/libi386.h" -#include "libi386/smbios.h" +#include #include "btxv86.h" #ifdef LOADER_ZFS_SUPPORT @@ -86,6 +86,12 @@ extern char end[]; static void *heap_top; static void *heap_bottom; +caddr_t +ptov(uintptr_t x) +{ + return (PTOV(x)); +} + int main(void) { diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile index 5c2edd49ff61..b9b70b93e039 100644 --- a/stand/libsa/Makefile +++ b/stand/libsa/Makefile @@ -137,6 +137,20 @@ CLEANFILES+= ${SAFE_INCS} ${STAND_H_INC} ${OTHER_INC} SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \ fstat.c close.c lseek.c open.c read.c write.c readdir.c +# SMBios routines +SRCS+= smbios.c +.if !defined(BOOT_HIDE_SERIAL_NUMBERS) +# Export serial numbers, UUID, and asset tag from loader. +CFLAGS.smbios.c+= -DSMBIOS_SERIAL_NUMBERS +.if defined(BOOT_LITTLE_ENDIAN_UUID) +# Use little-endian UUID format as defined in SMBIOS 2.6. +CFLAGS.smbios.c+= -DSMBIOS_LITTLE_ENDIAN_UUID +.elif defined(BOOT_NETWORK_ENDIAN_UUID) +# Use network-endian UUID format for backward compatibility. +CFLAGS.smbios.c+= -DSMBIOS_NETWORK_ENDIAN_UUID +.endif +.endif + # network routines SRCS+= arp.c ether.c ip.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c diff --git a/stand/i386/libi386/smbios.c b/stand/libsa/smbios.c similarity index 98% rename from stand/i386/libi386/smbios.c rename to stand/libsa/smbios.c index 2aa62fa85df7..c621114d9107 100644 --- a/stand/i386/libi386/smbios.c +++ b/stand/libsa/smbios.c @@ -28,16 +28,9 @@ __FBSDID("$FreeBSD$"); #include -#include #include -#ifdef EFI -/* In EFI, we don't need PTOV(). */ -#define PTOV(x) (caddr_t)(x) -#else -#include "btxv86.h" -#endif -#include "smbios.h" +#define PTOV(x) ptov(x) /* * Detect SMBIOS and export information about the SMBIOS into the diff --git a/stand/i386/libi386/smbios.h b/stand/libsa/smbios.h similarity index 100% rename from stand/i386/libi386/smbios.h rename to stand/libsa/smbios.h diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h index 5ad1166d4f67..6d566219c186 100644 --- a/stand/libsa/stand.h +++ b/stand/libsa/stand.h @@ -452,4 +452,9 @@ const char *x86_hypervisor(void); #define reallocf(x, y) Reallocf(x, y, NULL, 0) #endif +/* + * va <-> pa routines. MD code must supply. + */ +caddr_t ptov(uintptr_t); + #endif /* STAND_H */ diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h index 195194887db4..58582e235635 100644 --- a/sys/bsm/audit_kevents.h +++ b/sys/bsm/audit_kevents.h @@ -657,6 +657,7 @@ #define AUE_LGETUUID 43261 /* CADETS. */ #define AUE_EXECVEAT 43262 /* FreeBSD/Linux. */ #define AUE_SHMRENAME 43263 /* FreeBSD-specific. */ +#define AUE_REALPATHAT 43264 /* FreeBSD-specific. */ /* * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index 6f91a1190a1c..3ee4069b3423 100644 --- a/sys/compat/freebsd32/freebsd32_syscall.h +++ b/sys/compat/freebsd32/freebsd32_syscall.h @@ -500,4 +500,5 @@ #define FREEBSD32_SYS_shm_open2 571 #define FREEBSD32_SYS_shm_rename 572 #define FREEBSD32_SYS_sigfastblock 573 -#define FREEBSD32_SYS_MAXSYSCALL 574 +#define FREEBSD32_SYS___realpathat 574 +#define FREEBSD32_SYS_MAXSYSCALL 575 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index deefa2d22630..64ec98b68195 100644 --- a/sys/compat/freebsd32/freebsd32_syscalls.c +++ b/sys/compat/freebsd32/freebsd32_syscalls.c @@ -610,4 +610,5 @@ const char *freebsd32_syscallnames[] = { "shm_open2", /* 571 = shm_open2 */ "shm_rename", /* 572 = shm_rename */ "sigfastblock", /* 573 = sigfastblock */ + "__realpathat", /* 574 = __realpathat */ }; diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index 5f29aec0cc41..63d55ad6d4e3 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -663,4 +663,5 @@ struct sysent freebsd32_sysent[] = { { AS(shm_open2_args), (sy_call_t *)sys_shm_open2, AUE_SHMOPEN, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 571 = shm_open2 */ { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_SHMRENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */ { AS(sigfastblock_args), (sy_call_t *)sys_sigfastblock, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 573 = sigfastblock */ + { AS(__realpathat_args), (sy_call_t *)sys___realpathat, AUE_REALPATHAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 574 = __realpathat */ }; diff --git a/sys/compat/freebsd32/freebsd32_systrace_args.c b/sys/compat/freebsd32/freebsd32_systrace_args.c index 2abc302f3079..a2938b12a53a 100644 --- a/sys/compat/freebsd32/freebsd32_systrace_args.c +++ b/sys/compat/freebsd32/freebsd32_systrace_args.c @@ -3363,6 +3363,17 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 2; break; } + /* __realpathat */ + case 574: { + struct __realpathat_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->path; /* const char * */ + uarg[2] = (intptr_t) p->buf; /* char * */ + uarg[3] = p->size; /* size_t */ + iarg[4] = p->flags; /* int */ + *n_args = 5; + break; + } default: *n_args = 0; break; @@ -9062,6 +9073,28 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; + /* __realpathat */ + case 574: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "userland const char *"; + break; + case 2: + p = "userland char *"; + break; + case 3: + p = "size_t"; + break; + case 4: + p = "int"; + break; + default: + break; + }; + break; default: break; }; @@ -10956,6 +10989,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; + /* __realpathat */ + case 574: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index a82d75d26e22..049e0b78500c 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -1160,5 +1160,7 @@ 572 AUE_SHMRENAME NOPROTO { int shm_rename(const char *path_from, \ const char *path_to, int flags); } 573 AUE_NULL NOPROTO { int sigfastblock(int cmd, uint32_t *ptr); } +574 AUE_REALPATHAT NOPROTO { int __realpathat(int fd, const char *path, \ + char *buf, size_t size, int flags); } ; vim: syntax=off diff --git a/sys/compat/linuxkpi/common/include/linux/list.h b/sys/compat/linuxkpi/common/include/linux/list.h index 0609cee4e232..c16007eab143 100644 --- a/sys/compat/linuxkpi/common/include/linux/list.h +++ b/sys/compat/linuxkpi/common/include/linux/list.h @@ -449,6 +449,13 @@ static inline void list_cut_position(struct list_head *list, __list_cut_position(list, head, entry); } +static inline int list_is_first(const struct list_head *list, + const struct list_head *head) +{ + + return (list->prev == head); +} + static inline int list_is_last(const struct list_head *list, const struct list_head *head) { diff --git a/sys/compat/linuxkpi/common/include/linux/string.h b/sys/compat/linuxkpi/common/include/linux/string.h index 918ff8169a38..d8d509778adb 100644 --- a/sys/compat/linuxkpi/common/include/linux/string.h +++ b/sys/compat/linuxkpi/common/include/linux/string.h @@ -154,4 +154,13 @@ memchr_inv(const void *start, int c, size_t length) return (NULL); } +static inline size_t +str_has_prefix(const char *str, const char *prefix) +{ + size_t len; + + len = strlen(prefix); + return (strncmp(str, prefix, len) == 0 ? len : 0); +} + #endif /* _LINUX_STRING_H_ */ diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 0745d00ce3a8..fa3081cff296 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -760,7 +760,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", device_get_nameunit(sc->sc_dev)); - NET_TASK_INIT(&sc->sc_rxtask, 0, sc->sc_rx.recv_tasklet, sc); + TASK_INIT(&sc->sc_rxtask, 0, sc->sc_rx.recv_tasklet, sc); TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc); TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc); TASK_INIT(&sc->sc_resettask,0, ath_reset_proc, sc); diff --git a/sys/dev/ath/if_ath_rx.c b/sys/dev/ath/if_ath_rx.c index 93a1d7455191..dfa95e637ac4 100644 --- a/sys/dev/ath/if_ath_rx.c +++ b/sys/dev/ath/if_ath_rx.c @@ -656,6 +656,8 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, int is_good = 0; struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; + NET_EPOCH_ASSERT(); + /* * Calculate the correct 64 bit TSF given * the TSF64 register value and rs_tstamp. @@ -1074,6 +1076,8 @@ ath_rx_proc(struct ath_softc *sc, int resched) int kickpcu = 0; int ret; + NET_EPOCH_ASSERT(); + /* XXX we must not hold the ATH_LOCK here */ ATH_UNLOCK_ASSERT(sc); ATH_PCU_UNLOCK_ASSERT(sc); @@ -1293,6 +1297,7 @@ static void ath_legacy_rx_tasklet(void *arg, int npending) { struct ath_softc *sc = arg; + struct epoch_tracker et; ATH_KTR(sc, ATH_KTR_RXPROC, 1, "ath_rx_proc: pending=%d", npending); DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); @@ -1305,14 +1310,18 @@ ath_legacy_rx_tasklet(void *arg, int npending) } ATH_PCU_UNLOCK(sc); + NET_EPOCH_ENTER(et); ath_rx_proc(sc, 1); + NET_EPOCH_EXIT(et); } static void ath_legacy_flushrecv(struct ath_softc *sc) { - + struct epoch_tracker et; + NET_EPOCH_ENTER(et); ath_rx_proc(sc, 0); + NET_EPOCH_EXIT(et); } static void diff --git a/sys/dev/ath/if_ath_rx_edma.c b/sys/dev/ath/if_ath_rx_edma.c index 3d43d7fdd96f..3ef4061becb8 100644 --- a/sys/dev/ath/if_ath_rx_edma.c +++ b/sys/dev/ath/if_ath_rx_edma.c @@ -521,6 +521,7 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, int16_t nf; ath_bufhead rxlist; struct mbuf *m; + struct epoch_tracker et; TAILQ_INIT(&rxlist); @@ -537,6 +538,8 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, TAILQ_CONCAT(&rxlist, &sc->sc_rx_rxlist[qtype], bf_list); ATH_RX_UNLOCK(sc); + NET_EPOCH_ENTER(et); + /* Handle the completed descriptors */ /* * XXX is this SAFE call needed? The ath_buf entries @@ -560,6 +563,7 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, if (ngood) { sc->sc_lastrx = tsf; } + NET_EPOCH_EXIT(et); ATH_KTR(sc, ATH_KTR_INTERRUPTS, 1, "ath edma rx deferred proc: ngood=%d\n", diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h index eca14c711ecd..d580ef88b60c 100644 --- a/sys/dev/pci/pcireg.h +++ b/sys/dev/pci/pcireg.h @@ -151,6 +151,7 @@ #define PCIY_SATA 0x12 /* SATA */ #define PCIY_PCIAF 0x13 /* PCI Advanced Features */ #define PCIY_EA 0x14 /* PCI Extended Allocation */ +#define PCIY_FPB 0x15 /* Flattening Portal Bridge */ /* Extended Capability Register Fields */ @@ -194,6 +195,20 @@ #define PCIZ_LN_REQ 0x001c /* LN Requester */ #define PCIZ_DPC 0x001d /* Downstream Port Containment */ #define PCIZ_L1PM 0x001e /* L1 PM Substates */ +#define PCIZ_PTM 0x001f /* Precision Time Measurement */ +#define PCIZ_M_PCIE 0x0020 /* PCIe over M-PHY */ +#define PCIZ_FRS 0x0021 /* FRS Queuing */ +#define PCIZ_RTR 0x0022 /* Readiness Time Reporting */ +#define PCIZ_DVSEC 0x0023 /* Designated Vendor-Specific */ +#define PCIZ_VF_REBAR 0x0024 /* VF Resizable BAR */ +#define PCIZ_DLNK 0x0025 /* Data Link Feature */ +#define PCIZ_16GT 0x0026 /* Physical Layer 16.0 GT/s */ +#define PCIZ_LMR 0x0027 /* Lane Margining at Receiver */ +#define PCIZ_HIER_ID 0x0028 /* Hierarchy ID */ +#define PCIZ_NPEM 0x0029 /* Native PCIe Enclosure Management */ +#define PCIZ_PL32 0x002a /* Physical Layer 32.0 GT/s */ +#define PCIZ_AP 0x002b /* Alternate Protocol */ +#define PCIZ_SFI 0x002c /* System Firmware Intermediary */ /* config registers for header type 0 devices */ @@ -334,6 +349,8 @@ #define PCIS_STORAGE_NVM 0x08 #define PCIP_STORAGE_NVM_NVMHCI_1_0 0x01 #define PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0 0x02 +#define PCIS_STORAGE_UFS 0x09 +#define PCIP_STORAGE_UFS_UFSHCI_1_0 0x01 #define PCIS_STORAGE_OTHER 0x80 #define PCIC_NETWORK 0x02 @@ -344,6 +361,8 @@ #define PCIS_NETWORK_ISDN 0x04 #define PCIS_NETWORK_WORLDFIP 0x05 #define PCIS_NETWORK_PICMG 0x06 +#define PCIS_NETWORK_INFINIBAND 0x07 +#define PCIS_NETWORK_HFC 0x08 #define PCIS_NETWORK_OTHER 0x80 #define PCIC_DISPLAY 0x03 @@ -357,6 +376,7 @@ #define PCIS_MULTIMEDIA_AUDIO 0x01 #define PCIS_MULTIMEDIA_TELE 0x02 #define PCIS_MULTIMEDIA_HDA 0x03 +#define PCIP_MULTIMEDIA_HDA_VENDOR 0x01 #define PCIS_MULTIMEDIA_OTHER 0x80 #define PCIC_MEMORY 0x05 @@ -377,6 +397,8 @@ #define PCIS_BRIDGE_RACEWAY 0x08 #define PCIS_BRIDGE_PCI_TRANSPARENT 0x09 #define PCIS_BRIDGE_INFINIBAND 0x0a +#define PCIS_BRIDGE_AS_PCI 0x0b +#define PCIS_BRIDGE_AS_PCI_ASI_SIG 0x01 #define PCIS_BRIDGE_OTHER 0x80 #define PCIC_SIMPLECOMM 0x07 @@ -408,6 +430,7 @@ #define PCIS_BASEPERIPH_PCIHOT 0x04 #define PCIS_BASEPERIPH_SDHC 0x05 #define PCIS_BASEPERIPH_IOMMU 0x06 +#define PCIS_BASEPERIPH_RCEC 0x07 #define PCIS_BASEPERIPH_OTHER 0x80 #define PCIC_INPUTDEV 0x09 @@ -450,6 +473,7 @@ #define PCIP_SERIALBUS_IPMI_BT 0x02 #define PCIS_SERIALBUS_SERCOS 0x08 #define PCIS_SERIALBUS_CANBUS 0x09 +#define PCIS_SERIALBUS_MIPI_I3C 0x0a #define PCIC_WIRELESS 0x0d #define PCIS_WIRELESS_IRDA 0x00 @@ -459,6 +483,8 @@ #define PCIS_WIRELESS_BROADBAND 0x12 #define PCIS_WIRELESS_80211A 0x20 #define PCIS_WIRELESS_80211B 0x21 +#define PCIS_WIRELESS_CELL 0x40 +#define PCIS_WIRELESS_CELL_E 0x41 #define PCIS_WIRELESS_OTHER 0x80 #define PCIC_INTELLIIO 0x0e diff --git a/sys/dev/virtio/mmio/virtio_mmio.c b/sys/dev/virtio/mmio/virtio_mmio.c index 95eb86470529..ccafe3268689 100644 --- a/sys/dev/virtio/mmio/virtio_mmio.c +++ b/sys/dev/virtio/mmio/virtio_mmio.c @@ -196,7 +196,7 @@ vtmmio_setup_intr(device_t dev, enum intr_type type) return (ENXIO); } - if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, + if (bus_setup_intr(dev, sc->res[1], type | INTR_MPSAFE, NULL, vtmmio_vq_intr, sc, &sc->ih)) { device_printf(dev, "Can't setup the interrupt\n"); return (ENXIO); diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 7ae26621d1eb..a585500902d3 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -629,4 +629,5 @@ struct sysent sysent[] = { { AS(shm_open2_args), (sy_call_t *)sys_shm_open2, AUE_SHMOPEN, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 571 = shm_open2 */ { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_SHMRENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */ { AS(sigfastblock_args), (sy_call_t *)sys_sigfastblock, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 573 = sigfastblock */ + { AS(__realpathat_args), (sy_call_t *)sys___realpathat, AUE_REALPATHAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 574 = __realpathat */ }; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 3fa76d659a37..0dedcf45926d 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1035,9 +1035,7 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv) imgp->vmspace_destroyed = 1; imgp->sysent = sv; - td->td_pflags &= ~TDP_SIGFASTBLOCK; - td->td_sigblock_ptr = NULL; - td->td_sigblock_val = 0; + sigfastblock_clear(td); /* May be called with Giant held */ EVENTHANDLER_DIRECT_INVOKE(process_exec, p, imgp); diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 5d6a677748ea..97de24b88a89 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -157,6 +157,12 @@ static int kern_lognosys = 0; SYSCTL_INT(_kern, OID_AUTO, lognosys, CTLFLAG_RWTUN, &kern_lognosys, 0, "Log invalid syscalls"); +__read_frequently bool sigfastblock_fetch_always = false; +SYSCTL_BOOL(_kern, OID_AUTO, sigfastblock_fetch_always, CTLFLAG_RWTUN, + &sigfastblock_fetch_always, 0, + "Fetch sigfastblock word on each syscall entry for proper " + "blocking semantic"); + SYSINIT(signal, SI_SUB_P1003_1B, SI_ORDER_FIRST+3, sigqueue_start, NULL); /* @@ -2005,6 +2011,7 @@ trapsignal(struct thread *td, ksiginfo_t *ksi) code = ksi->ksi_code; KASSERT(_SIG_VALID(sig), ("invalid signal")); + sigfastblock_fetch(td); PROC_LOCK(p); ps = p->p_sigacts; mtx_lock(&ps->ps_mtx); @@ -3952,6 +3959,42 @@ sig_drop_caught(struct proc *p) } } +static void +sigfastblock_failed(struct thread *td, bool sendsig, bool write) +{ + ksiginfo_t ksi; + + /* + * Prevent further fetches and SIGSEGVs, allowing thread to + * issue syscalls despite corruption. + */ + sigfastblock_clear(td); + + if (!sendsig) + return; + ksiginfo_init_trap(&ksi); + ksi.ksi_signo = SIGSEGV; + ksi.ksi_code = write ? SEGV_ACCERR : SEGV_MAPERR; + ksi.ksi_addr = td->td_sigblock_ptr; + trapsignal(td, &ksi); +} + +static bool +sigfastblock_fetch_sig(struct thread *td, bool sendsig, uint32_t *valp) +{ + uint32_t res; + + if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0) + return (true); + if (fueword32((void *)td->td_sigblock_ptr, &res) == -1) { + sigfastblock_failed(td, sendsig, false); + return (false); + } + *valp = res; + td->td_sigblock_val = res & ~SIGFASTBLOCK_FLAGS; + return (true); +} + int sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap) { @@ -3960,6 +4003,7 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap) uint32_t oldval; error = 0; + p = td->td_proc; switch (uap->cmd) { case SIGFASTBLOCK_SETPTR: if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0) { @@ -3975,18 +4019,22 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap) break; case SIGFASTBLOCK_UNBLOCK: - if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0) { + if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0) { error = EINVAL; break; } -again: - res = casueword32(td->td_sigblock_ptr, SIGFASTBLOCK_PEND, - &oldval, 0); - if (res == -1) { - error = EFAULT; - break; - } - if (res == 1) { + + for (;;) { + res = casueword32(td->td_sigblock_ptr, + SIGFASTBLOCK_PEND, &oldval, 0); + if (res == -1) { + error = EFAULT; + sigfastblock_failed(td, false, true); + break; + } + if (res == 0) + break; + MPASS(res == 1); if (oldval != SIGFASTBLOCK_PEND) { error = EBUSY; break; @@ -3994,8 +4042,22 @@ again: error = thread_check_susp(td, false); if (error != 0) break; - goto again; } + if (error != 0) + break; + + /* + * td_sigblock_val is cleared there, but not on a + * syscall exit. The end effect is that a single + * interruptible sleep, while user sigblock word is + * set, might return EINTR or ERESTART to usermode + * without delivering signal. All further sleeps, + * until userspace clears the word and does + * sigfastblock(UNBLOCK), observe current word and no + * longer get interrupted. It is slight + * non-conformance, with alternative to have read the + * sigblock word on each syscall entry. + */ td->td_sigblock_val = 0; /* @@ -4003,7 +4065,6 @@ again: * signals to current thread. But notify others about * fake unblock. */ - p = td->td_proc; if (error == 0 && p->p_numthreads != 1) { PROC_LOCK(p); reschedule_signals(p, td->td_sigmask, 0); @@ -4016,8 +4077,7 @@ again: error = EINVAL; break; } - res = fueword32(td->td_sigblock_ptr, &oldval); - if (res == -1) { + if (!sigfastblock_fetch_sig(td, false, &oldval)) { error = EFAULT; break; } @@ -4025,8 +4085,7 @@ again: error = EBUSY; break; } - td->td_pflags &= ~TDP_SIGFASTBLOCK; - td->td_sigblock_val = 0; + sigfastblock_clear(td); break; default: @@ -4037,32 +4096,59 @@ again: } void -fetch_sigfastblock(struct thread *td) +sigfastblock_clear(struct thread *td) { + struct proc *p; + bool resched; if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0) return; - if (fueword32(td->td_sigblock_ptr, &td->td_sigblock_val) == -1) { - fetch_sigfastblock_failed(td, false); - return; + td->td_sigblock_val = 0; + resched = (td->td_pflags & TDP_SIGFASTPENDING) != 0; + td->td_pflags &= ~(TDP_SIGFASTBLOCK | TDP_SIGFASTPENDING); + if (resched) { + p = td->td_proc; + PROC_LOCK(p); + reschedule_signals(p, td->td_sigmask, 0); + PROC_UNLOCK(p); } - td->td_sigblock_val &= ~SIGFASTBLOCK_FLAGS; } void -fetch_sigfastblock_failed(struct thread *td, bool write) +sigfastblock_fetch(struct thread *td) { - ksiginfo_t ksi; + uint32_t val; - /* - * Prevent further fetches and SIGSEGVs, allowing thread to - * issue syscalls despite corruption. - */ - td->td_pflags &= ~TDP_SIGFASTBLOCK; - - ksiginfo_init_trap(&ksi); - ksi.ksi_signo = SIGSEGV; - ksi.ksi_code = write ? SEGV_ACCERR : SEGV_MAPERR; - ksi.ksi_addr = td->td_sigblock_ptr; - trapsignal(td, &ksi); + (void)sigfastblock_fetch_sig(td, true, &val); +} + +void +sigfastblock_setpend(struct thread *td) +{ + int res; + uint32_t oldval; + + if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0) + return; + res = fueword32((void *)td->td_sigblock_ptr, &oldval); + if (res == -1) { + sigfastblock_failed(td, true, false); + return; + } + for (;;) { + res = casueword32(td->td_sigblock_ptr, oldval, &oldval, + oldval | SIGFASTBLOCK_PEND); + if (res == -1) { + sigfastblock_failed(td, true, true); + return; + } + if (res == 0) { + td->td_sigblock_val = oldval & ~SIGFASTBLOCK_FLAGS; + td->td_pflags &= ~TDP_SIGFASTPENDING; + break; + } + MPASS(res == 1); + if (thread_check_susp(td, false) != 0) + break; + } } diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c index 938e577fa9fb..e160e357924f 100644 --- a/sys/kern/subr_syscall.c +++ b/sys/kern/subr_syscall.c @@ -132,11 +132,11 @@ syscallenter(struct thread *td) } /* - * Fetch fast sigblock value at the time of syscall - * entry because sleepqueue primitives might call - * cursig(). + * Fetch fast sigblock value at the time of syscall entry to + * handle sleepqueue primitives which might call cursig(). */ - fetch_sigfastblock(td); + if (__predict_false(sigfastblock_fetch_always)) + (void)sigfastblock_fetch(td); /* Let system calls set td_errno directly. */ td->td_pflags &= ~TDP_NERRNO; diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 0349f4320cce..5ef3f1c6935f 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -134,6 +134,7 @@ userret(struct thread *td, struct trapframe *frame) #ifdef KTRACE KTRUSERRET(td); #endif + td_softdep_cleanup(td); MPASS(td->td_su == NULL); @@ -222,8 +223,7 @@ ast(struct trapframe *framep) { struct thread *td; struct proc *p; - uint32_t oldval; - int flags, sig, res; + int flags, sig; td = curthread; p = td->td_proc; @@ -325,11 +325,12 @@ ast(struct trapframe *framep) */ if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 || !SIGISEMPTY(p->p_siglist)) { - fetch_sigfastblock(td); + sigfastblock_fetch(td); PROC_LOCK(p); mtx_lock(&p->p_sigacts->ps_mtx); if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0 && td->td_sigblock_val != 0) { + sigfastblock_setpend(td); reschedule_signals(p, fastblock_mask, SIGPROCMASK_PS_LOCKED | SIGPROCMASK_FASTBLK); } else { @@ -346,32 +347,8 @@ ast(struct trapframe *framep) * Handle deferred update of the fast sigblock value, after * the postsig() loop was performed. */ - if (td->td_pflags & TDP_SIGFASTPENDING) { - td->td_pflags &= ~TDP_SIGFASTPENDING; - res = fueword32(td->td_sigblock_ptr, &oldval); - if (res == -1) { - fetch_sigfastblock_failed(td, false); - } else { - for (;;) { - oldval |= SIGFASTBLOCK_PEND; - res = casueword32(td->td_sigblock_ptr, oldval, - &oldval, oldval | SIGFASTBLOCK_PEND); - if (res == -1) { - fetch_sigfastblock_failed(td, true); - break; - } - if (res == 0) { - td->td_sigblock_val = oldval & - ~SIGFASTBLOCK_FLAGS; - break; - } - MPASS(res == 1); - res = thread_check_susp(td, false); - if (res != 0) - break; - } - } - } + if (td->td_pflags & TDP_SIGFASTPENDING) + sigfastblock_setpend(td); /* * We need to check to see if we have to exit or wait due to a diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 0df4e03756eb..c0592692c961 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -580,4 +580,5 @@ const char *syscallnames[] = { "shm_open2", /* 571 = shm_open2 */ "shm_rename", /* 572 = shm_rename */ "sigfastblock", /* 573 = sigfastblock */ + "__realpathat", /* 574 = __realpathat */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 47a42020d2c6..8a61610daf06 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -3218,6 +3218,15 @@ _Inout_opt_ uint32_t *ptr ); } +574 AUE_REALPATHAT STD { + int __realpathat( + int fd, + _In_z_ const char *path, + _Out_writes_z_(size) char *buf, + size_t size, + int flags + ); + } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c index 346415a69787..15f343bafec4 100644 --- a/sys/kern/systrace_args.c +++ b/sys/kern/systrace_args.c @@ -3355,6 +3355,17 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 2; break; } + /* __realpathat */ + case 574: { + struct __realpathat_args *p = params; + iarg[0] = p->fd; /* int */ + uarg[1] = (intptr_t) p->path; /* const char * */ + uarg[2] = (intptr_t) p->buf; /* char * */ + uarg[3] = p->size; /* size_t */ + iarg[4] = p->flags; /* int */ + *n_args = 5; + break; + } default: *n_args = 0; break; @@ -8967,6 +8978,28 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; + /* __realpathat */ + case 574: + switch(ndx) { + case 0: + p = "int"; + break; + case 1: + p = "userland const char *"; + break; + case 2: + p = "userland char *"; + break; + case 3: + p = "size_t"; + break; + case 4: + p = "int"; + break; + default: + break; + }; + break; default: break; }; @@ -10888,6 +10921,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; + /* __realpathat */ + case 574: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index f0026e1be18e..9302deb6f8fd 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -387,8 +388,12 @@ STATNODE_COUNTER(shrinking_skipped, "Number of times shrinking was already in progress"); static void cache_zap_locked(struct namecache *ncp, bool neg_locked); -static int vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, +static int vn_fullpath_hardlink(struct thread *td, struct nameidata *ndp, char **retbuf, + char **freebuf, size_t *buflen); +static int vn_fullpath_any(struct thread *td, struct vnode *vp, struct vnode *rdir, char *buf, char **retbuf, size_t *buflen); +static int vn_fullpath_dir(struct thread *td, struct vnode *vp, struct vnode *rdir, + char *buf, char **retbuf, size_t *len, bool slash_prefixed, size_t addend); static MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries"); @@ -2201,7 +2206,7 @@ vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen) rdir = fdp->fd_rdir; vrefact(rdir); FILEDESC_SUNLOCK(fdp); - error = vn_fullpath1(td, cdir, rdir, buf, retbuf, buflen); + error = vn_fullpath_any(td, cdir, rdir, buf, retbuf, buflen); vrele(rdir); vrele(cdir); @@ -2212,6 +2217,37 @@ vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen) return (error); } +static int +kern___realpathat(struct thread *td, int fd, const char *path, char *buf, + size_t size, int flags, enum uio_seg pathseg) +{ + struct nameidata nd; + char *retbuf, *freebuf; + int error; + + if (flags != 0) + return (EINVAL); + NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | SAVENAME | WANTPARENT | AUDITVNODE1, + pathseg, path, fd, &cap_fstat_rights, td); + if ((error = namei(&nd)) != 0) + return (error); + error = vn_fullpath_hardlink(td, &nd, &retbuf, &freebuf, &size); + if (error == 0) { + error = copyout(retbuf, buf, size); + free(freebuf, M_TEMP); + } + NDFREE(&nd, 0); + return (error); +} + +int +sys___realpathat(struct thread *td, struct __realpathat_args *uap) +{ + + return (kern___realpathat(td, uap->fd, uap->path, uap->buf, uap->size, + uap->flags, UIO_USERSPACE)); +} + /* * Retrieve the full filesystem path that correspond to a vnode from the name * cache (if available) @@ -2235,7 +2271,7 @@ vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf) rdir = fdp->fd_rdir; vrefact(rdir); FILEDESC_SUNLOCK(fdp); - error = vn_fullpath1(td, vn, rdir, buf, retbuf, &buflen); + error = vn_fullpath_any(td, vn, rdir, buf, retbuf, &buflen); vrele(rdir); if (!error) @@ -2263,7 +2299,7 @@ vn_fullpath_global(struct thread *td, struct vnode *vn, return (EINVAL); buflen = MAXPATHLEN; buf = malloc(buflen, M_TEMP, M_WAITOK); - error = vn_fullpath1(td, vn, rootvnode, buf, retbuf, &buflen); + error = vn_fullpath_any(td, vn, rootvnode, buf, retbuf, &buflen); if (!error) *freebuf = buf; else @@ -2334,40 +2370,40 @@ vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, size_t *buflen) } /* - * The magic behind vn_getcwd() and vn_fullpath(). + * Resolve a directory to a pathname. + * + * The name of the directory can always be found in the namecache or fetched + * from the filesystem. There is also guaranteed to be only one parent, meaning + * we can just follow vnodes up until we find the root. + * + * The vnode must be referenced. */ static int -vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, - char *buf, char **retbuf, size_t *len) +vn_fullpath_dir(struct thread *td, struct vnode *vp, struct vnode *rdir, + char *buf, char **retbuf, size_t *len, bool slash_prefixed, size_t addend) { - int error, slash_prefixed; #ifdef KDTRACE_HOOKS struct vnode *startvp = vp; #endif struct vnode *vp1; size_t buflen; + int error; + + VNPASS(vp->v_type == VDIR || VN_IS_DOOMED(vp), vp); + VNPASS(vp->v_usecount > 0, vp); buflen = *len; - buflen--; - buf[buflen] = '\0'; + if (!slash_prefixed) { + MPASS(*len >= 2); + buflen--; + buf[buflen] = '\0'; + } + error = 0; - slash_prefixed = 0; SDT_PROBE1(vfs, namecache, fullpath, entry, vp); counter_u64_add(numfullpathcalls, 1); - vref(vp); - if (vp->v_type != VDIR) { - error = vn_vptocnp(&vp, td->td_ucred, buf, &buflen); - if (error) - return (error); - if (buflen == 0) { - vrele(vp); - return (ENOMEM); - } - buf[--buflen] = '/'; - slash_prefixed = 1; - } while (vp != rdir && vp != rootvnode) { /* * The vp vnode must be already fully constructed, @@ -2420,7 +2456,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, break; } buf[--buflen] = '/'; - slash_prefixed = 1; + slash_prefixed = true; } if (error) return (error); @@ -2437,12 +2473,128 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, counter_u64_add(numfullpathfound, 1); vrele(vp); - SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, buf + buflen); *retbuf = buf + buflen; + SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, *retbuf); *len -= buflen; + *len += addend; return (0); } +/* + * Resolve an arbitrary vnode to a pathname. + * + * Note 2 caveats: + * - hardlinks are not tracked, thus if the vnode is not a directory this can + * resolve to a different path than the one used to find it + * - namecache is not mandatory, meaning names are not guaranteed to be added + * (in which case resolving fails) + */ +static int +vn_fullpath_any(struct thread *td, struct vnode *vp, struct vnode *rdir, + char *buf, char **retbuf, size_t *buflen) +{ + size_t orig_buflen; + bool slash_prefixed; + int error; + + if (*buflen < 2) + return (EINVAL); + + orig_buflen = *buflen; + + vref(vp); + slash_prefixed = false; + if (vp->v_type != VDIR) { + *buflen -= 1; + buf[*buflen] = '\0'; + error = vn_vptocnp(&vp, td->td_ucred, buf, buflen); + if (error) + return (error); + if (*buflen == 0) { + vrele(vp); + return (ENOMEM); + } + *buflen -= 1; + buf[*buflen] = '/'; + slash_prefixed = true; + } + + return (vn_fullpath_dir(td, vp, rdir, buf, retbuf, buflen, slash_prefixed, + orig_buflen - *buflen)); +} + +/* + * Resolve an arbitrary vnode to a pathname (taking care of hardlinks). + * + * Since the namecache does not track handlings, the caller is expected to first + * look up the target vnode with SAVENAME | WANTPARENT flags passed to namei. + * + * Then we have 2 cases: + * - if the found vnode is a directory, the path can be constructed just by + * fullowing names up the chain + * - otherwise we populate the buffer with the saved name and start resolving + * from the parent + */ +static int +vn_fullpath_hardlink(struct thread *td, struct nameidata *ndp, char **retbuf, + char **freebuf, size_t *buflen) +{ + char *buf, *tmpbuf; + struct filedesc *fdp; + struct vnode *rdir; + struct componentname *cnp; + struct vnode *vp; + size_t addend; + int error; + bool slash_prefixed; + + if (*buflen < 2) + return (EINVAL); + if (*buflen > MAXPATHLEN) + *buflen = MAXPATHLEN; + + slash_prefixed = false; + + buf = malloc(*buflen, M_TEMP, M_WAITOK); + fdp = td->td_proc->p_fd; + FILEDESC_SLOCK(fdp); + rdir = fdp->fd_rdir; + vrefact(rdir); + FILEDESC_SUNLOCK(fdp); + + addend = 0; + vp = ndp->ni_vp; + if (vp->v_type != VDIR) { + cnp = &ndp->ni_cnd; + addend = cnp->cn_namelen + 2; + if (*buflen < addend) { + error = ENOMEM; + goto out_bad; + } + *buflen -= addend; + tmpbuf = buf + *buflen; + tmpbuf[0] = '/'; + memcpy(&tmpbuf[1], cnp->cn_nameptr, cnp->cn_namelen); + tmpbuf[addend - 1] = '\0'; + slash_prefixed = true; + vp = ndp->ni_dvp; + } + + vref(vp); + error = vn_fullpath_dir(td, vp, rdir, buf, retbuf, buflen, slash_prefixed, addend); + if (error != 0) + goto out_bad; + + vrele(rdir); + *freebuf = buf; + + return (0); +out_bad: + vrele(rdir); + free(buf, M_TEMP); + return (error); +} + struct vnode * vn_dir_dd_ino(struct vnode *vp) { diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index 9da2ccaa9847..5298a5c6165c 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -543,14 +543,13 @@ __FBSDID("$FreeBSD$"); #define SCTP_TIMER_TYPE_ASCONF 10 #define SCTP_TIMER_TYPE_SHUTDOWNGUARD 11 #define SCTP_TIMER_TYPE_AUTOCLOSE 12 -#define SCTP_TIMER_TYPE_EVENTWAKE 13 -#define SCTP_TIMER_TYPE_STRRESET 14 -#define SCTP_TIMER_TYPE_INPKILL 15 -#define SCTP_TIMER_TYPE_ASOCKILL 16 -#define SCTP_TIMER_TYPE_ADDR_WQ 17 -#define SCTP_TIMER_TYPE_PRIM_DELETED 18 +#define SCTP_TIMER_TYPE_STRRESET 13 +#define SCTP_TIMER_TYPE_INPKILL 14 +#define SCTP_TIMER_TYPE_ASOCKILL 15 +#define SCTP_TIMER_TYPE_ADDR_WQ 16 +#define SCTP_TIMER_TYPE_PRIM_DELETED 17 /* add new timers here - and increment LAST */ -#define SCTP_TIMER_TYPE_LAST 19 +#define SCTP_TIMER_TYPE_LAST 18 #define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \ ((t) < SCTP_TIMER_TYPE_LAST)) diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 36a0fe27455e..06c57bcec485 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -156,10 +156,10 @@ static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int); /* - * Make an extension header from option data. hp is the source, and - * mp is the destination. + * Make an extension header from option data. hp is the source, + * mp is the destination, and _ol is the optlen. */ -#define MAKE_EXTHDR(hp, mp) \ +#define MAKE_EXTHDR(hp, mp, _ol) \ do { \ if (hp) { \ struct ip6_ext *eh = (struct ip6_ext *)(hp); \ @@ -167,6 +167,7 @@ static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int); ((eh)->ip6e_len + 1) << 3); \ if (error) \ goto freehdrs; \ + (_ol) += (*(mp))->m_len; \ } \ } while (/*CONSTCOND*/ 0) @@ -384,22 +385,23 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, struct ip6_hdr *ip6; struct ifnet *ifp, *origifp; struct mbuf *m = m0; - struct mbuf *mprev = NULL; + struct mbuf *mprev; int hlen, tlen, len; struct route_in6 ip6route; struct rtentry *rt = NULL; struct sockaddr_in6 *dst, src_sa, dst_sa; struct in6_addr odst; + u_char *nexthdrp; int error = 0; struct in6_ifaddr *ia = NULL; u_long mtu; int alwaysfrag, dontfrag; - u_int32_t optlen = 0, plen = 0, unfragpartlen = 0; + u_int32_t optlen, plen = 0, unfragpartlen; struct ip6_exthdrs exthdrs; struct in6_addr src0, dst0; u_int32_t zone; struct route_in6 *ro_pmtu = NULL; - int hdrsplit = 0; + bool hdrsplit; int sw_csum, tso; int needfiblookup; uint32_t fibnum; @@ -436,12 +438,49 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, } #endif /* IPSEC */ + /* Source address validation. */ + ip6 = mtod(m, struct ip6_hdr *); + if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && + (flags & IPV6_UNSPECSRC) == 0) { + error = EOPNOTSUPP; + IP6STAT_INC(ip6s_badscope); + goto bad; + } + if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) { + error = EOPNOTSUPP; + IP6STAT_INC(ip6s_badscope); + goto bad; + } + + /* + * If we are given packet options to add extension headers prepare them. + * Calculate the total length of the extension header chain. + * Keep the length of the unfragmentable part for fragmentation. + */ bzero(&exthdrs, sizeof(exthdrs)); + optlen = 0; + unfragpartlen = 0; if (opt) { /* Hop-by-Hop options header. */ - MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh); + MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh, optlen); + /* Destination options header (1st part). */ if (opt->ip6po_rthdr) { +#ifndef RTHDR_SUPPORT_IMPLEMENTED + /* + * If there is a routing header, discard the packet + * right away here. RH0/1 are obsolete and we do not + * currently support RH2/3/4. + * People trying to use RH253/254 may want to disable + * this check. + * The moment we do support any routing header (again) + * this block should check the routing type more + * selectively. + */ + error = EINVAL; + goto bad; +#endif + /* * Destination options header (1st part). * This only makes sense with a routing header. @@ -452,46 +491,38 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, * options, which might automatically be inserted in * the kernel. */ - MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1); + MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1, + optlen); } /* Routing header. */ - MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr); + MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr, optlen); + + unfragpartlen = optlen + sizeof(struct ip6_hdr); + + /* + * NOTE: we don't add AH/ESP length here (done in + * ip6_ipsec_output()). + */ + /* Destination options header (2nd part). */ - MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2); + MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2, optlen); } - /* - * Calculate the total length of the extension header chain. - * Keep the length of the unfragmentable part for fragmentation. - */ - optlen = 0; - if (exthdrs.ip6e_hbh) - optlen += exthdrs.ip6e_hbh->m_len; - if (exthdrs.ip6e_dest1) - optlen += exthdrs.ip6e_dest1->m_len; - if (exthdrs.ip6e_rthdr) - optlen += exthdrs.ip6e_rthdr->m_len; - unfragpartlen = optlen + sizeof(struct ip6_hdr); - - /* NOTE: we don't add AH/ESP length here (done in ip6_ipsec_output). */ - if (exthdrs.ip6e_dest2) - optlen += exthdrs.ip6e_dest2->m_len; - /* * If there is at least one extension header, * separate IP6 header from the payload. */ - if (optlen && !hdrsplit) { + hdrsplit = false; + if (optlen) { if ((error = ip6_splithdr(m, &exthdrs)) != 0) { m = NULL; goto freehdrs; } m = exthdrs.ip6e_ip6; - hdrsplit++; + ip6 = mtod(m, struct ip6_hdr *); + hdrsplit = true; } - ip6 = mtod(m, struct ip6_hdr *); - /* Adjust mbuf packet header length. */ m->m_pkthdr.len += optlen; plen = m->m_pkthdr.len - sizeof(*ip6); @@ -504,77 +535,59 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, goto freehdrs; } m = exthdrs.ip6e_ip6; - hdrsplit++; + ip6 = mtod(m, struct ip6_hdr *); + hdrsplit = true; } - /* Adjust pointer. */ - ip6 = mtod(m, struct ip6_hdr *); if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0) goto freehdrs; ip6->ip6_plen = 0; } else ip6->ip6_plen = htons(plen); + nexthdrp = &ip6->ip6_nxt; - /* - * Concatenate headers and fill in next header fields. - * Here we have, on "m" - * IPv6 payload - * and we insert headers accordingly. - * Finally, we should be getting: - * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]. - * - * During the header composing process "m" points to IPv6 - * header. "mprev" points to an extension header prior to esp. - */ - u_char *nexthdrp = &ip6->ip6_nxt; - mprev = m; + if (optlen) { + /* + * Concatenate headers and fill in next header fields. + * Here we have, on "m" + * IPv6 payload + * and we insert headers accordingly. + * Finally, we should be getting: + * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]. + * + * During the header composing process "m" points to IPv6 + * header. "mprev" points to an extension header prior to esp. + */ + mprev = m; - /* - * We treat dest2 specially. This makes IPsec processing - * much easier. The goal here is to make mprev point the - * mbuf prior to dest2. - * - * Result: IPv6 dest2 payload. - * m and mprev will point to IPv6 header. - */ - if (exthdrs.ip6e_dest2) { - if (!hdrsplit) - panic("%s:%d: assumption failed: " - "hdr not split: hdrsplit %d exthdrs %p", - __func__, __LINE__, hdrsplit, &exthdrs); - exthdrs.ip6e_dest2->m_next = m->m_next; - m->m_next = exthdrs.ip6e_dest2; - *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt; - ip6->ip6_nxt = IPPROTO_DSTOPTS; - } + /* + * We treat dest2 specially. This makes IPsec processing + * much easier. The goal here is to make mprev point the + * mbuf prior to dest2. + * + * Result: IPv6 dest2 payload. + * m and mprev will point to IPv6 header. + */ + if (exthdrs.ip6e_dest2) { + if (!hdrsplit) + panic("%s:%d: assumption failed: " + "hdr not split: hdrsplit %d exthdrs %p", + __func__, __LINE__, hdrsplit, &exthdrs); + exthdrs.ip6e_dest2->m_next = m->m_next; + m->m_next = exthdrs.ip6e_dest2; + *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt; + ip6->ip6_nxt = IPPROTO_DSTOPTS; + } - /* - * Result: IPv6 hbh dest1 rthdr dest2 payload. - * m will point to IPv6 header. mprev will point to the - * extension header prior to dest2 (rthdr in the above case). - */ - MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS); - MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp, - IPPROTO_DSTOPTS); - MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp, - IPPROTO_ROUTING); - - /* If there is a routing header, discard the packet. */ - if (exthdrs.ip6e_rthdr) { - error = EINVAL; - goto bad; - } - - /* Source address validation. */ - if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && - (flags & IPV6_UNSPECSRC) == 0) { - error = EOPNOTSUPP; - IP6STAT_INC(ip6s_badscope); - goto bad; - } - if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) { - error = EOPNOTSUPP; - IP6STAT_INC(ip6s_badscope); - goto bad; + /* + * Result: IPv6 hbh dest1 rthdr dest2 payload. + * m will point to IPv6 header. mprev will point to the + * extension header prior to dest2 (rthdr in the above case). + */ + MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS); + MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp, + IPPROTO_DSTOPTS); + MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp, + IPPROTO_ROUTING); } IP6STAT_INC(ip6s_localout); diff --git a/sys/security/audit/audit_bsm.c b/sys/security/audit/audit_bsm.c index feaae8edce9b..3ff90b68a708 100644 --- a/sys/security/audit/audit_bsm.c +++ b/sys/security/audit/audit_bsm.c @@ -830,6 +830,7 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) case AUE_UNLINK: case AUE_UNLINKAT: case AUE_UTIMES: + case AUE_REALPATHAT: ATFD1_TOKENS(1); UPATH1_VNODE1_TOKENS; break; diff --git a/sys/sys/param.h b/sys/sys/param.h index 398038a0c31a..e10be84bd0f8 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300078 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300080 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 66a87c0e4b23..f963725993a7 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -273,6 +273,7 @@ int __sys_sigfastblock(int cmd, void *ptr); #ifdef _KERNEL extern sigset_t fastblock_mask; +extern bool sigfastblock_fetch_always; /* Return nonzero if process p has an unmasked pending signal. */ #define SIGPENDING(td) \ @@ -382,8 +383,6 @@ sigallowstop(int prev) int cursig(struct thread *td); void execsigs(struct proc *p); -void fetch_sigfastblock(struct thread *td); -void fetch_sigfastblock_failed(struct thread *td, bool write); void gsignal(int pgid, int sig, ksiginfo_t *ksi); void killproc(struct proc *p, char *why); ksiginfo_t * ksiginfo_alloc(int wait); @@ -405,6 +404,9 @@ void sig_drop_caught(struct proc *p); void sigexit(struct thread *td, int sig) __dead2; int sigev_findtd(struct proc *p, struct sigevent *sigev, struct thread **); int sig_ffs(sigset_t *set); +void sigfastblock_clear(struct thread *td); +void sigfastblock_fetch(struct thread *td); +void sigfastblock_setpend(struct thread *td); void siginit(struct proc *p); void signotify(struct thread *td); void sigqueue_delete(struct sigqueue *queue, int sig); diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 5b183036661f..65b1736c4e0e 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -509,4 +509,5 @@ #define SYS_shm_open2 571 #define SYS_shm_rename 572 #define SYS_sigfastblock 573 -#define SYS_MAXSYSCALL 574 +#define SYS___realpathat 574 +#define SYS_MAXSYSCALL 575 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index c095831023a4..471d1d0ad258 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -414,4 +414,5 @@ MIASM = \ __sysctlbyname.o \ shm_open2.o \ shm_rename.o \ - sigfastblock.o + sigfastblock.o \ + __realpathat.o diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 6817ecf6f4ee..5f19a5228e13 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -1823,6 +1823,13 @@ struct sigfastblock_args { char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; char ptr_l_[PADL_(uint32_t *)]; uint32_t * ptr; char ptr_r_[PADR_(uint32_t *)]; }; +struct __realpathat_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char size_l_[PADL_(size_t)]; size_t size; char size_r_[PADR_(size_t)]; + char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_sys_exit(struct thread *, struct sys_exit_args *); int sys_fork(struct thread *, struct fork_args *); @@ -2212,6 +2219,7 @@ int sys___sysctlbyname(struct thread *, struct __sysctlbyname_args *); int sys_shm_open2(struct thread *, struct shm_open2_args *); int sys_shm_rename(struct thread *, struct shm_rename_args *); int sys_sigfastblock(struct thread *, struct sigfastblock_args *); +int sys___realpathat(struct thread *, struct __realpathat_args *); #ifdef COMPAT_43 @@ -3136,6 +3144,7 @@ int freebsd12_shm_open(struct thread *, struct freebsd12_shm_open_args *); #define SYS_AUE_shm_open2 AUE_SHMOPEN #define SYS_AUE_shm_rename AUE_SHMRENAME #define SYS_AUE_sigfastblock AUE_NULL +#define SYS_AUE___realpathat AUE_REALPATHAT #undef PAD_ #undef PADL_ diff --git a/sys/vm/vm_radix.c b/sys/vm/vm_radix.c index b810a375c773..7fe7e5bd863e 100644 --- a/sys/vm/vm_radix.c +++ b/sys/vm/vm_radix.c @@ -208,6 +208,8 @@ vm_radix_node_load(smrnode_t *p, enum vm_radix_access access) case SMR: return (smr_entered_load(p, vm_radix_smr)); } + /* This is unreachable, silence gcc. */ + panic("vm_radix_node_get: Unknown access type"); } static __inline void diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 3216ef56579d..7c8bcc9d239c 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -628,8 +628,11 @@ vnode_pager_input_smlfs(vm_object_t object, vm_page_t m) bwait(bp, PVM, "vnsrd"); - if ((bp->b_ioflags & BIO_ERROR) != 0) - error = EIO; + if ((bp->b_ioflags & BIO_ERROR) != 0) { + KASSERT(bp->b_error != 0, + ("%s: buf error but b_error == 0\n", __func__)); + error = bp->b_error; + } /* * free the buffer header back to the swap buffer pool @@ -1113,7 +1116,9 @@ vnode_pager_generic_getpages_done(struct buf *bp) off_t tfoff, nextoff; int i, error; - error = (bp->b_ioflags & BIO_ERROR) != 0 ? EIO : 0; + KASSERT((bp->b_ioflags & BIO_ERROR) == 0 || bp->b_error != 0, + ("%s: buf error but b_error == 0\n", __func__)); + error = (bp->b_ioflags & BIO_ERROR) != 0 ? bp->b_error : 0; object = bp->b_vp->v_object; if (error == 0 && bp->b_bcount != bp->b_npages * PAGE_SIZE) { @@ -1169,8 +1174,6 @@ vnode_pager_generic_getpages_done(struct buf *bp) vm_page_readahead_finish(mt); } VM_OBJECT_RUNLOCK(object); - if (error != 0) - printf("%s: I/O read error %d\n", __func__, error); return (error); } diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 214138c4dd6a..e9c02379e12c 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -115,6 +115,9 @@ static struct syscall decoded_syscalls[] = { .args = { { Int, 0 }, { Int, 1 }, { CapRights | OUT, 2 } } }, { .name = "__getcwd", .ret_type = 1, .nargs = 2, .args = { { Name | OUT, 0 }, { Int, 1 } } }, + { .name = "__realpathat", .ret_type = 1, .nargs = 5, + .args = { { Atfd, 0 }, { Name | IN, 1 }, { Name | OUT, 2 }, + { Sizet, 3 }, { Int, 4} } }, { .name = "_umtx_op", .ret_type = 1, .nargs = 5, .args = { { Ptr, 0 }, { Umtxop, 1 }, { LongHex, 2 }, { Ptr, 3 }, { Ptr, 4 } } }, diff --git a/usr.sbin/pciconf/cap.c b/usr.sbin/pciconf/cap.c index cb8e28a7427b..3fce34519bec 100644 --- a/usr.sbin/pciconf/cap.c +++ b/usr.sbin/pciconf/cap.c @@ -1015,6 +1015,20 @@ static struct { { PCIZ_LN_REQ, "LN Requester" }, { PCIZ_DPC, "Downstream Port Containment" }, { PCIZ_L1PM, "L1 PM Substates" }, + { PCIZ_PTM, "Precision Time Measurement" }, + { PCIZ_M_PCIE, "PCIe over M-PHY" }, + { PCIZ_FRS, "FRS Queuing" }, + { PCIZ_RTR, "Readiness Time Reporting" }, + { PCIZ_DVSEC, "Designated Vendor-Specific" }, + { PCIZ_VF_REBAR, "VF Resizable BAR" }, + { PCIZ_DLNK, "Data Link Feature" }, + { PCIZ_16GT, "Physical Layer 16.0 GT/s" }, + { PCIZ_LMR, "Lane Margining at Receiver" }, + { PCIZ_HIER_ID, "Hierarchy ID" }, + { PCIZ_NPEM, "Native PCIe Enclosure Management" }, + { PCIZ_PL32, "Physical Layer 32.0 GT/s" }, + { PCIZ_AP, "Alternate Protocol" }, + { PCIZ_SFI, "System Firmware Intermediary" }, { 0, NULL } }; diff --git a/usr.sbin/pciconf/pciconf.c b/usr.sbin/pciconf/pciconf.c index 0d2aad12e305..817de6ec09ed 100644 --- a/usr.sbin/pciconf/pciconf.c +++ b/usr.sbin/pciconf/pciconf.c @@ -665,12 +665,17 @@ static struct {PCIC_STORAGE, PCIS_STORAGE_SATA, "SATA"}, {PCIC_STORAGE, PCIS_STORAGE_SAS, "SAS"}, {PCIC_STORAGE, PCIS_STORAGE_NVM, "NVM"}, + {PCIC_STORAGE, PCIS_STORAGE_UFS, "UFS"}, {PCIC_NETWORK, -1, "network"}, {PCIC_NETWORK, PCIS_NETWORK_ETHERNET, "ethernet"}, {PCIC_NETWORK, PCIS_NETWORK_TOKENRING, "token ring"}, {PCIC_NETWORK, PCIS_NETWORK_FDDI, "fddi"}, {PCIC_NETWORK, PCIS_NETWORK_ATM, "ATM"}, {PCIC_NETWORK, PCIS_NETWORK_ISDN, "ISDN"}, + {PCIC_NETWORK, PCIS_NETWORK_WORLDFIP, "WorldFip"}, + {PCIC_NETWORK, PCIS_NETWORK_PICMG, "PICMG"}, + {PCIC_NETWORK, PCIS_NETWORK_INFINIBAND, "InfiniBand"}, + {PCIC_NETWORK, PCIS_NETWORK_HFC, "host fabric"}, {PCIC_DISPLAY, -1, "display"}, {PCIC_DISPLAY, PCIS_DISPLAY_VGA, "VGA"}, {PCIC_DISPLAY, PCIS_DISPLAY_XGA, "XGA"}, @@ -693,6 +698,11 @@ static struct {PCIC_BRIDGE, PCIS_BRIDGE_NUBUS, "PCI-NuBus"}, {PCIC_BRIDGE, PCIS_BRIDGE_CARDBUS, "PCI-CardBus"}, {PCIC_BRIDGE, PCIS_BRIDGE_RACEWAY, "PCI-RACEway"}, + {PCIC_BRIDGE, PCIS_BRIDGE_PCI_TRANSPARENT, + "Semi-transparent PCI-to-PCI"}, + {PCIC_BRIDGE, PCIS_BRIDGE_INFINIBAND, "InfiniBand-PCI"}, + {PCIC_BRIDGE, PCIS_BRIDGE_AS_PCI, + "AdvancedSwitching-PCI"}, {PCIC_SIMPLECOMM, -1, "simple comms"}, {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_UART, "UART"}, /* could detect 16550 */ {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_PAR, "parallel port"}, @@ -706,6 +716,8 @@ static struct {PCIC_BASEPERIPH, PCIS_BASEPERIPH_PCIHOT, "PCI hot-plug controller"}, {PCIC_BASEPERIPH, PCIS_BASEPERIPH_SDHC, "SD host controller"}, {PCIC_BASEPERIPH, PCIS_BASEPERIPH_IOMMU, "IOMMU"}, + {PCIC_BASEPERIPH, PCIS_BASEPERIPH_RCEC, + "Root Complex Event Collector"}, {PCIC_INPUTDEV, -1, "input device"}, {PCIC_INPUTDEV, PCIS_INPUTDEV_KEYBOARD, "keyboard"}, {PCIC_INPUTDEV, PCIS_INPUTDEV_DIGITIZER,"digitizer"}, @@ -721,10 +733,23 @@ static struct {PCIC_SERIALBUS, PCIS_SERIALBUS_USB, "USB"}, {PCIC_SERIALBUS, PCIS_SERIALBUS_FC, "Fibre Channel"}, {PCIC_SERIALBUS, PCIS_SERIALBUS_SMBUS, "SMBus"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_INFINIBAND, "InfiniBand"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_IPMI, "IPMI"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_SERCOS, "SERCOS"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_CANBUS, "CANbus"}, + {PCIC_SERIALBUS, PCIS_SERIALBUS_MIPI_I3C, "MIPI I3C"}, {PCIC_WIRELESS, -1, "wireless controller"}, {PCIC_WIRELESS, PCIS_WIRELESS_IRDA, "iRDA"}, {PCIC_WIRELESS, PCIS_WIRELESS_IR, "IR"}, {PCIC_WIRELESS, PCIS_WIRELESS_RF, "RF"}, + {PCIC_WIRELESS, PCIS_WIRELESS_BLUETOOTH, "bluetooth"}, + {PCIC_WIRELESS, PCIS_WIRELESS_BROADBAND, "broadband"}, + {PCIC_WIRELESS, PCIS_WIRELESS_80211A, "ethernet 802.11a"}, + {PCIC_WIRELESS, PCIS_WIRELESS_80211B, "ethernet 802.11b"}, + {PCIC_WIRELESS, PCIS_WIRELESS_CELL, + "cellular controller/modem"}, + {PCIC_WIRELESS, PCIS_WIRELESS_CELL_E, + "cellular controller/modem plus ethernet"}, {PCIC_INTELLIIO, -1, "intelligent I/O controller"}, {PCIC_INTELLIIO, PCIS_INTELLIIO_I2O, "I2O"}, {PCIC_SATCOM, -1, "satellite communication"}, diff --git a/usr.sbin/services_mkdb/services_mkdb.c b/usr.sbin/services_mkdb/services_mkdb.c index d6eb0a08b492..368b8390cc48 100644 --- a/usr.sbin/services_mkdb/services_mkdb.c +++ b/usr.sbin/services_mkdb/services_mkdb.c @@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$"); static char tname[MAXPATHLEN]; #define PMASK 0xffff -#define PROTOMAX 5 +#define PROTOMAX 6 static void add(DB *, StringList *, size_t, const char *, size_t *, int); static StringList ***parseservices(const char *, StringList *);