diff options
220 files changed, 2710 insertions, 2014 deletions
diff --git a/.github/workflows/cross-bootstrap-tools.yml b/.github/workflows/cross-bootstrap-tools.yml index 0aa1d9a35c1e..8a714788cce7 100644 --- a/.github/workflows/cross-bootstrap-tools.yml +++ b/.github/workflows/cross-bootstrap-tools.yml @@ -30,7 +30,7 @@ jobs: pkgs: bmake libarchive-dev clang-14 lld-14 - os: macos-latest compiler: clang-13 - cross-bindir: /usr/local/opt/llvm@13/bin + cross-bindir: /opt/homebrew/opt/llvm@13/bin pkgs: bmake libarchive llvm@13 - target_arch: amd64 target: amd64 diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index b5253c28d42c..b99bd4f890e5 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -51,6 +51,9 @@ # xargs -n1 | sort | uniq -d; # done +# 20240509: Remove remnants of portsnap(8) +OLD_DIRS+=var/db/portsnap + # 20240419: new clang import which bumps version from 17 to 18 OLD_FILES+=usr/lib/clang/17/include/__clang_cuda_builtin_vars.h OLD_FILES+=usr/lib/clang/17/include/__clang_cuda_cmath.h diff --git a/bin/cat/cat.c b/bin/cat/cat.c index 81ec5feec240..9d40a3f0fa35 100644 --- a/bin/cat/cat.c +++ b/bin/cat/cat.c @@ -139,7 +139,7 @@ init_casper_net(cap_channel_t *casper) familylimit = AF_LOCAL; cap_net_limit_name2addr_family(limit, &familylimit, 1); - if (cap_net_limit(limit) < 0) + if (cap_net_limit(limit) != 0) err(EXIT_FAILURE, "unable to apply limits"); } #endif @@ -212,7 +212,7 @@ main(int argc, char *argv[]) stdout_lock.l_start = 0; stdout_lock.l_type = F_WRLCK; stdout_lock.l_whence = SEEK_SET; - if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1) + if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) != 0) err(EXIT_FAILURE, "stdout"); } @@ -220,7 +220,7 @@ main(int argc, char *argv[]) caph_cache_catpages(); - if (caph_enter_casper() < 0) + if (caph_enter_casper() != 0) err(EXIT_FAILURE, "capsicum"); if (bflag || eflag || nflag || sflag || tflag || vflag) @@ -280,7 +280,7 @@ scanfiles(char *argv[], int cooked __unused) #endif } else { #ifndef BOOTSTRAP_CAT - if (in_kernel_copy(fd) == -1) { + if (in_kernel_copy(fd) != 0) { if (errno == EINVAL || errno == EBADF || errno == EISDIR) raw_cat(fd); @@ -485,7 +485,7 @@ udom_open(const char *path, int flags) errno = serrno; return (-1); } - if (caph_rights_limit(fd, &rights) < 0) { + if (caph_rights_limit(fd, &rights) != 0) { serrno = errno; close(fd); freeaddrinfo(res0); @@ -514,12 +514,12 @@ udom_open(const char *path, int flags) switch (flags & O_ACCMODE) { case O_RDONLY: cap_rights_clear(&rights, CAP_WRITE); - if (shutdown(fd, SHUT_WR) == -1) + if (shutdown(fd, SHUT_WR) != 0) warn(NULL); break; case O_WRONLY: cap_rights_clear(&rights, CAP_READ); - if (shutdown(fd, SHUT_RD) == -1) + if (shutdown(fd, SHUT_RD) != 0) warn(NULL); break; default: @@ -527,7 +527,7 @@ udom_open(const char *path, int flags) } cap_rights_clear(&rights, CAP_CONNECT, CAP_SHUTDOWN); - if (caph_rights_limit(fd, &rights) < 0) { + if (caph_rights_limit(fd, &rights) != 0) { serrno = errno; close(fd); errno = serrno; diff --git a/cddl/usr.sbin/zfsd/case_file.cc b/cddl/usr.sbin/zfsd/case_file.cc index 39f89fbbf7c8..f9fd84da7277 100644 --- a/cddl/usr.sbin/zfsd/case_file.cc +++ b/cddl/usr.sbin/zfsd/case_file.cc @@ -53,6 +53,7 @@ #include <syslog.h> #include <unistd.h> +#include <libzutil.h> #include <libzfs.h> #include <list> @@ -91,7 +92,6 @@ using DevdCtl::ParseException; CaseFileList CaseFile::s_activeCases; const string CaseFile::s_caseFilePath = "/var/db/zfsd/cases"; -const timeval CaseFile::s_removeGracePeriod = { 60 /*sec*/, 0 /*usec*/}; //- CaseFile Static Public Methods --------------------------------------------- CaseFile * @@ -255,6 +255,7 @@ CaseFile::RefreshVdevState() m_vdevState = vd.State(); m_vdevPhysPath = vd.PhysicalPath(); + m_vdevName = vd.Name(casePool, false); return (true); } @@ -610,15 +611,55 @@ CaseFile::ActivateSpare() { return (Replace(vdev_type, devPath, /*isspare*/true)); } +/* Does the argument event refer to a checksum error? */ +static bool +IsChecksumEvent(const Event* const event) +{ + return ("ereport.fs.zfs.checksum" == event->Value("type")); +} + +/* Does the argument event refer to an IO error? */ +static bool +IsIOEvent(const Event* const event) +{ + return ("ereport.fs.zfs.io" == event->Value("type")); +} + +/* Does the argument event refer to an IO delay? */ +static bool +IsDelayEvent(const Event* const event) +{ + return ("ereport.fs.zfs.delay" == event->Value("type")); +} + void CaseFile::RegisterCallout(const Event &event) { timeval now, countdown, elapsed, timestamp, zero, remaining; + /** + * The time ZFSD waits before promoting a tentative event + * into a permanent event. + */ + int sec = -1; + if (IsChecksumEvent(&event)) + sec = CaseFile::GetVdevProp(VDEV_PROP_CHECKSUM_T); + else if (IsIOEvent(&event)) + sec = CaseFile::GetVdevProp(VDEV_PROP_IO_T); + else if (IsDelayEvent(&event)) + sec = CaseFile::GetVdevProp(VDEV_PROP_SLOW_IO_T); + + if (sec == -1) + sec = 60; /* default */ + + timeval removeGracePeriod = { + sec, /*sec*/ + 0 /*usec*/ + }; gettimeofday(&now, 0); timestamp = event.GetTimestamp(); timersub(&now, ×tamp, &elapsed); - timersub(&s_removeGracePeriod, &elapsed, &countdown); + timersub(&removeGracePeriod, &elapsed, &countdown); /* * If countdown is <= zero, Reset the timer to the * smallest positive time value instead @@ -827,6 +868,10 @@ CaseFile::CaseFile(const Vdev &vdev) guidString << m_poolGUID; m_poolGUIDString = guidString.str(); + ZpoolList zpl(ZpoolList::ZpoolByGUID, &m_poolGUID); + zpool_handle_t *zhp(zpl.empty() ? NULL : zpl.front()); + m_vdevName = vdev.Name(zhp, false); + s_activeCases.push_back(this); syslog(LOG_INFO, "Creating new CaseFile:\n"); @@ -1158,43 +1203,54 @@ CaseFile::Replace(const char* vdev_type, const char* path, bool isspare) { return (retval); } -/* Does the argument event refer to a checksum error? */ -static bool -IsChecksumEvent(const Event* const event) +/* Lookup the vdev prop. Used for checksum, IO, or slow IO props */ +int +CaseFile::GetVdevProp(vdev_prop_t vdev_prop) const { - return ("ereport.fs.zfs.checksum" == event->Value("type")); -} + char val[ZFS_MAXPROPLEN]; + zprop_source_t srctype; + DevdCtl::Guid poolGUID = PoolGUID(); + ZpoolList zpl(ZpoolList::ZpoolByGUID, &poolGUID); + zpool_handle_t *zhp(zpl.empty() ? NULL : zpl.front()); -/* Does the argument event refer to an IO error? */ -static bool -IsIOEvent(const Event* const event) -{ - return ("ereport.fs.zfs.io" == event->Value("type")); -} + char *prop_str = (char *) vdev_prop_to_name(vdev_prop); + if (zhp == NULL || zpool_get_vdev_prop(zhp, m_vdevName.c_str(), + vdev_prop, prop_str, val, sizeof (val), &srctype, B_FALSE) != 0) + return (-1); -/* Does the argument event refer to an IO delay? */ -static bool -IsDelayEvent(const Event* const event) -{ - return ("ereport.fs.zfs.delay" == event->Value("type")); + /* we'll get "-" from libzfs for a prop that is not set */ + if (zfs_isnumber(val) == B_FALSE) + return (-1); + + return (atoi(val)); } bool CaseFile::ShouldDegrade() const { + int checksum_n = GetVdevProp(VDEV_PROP_CHECKSUM_N); + if (checksum_n == -1) + checksum_n = DEFAULT_ZFS_DEGRADE_IO_COUNT; return (std::count_if(m_events.begin(), m_events.end(), - IsChecksumEvent) > ZFS_DEGRADE_IO_COUNT); + IsChecksumEvent) > checksum_n); } bool CaseFile::ShouldFault() const { bool should_fault_for_io, should_fault_for_delay; + int io_n = GetVdevProp(VDEV_PROP_IO_N); + int slow_io_n = GetVdevProp(VDEV_PROP_SLOW_IO_N); + + if (io_n == -1) + io_n = DEFAULT_ZFS_DEGRADE_IO_COUNT; + if (slow_io_n == -1) + slow_io_n = DEFAULT_ZFS_FAULT_SLOW_IO_COUNT; should_fault_for_io = std::count_if(m_events.begin(), m_events.end(), - IsIOEvent) > ZFS_DEGRADE_IO_COUNT; + IsIOEvent) > io_n; should_fault_for_delay = std::count_if(m_events.begin(), m_events.end(), - IsDelayEvent) > ZFS_FAULT_DELAY_COUNT; + IsDelayEvent) > slow_io_n; return (should_fault_for_io || should_fault_for_delay); } diff --git a/cddl/usr.sbin/zfsd/case_file.h b/cddl/usr.sbin/zfsd/case_file.h index 9566b1586ef5..199918c4fead 100644 --- a/cddl/usr.sbin/zfsd/case_file.h +++ b/cddl/usr.sbin/zfsd/case_file.h @@ -235,18 +235,27 @@ public: */ int IsSpare(); + /** + * \brief Get case vdev's specified property + */ + int GetVdevProp(vdev_prop_t) const; + protected: enum { + /* + * Use these defaults if we can't get the corresponding vdev + * prop or if the prop is not set + */ /** * The number of soft errors on a vdev required * to transition a vdev from healthy to degraded - * status. + * status */ - ZFS_DEGRADE_IO_COUNT = 50, + DEFAULT_ZFS_DEGRADE_IO_COUNT = 50, /** * The number of delay errors on a vdev required to fault it */ - ZFS_FAULT_DELAY_COUNT = 8, + DEFAULT_ZFS_FAULT_SLOW_IO_COUNT = 8, }; static CalloutFunc_t OnGracePeriodEnded; @@ -380,12 +389,6 @@ protected: static const string s_caseFilePath; /** - * \brief The time ZFSD waits before promoting a tentative event - * into a permanent event. - */ - static const timeval s_removeGracePeriod; - - /** * \brief A list of soft error events counted against the health of * a vdev. */ @@ -404,6 +407,7 @@ protected: string m_poolGUIDString; string m_vdevGUIDString; string m_vdevPhysPath; + string m_vdevName; int m_is_spare; /** diff --git a/cddl/usr.sbin/zfsd/tests/zfsd_unittest.cc b/cddl/usr.sbin/zfsd/tests/zfsd_unittest.cc index d76abb54c9ed..f1e925b0b4ef 100644 --- a/cddl/usr.sbin/zfsd/tests/zfsd_unittest.cc +++ b/cddl/usr.sbin/zfsd/tests/zfsd_unittest.cc @@ -134,6 +134,7 @@ public: MOCK_CONST_METHOD0(PoolGUID, Guid()); MOCK_CONST_METHOD0(State, vdev_state()); MOCK_CONST_METHOD0(PhysicalPath, string()); + MOCK_CONST_METHOD2(Name, string(zpool_handle_t * zhp, bool verbose)); }; MockVdev::MockVdev(nvlist_t *vdevConfig) @@ -431,6 +432,8 @@ protected: m_vdev = new MockVdev(m_vdevConfig); ON_CALL(*m_vdev, GUID()) .WillByDefault(::testing::Return(Guid(123))); + ON_CALL(*m_vdev, Name(::testing::_, ::testing::_)) + .WillByDefault(::testing::Return(string("/dev/da999"))); ON_CALL(*m_vdev, PoolGUID()) .WillByDefault(::testing::Return(Guid(456))); ON_CALL(*m_vdev, State()) diff --git a/cddl/usr.sbin/zfsd/vdev.h b/cddl/usr.sbin/zfsd/vdev.h index ace5d5a009fa..42278a3d7229 100644 --- a/cddl/usr.sbin/zfsd/vdev.h +++ b/cddl/usr.sbin/zfsd/vdev.h @@ -130,7 +130,7 @@ public: nvlist_t *Config() const; Vdev Parent(); Vdev RootVdev(); - std::string Name(zpool_handle_t *, bool verbose) const; + virtual std::string Name(zpool_handle_t *, bool verbose) const; bool IsSpare(); bool IsAvailableSpare() const; bool IsActiveSpare() const; diff --git a/cddl/usr.sbin/zfsd/zfsd.8 b/cddl/usr.sbin/zfsd/zfsd.8 index 75a3333e6f9e..d6b0e1d4bd22 100644 --- a/cddl/usr.sbin/zfsd/zfsd.8 +++ b/cddl/usr.sbin/zfsd/zfsd.8 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 18, 2020 +.Dd February 20, 2024 .Dt ZFSD 8 .Os .Sh NAME @@ -55,7 +55,7 @@ directly. Instead, they control its behavior indirectly through zpool configuration. There are two ways to influence .Nm : -assigning hotspares and setting pool properties. +assigning hot spares and setting pool properties. Currently, only the .Em autoreplace property has any effect. @@ -69,7 +69,7 @@ will attempt to resolve the following types of fault: .It device removal When a leaf vdev disappears, .Nm -will activate any available hotspare. +will activate any available hot spare. .It device arrival When a new GEOM device appears, .Nm @@ -77,40 +77,71 @@ will attempt to read its ZFS label, if any. If it matches a previously removed vdev on an active pool, .Nm will online it. -Once resilvering completes, any active hotspare will detach automatically. +Once resilvering completes, any active hot spare will detach automatically. .Pp If the new device has no ZFS label but its physical path matches the physical path of a previously removed vdev on an active pool, and that pool has the autoreplace property set, then .Nm will replace the missing vdev with the newly arrived device. -Once resilvering completes, any active hotspare will detach automatically. +Once resilvering completes, any active hot spare will detach automatically. .It vdev degrade or fault events If a vdev becomes degraded or faulted, .Nm -will activate any available hotspare. +will activate any available hot spare. .It I/O errors -If a leaf vdev generates more than 50 I/O errors in a 60 second period, then +By default, if a leaf vdev generates more than 50 I/O errors in a 60 second +period, then +.Nm +will mark that vdev as +.Em FAULTED . +ZFS will no longer issue any I/Os to it. +.Nm +will activate a hot spare if one is available. The defaults can be changed by +setting the +.Em io_n +and/or +.Em io_t +vdev properties. See +.Xr vdevprops 7 +for details. +.It I/O delays +By default, if a leaf vdev generates more than delayed 8 I/O events in a 60 +second period, then .Nm will mark that vdev as .Em FAULTED . ZFS will no longer issue any I/Os to it. .Nm -will activate a hotspare if one is available. +will activate a hot spare if one is available. The defaults can be changed by +setting the +.Em slow_io_n +and/or +.Em slow_io_t +vdev properties. See +.Xr vdevprops 7 +for details. .It Checksum errors -If a leaf vdev generates more than 50 checksum errors in a 60 second -period, then +By default, if a leaf vdev generates more than 50 checksum errors in a 60 +second period, then .Nm will mark that vdev as .Em DEGRADED . -ZFS will still use it, but zfsd will activate a spare anyway. +ZFS will still use it, but zfsd will also activate a hot spare if one is +available. The defaults can be changed by setting the +.Em checksum_n +and/or +.Em checksum_t +vdev properties. See +.Xr vdevprops 7 +for details. .It Spare addition -If the system administrator adds a hotspare to a pool that is already degraded, +If the system administrator adds a hot spare to a pool that is already degraded, .Nm will activate the spare. .It Resilver complete .Nm -will detach any hotspare once a permanent replacement finishes resilvering. +will detach any hot spare once a permanent replacement finishes resilvering. .It Physical path change If the physical path of an existing disk changes, .Nm @@ -134,6 +165,7 @@ then reads them back in when next it starts up. .El .Sh SEE ALSO .Xr devctl 4 , +.Xr vdevprops 7 , .Xr zpool 8 .Sh HISTORY .Nm diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp index a4f26a6f0eb1..44ddd2428b10 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp @@ -823,29 +823,32 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( ASTContext &Ctx, const RecordDecl *RD, StringRef Name, uint64_t &Offset) { const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel(); - unsigned FieldNo = 0; - bool IsUnion = RD->isUnion(); + uint32_t FieldNo = 0; - for (const Decl *D : RD->decls()) { - if (const auto *Field = dyn_cast<FieldDecl>(D); - Field && (Name.empty() || Field->getNameAsString() == Name) && + if (RD->isImplicit()) + return nullptr; + + for (const FieldDecl *FD : RD->fields()) { + if ((Name.empty() || FD->getNameAsString() == Name) && Decl::isFlexibleArrayMemberLike( - Ctx, Field, Field->getType(), StrictFlexArraysLevel, + Ctx, FD, FD->getType(), StrictFlexArraysLevel, /*IgnoreTemplateOrMacroSubstitution=*/true)) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); Offset += Layout.getFieldOffset(FieldNo); - return Field; + return FD; } - if (const auto *Record = dyn_cast<RecordDecl>(D)) - if (const FieldDecl *Field = - FindFlexibleArrayMemberField(Ctx, Record, Name, Offset)) { + QualType Ty = FD->getType(); + if (Ty->isRecordType()) { + if (const FieldDecl *Field = FindFlexibleArrayMemberField( + Ctx, Ty->getAsRecordDecl(), Name, Offset)) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); Offset += Layout.getFieldOffset(FieldNo); return Field; } + } - if (!IsUnion && isa<FieldDecl>(D)) + if (!RD->isUnion()) ++FieldNo; } diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp index 28c211aa631e..a6a2f3595fe7 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp @@ -1581,6 +1581,11 @@ bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) { return RI.isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet()); } +bool CodeGenModule::ReturnTypeHasInReg(const CGFunctionInfo &FI) { + const auto &RI = FI.getReturnInfo(); + return RI.getInReg(); +} + bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) { return ReturnTypeUsesSRet(FI) && getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs(); diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp index a36b0cdddaf0..05e3f8d4bfc2 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGObjCGNU.cpp @@ -2903,23 +2903,29 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, break; case CodeGenOptions::Mixed: case CodeGenOptions::NonLegacy: + StringRef name = "objc_msgSend"; if (CGM.ReturnTypeUsesFPRet(ResultType)) { - imp = - CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), - "objc_msgSend_fpret") - .getCallee(); + name = "objc_msgSend_fpret"; } else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) { - // The actual types here don't matter - we're going to bitcast the - // function anyway - imp = - CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), - "objc_msgSend_stret") - .getCallee(); - } else { - imp = CGM.CreateRuntimeFunction( - llvm::FunctionType::get(IdTy, IdTy, true), "objc_msgSend") - .getCallee(); + name = "objc_msgSend_stret"; + + // The address of the memory block is be passed in x8 for POD type, + // or in x0 for non-POD type (marked as inreg). + bool shouldCheckForInReg = + CGM.getContext() + .getTargetInfo() + .getTriple() + .isWindowsMSVCEnvironment() && + CGM.getContext().getTargetInfo().getTriple().isAArch64(); + if (shouldCheckForInReg && CGM.ReturnTypeHasInReg(MSI.CallInfo)) { + name = "objc_msgSend_stret2"; + } } + // The actual types here don't matter - we're going to bitcast the + // function anyway + imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), + name) + .getCallee(); } // Reset the receiver in case the lookup modified it diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h index ec34680fd3f7..d9ece4d98eec 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h @@ -1239,6 +1239,9 @@ public: /// Return true iff the given type uses 'sret' when used as a return type. bool ReturnTypeUsesSRet(const CGFunctionInfo &FI); + /// Return true iff the given type has `inreg` set. + bool ReturnTypeHasInReg(const CGFunctionInfo &FI); + /// Return true iff the given type uses an argument slot when 'sret' is used /// as a return type. bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI); diff --git a/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp b/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp index 0c43317642bc..ae4e6d4c88c0 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1207,6 +1207,12 @@ struct CounterCoverageMappingBuilder /// Find a valid gap range between \p AfterLoc and \p BeforeLoc. std::optional<SourceRange> findGapAreaBetween(SourceLocation AfterLoc, SourceLocation BeforeLoc) { + // Some statements (like AttributedStmt and ImplicitValueInitExpr) don't + // have valid source locations. Do not emit a gap region if this is the case + // in either AfterLoc end or BeforeLoc end. + if (AfterLoc.isInvalid() || BeforeLoc.isInvalid()) + return std::nullopt; + // If AfterLoc is in function-like macro, use the right parenthesis // location. if (AfterLoc.isMacroID()) { @@ -1370,9 +1376,8 @@ struct CounterCoverageMappingBuilder for (const Stmt *Child : S->children()) if (Child) { // If last statement contains terminate statements, add a gap area - // between the two statements. Skipping attributed statements, because - // they don't have valid start location. - if (LastStmt && HasTerminateStmt && !isa<AttributedStmt>(Child)) { + // between the two statements. + if (LastStmt && HasTerminateStmt) { auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child)); if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), diff --git a/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 172c4c937b97..4d0f4c63f843 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1135,9 +1135,15 @@ static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty, return false; if (RD->hasNonTrivialCopyAssignment()) return false; - for (const CXXConstructorDecl *Ctor : RD->ctors()) - if (Ctor->isUserProvided()) - return false; + for (const Decl *D : RD->decls()) { + if (auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) { + if (Ctor->isUserProvided()) + return false; + } else if (auto *Template = dyn_cast<FunctionTemplateDecl>(D)) { + if (isa<CXXConstructorDecl>(Template->getTemplatedDecl())) + return false; + } + } if (RD->hasNonTrivialDestructor()) return false; return true; diff --git a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp index a3eb9138b218..53cd169b0590 100644 --- a/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp +++ b/contrib/llvm-project/clang/lib/Format/ContinuationIndenter.cpp @@ -674,7 +674,13 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun, // arguments to function calls. We do this by ensuring that either all // arguments (including any lambdas) go on the same line as the function // call, or we break before the first argument. - auto PrevNonComment = Current.getPreviousNonComment(); + const auto *Prev = Current.Previous; + if (!Prev) + return false; + // For example, `/*Newline=*/false`. + if (Prev->is(TT_BlockComment) && Current.SpacesRequiredBefore == 0) + return false; + const auto *PrevNonComment = Current.getPreviousNonComment(); if (!PrevNonComment || PrevNonComment->isNot(tok::l_paren)) return false; if (Current.isOneOf(tok::comment, tok::l_paren, TT_LambdaLSquare)) diff --git a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp index 4d482e6543d6..c1f166248192 100644 --- a/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp +++ b/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp @@ -3532,6 +3532,8 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const { } } else if (ClosingParen) { for (auto *Tok = ClosingParen->Next; Tok; Tok = Tok->Next) { + if (Tok->is(TT_CtorInitializerColon)) + break; if (Tok->is(tok::arrow)) { Tok->setType(TT_TrailingReturnArrow); break; @@ -5157,12 +5159,8 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, return true; if (Left.IsUnterminatedLiteral) return true; - // FIXME: Breaking after newlines seems useful in general. Turn this into an - // option and recognize more cases like endl etc, and break independent of - // what comes after operator lessless. - if (Right.is(tok::lessless) && Right.Next && - Right.Next->is(tok::string_literal) && Left.is(tok::string_literal) && - Left.TokenText.ends_with("\\n\"")) { + if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) && + Right.Next->is(tok::string_literal)) { return true; } if (Right.is(TT_RequiresClause)) { diff --git a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp index 573919798870..a6eb18bb2b32 100644 --- a/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp +++ b/contrib/llvm-project/clang/lib/Format/UnwrappedLineParser.cpp @@ -489,18 +489,23 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { }; SmallVector<StackEntry, 8> LBraceStack; assert(Tok->is(tok::l_brace)); + do { - // Get next non-comment, non-preprocessor token. FormatToken *NextTok; do { NextTok = Tokens->getNextToken(); } while (NextTok->is(tok::comment)); - while (NextTok->is(tok::hash) && !Line->InMacroBody) { - NextTok = Tokens->getNextToken(); - do { - NextTok = Tokens->getNextToken(); - } while (NextTok->is(tok::comment) || - (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof))); + + if (!Line->InMacroBody) { + // Skip PPDirective lines and comments. + while (NextTok->is(tok::hash)) { + do { + NextTok = Tokens->getNextToken(); + } while (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof)); + + while (NextTok->is(tok::comment)) + NextTok = Tokens->getNextToken(); + } } switch (Tok->Tok.getKind()) { @@ -534,16 +539,6 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { if (Style.Language == FormatStyle::LK_Proto) { ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square); } else { - // Skip NextTok over preprocessor lines, otherwise we may not - // properly diagnose the block as a braced intializer - // if the comma separator appears after the pp directive. - while (NextTok->is(tok::hash)) { - ScopedMacroState MacroState(*Line, Tokens, NextTok); - do { - NextTok = Tokens->getNextToken(); - } while (NextTok->isNot(tok::eof)); - } - // Using OriginalColumn to distinguish between ObjC methods and // binary operators is a bit hacky. bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) && @@ -602,6 +597,16 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { NextTok = Tokens->getNextToken(); ProbablyBracedList = NextTok->isNot(tok::l_square); } + + // Cpp macro definition body that is a nonempty braced list or block: + if (Style.isCpp() && Line->InMacroBody && PrevTok != FormatTok && + !FormatTok->Previous && NextTok->is(tok::eof) && + // A statement can end with only `;` (simple statement), a block + // closing brace (compound statement), or `:` (label statement). + // If PrevTok is a block opening brace, Tok ends an empty block. + !PrevTok->isOneOf(tok::semi, BK_Block, tok::colon)) { + ProbablyBracedList = true; + } } if (ProbablyBracedList) { Tok->setBlockKind(BK_BracedInit); @@ -631,6 +636,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { default: break; } + PrevTok = Tok; Tok = NextTok; } while (Tok->isNot(tok::eof) && !LBraceStack.empty()); diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Taint.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Taint.cpp index 4edb671753bf..6362c82b009d 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Taint.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/Taint.cpp @@ -216,21 +216,17 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State, std::vector<SymbolRef> TaintedSymbols; if (!Reg) return TaintedSymbols; - // Element region (array element) is tainted if either the base or the offset - // are tainted. + + // Element region (array element) is tainted if the offset is tainted. if (const ElementRegion *ER = dyn_cast<ElementRegion>(Reg)) { std::vector<SymbolRef> TaintedIndex = getTaintedSymbolsImpl(State, ER->getIndex(), K, returnFirstOnly); llvm::append_range(TaintedSymbols, TaintedIndex); if (returnFirstOnly && !TaintedSymbols.empty()) return TaintedSymbols; // return early if needed - std::vector<SymbolRef> TaintedSuperRegion = - getTaintedSymbolsImpl(State, ER->getSuperRegion(), K, returnFirstOnly); - llvm::append_range(TaintedSymbols, TaintedSuperRegion); - if (returnFirstOnly && !TaintedSymbols.empty()) - return TaintedSymbols; // return early if needed } + // Symbolic region is tainted if the corresponding symbol is tainted. if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) { std::vector<SymbolRef> TaintedRegions = getTaintedSymbolsImpl(State, SR->getSymbol(), K, returnFirstOnly); @@ -239,6 +235,8 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State, return TaintedSymbols; // return early if needed } + // Any subregion (including Element and Symbolic regions) is tainted if its + // super-region is tainted. if (const SubRegion *ER = dyn_cast<SubRegion>(Reg)) { std::vector<SymbolRef> TaintedSubRegions = getTaintedSymbolsImpl(State, ER->getSuperRegion(), K, returnFirstOnly); @@ -318,4 +316,4 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State, } } return TaintedSymbols; -}
\ No newline at end of file +} diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp index e5dd907c660d..b2947f590c4e 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/cert/InvalidPtrChecker.cpp @@ -205,8 +205,12 @@ void InvalidPtrChecker::postPreviousReturnInvalidatingCall( CE, LCtx, CE->getType(), C.blockCount()); State = State->BindExpr(CE, LCtx, RetVal); + const auto *SymRegOfRetVal = + dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion()); + if (!SymRegOfRetVal) + return; + // Remember to this region. - const auto *SymRegOfRetVal = cast<SymbolicRegion>(RetVal.getAsRegion()); const MemRegion *MR = SymRegOfRetVal->getBaseRegion(); State = State->set<PreviousCallResultMap>(FD, MR); diff --git a/contrib/llvm-project/libcxx/modules/std.compat/cstdlib.inc b/contrib/llvm-project/libcxx/modules/std.compat/cstdlib.inc index a45a0a1caf8b..4783cbf51623 100644 --- a/contrib/llvm-project/libcxx/modules/std.compat/cstdlib.inc +++ b/contrib/llvm-project/libcxx/modules/std.compat/cstdlib.inc @@ -25,7 +25,7 @@ export { using ::system; // [c.malloc], C library memory allocation - using ::aligned_alloc; + using ::aligned_alloc _LIBCPP_USING_IF_EXISTS; using ::calloc; using ::free; using ::malloc; diff --git a/contrib/llvm-project/lld/ELF/Writer.cpp b/contrib/llvm-project/lld/ELF/Writer.cpp index 8a08b0fcc90d..0c1bd27bb1fe 100644 --- a/contrib/llvm-project/lld/ELF/Writer.cpp +++ b/contrib/llvm-project/lld/ELF/Writer.cpp @@ -2148,9 +2148,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { addPhdrForSection(part, SHT_MIPS_OPTIONS, PT_MIPS_OPTIONS, PF_R); addPhdrForSection(part, SHT_MIPS_ABIFLAGS, PT_MIPS_ABIFLAGS, PF_R); } +#if 0 + // XXX: This stops elftoolchain strip adjusting .riscv.attributes, + // leaving large holes in binaries. if (config->emachine == EM_RISCV) addPhdrForSection(part, SHT_RISCV_ATTRIBUTES, PT_RISCV_ATTRIBUTES, PF_R); +#endif } Out::programHeaders->size = sizeof(Elf_Phdr) * mainPart->phdrs.size(); diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LoadStoreOpt.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LoadStoreOpt.h index 0f20a33f3a75..7990997835d0 100644 --- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LoadStoreOpt.h +++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LoadStoreOpt.h @@ -35,11 +35,23 @@ struct LegalityQuery; class MachineRegisterInfo; namespace GISelAddressing { /// Helper struct to store a base, index and offset that forms an address -struct BaseIndexOffset { +class BaseIndexOffset { +private: Register BaseReg; Register IndexReg; - int64_t Offset = 0; - bool IsIndexSignExt = false; + std::optional<int64_t> Offset; + +public: + BaseIndexOffset() = default; + Register getBase() { return BaseReg; } + Register getBase() const { return BaseReg; } + Register getIndex() { return IndexReg; } + Register getIndex() const { return IndexReg; } + void setBase(Register NewBase) { BaseReg = NewBase; } + void setIndex(Register NewIndex) { IndexReg = NewIndex; } + void setOffset(std::optional<int64_t> NewOff) { Offset = NewOff; } + bool hasValidOffset() const { return Offset.has_value(); } + int64_t getOffset() const { return *Offset; } }; /// Returns a BaseIndexOffset which describes the pointer in \p Ptr. @@ -89,7 +101,7 @@ private: // order stores are writing to incremeneting consecutive addresses. So when // we walk the block in reverse order, the next eligible store must write to // an offset one store width lower than CurrentLowestOffset. - uint64_t CurrentLowestOffset; + int64_t CurrentLowestOffset; SmallVector<GStore *> Stores; // A vector of MachineInstr/unsigned pairs to denote potential aliases that // need to be checked before the candidate is considered safe to merge. The diff --git a/contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp b/contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp index 8ee1f19e083e..1cca56fc19cf 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -8154,6 +8154,7 @@ static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI, IRBuilder<> Builder(Branch); if (UI->getParent() != Branch->getParent()) UI->moveBefore(Branch); + UI->dropPoisonGeneratingFlags(); Value *NewCmp = Builder.CreateCmp(ICmpInst::ICMP_EQ, UI, ConstantInt::get(UI->getType(), 0)); LLVM_DEBUG(dbgs() << "Converting " << *Cmp << "\n"); @@ -8167,6 +8168,7 @@ static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI, IRBuilder<> Builder(Branch); if (UI->getParent() != Branch->getParent()) UI->moveBefore(Branch); + UI->dropPoisonGeneratingFlags(); Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI, ConstantInt::get(UI->getType(), 0)); LLVM_DEBUG(dbgs() << "Converting " << *Cmp << "\n"); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 772229215e79..61ddc858ba44 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -591,8 +591,8 @@ bool CombinerHelper::matchCombineExtendingLoads(MachineInstr &MI, UseMI.getOpcode() == TargetOpcode::G_ZEXT || (UseMI.getOpcode() == TargetOpcode::G_ANYEXT)) { const auto &MMO = LoadMI->getMMO(); - // For atomics, only form anyextending loads. - if (MMO.isAtomic() && UseMI.getOpcode() != TargetOpcode::G_ANYEXT) + // Don't do anything for atomics. + if (MMO.isAtomic()) continue; // Check for legality. if (!isPreLegalize()) { diff --git a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index c0c22e36004f..47d045ac4817 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -4180,6 +4180,10 @@ LegalizerHelper::fewerElementsVectorPhi(GenericMachineInstr &MI, } } + // Set the insert point after the existing PHIs + MachineBasicBlock &MBB = *MI.getParent(); + MIRBuilder.setInsertPt(MBB, MBB.getFirstNonPHI()); + // Merge small outputs into MI's def. if (NumLeftovers) { mergeMixedSubvectors(MI.getReg(0), OutputRegs); diff --git a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp index 246aa88b09ac..ee499c41c558 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp @@ -84,21 +84,20 @@ BaseIndexOffset GISelAddressing::getPointerInfo(Register Ptr, MachineRegisterInfo &MRI) { BaseIndexOffset Info; Register PtrAddRHS; - if (!mi_match(Ptr, MRI, m_GPtrAdd(m_Reg(Info.BaseReg), m_Reg(PtrAddRHS)))) { - Info.BaseReg = Ptr; - Info.IndexReg = Register(); - Info.IsIndexSignExt = false; + Register BaseReg; + if (!mi_match(Ptr, MRI, m_GPtrAdd(m_Reg(BaseReg), m_Reg(PtrAddRHS)))) { + Info.setBase(Ptr); + Info.setOffset(0); return Info; } - + Info.setBase(BaseReg); auto RHSCst = getIConstantVRegValWithLookThrough(PtrAddRHS, MRI); if (RHSCst) - Info.Offset = RHSCst->Value.getSExtValue(); + Info.setOffset(RHSCst->Value.getSExtValue()); // Just recognize a simple case for now. In future we'll need to match // indexing patterns for base + index + constant. - Info.IndexReg = PtrAddRHS; - Info.IsIndexSignExt = false; + Info.setIndex(PtrAddRHS); return Info; } @@ -114,15 +113,16 @@ bool GISelAddressing::aliasIsKnownForLoadStore(const MachineInstr &MI1, BaseIndexOffset BasePtr0 = getPointerInfo(LdSt1->getPointerReg(), MRI); BaseIndexOffset BasePtr1 = getPointerInfo(LdSt2->getPointerReg(), MRI); - if (!BasePtr0.BaseReg.isValid() || !BasePtr1.BaseReg.isValid()) + if (!BasePtr0.getBase().isValid() || !BasePtr1.getBase().isValid()) return false; int64_t Size1 = LdSt1->getMemSize(); int64_t Size2 = LdSt2->getMemSize(); int64_t PtrDiff; - if (BasePtr0.BaseReg == BasePtr1.BaseReg) { - PtrDiff = BasePtr1.Offset - BasePtr0.Offset; + if (BasePtr0.getBase() == BasePtr1.getBase() && BasePtr0.hasValidOffset() && + BasePtr1.hasValidOffset()) { + PtrDiff = BasePtr1.getOffset() - BasePtr0.getOffset(); // If the size of memory access is unknown, do not use it to do analysis. // One example of unknown size memory access is to load/store scalable // vector objects on the stack. @@ -151,8 +151,8 @@ bool GISelAddressing::aliasIsKnownForLoadStore(const MachineInstr &MI1, // able to calculate their relative offset if at least one arises // from an alloca. However, these allocas cannot overlap and we // can infer there is no alias. - auto *Base0Def = getDefIgnoringCopies(BasePtr0.BaseReg, MRI); - auto *Base1Def = getDefIgnoringCopies(BasePtr1.BaseReg, MRI); + auto *Base0Def = getDefIgnoringCopies(BasePtr0.getBase(), MRI); + auto *Base1Def = getDefIgnoringCopies(BasePtr1.getBase(), MRI); if (!Base0Def || !Base1Def) return false; // Couldn't tell anything. @@ -520,16 +520,20 @@ bool LoadStoreOpt::addStoreToCandidate(GStore &StoreMI, Register StoreAddr = StoreMI.getPointerReg(); auto BIO = getPointerInfo(StoreAddr, *MRI); - Register StoreBase = BIO.BaseReg; - uint64_t StoreOffCst = BIO.Offset; + Register StoreBase = BIO.getBase(); if (C.Stores.empty()) { + C.BasePtr = StoreBase; + if (!BIO.hasValidOffset()) { + C.CurrentLowestOffset = 0; + } else { + C.CurrentLowestOffset = BIO.getOffset(); + } // This is the first store of the candidate. // If the offset can't possibly allow for a lower addressed store with the // same base, don't bother adding it. - if (StoreOffCst < ValueTy.getSizeInBytes()) + if (BIO.hasValidOffset() && + BIO.getOffset() < static_cast<int64_t>(ValueTy.getSizeInBytes())) return false; - C.BasePtr = StoreBase; - C.CurrentLowestOffset = StoreOffCst; C.Stores.emplace_back(&StoreMI); LLVM_DEBUG(dbgs() << "Starting a new merge candidate group with: " << StoreMI); @@ -549,8 +553,12 @@ bool LoadStoreOpt::addStoreToCandidate(GStore &StoreMI, // writes to the next lowest adjacent address. if (C.BasePtr != StoreBase) return false; - if ((C.CurrentLowestOffset - ValueTy.getSizeInBytes()) != - static_cast<uint64_t>(StoreOffCst)) + // If we don't have a valid offset, we can't guarantee to be an adjacent + // offset. + if (!BIO.hasValidOffset()) + return false; + if ((C.CurrentLowestOffset - + static_cast<int64_t>(ValueTy.getSizeInBytes())) != BIO.getOffset()) return false; // This writes to an adjacent address. Allow it. diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e806e0f0731f..5038f8a1fc15 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -9636,8 +9636,15 @@ static SDValue combineShiftOfShiftedLogic(SDNode *Shift, SelectionDAG &DAG) { if (ShiftAmtVal->getBitWidth() != C1Val.getBitWidth()) return false; + // The fold is not valid if the sum of the shift values doesn't fit in the + // given shift amount type. + bool Overflow = false; + APInt NewShiftAmt = C1Val.uadd_ov(*ShiftAmtVal, Overflow); + if (Overflow) + return false; + // The fold is not valid if the sum of the shift values exceeds bitwidth. - if ((*ShiftAmtVal + C1Val).uge(V.getScalarValueSizeInBits())) + if (NewShiftAmt.uge(V.getScalarValueSizeInBits())) return false; return true; diff --git a/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 03baa7497615..ac61dd8745d4 100644 --- a/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -4885,19 +4885,9 @@ defm UABDL : SIMDLongThreeVectorBHSabdl<1, 0b0111, "uabdl", def : Pat<(abs (v8i16 (sub (zext (v8i8 V64:$opA)), (zext (v8i8 V64:$opB))))), (UABDLv8i8_v8i16 V64:$opA, V64:$opB)>; -def : Pat<(xor (v8i16 (AArch64vashr v8i16:$src, (i32 15))), - (v8i16 (add (sub (zext (v8i8 V64:$opA)), - (zext (v8i8 V64:$opB))), - (AArch64vashr v8i16:$src, (i32 15))))), - (UABDLv8i8_v8i16 V64:$opA, V64:$opB)>; def : Pat<(abs (v8i16 (sub (zext (extract_high_v16i8 (v16i8 V128:$opA))), (zext (extract_high_v16i8 (v16i8 V128:$opB)))))), (UABDLv16i8_v8i16 V128:$opA, V128:$opB)>; -def : Pat<(xor (v8i16 (AArch64vashr v8i16:$src, (i32 15))), - (v8i16 (add (sub (zext (extract_high_v16i8 (v16i8 V128:$opA))), - (zext (extract_high_v16i8 (v16i8 V128:$opB)))), - (AArch64vashr v8i16:$src, (i32 15))))), - (UABDLv16i8_v8i16 V128:$opA, V128:$opB)>; def : Pat<(abs (v4i32 (sub (zext (v4i16 V64:$opA)), (zext (v4i16 V64:$opB))))), (UABDLv4i16_v4i32 V64:$opA, V64:$opB)>; diff --git a/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp b/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp index 84b9330ef963..50d8bfa87508 100644 --- a/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp +++ b/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp @@ -2358,6 +2358,11 @@ bool SIGfx12CacheControl::enableVolatileAndOrNonTemporal( bool Changed = false; + if (IsNonTemporal) { + // Set non-temporal hint for all cache levels. + Changed |= setTH(MI, AMDGPU::CPol::TH_NT); + } + if (IsVolatile) { Changed |= setScope(MI, AMDGPU::CPol::SCOPE_SYS); @@ -2370,11 +2375,6 @@ bool SIGfx12CacheControl::enableVolatileAndOrNonTemporal( Position::AFTER); } - if (IsNonTemporal) { - // Set non-temporal hint for all cache levels. - Changed |= setTH(MI, AMDGPU::CPol::TH_NT); - } - return Changed; } diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index a0cec426002b..d46093b9e260 100644 --- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -14559,7 +14559,7 @@ static SDValue tryFoldSelectIntoOp(SDNode *N, SelectionDAG &DAG, EVT VT = N->getValueType(0); SDLoc DL(N); SDValue OtherOp = TrueVal.getOperand(1 - OpToFold); - EVT OtherOpVT = OtherOp->getValueType(0); + EVT OtherOpVT = OtherOp.getValueType(); SDValue IdentityOperand = DAG.getNeutralElement(Opc, DL, OtherOpVT, N->getFlags()); if (!Commutative) diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 833f058253d8..553d338b7790 100644 --- a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -2923,11 +2923,10 @@ bool X86DAGToDAGISel::selectAddr(SDNode *Parent, SDValue N, SDValue &Base, } bool X86DAGToDAGISel::selectMOV64Imm32(SDValue N, SDValue &Imm) { - // Cannot use 32 bit constants to reference objects in kernel code model. - // Cannot use 32 bit constants to reference objects in large PIC mode since - // GOTOFF is 64 bits. + // Cannot use 32 bit constants to reference objects in kernel/large code + // model. if (TM.getCodeModel() == CodeModel::Kernel || - (TM.getCodeModel() == CodeModel::Large && TM.isPositionIndependent())) + TM.getCodeModel() == CodeModel::Large) return false; // In static codegen with small code model, we can get the address of a label diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp index 96bbd981ff24..201dd8382536 100644 --- a/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/contrib/llvm-project/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -47038,10 +47038,13 @@ static SDValue combineShiftRightArithmetic(SDNode *N, SelectionDAG &DAG, if (SDValue V = combineShiftToPMULH(N, DAG, Subtarget)) return V; - // fold (ashr (shl, a, [56,48,32,24,16]), SarConst) - // into (shl, (sext (a), [56,48,32,24,16] - SarConst)) or - // into (lshr, (sext (a), SarConst - [56,48,32,24,16])) - // depending on sign of (SarConst - [56,48,32,24,16]) + // fold (SRA (SHL X, ShlConst), SraConst) + // into (SHL (sext_in_reg X), ShlConst - SraConst) + // or (sext_in_reg X) + // or (SRA (sext_in_reg X), SraConst - ShlConst) + // depending on relation between SraConst and ShlConst. + // We only do this if (Size - ShlConst) is equal to 8, 16 or 32. That allows + // us to do the sext_in_reg from corresponding bit. // sexts in X86 are MOVs. The MOVs have the same code size // as above SHIFTs (only SHIFT on 1 has lower code size). @@ -47057,29 +47060,29 @@ static SDValue combineShiftRightArithmetic(SDNode *N, SelectionDAG &DAG, SDValue N00 = N0.getOperand(0); SDValue N01 = N0.getOperand(1); APInt ShlConst = N01->getAsAPIntVal(); - APInt SarConst = N1->getAsAPIntVal(); + APInt SraConst = N1->getAsAPIntVal(); EVT CVT = N1.getValueType(); - if (SarConst.isNegative()) + if (CVT != N01.getValueType()) + return SDValue(); + if (SraConst.isNegative()) return SDValue(); for (MVT SVT : { MVT::i8, MVT::i16, MVT::i32 }) { unsigned ShiftSize = SVT.getSizeInBits(); - // skipping types without corresponding sext/zext and - // ShlConst that is not one of [56,48,32,24,16] + // Only deal with (Size - ShlConst) being equal to 8, 16 or 32. if (ShiftSize >= Size || ShlConst != Size - ShiftSize) continue; SDLoc DL(N); SDValue NN = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, N00, DAG.getValueType(SVT)); - SarConst = SarConst - (Size - ShiftSize); - if (SarConst == 0) + if (SraConst.eq(ShlConst)) return NN; - if (SarConst.isNegative()) + if (SraConst.ult(ShlConst)) return DAG.getNode(ISD::SHL, DL, VT, NN, - DAG.getConstant(-SarConst, DL, CVT)); + DAG.getConstant(ShlConst - SraConst, DL, CVT)); return DAG.getNode(ISD::SRA, DL, VT, NN, - DAG.getConstant(SarConst, DL, CVT)); + DAG.getConstant(SraConst - ShlConst, DL, CVT)); } return SDValue(); } diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h b/contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h index a458b5f9ec8f..4d55a084b730 100644 --- a/contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h +++ b/contrib/llvm-project/llvm/lib/Target/X86/X86Subtarget.h @@ -244,7 +244,8 @@ public: // TODO: Currently we're always allowing widening on CPUs without VLX, // because for many cases we don't have a better option. bool canExtendTo512DQ() const { - return hasAVX512() && (!hasVLX() || getPreferVectorWidth() >= 512); + return hasAVX512() && hasEVEX512() && + (!hasVLX() || getPreferVectorWidth() >= 512); } bool canExtendTo512BW() const { return hasBWI() && canExtendTo512DQ(); diff --git a/contrib/llvm-project/llvm/lib/TargetParser/Host.cpp b/contrib/llvm-project/llvm/lib/TargetParser/Host.cpp index 4466d50458e1..1adef15771fa 100644 --- a/contrib/llvm-project/llvm/lib/TargetParser/Host.cpp +++ b/contrib/llvm-project/llvm/lib/TargetParser/Host.cpp @@ -1266,8 +1266,10 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(X86::FEATURE_AVX2); if (HasLeaf7 && ((EBX >> 8) & 1)) setFeature(X86::FEATURE_BMI2); - if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) + if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) { setFeature(X86::FEATURE_AVX512F); + setFeature(X86::FEATURE_EVEX512); + } if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512DQ); if (HasLeaf7 && ((EBX >> 19) & 1)) @@ -1772,6 +1774,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1); // AVX512 is only supported if the OS supports the context save for it. Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save; + Features["evex512"] = Features["avx512f"]; Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save; Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1); Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1); diff --git a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 9f220ec003ec..8cc7901cbac7 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2606,7 +2606,7 @@ static Instruction *foldSelectWithSRem(SelectInst &SI, InstCombinerImpl &IC, // %cnd = icmp slt i32 %rem, 0 // %add = add i32 %rem, %n // %sel = select i1 %cnd, i32 %add, i32 %rem - if (match(TrueVal, m_Add(m_Value(RemRes), m_Value(Remainder))) && + if (match(TrueVal, m_Add(m_Specific(RemRes), m_Value(Remainder))) && match(RemRes, m_SRem(m_Value(Op), m_Specific(Remainder))) && IC.isKnownToBeAPowerOfTwo(Remainder, /*OrZero*/ true) && FalseVal == RemRes) diff --git a/contrib/llvm-project/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/contrib/llvm-project/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index 9df28747570c..104e8ceb7967 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -279,6 +279,9 @@ bool InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI, Value *LHS = ICI->getOperand(0); Value *RHS = ICI->getOperand(1); + if (!LHS->getType()->isIntegerTy()) + return false; + // Canonicalize to the `Index Pred Invariant` comparison if (IsLoopInvariant(LHS)) { std::swap(LHS, RHS); diff --git a/contrib/llvm-project/openmp/runtime/src/kmp_settings.cpp b/contrib/llvm-project/openmp/runtime/src/kmp_settings.cpp index ec86ee07472c..58f19ea5b8ab 100644 --- a/contrib/llvm-project/openmp/runtime/src/kmp_settings.cpp +++ b/contrib/llvm-project/openmp/runtime/src/kmp_settings.cpp @@ -6426,6 +6426,8 @@ void __kmp_env_initialize(char const *string) { } if ((__kmp_nested_proc_bind.bind_types[0] != proc_bind_intel) && (__kmp_nested_proc_bind.bind_types[0] != proc_bind_default)) { + if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false) + __kmp_affinity.type = affinity_none; if (__kmp_affinity.type == affinity_default) { __kmp_affinity.type = affinity_compact; __kmp_affinity.flags.dups = FALSE; diff --git a/contrib/llvm-project/openmp/runtime/src/z_Linux_util.cpp b/contrib/llvm-project/openmp/runtime/src/z_Linux_util.cpp index b9ff96873702..97ddb8a608b7 100644 --- a/contrib/llvm-project/openmp/runtime/src/z_Linux_util.cpp +++ b/contrib/llvm-project/openmp/runtime/src/z_Linux_util.cpp @@ -2129,10 +2129,10 @@ int __kmp_is_address_mapped(void *addr) { // We pass from number of vm entry's semantic // to size of whole entry map list. lstsz = lstsz * 4 / 3; - buf = reinterpret_cast<char *>(kmpc_malloc(lstsz)); + buf = reinterpret_cast<char *>(KMP_INTERNAL_MALLOC(lstsz)); rc = sysctl(mib, 4, buf, &lstsz, NULL, 0); if (rc < 0) { - kmpc_free(buf); + KMP_INTERNAL_FREE(buf); return 0; } @@ -2156,7 +2156,7 @@ int __kmp_is_address_mapped(void *addr) { } lw += cursz; } - kmpc_free(buf); + KMP_INTERNAL_FREE(buf); #elif KMP_OS_DARWIN diff --git a/contrib/netbsd-tests/fs/tmpfs/t_times.sh b/contrib/netbsd-tests/fs/tmpfs/t_times.sh index 2d8eb6f67aa0..7b3be8d98d03 100755 --- a/contrib/netbsd-tests/fs/tmpfs/t_times.sh +++ b/contrib/netbsd-tests/fs/tmpfs/t_times.sh @@ -70,8 +70,6 @@ holey_head() { atf_set "require.user" "root" } holey_body() { - atf_expect_fail "https://bugs.freebsd.org/274615" - test_mount atf_check -s eq:0 -o empty -e empty truncate -s 8k a diff --git a/etc/mtree/BSD.var.dist b/etc/mtree/BSD.var.dist index 6f2327b59f0c..0845d8a59f65 100644 --- a/etc/mtree/BSD.var.dist +++ b/etc/mtree/BSD.var.dist @@ -53,8 +53,6 @@ .. ports .. - portsnap - .. zfsd tags=package=zfs cases .. diff --git a/lib/clang/include/VCSVersion.inc b/lib/clang/include/VCSVersion.inc index 687fb1656937..c4bb0df4e3a5 100644 --- a/lib/clang/include/VCSVersion.inc +++ b/lib/clang/include/VCSVersion.inc @@ -1,8 +1,8 @@ -#define LLVM_REVISION "llvmorg-18.1.4-0-ge6c3289804a6" +#define LLVM_REVISION "llvmorg-18.1.5-0-g617a15a9eac9" #define LLVM_REPOSITORY "https://github.com/llvm/llvm-project.git" -#define CLANG_REVISION "llvmorg-18.1.4-0-ge6c3289804a6" +#define CLANG_REVISION "llvmorg-18.1.5-0-g617a15a9eac9" #define CLANG_REPOSITORY "https://github.com/llvm/llvm-project.git" -#define LLDB_REVISION "llvmorg-18.1.4-0-ge6c3289804a6" +#define LLDB_REVISION "llvmorg-18.1.5-0-g617a15a9eac9" #define LLDB_REPOSITORY "https://github.com/llvm/llvm-project.git" diff --git a/lib/clang/include/clang/Basic/Version.inc b/lib/clang/include/clang/Basic/Version.inc index 536f72efec52..c243016c5f73 100644 --- a/lib/clang/include/clang/Basic/Version.inc +++ b/lib/clang/include/clang/Basic/Version.inc @@ -1,8 +1,8 @@ -#define CLANG_VERSION 18.1.4 -#define CLANG_VERSION_STRING "18.1.4" +#define CLANG_VERSION 18.1.5 +#define CLANG_VERSION_STRING "18.1.5" #define CLANG_VERSION_MAJOR 18 #define CLANG_VERSION_MAJOR_STRING "18" #define CLANG_VERSION_MINOR 1 -#define CLANG_VERSION_PATCHLEVEL 4 +#define CLANG_VERSION_PATCHLEVEL 5 #define CLANG_VENDOR "FreeBSD " diff --git a/lib/clang/include/lld/Common/Version.inc b/lib/clang/include/lld/Common/Version.inc index 65838f76ba5d..4079a361ce8d 100644 --- a/lib/clang/include/lld/Common/Version.inc +++ b/lib/clang/include/lld/Common/Version.inc @@ -1,4 +1,4 @@ // Local identifier in __FreeBSD_version style #define LLD_FREEBSD_VERSION 1400006 -#define LLD_VERSION_STRING "18.1.4 (FreeBSD llvmorg-18.1.4-0-ge6c3289804a6-" __XSTRING(LLD_FREEBSD_VERSION) ")" +#define LLD_VERSION_STRING "18.1.5 (FreeBSD llvmorg-18.1.5-0-g617a15a9eac9-" __XSTRING(LLD_FREEBSD_VERSION) ")" diff --git a/lib/clang/include/lldb/Version/Version.inc b/lib/clang/include/lldb/Version/Version.inc index 1fc1a4d88b7b..0e86bd2e01ba 100644 --- a/lib/clang/include/lldb/Version/Version.inc +++ b/lib/clang/include/lldb/Version/Version.inc @@ -1,6 +1,6 @@ -#define LLDB_VERSION 18.1.4 -#define LLDB_VERSION_STRING "18.1.4" +#define LLDB_VERSION 18.1.5 +#define LLDB_VERSION_STRING "18.1.5" #define LLDB_VERSION_MAJOR 18 #define LLDB_VERSION_MINOR 1 -#define LLDB_VERSION_PATCH 4 +#define LLDB_VERSION_PATCH 5 /* #undef LLDB_FULL_VERSION_STRING */ diff --git a/lib/clang/include/llvm/Config/AsmParsers.def b/lib/clang/include/llvm/Config/AsmParsers.def index afd86d898673..3dccab75a285 100644 --- a/lib/clang/include/llvm/Config/AsmParsers.def +++ b/lib/clang/include/llvm/Config/AsmParsers.def @@ -42,9 +42,6 @@ LLVM_ASM_PARSER(PowerPC) #ifdef LLVM_TARGET_ENABLE_RISCV LLVM_ASM_PARSER(RISCV) #endif -#ifdef LLVM_TARGET_ENABLE_SPARC -LLVM_ASM_PARSER(Sparc) -#endif #ifdef LLVM_TARGET_ENABLE_X86 LLVM_ASM_PARSER(X86) #endif diff --git a/lib/clang/include/llvm/Config/AsmPrinters.def b/lib/clang/include/llvm/Config/AsmPrinters.def index ffcca0730101..649b8353c926 100644 --- a/lib/clang/include/llvm/Config/AsmPrinters.def +++ b/lib/clang/include/llvm/Config/AsmPrinters.def @@ -42,9 +42,6 @@ LLVM_ASM_PRINTER(PowerPC) #ifdef LLVM_TARGET_ENABLE_RISCV LLVM_ASM_PRINTER(RISCV) #endif -#ifdef LLVM_TARGET_ENABLE_SPARC -LLVM_ASM_PRINTER(Sparc) -#endif #ifdef LLVM_TARGET_ENABLE_X86 LLVM_ASM_PRINTER(X86) #endif diff --git a/lib/clang/include/llvm/Config/Disassemblers.def b/lib/clang/include/llvm/Config/Disassemblers.def index 18e29e3a09ff..c44fa4e303e2 100644 --- a/lib/clang/include/llvm/Config/Disassemblers.def +++ b/lib/clang/include/llvm/Config/Disassemblers.def @@ -42,9 +42,6 @@ LLVM_DISASSEMBLER(PowerPC) #ifdef LLVM_TARGET_ENABLE_RISCV LLVM_DISASSEMBLER(RISCV) #endif -#ifdef LLVM_TARGET_ENABLE_SPARC -LLVM_DISASSEMBLER(Sparc) -#endif #ifdef LLVM_TARGET_ENABLE_X86 LLVM_DISASSEMBLER(X86) #endif diff --git a/lib/clang/include/llvm/Config/Targets.def b/lib/clang/include/llvm/Config/Targets.def index 604fd9337048..d3332a51a2cc 100644 --- a/lib/clang/include/llvm/Config/Targets.def +++ b/lib/clang/include/llvm/Config/Targets.def @@ -41,9 +41,6 @@ LLVM_TARGET(PowerPC) #ifdef LLVM_TARGET_ENABLE_RISCV LLVM_TARGET(RISCV) #endif -#ifdef LLVM_TARGET_ENABLE_SPARC -LLVM_TARGET(Sparc) -#endif #ifdef LLVM_TARGET_ENABLE_X86 LLVM_TARGET(X86) #endif diff --git a/lib/clang/include/llvm/Config/config.h b/lib/clang/include/llvm/Config/config.h index a017437dc568..0760c0b17a87 100644 --- a/lib/clang/include/llvm/Config/config.h +++ b/lib/clang/include/llvm/Config/config.h @@ -344,10 +344,10 @@ #define PACKAGE_NAME "LLVM" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "LLVM 18.1.4" +#define PACKAGE_STRING "LLVM 18.1.5" /* Define to the version of this package. */ -#define PACKAGE_VERSION "18.1.4" +#define PACKAGE_VERSION "18.1.5" /* Define to the vendor of this package. */ /* #undef PACKAGE_VENDOR */ diff --git a/lib/clang/include/llvm/Config/llvm-config.h b/lib/clang/include/llvm/Config/llvm-config.h index fb878ccdde4d..049529efdd7f 100644 --- a/lib/clang/include/llvm/Config/llvm-config.h +++ b/lib/clang/include/llvm/Config/llvm-config.h @@ -130,11 +130,7 @@ #endif /* Define if the Sparc target is built in */ -#ifdef LLVM_TARGET_ENABLE_SPARC -#define LLVM_HAS_SPARC_TARGET 1 -#else #define LLVM_HAS_SPARC_TARGET 0 -#endif /* Define if the SPIRV target is built in */ #define LLVM_HAS_SPIRV_TARGET 0 @@ -180,10 +176,10 @@ #define LLVM_VERSION_MINOR 1 /* Patch version of the LLVM API */ -#define LLVM_VERSION_PATCH 4 +#define LLVM_VERSION_PATCH 5 /* LLVM version string */ -#define LLVM_VERSION_STRING "18.1.4" +#define LLVM_VERSION_STRING "18.1.5" /* Whether LLVM records statistics for use with GetStatistics(), * PrintStatistics() or PrintStatisticsJSON() diff --git a/lib/clang/include/llvm/Support/VCSRevision.h b/lib/clang/include/llvm/Support/VCSRevision.h index e324de0f9fc6..433b2b53b8fe 100644 --- a/lib/clang/include/llvm/Support/VCSRevision.h +++ b/lib/clang/include/llvm/Support/VCSRevision.h @@ -1,2 +1,2 @@ -#define LLVM_REVISION "llvmorg-18.1.4-0-ge6c3289804a6" +#define LLVM_REVISION "llvmorg-18.1.5-0-g617a15a9eac9" #define LLVM_REPOSITORY "https://github.com/llvm/llvm-project.git" diff --git a/lib/geom/eli/geli.8 b/lib/geom/eli/geli.8 index c378c591290c..098ba4d0485e 100644 --- a/lib/geom/eli/geli.8 +++ b/lib/geom/eli/geli.8 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 18, 2022 +.Dd April 24, 2024 .Dt GELI 8 .Os .Sh NAME @@ -851,6 +851,15 @@ This variable should be set in Specifies how many times the Master Key is overwritten with random values when it is destroyed. After this operation it is filled with zeros. +.It Va kern.geom.eli.use_uma_bytes +.Nm +must allocate a buffer for every write operation, used when performing +encryption. +This sysctl reports the maximum size in bytes for which geli will perform the +allocation using +.Xr UMA 9 , +as opposed to +.Xr malloc 9 . .It Va kern.geom.eli.visible_passphrase : No 0 If set to 1, the passphrase entered on boot will be visible. This alternative should be used with caution as the entered @@ -863,11 +872,14 @@ Specifies how many kernel threads should be used for doing software cryptography. Its purpose is to increase performance on SMP systems. If set to 0, a CPU-pinned thread will be started for every active CPU. +Note that this variable must be set prior to attaching +.Nm +to a disk. .It Va kern.geom.eli.batch : No 0 When set to 1, can speed-up crypto operations by using batching. Batching reduces the number of interrupts by responding to a group of crypto requests with one interrupt. -The crypto card and the driver has to support this feature. +The crypto card and the driver have to support this feature. .It Va kern.geom.eli.key_cache_limit : No 8192 Specifies how many Data Keys to cache. The default limit @@ -884,13 +896,41 @@ Reports how many times we were looking up a Data Key and it was not in cache. This sysctl is not updated for providers that need fewer Data Keys than the limit specified in .Va kern.geom.eli.key_cache_limit . -.Va kern.geom.eli.unmapped_io +.It Va kern.geom.eli.unmapped_io Enable support for unmapped I/O buffers, currently implemented only on 64-bit platforms. This is an optimization which reduces the overhead of I/O processing. This variable is intended for debugging purposes and must be set in .Pa /boot/loader.conf . .El +.Sh PERFORMANCE CONSIDERATIONS +The default value of +.Va kern.geom.eli.threads +is usually good for a system with one SSD. +However, it may need to be lowered on systems with many disks, +so as to avoid creating too much thread-switching overhead. +On systems with more disks than CPUs, it's best to set this variable +to 1. +.Pp +.Nm +internally uses +.Xr malloc 9 +to allocate memory for operations larger than +.Va kern.geom.eli.use_uma_bytes , +but malloc is slow for allocations larger than +.Va vm.kmem_zmax . +So it's best to avoid writing more than +.Ms MAX(kern.geom.eli.use_uma_bytes, vm.kmem_zmax) +in a single write operation. +On systems that format +.Xr zfs 4 +on top of +.Nm , +the maximum write size can be controlled by +.Va vfs.zfs.vdev.aggregation_limit +and +.Va vfs.zfs.vdev.aggregation_limit_non_rotating +for HDDs and SSDs, respectively. .Sh EXIT STATUS Exit status is 0 on success, and 1 if the command fails. .Sh EXAMPLES diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3 index 09f37ff2fa93..340545114114 100644 --- a/lib/libc/gen/dlopen.3 +++ b/lib/libc/gen/dlopen.3 @@ -29,9 +29,7 @@ .\" .\" Copyright (c) 1991 Sun Microsystems, Inc. .\" -.\" @(#) dlopen.3 1.6 90/01/31 SMI -.\" -.Dd May 14, 2020 +.Dd May 7, 2024 .Dt DLOPEN 3 .Os .Sh NAME @@ -201,6 +199,10 @@ The function can be used by the code that needs to perform additional checks on the loaded objects, to prevent races with symlinking or renames. +Applications sandboxed using +.Xr capsicum 4 +can also make beneficial use of +.Fn fdlopen . .Pp The .Fn dlsym diff --git a/lib/libc/stdlib/cxa_thread_atexit_impl.c b/lib/libc/stdlib/cxa_thread_atexit_impl.c index f95384b30347..3123bd12dca8 100644 --- a/lib/libc/stdlib/cxa_thread_atexit_impl.c +++ b/lib/libc/stdlib/cxa_thread_atexit_impl.c @@ -102,7 +102,7 @@ walk_cb_call(struct cxa_thread_dtor *dtor) { struct dl_phdr_info phdr_info; - if (_rtld_addr_phdr(dtor->dso, &phdr_info) && + if (_rtld_addr_phdr(dtor->func, &phdr_info) && __elf_phdr_match_addr(&phdr_info, dtor->func)) dtor->func(dtor->obj); else diff --git a/lib/libc/sys/clock_gettime.2 b/lib/libc/sys/clock_gettime.2 index ed469153a40e..c8bef4c5424f 100644 --- a/lib/libc/sys/clock_gettime.2 +++ b/lib/libc/sys/clock_gettime.2 @@ -94,29 +94,29 @@ Returns the execution time of the calling thread. .El .Pp The clock IDs -.Fa CLOCK_REALTIME , -.Fa CLOCK_MONOTONIC , +.Dv CLOCK_REALTIME , +.Dv CLOCK_MONOTONIC , and -.Fa CLOCK_UPTIME +.Dv CLOCK_UPTIME perform a full time counter query. The clock IDs with the _FAST suffix, i.e., -.Fa CLOCK_REALTIME_FAST , -.Fa CLOCK_MONOTONIC_FAST , +.Dv CLOCK_REALTIME_FAST , +.Dv CLOCK_MONOTONIC_FAST , and -.Fa CLOCK_UPTIME_FAST , +.Dv CLOCK_UPTIME_FAST , do not perform a full time counter query, so their accuracy is one timer tick. Similarly, -.Fa CLOCK_REALTIME_PRECISE , -.Fa CLOCK_MONOTONIC_PRECISE , +.Dv CLOCK_REALTIME_PRECISE , +.Dv CLOCK_MONOTONIC_PRECISE , and -.Fa CLOCK_UPTIME_PRECISE +.Dv CLOCK_UPTIME_PRECISE are used to get the most exact value as possible, at the expense of execution time. The clock IDs -.Fa CLOCK_REALTIME_COARSE +.Dv CLOCK_REALTIME_COARSE and -.Fa CLOCK_MONOTONIC_COARSE +.Dv CLOCK_MONOTONIC_COARSE are aliases of corresponding IDs with _FAST suffix for compatibility with other systems. Finally, @@ -138,7 +138,7 @@ struct timespec { .Ed .Pp Only the super-user may set the time of day, using only -.Fa CLOCK_REALTIME . +.Dv CLOCK_REALTIME . If the system .Xr securelevel 7 is greater than 1 (see @@ -186,14 +186,14 @@ and system calls conform to .St -p1003.1b-93 . The clock IDs -.Fa CLOCK_REALTIME_FAST , -.Fa CLOCK_REALTIME_PRECISE , -.Fa CLOCK_MONOTONIC_FAST , -.Fa CLOCK_MONOTONIC_PRECISE , -.Fa CLOCK_UPTIME , -.Fa CLOCK_UPTIME_FAST , -.Fa CLOCK_UPTIME_PRECISE , -.Fa CLOCK_SECOND +.Dv CLOCK_REALTIME_FAST , +.Dv CLOCK_REALTIME_PRECISE , +.Dv CLOCK_MONOTONIC_FAST , +.Dv CLOCK_MONOTONIC_PRECISE , +.Dv CLOCK_UPTIME , +.Dv CLOCK_UPTIME_FAST , +.Dv CLOCK_UPTIME_PRECISE , +.Dv CLOCK_SECOND are .Fx extensions to the POSIX interface. diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index f43fb78d9a0f..7dc375717acc 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -250,7 +250,7 @@ pfctl_get_status(int dev) _pfctl_get_status_counters(nvlist_get_nvlist(nvl, "scounters"), &status->scounters); - pf_nvuint_64_array(nvl, "pcounters", 2 * 2 * 3, + pf_nvuint_64_array(nvl, "pcounters", 2 * 2 * 2, (uint64_t *)status->pcounters, NULL); pf_nvuint_64_array(nvl, "bcounters", 2 * 2, (uint64_t *)status->bcounters, NULL); diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index edaffdd12118..a2991cc05b04 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -62,7 +62,7 @@ struct pfctl_status { struct pfctl_status_counters lcounters; struct pfctl_status_counters fcounters; struct pfctl_status_counters scounters; - uint64_t pcounters[2][2][3]; + uint64_t pcounters[2][2][2]; uint64_t bcounters[2][2]; }; diff --git a/libexec/phttpget/phttpget.8 b/libexec/phttpget/phttpget.8 index b82c788c53c6..16e0be65cd4c 100644 --- a/libexec/phttpget/phttpget.8 +++ b/libexec/phttpget/phttpget.8 @@ -49,9 +49,7 @@ small files need to be downloaded. .Pp The .Xr freebsd-update 8 -and -.Xr portsnap 8 -tools use +tool uses .Nm to download binary patch files. .Sh ENVIRONMENT @@ -69,17 +67,16 @@ Timeout for HTTP request in seconds. .El .Sh SEE ALSO .Xr fetch 1 , -.Xr freebsd-update 8 , -.Xr portsnap 8 +.Xr freebsd-update 8 .Sh AUTHORS .An -nosplit The .Nm utility was written by .An Colin Percival Aq Mt cperciva@FreeBSD.org -for use with +initially for use with .Xr portsnap 8 -and later with +(now removed) and has been used by .Xr freebsd-update 8 . This manual page was written by .An Xin LI Aq Mt delphij@FreeBSD.org . diff --git a/libexec/rc/rc.d/devmatch b/libexec/rc/rc.d/devmatch index 78050cfa4541..67bb14761614 100755 --- a/libexec/rc/rc.d/devmatch +++ b/libexec/rc/rc.d/devmatch @@ -46,6 +46,7 @@ devmatch_start() if [ -n "$one_nomatch" ]; then list=$(devmatch -p "${one_nomatch}" | sort -u) else + sysctl hw.bus.devctl_nomatch_enabled=1 list=$(devmatch | sort -u) fi diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1 index a152dd444bd7..4cc5b639c89a 100644 --- a/libexec/rtld-elf/rtld.1 +++ b/libexec/rtld-elf/rtld.1 @@ -26,7 +26,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd October 29, 2023 +.Dd April 28, 2024 .Dt RTLD 1 .Os .Sh NAME @@ -352,6 +352,7 @@ The syntax of the direct invocation is .Op Fl b Ar exe .Op Fl d .Op Fl f Ar fd +.Op Fl o Ar OPT=NAME .Op Fl p .Op Fl u .Op Fl v @@ -387,6 +388,23 @@ If this option is specified, is only used to provide the .Va argv[0] value to the program. +.It Fl o Ar OPT=VALUE +Set the +.Ar OPT +configuration variable to the value +.Ar VALUE . +The possible variable names are listed above as +.Ev LD_ +prefixed environment variables, but here are referenced without the +.Ev LD_ +prefix. +A configuration variable set this way does not leak into +the activated image's environment. +.Pp +The option can be repeated as many times as needed to set +all configuration parameters. +The parameters set using this option have priority over +the same parameters assigned via environment. .It Fl p If the .Pa image_path @@ -400,7 +418,9 @@ to find the binary to execute. .It Fl u Ignore all .Ev LD_ -environment variables that otherwise affect the dynamic +environment variables and previous command line +.Fl o +options that otherwise affect the dynamic linker behavior. .It Fl v Display information about this run-time linker binary, then exit. diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index d5e702652058..96042f7b5af3 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -6155,10 +6155,42 @@ parse_args(char* argv[], int argc, bool *use_pathp, int *fdp, *fdp = fd; seen_f = true; break; + } else if (opt == 'o') { + struct ld_env_var_desc *l; + char *n, *v; + u_int ll; + + if (j != arglen - 1) { + _rtld_error("Invalid options: %s", arg); + rtld_die(); + } + i++; + n = argv[i]; + v = strchr(n, '='); + if (v == NULL) { + _rtld_error("No '=' in -o parameter"); + rtld_die(); + } + for (ll = 0; ll < nitems(ld_env_vars); ll++) { + l = &ld_env_vars[ll]; + if (v - n == (ptrdiff_t)strlen(l->n) && + strncmp(n, l->n, v - n) == 0) { + l->val = v + 1; + break; + } + } + if (ll == nitems(ld_env_vars)) { + _rtld_error("Unknown LD_ option %s", + n); + rtld_die(); + } } else if (opt == 'p') { *use_pathp = true; } else if (opt == 'u') { - trust = false; + u_int ll; + + for (ll = 0; ll < nitems(ld_env_vars); ll++) + ld_env_vars[ll].val = NULL; } else if (opt == 'v') { machine[0] = '\0'; mib[0] = CTL_HW; @@ -6238,6 +6270,7 @@ print_usage(const char *argv0) " -b <exe> Execute <exe> instead of <binary>, arg0 is <binary>\n" " -d Ignore lack of exec permissions for the binary\n" " -f <FD> Execute <FD> instead of searching for <binary>\n" + " -o <OPT>=<VAL> Set LD_<OPT> to <VAL>, without polluting env\n" " -p Search in PATH for named binary\n" " -u Ignore LD_ environment variables\n" " -v Display identification information\n" diff --git a/libexec/tftpd/tests/functional.c b/libexec/tftpd/tests/functional.c index f31d2a893da1..32e5f85cf421 100644 --- a/libexec/tftpd/tests/functional.c +++ b/libexec/tftpd/tests/functional.c @@ -29,6 +29,7 @@ #include <sys/param.h> #include <sys/socket.h> #include <sys/stat.h> +#include <sys/time.h> #include <sys/wait.h> #include <netinet/in.h> diff --git a/libexec/tftpd/tftp-file.h b/libexec/tftpd/tftp-file.h index 0fb7f6c1decc..c424e5cbc75b 100644 --- a/libexec/tftpd/tftp-file.h +++ b/libexec/tftpd/tftp-file.h @@ -25,7 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> int write_init(int fd, FILE *f, const char *mode); size_t write_file(char *buffer, int count); int write_close(void); diff --git a/libexec/tftpd/tftp-io.c b/libexec/tftpd/tftp-io.c index b5f39423fd60..aaacc9dd7f45 100644 --- a/libexec/tftpd/tftp-io.c +++ b/libexec/tftpd/tftp-io.c @@ -72,13 +72,13 @@ static struct errmsg { #define DROPPACKET(s) \ if (packetdroppercentage != 0 && \ - random()%100 < packetdroppercentage) { \ + arc4random()%100 < packetdroppercentage) { \ tftp_log(LOG_DEBUG, "Artificial packet drop in %s", s); \ return; \ } #define DROPPACKETn(s,n) \ if (packetdroppercentage != 0 && \ - random()%100 < packetdroppercentage) { \ + arc4random()%100 < packetdroppercentage) { \ tftp_log(LOG_DEBUG, "Artificial packet drop in %s", s); \ return (n); \ } @@ -157,10 +157,8 @@ send_error(int peer, int error) pe->e_msg = strerror(error - 100); tp->th_code = EUNDEF; /* set 'undef' errorcode */ } - strcpy(tp->th_msg, pe->e_msg); - length = strlen(pe->e_msg); - tp->th_msg[length] = '\0'; - length += 5; + snprintf(tp->th_msg, MAXPKTSIZE - 4, "%s%n", pe->e_msg, &length); + length += 5; /* header and terminator */ if (debug & DEBUG_PACKETS) tftp_log(LOG_DEBUG, "Sending ERROR %d: %s", error, tp->th_msg); @@ -331,7 +329,6 @@ send_ack(int fp, uint16_t block) DROPPACKETn("send_ack", 0); tp = (struct tftphdr *)buf; - size = sizeof(buf) - 2; tp->th_opcode = htons((u_short)ACK); tp->th_block = htons((u_short)block); size = 4; diff --git a/libexec/tftpd/tftp-io.h b/libexec/tftpd/tftp-io.h index 85934e824a1a..1d6bc2bd8b5e 100644 --- a/libexec/tftpd/tftp-io.h +++ b/libexec/tftpd/tftp-io.h @@ -25,7 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> #define RP_NONE 0 #define RP_RECVFROM -1 #define RP_TOOSMALL -2 diff --git a/libexec/tftpd/tftp-options.h b/libexec/tftpd/tftp-options.h index c68db53de4e2..f1b0a5cfaf32 100644 --- a/libexec/tftpd/tftp-options.h +++ b/libexec/tftpd/tftp-options.h @@ -25,7 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> /* * Options */ diff --git a/libexec/tftpd/tftp-transfer.h b/libexec/tftpd/tftp-transfer.h index 48431ebbc863..449f29c246e0 100644 --- a/libexec/tftpd/tftp-transfer.h +++ b/libexec/tftpd/tftp-transfer.h @@ -25,7 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> int tftp_send(int peer, uint16_t *block, struct tftp_stats *tp); int tftp_receive(int peer, uint16_t *block, struct tftp_stats *tp, struct tftphdr *firstblock, size_t fb_size); diff --git a/libexec/tftpd/tftp-utils.c b/libexec/tftpd/tftp-utils.c index b309a94f7653..8ce7c09c9992 100644 --- a/libexec/tftpd/tftp-utils.c +++ b/libexec/tftpd/tftp-utils.c @@ -204,7 +204,7 @@ struct debugs debugs[] = { { DEBUG_ACCESS, "access", "TCPd access debugging" }, { DEBUG_NONE, NULL, "No debugging" }, }; -int packetdroppercentage = 0; +unsigned int packetdroppercentage = 0; int debug_find(char *s) diff --git a/libexec/tftpd/tftp-utils.h b/libexec/tftpd/tftp-utils.h index 763b3b493c7e..276dedcf74cd 100644 --- a/libexec/tftpd/tftp-utils.h +++ b/libexec/tftpd/tftp-utils.h @@ -25,7 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> /* */ #define TIMEOUT 5 @@ -100,7 +99,7 @@ struct debugs { }; extern int debug; extern struct debugs debugs[]; -extern int packetdroppercentage; +extern unsigned int packetdroppercentage; int debug_find(char *s); int debug_finds(char *s); const char *debug_show(int d); diff --git a/libexec/tftpd/tftpd.8 b/libexec/tftpd/tftpd.8 index 3de042197618..24a743a92e14 100644 --- a/libexec/tftpd/tftpd.8 +++ b/libexec/tftpd/tftpd.8 @@ -27,7 +27,7 @@ .\" .\" @(#)tftpd.8 8.1 (Berkeley) 6/4/93 .\" -.Dd July 20, 2023 +.Dd May 8, 2024 .Dt TFTPD 8 .Os .Sh NAME @@ -35,11 +35,11 @@ .Nd Internet Trivial File Transfer Protocol server .Sh SYNOPSIS .Nm tftpd -.Op Fl cdClnow +.Op Fl CcdlnoSw .Op Fl F Ar strftime-format .Op Fl s Ar directory -.Op Fl u Ar user .Op Fl U Ar umask +.Op Fl u Ar user .Op Ar directory ... .Sh DESCRIPTION The diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c index 78348a8c6aaf..00c1257ce548 100644 --- a/libexec/tftpd/tftpd.c +++ b/libexec/tftpd/tftpd.c @@ -172,7 +172,7 @@ main(int argc, char *argv[]) options_extra_enabled = 0; break; case 'p': - packetdroppercentage = atoi(optarg); + packetdroppercentage = (unsigned int)atoi(optarg); tftp_log(LOG_INFO, "Randomly dropping %d out of 100 packets", packetdroppercentage); @@ -463,9 +463,9 @@ static char * parse_header(int peer, char *recvbuffer, size_t size, char **filename, char **mode) { - char *cp; - int i; struct formats *pf; + char *cp; + size_t i; *mode = NULL; cp = recvbuffer; @@ -482,12 +482,11 @@ parse_header(int peer, char *recvbuffer, size_t size, i = get_field(peer, cp, size); *mode = cp; - cp += i; /* Find the file transfer mode */ - for (cp = *mode; *cp; cp++) - if (isupper(*cp)) - *cp = tolower(*cp); + for (; *cp; cp++) + if (isupper((unsigned char)*cp)) + *cp = tolower((unsigned char)*cp); for (pf = formats; pf->f_mode; pf++) if (strcmp(pf->f_mode, *mode) == 0) break; @@ -624,12 +623,20 @@ tftp_rrq(int peer, char *recvbuffer, size_t size) static int find_next_name(char *filename, int *fd) { - int i; + /* + * GCC "knows" that we might write all of yyyymmdd plus the static + * elemenents in the format into into newname and thus complains + * unless we reduce the size. This array is still too big, but since + * the format is user supplied, it's not clear what a better limit + * value would be and this is sufficent to silence the warnings. + */ + static const int suffix_len = strlen("..00"); + char yyyymmdd[MAXPATHLEN - suffix_len]; + char newname[MAXPATHLEN]; + int i, ret; time_t tval; - size_t len; + size_t len, namelen; struct tm lt; - char yyyymmdd[MAXPATHLEN]; - char newname[MAXPATHLEN]; /* Create the YYYYMMDD part of the filename */ time(&tval); @@ -637,26 +644,33 @@ find_next_name(char *filename, int *fd) len = strftime(yyyymmdd, sizeof(yyyymmdd), newfile_format, <); if (len == 0) { syslog(LOG_WARNING, - "Filename suffix too long (%d characters maximum)", - MAXPATHLEN); + "Filename suffix too long (%zu characters maximum)", + sizeof(yyyymmdd) - 1); return (EACCESS); } /* Make sure the new filename is not too long */ - if (strlen(filename) > MAXPATHLEN - len - 5) { + namelen = strlen(filename); + if (namelen >= sizeof(newname) - len - suffix_len) { syslog(LOG_WARNING, - "Filename too long (%zd characters, %zd maximum)", - strlen(filename), MAXPATHLEN - len - 5); + "Filename too long (%zu characters, %zu maximum)", + namelen, + sizeof(newname) - len - suffix_len - 1); return (EACCESS); } /* Find the first file which doesn't exist */ for (i = 0; i < 100; i++) { - sprintf(newname, "%s.%s.%02d", filename, yyyymmdd, i); - *fd = open(newname, - O_WRONLY | O_CREAT | O_EXCL, - S_IRUSR | S_IWUSR | S_IRGRP | - S_IWGRP | S_IROTH | S_IWOTH); + ret = snprintf(newname, sizeof(newname), "%s.%s.%02d", + filename, yyyymmdd, i); + /* + * Size checked above so this can't happen, we'd use a + * (void) cast, but gcc intentionally ignores that if + * snprintf has __attribute__((warn_unused_result)). + */ + if (ret < 0 || (size_t)ret >= sizeof(newname)) + __unreachable(); + *fd = open(newname, O_WRONLY | O_CREAT | O_EXCL, 0666); if (*fd > 0) return 0; } diff --git a/release/Makefile.mirrors b/release/Makefile.mirrors index cbc5cd768e28..591fd85b29ea 100644 --- a/release/Makefile.mirrors +++ b/release/Makefile.mirrors @@ -193,6 +193,16 @@ vm-images-stage: cd ${VM_DIR}/Latest && \ ln -s ../${BUILDDATE}/${OSRELEASE}-${SNAP_SUFFIX}.${VMFORMAT}.xz \ ${OSRELEASE}.${VMFORMAT}.xz +. for FS in ${VMFSLIST} + cd ${RELEASEDIR}/vmimages && \ + mv ${OSRELEASE}-${FS}.${VMFORMAT}.xz \ + ${OSRELEASE}-${FS}-${SNAP_SUFFIX}.${VMFORMAT}.xz + cp -p ${RELEASEDIR}/vmimages/${OSRELEASE}-${FS}-${SNAP_SUFFIX}.${VMFORMAT}.xz \ + ${VM_DIR}/${BUILDDATE}/${OSRELEASE}-${FS}-${SNAP_SUFFIX}.${VMFORMAT}.xz + cd ${VM_DIR}/Latest && \ + ln -s ../${BUILDDATE}/${OSRELEASE}-${FS}-${SNAP_SUFFIX}.${VMFORMAT}.xz \ + ${OSRELEASE}-${FS}.${VMFORMAT}.xz +. endfor . endfor cd ${RELEASEDIR}/vmimages && rm -f CHECKSUM.* . for CHECKSUM in ${CHECKSUM_FILES} @@ -212,6 +222,10 @@ vm-images-stage: . for VMFORMAT in ${VMFORMATS} cp -p ${RELEASEDIR}/vmimages/${OSRELEASE}.${VMFORMAT}.xz \ ${VM_DIR}/Latest/${OSRELEASE}.${VMFORMAT}.xz +. for FS in ${VMFSLIST} + cp -p ${RELEASEDIR}/vmimages/${OSRELEASE}-${FS}.${VMFORMAT}.xz \ + ${VM_DIR}/Latest/${OSRELEASE}-${FS}.${VMFORMAT}.xz +. endfor . endfor . for CHECKSUM in ${CHECKSUM_FILES} cp -p ${RELEASEDIR}/vmimages/CHECKSUM.${CHECKSUM} \ diff --git a/release/Makefile.vm b/release/Makefile.vm index 0eb549ec7bc2..95d48490c353 100644 --- a/release/Makefile.vm +++ b/release/Makefile.vm @@ -157,12 +157,13 @@ CLEANFILES+= ${VMBASE}.${FS}.${FORMAT} vm-base: vm-image -vm-image: +vm-image: ${QEMUTGT} .if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) . for FORMAT in ${VMFORMATS} . for FS in ${VMFSLIST} mkdir -p ${.OBJDIR}/${.TARGET}-${FORMAT}-${FS} env TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} SWAPSIZE=${SWAPSIZE} \ + QEMUSTATIC=${QEMUSTATIC} \ ${.CURDIR}/scripts/mk-vmimage.sh \ -C ${.CURDIR}/tools/vmimage.subr \ -d ${.OBJDIR}/${.TARGET}-${FORMAT}-${FS} -F ${FS} \ @@ -222,14 +223,16 @@ vm-install: ${DESTDIR}/vmimages/CHECKSUM.SHA256 .endif -vm-release: .if defined(WITH_VMIMAGES) && !empty(WITH_VMIMAGES) - ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${VMTARGETS} +vm-release: ${VMTARGETS} +.else +vm-release: .endif -cloudware-release: .if defined(WITH_CLOUDWARE) && !empty(WITH_CLOUDWARE) && !empty(CLOUDWARE) - ${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} ${CLOUDTARGETS} +cloudware-release: ${CLOUDTARGETS} +.else +cloudware-release: .endif .include "${.CURDIR}/Makefile.azure" diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh index ca6a359affbd..dfd91f43140d 100755 --- a/release/scripts/mk-vmimage.sh +++ b/release/scripts/mk-vmimage.sh @@ -97,13 +97,14 @@ main() { vm_create_base vm_install_base + vm_emulation_setup vm_extra_install_base vm_extra_install_packages vm_extra_install_ports vm_extra_enable_services vm_extra_pre_umount vm_extra_pkg_rmcache - cleanup + vm_emulation_cleanup vm_copy_base vm_create_disk || return 0 vm_extra_create_disk diff --git a/release/tools/azure.conf b/release/tools/azure.conf index b6526f21e474..9da2b19de694 100644 --- a/release/tools/azure.conf +++ b/release/tools/azure.conf @@ -53,7 +53,5 @@ EOF touch ${DESTDIR}/firstboot - rm -f ${DESTDIR}/etc/resolv.conf - return 0 } diff --git a/release/tools/ec2.conf b/release/tools/ec2.conf index a233bf5981c1..ce09ab0d2367 100644 --- a/release/tools/ec2.conf +++ b/release/tools/ec2.conf @@ -102,10 +102,5 @@ EOF # The first time the AMI boots, run "first boot" scripts. touch ${DESTDIR}/firstboot - if ! [ -z "${QEMUSTATIC}" ]; then - rm -f ${DESTDIR}/${EMULATOR} - fi - rm -f ${DESTDIR}/etc/resolv.conf - return 0 } diff --git a/release/tools/gce.conf b/release/tools/gce.conf index aad4a74d2e39..5ad83bcded53 100644 --- a/release/tools/gce.conf +++ b/release/tools/gce.conf @@ -118,7 +118,15 @@ EOF touch ${DESTDIR}/firstboot - rm -f ${DESTDIR}/etc/resolv.conf + return 0 +} +# Do everything except deleting resolv.conf since we construct our own +# Googlized resolv.conf file in vm_extra_install_base. +vm_emulation_cleanup() { + if ! [ -z "${QEMUSTATIC}" ]; then + rm -f ${DESTDIR}/${EMULATOR} + fi + umount_loop ${DESTDIR}/dev return 0 } diff --git a/release/tools/oci.conf b/release/tools/oci.conf index c57a7683a500..a4fe54ad3031 100644 --- a/release/tools/oci.conf +++ b/release/tools/oci.conf @@ -90,10 +90,5 @@ EOF touch ${DESTDIR}/firstboot - if ! [ -z "${QEMUSTATIC}" ]; then - rm -f ${DESTDIR}/${EMULATOR} - fi - rm -f ${DESTDIR}/etc/resolv.conf - return 0 } diff --git a/release/tools/openstack.conf b/release/tools/openstack.conf index 4c905fbae4ba..05d2d13bbb39 100644 --- a/release/tools/openstack.conf +++ b/release/tools/openstack.conf @@ -35,8 +35,6 @@ vm_extra_pre_umount() { echo 'ALL ALL=(ALL) NOPASSWD:ALL' >> \ ${DESTDIR}/usr/local/etc/sudoers.d/cloud-init - rm -f ${DESTDIR}/etc/resolv.conf - # The console is not interactive, so we might as well boot quickly. echo 'autoboot_delay="-1"' >> ${DESTDIR}/boot/loader.conf echo 'beastie_disable="YES"' >> ${DESTDIR}/boot/loader.conf diff --git a/release/tools/vagrant-virtualbox.conf b/release/tools/vagrant-virtualbox.conf index 4dd7ca8953ad..9e0e430bbc88 100644 --- a/release/tools/vagrant-virtualbox.conf +++ b/release/tools/vagrant-virtualbox.conf @@ -14,5 +14,4 @@ vm_extra_pre_umount () { # Setup the Vagrant common items vagrant_common - rm -f ${DESTDIR}/etc/resolv.conf } diff --git a/release/tools/vagrant-vmware.conf b/release/tools/vagrant-vmware.conf index 52ff7f1aac1a..fff929829222 100644 --- a/release/tools/vagrant-vmware.conf +++ b/release/tools/vagrant-vmware.conf @@ -18,5 +18,4 @@ vm_extra_pre_umount () { # Setup the Vagrant common items vagrant_common - rm -f ${DESTDIR}/etc/resolv.conf } diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr index eda22e061c6d..72540dad14a8 100644 --- a/release/tools/vmimage.subr +++ b/release/tools/vmimage.subr @@ -83,8 +83,14 @@ vm_install_base() { echo "zfs_enable=\"YES\"" >> ${DESTDIR}/etc/rc.conf echo "zpool_reguid=\"zroot\"" >> ${DESTDIR}/etc/rc.conf echo "zpool_upgrade=\"zroot\"" >> ${DESTDIR}/etc/rc.conf + echo "kern.geom.label.disk_ident.enable=0" >> ${DESTDIR}/boot/loader.conf + echo "zfs_load=YES" >> ${DESTDIR}/boot/loader.conf fi + return 0 +} + +vm_emulation_setup() { if ! [ -z "${QEMUSTATIC}" ]; then export EMULATOR=/qemu cp ${QEMUSTATIC} ${DESTDIR}/${EMULATOR} @@ -94,15 +100,8 @@ vm_install_base() { mount -t devfs devfs ${DESTDIR}/dev chroot ${DESTDIR} ${EMULATOR} /usr/bin/newaliases chroot ${DESTDIR} ${EMULATOR} /bin/sh /etc/rc.d/ldconfig forcestart - umount_loop ${DESTDIR}/dev - cp /etc/resolv.conf ${DESTDIR}/etc/resolv.conf - if [ "${VMFS}" = zfs ]; then - echo "kern.geom.label.disk_ident.enable=0" >> ${DESTDIR}/boot/loader.conf - echo "zfs_load=YES" >> ${DESTDIR}/boot/loader.conf - fi - return 0 } @@ -136,15 +135,12 @@ vm_extra_install_packages() { if [ -z "${VM_EXTRA_PACKAGES}" ]; then return 0 fi - mkdir -p ${DESTDIR}/dev - mount -t devfs devfs ${DESTDIR}/dev chroot ${DESTDIR} ${EMULATOR} env ASSUME_ALWAYS_YES=yes \ /usr/sbin/pkg bootstrap -y for p in ${VM_EXTRA_PACKAGES}; do chroot ${DESTDIR} ${EMULATOR} env ASSUME_ALWAYS_YES=yes \ /usr/sbin/pkg install -y ${p} done - umount_loop ${DESTDIR}/dev return 0 } @@ -159,13 +155,16 @@ vm_extra_install_ports() { vm_extra_pre_umount() { # Prototype. When overridden, performs additional tasks within the # virtual machine environment prior to unmounting the filesystem. - # Note: When overriding this function, removing resolv.conf in the - # disk image must be included. + return 0 +} + +vm_emulation_cleanup() { if ! [ -z "${QEMUSTATIC}" ]; then rm -f ${DESTDIR}/${EMULATOR} fi rm -f ${DESTDIR}/etc/resolv.conf + umount_loop ${DESTDIR}/dev return 0 } diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8 index e1496af814ca..0dc93cb8b78d 100644 --- a/sbin/newfs/newfs.8 +++ b/sbin/newfs/newfs.8 @@ -27,7 +27,7 @@ .\" .\" @(#)newfs.8 8.6 (Berkeley) 5/3/95 .\" -.Dd October 21, 2022 +.Dd May 18, 2024 .Dt NEWFS 8 .Os .Sh NAME @@ -100,6 +100,10 @@ The default format is UFS2. For backward compatibility. .It Fl U Enable soft updates on the new file system. +Soft updates are enabled by default for UFS2 format file systems. +Use +.Xr tunefs 8 +to disable soft updates if they are not wanted. .It Fl a Ar maxcontig Specify the maximum number of contiguous blocks that will be laid out before forcing a rotational delay. diff --git a/sbin/newfs/newfs.c b/sbin/newfs/newfs.c index afb71f9f25b4..c96e414b85dd 100644 --- a/sbin/newfs/newfs.c +++ b/sbin/newfs/newfs.c @@ -395,6 +395,9 @@ main(int argc, char *argv[]) fprintf(stderr, "because minfree is less than %d%%\n", MINFREE); opt = FS_OPTSPACE; } + /* Use soft updates by default for UFS2 and above */ + if (Oflag > 1) + Uflag = 1; realsectorsize = sectorsize; if (sectorsize != DEV_BSIZE) { /* XXX */ int secperblk = sectorsize / DEV_BSIZE; diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index a2d544034005..222422526180 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -342,6 +342,7 @@ MAN= aac.4 \ netlink.4 \ netmap.4 \ ${_nfe.4} \ + nfslockd.4 \ ${_nfsmb.4} \ ng_async.4 \ ng_bpf.4 \ diff --git a/share/man/man4/nfslockd.4 b/share/man/man4/nfslockd.4 new file mode 100644 index 000000000000..770d9b8736b0 --- /dev/null +++ b/share/man/man4/nfslockd.4 @@ -0,0 +1,45 @@ +.\"- +.\" Copyright (c) 2024 Dag-Erling Smørgrav +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.Dd May 8, 2024 +.Dt NFSLOCKD 4 +.Os +.Sh NAME +.Nm nfslockd +.Nd NFS advisory locking +.Sh SYNOPSIS +To compile this driver into the kernel, place the following lines in +your kernel configuration file: +.Bd -ragged -offset indent +.Cd "options NFSLOCKD" +.Ed +.Pp +Alternatively, to load the driver as a module at boot time, place the +following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +nfslockd_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides kernel support for NFSv3 advisory locking. +It works in tandem with +.Xr rpc.lockd 8 , +which will normally load it on startup if it is not already loaded or +compiled-in. +.Sh SEE ALSO +.Xr rpc.lockd 8 +.Sh HISTORY +The +.Nm +driver first appeared in +.Fx 6.4 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Doug Rabson Aq Mt dfr@FreeBSD.org . diff --git a/share/man/man4/smsc.4 b/share/man/man4/smsc.4 index 56c1556e5f83..61b12c7d230c 100644 --- a/share/man/man4/smsc.4 +++ b/share/man/man4/smsc.4 @@ -25,12 +25,12 @@ .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd November 24, 2015 +.Dd May 7, 2024 .Dt SMSC 4 .Os .Sh NAME .Nm smsc -.Nd "USB SMSC LAN9xxx Fast Ethernet driver" +.Nd "USB Microchip LAN9xxx Fast Ethernet driver" .Sh SYNOPSIS To load the driver as a module at boot time, place the following line in @@ -53,7 +53,7 @@ following lines in your kernel configuration file: The .Nm device driver provides support for USB Fast Ethernet adapters based -on the SMSC LAN9xxx chipsets. +on the Microchip (formerly SMSC) LAN9xxx chipsets. .Pp For more information on configuring this device, see .Xr ifconfig 8 . @@ -64,11 +64,11 @@ driver: .Pp .Bl -bullet -compact .It -SMSC LAN9500, LAN9500A, LAN9505 and LAN9505A based Ethernet adapters +LAN9500, LAN9500A, LAN9505 and LAN9505A based Ethernet adapters .It -SMSC LAN89530, LAN9530 and LAN9730 based Ethernet adapters +LAN89530, LAN9530 and LAN9730 based Ethernet adapters .It -SMSC LAN951x Ethernet adapters with integrated USB hub +LAN951x Ethernet adapters with integrated USB hub .El .Sh SEE ALSO .Xr arp 4 , diff --git a/share/man/man4/vmm.4 b/share/man/man4/vmm.4 index cb3276a7d8f1..dfd7ad26fb98 100644 --- a/share/man/man4/vmm.4 +++ b/share/man/man4/vmm.4 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd October 12, 2023 +.Dd March 6, 2024 .Dt VMM 4 .Os .Sh NAME @@ -70,6 +70,19 @@ See the .Sx EXAMPLES section below for sample usage. .Pp +Note that +.Nm vmm +must be given first the right of refusal to all +.Xr pci 4 +devices it may need to claim. +As a result, the +.Nm vmm +kernel module almost certainly needs to be loaded from +.Xr loader.conf 5 +rather than by adding it to +.Va kld_list in +.Xr rc.conf 5 . +.Pp A large number of PCI device entries may require a string longer than the 128-character limit of .Xr loader.conf 5 diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 8effacbc0cee..55427c5b0eca 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -633,6 +633,8 @@ MLINKS+=bitset.9 BITSET_DEFINE.9 \ bitset.9 BIT_CMP.9 \ bitset.9 BIT_OR.9 \ bitset.9 BIT_OR2.9 \ + bitset.9 BIT_ORNOT.9 \ + bitset.9 BIT_ORNOT2.9 \ bitset.9 BIT_AND.9 \ bitset.9 BIT_AND2.9 \ bitset.9 BIT_ANDNOT.9 \ @@ -922,6 +924,7 @@ MLINKS+=cpuset.9 CPUSET_T_INITIALIZER.9 \ cpuset.9 CPU_OVERLAP.9 \ cpuset.9 CPU_CMP.9 \ cpuset.9 CPU_OR.9 \ + cpuset.9 CPU_ORNOT.9 \ cpuset.9 CPU_AND.9 \ cpuset.9 CPU_ANDNOT.9 \ cpuset.9 CPU_CLR_ATOMIC.9 \ diff --git a/share/man/man9/bitset.9 b/share/man/man9/bitset.9 index 1bdfdeb7484c..a4e360a678d7 100644 --- a/share/man/man9/bitset.9 +++ b/share/man/man9/bitset.9 @@ -51,6 +51,8 @@ .Nm BIT_CMP , .Nm BIT_OR , .Nm BIT_OR2 , +.Nm BIT_ORNOT , +.Nm BIT_ORNOT2 , .Nm BIT_AND , .Nm BIT_AND2 , .Nm BIT_ANDNOT , @@ -123,6 +125,13 @@ .Fa "struct STRUCTNAME *src1" .Fa "struct STRUCTNAME *src2" .Fc +.Fn BIT_ORNOT "const SETSIZE" "struct STRUCTNAME *dst" "struct STRUCTNAME *src" +.Fo BIT_ORNOT2 +.Fa "const SETSIZE" +.Fa "struct STRUCTNAME *dst" +.Fa "struct STRUCTNAME *src1" +.Fa "struct STRUCTNAME *src2" +.Fc .Fn BIT_AND "const SETSIZE" "struct STRUCTNAME *dst" "struct STRUCTNAME *src" .Fo BIT_AND2 .Fa "const SETSIZE" @@ -459,6 +468,36 @@ equivalent of the scalar: .Fa src2 . ) .Pp The +.Fn BIT_ORNOT +macro sets bits not in +.Fa src +in +.Fa dst . +(It is the +.Nm +equivalent of the scalar: +.Fa dst +|= +.Fa ~ src . ) +.Pp +The +.Fn BIT_ORNOT2 +macro computes +.Fa src1 +bitwise or not +.Fa src2 +and assigns the result to +.Fa dst . +(It is the +.Nm +equivalent of the scalar: +.Fa dst += +.Fa src1 +| ~ +.Fa src2 . ) +.Pp +The .Fn BIT_AND macro clears bits absent from .Fa src diff --git a/share/man/man9/cpuset.9 b/share/man/man9/cpuset.9 index 974dc55b2c65..20485059a4c8 100644 --- a/share/man/man9/cpuset.9 +++ b/share/man/man9/cpuset.9 @@ -45,6 +45,7 @@ .Nm CPU_OVERLAP , .Nm CPU_CMP , .Nm CPU_OR , +.Nm CPU_ORNOT , .Nm CPU_AND , .Nm CPU_ANDNOT , .Nm CPU_XOR , @@ -86,6 +87,7 @@ .Ft bool .Fn CPU_CMP "cpuset_t *cpuset1" "cpuset_t *cpuset2" .Fn CPU_OR "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2" +.Fn CPU_ORNOT "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2" .Fn CPU_AND "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2" .Fn CPU_ANDNOT "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2" .Fn CPU_XOR "cpuset_t *dst" "cpuset_t *src1" "cpuset_t *src2" @@ -296,6 +298,19 @@ is composed of multiple machine words, performs multiple individually atomic operations.) .Pp The +.Fn CPU_ORNOT +macro add CPUs not in +.Fa src +to +.Fa dst . +(It is the +.Nm +equivalent of the scalar: +.Fa dst +|= +.Fa ~ src . ) +.Pp +The .Fn CPU_AND macro removes CPUs absent from .Fa src diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree index d81c8829f4e8..ed18b96cb39a 100644 --- a/share/misc/bsd-family-tree +++ b/share/misc/bsd-family-tree @@ -446,11 +446,20 @@ FreeBSD 5.2 | | | | | | | | OpenBSD 7.3 | | FreeBSD | | | | | 13.2 | | | | - | macOS | | | - | 14 | | | - | | | OpenBSD 7.4 | - *--FreeBSD | | | | - | 14.0 | | | | + | | | | | | + | `------. | | | | + | | macOS | | | + | | 14 | | | + | | | | OpenBSD 7.4 | + *--FreeBSD | | | | | + | 14.0 | | | | | + | | | | | | + | FreeBSD | | | | + | 13.3 | | | | + | | *--NetBSD | | + | | | 10.0 | | + | | | | | + | | | OpenBSD 7.5 | | | | | | FreeBSD 15 -current | NetBSD -current OpenBSD -current DragonFly -current | | | | | @@ -479,7 +488,8 @@ was the announcement in Usenet or if it was available as tape. Distribution UNIX Version 2.9, July, 1983. [NBD] NetBSD Project, The. [OBD] OpenBSD Project, The. -[QCU] Salus, Peter H. A quarter century of UNIX. +[QCU] Salus, Peter H. A quarter century of UNIX. ISBN 0201547775, + EAN 9780201547771 [SMS] Steven M. Schultz. 2.11BSD, UNIX for the PDP-11. [TUHS] The Unix Historical Society. https://minnie.tuhs.org/Unix_History/. [USE] Usenet announcement. @@ -880,6 +890,9 @@ FreeBSD 13.2 2023-04-11 [FBD] macOS 14 2023-09-26 [APL] OpenBSD 7.4 2023-10-16 [OBD] FreeBSD 14.0 2023-11-20 [FBD] +FreeBSD 13.3 2024-03-05 [FBD] +NetBSD 10.0 2024-03-28 [NBD] +OpenBSD 7.5 2024-04-05 [OBD] Bibliography ------------------------ diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c index 6f8d6feaf60b..6c8b038bdb09 100644 --- a/sys/amd64/amd64/sys_machdep.c +++ b/sys/amd64/amd64/sys_machdep.c @@ -189,35 +189,33 @@ sysarch(struct thread *td, struct sysarch_args *uap) * explicitly indicate whether or not the operation is safe to * perform in capability mode. */ - if (IN_CAPABILITY_MODE(td)) { - switch (uap->op) { - case I386_GET_LDT: - case I386_SET_LDT: - case I386_GET_IOPERM: - case I386_GET_FSBASE: - case I386_SET_FSBASE: - case I386_GET_GSBASE: - case I386_SET_GSBASE: - case I386_GET_XFPUSTATE: - case I386_SET_PKRU: - case I386_CLEAR_PKRU: - case AMD64_GET_FSBASE: - case AMD64_SET_FSBASE: - case AMD64_GET_GSBASE: - case AMD64_SET_GSBASE: - case AMD64_GET_XFPUSTATE: - case AMD64_SET_PKRU: - case AMD64_CLEAR_PKRU: - break; + switch (uap->op) { + case I386_GET_LDT: + case I386_SET_LDT: + case I386_GET_IOPERM: + case I386_GET_FSBASE: + case I386_SET_FSBASE: + case I386_GET_GSBASE: + case I386_SET_GSBASE: + case I386_GET_XFPUSTATE: + case I386_SET_PKRU: + case I386_CLEAR_PKRU: + case AMD64_GET_FSBASE: + case AMD64_SET_FSBASE: + case AMD64_GET_GSBASE: + case AMD64_SET_GSBASE: + case AMD64_GET_XFPUSTATE: + case AMD64_SET_PKRU: + case AMD64_CLEAR_PKRU: + break; - case I386_SET_IOPERM: - default: -#ifdef KTRACE - if (KTRPOINT(td, KTR_CAPFAIL)) - ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL); -#endif + case I386_SET_IOPERM: + default: + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_SYSCALL, &uap->op); + if (IN_CAPABILITY_MODE(td)) return (ECAPMODE); - } + break; } #endif diff --git a/sys/arm/allwinner/a10_codec.c b/sys/arm/allwinner/a10_codec.c index 05fb25d9b02d..036de684b788 100644 --- a/sys/arm/allwinner/a10_codec.c +++ b/sys/arm/allwinner/a10_codec.c @@ -41,7 +41,6 @@ #include <machine/bus.h> #include <dev/sound/pcm/sound.h> -#include <dev/sound/chip.h> #include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus_subr.h> diff --git a/sys/arm/arm/sys_machdep.c b/sys/arm/arm/sys_machdep.c index 208026db85ba..d167c757952b 100644 --- a/sys/arm/arm/sys_machdep.c +++ b/sys/arm/arm/sys_machdep.c @@ -177,22 +177,19 @@ sysarch(struct thread *td, struct sysarch_args *uap) * explicitly indicate whether or not the operation is safe to * perform in capability mode. */ - if (IN_CAPABILITY_MODE(td)) { - switch (uap->op) { - case ARM_SYNC_ICACHE: - case ARM_DRAIN_WRITEBUF: - case ARM_SET_TP: - case ARM_GET_TP: - case ARM_GET_VFPSTATE: - break; - - default: -#ifdef KTRACE - if (KTRPOINT(td, KTR_CAPFAIL)) - ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL); -#endif + switch (uap->op) { + case ARM_SYNC_ICACHE: + case ARM_DRAIN_WRITEBUF: + case ARM_SET_TP: + case ARM_GET_TP: + case ARM_GET_VFPSTATE: + break; + + default: + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_SYSCALL, &uap->op); + if (IN_CAPABILITY_MODE(td)) return (ECAPMODE); - } } #endif diff --git a/sys/arm/broadcom/bcm2835/bcm2835_audio.c b/sys/arm/broadcom/bcm2835/bcm2835_audio.c index e0f525fa9520..75a0c81f29a1 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_audio.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_audio.c @@ -28,7 +28,6 @@ #endif #include <dev/sound/pcm/sound.h> -#include <dev/sound/chip.h> #include "mixer_if.h" diff --git a/sys/arm/freescale/imx/imx6_ssi.c b/sys/arm/freescale/imx/imx6_ssi.c index 931a2b677eae..6b23334a4e97 100644 --- a/sys/arm/freescale/imx/imx6_ssi.c +++ b/sys/arm/freescale/imx/imx6_ssi.c @@ -43,7 +43,6 @@ #include <sys/timetc.h> #include <dev/sound/pcm/sound.h> -#include <dev/sound/chip.h> #include <mixer_if.h> #include <dev/ofw/openfirm.h> diff --git a/sys/arm/freescale/vybrid/vf_sai.c b/sys/arm/freescale/vybrid/vf_sai.c index 5336dfc6dd57..3b3a120df4e1 100644 --- a/sys/arm/freescale/vybrid/vf_sai.c +++ b/sys/arm/freescale/vybrid/vf_sai.c @@ -44,7 +44,6 @@ #include <sys/watchdog.h> #include <dev/sound/pcm/sound.h> -#include <dev/sound/chip.h> #include <mixer_if.h> #include <dev/ofw/openfirm.h> diff --git a/sys/arm/include/armreg.h b/sys/arm/include/armreg.h index 8beef9b31022..819355111909 100644 --- a/sys/arm/include/armreg.h +++ b/sys/arm/include/armreg.h @@ -41,8 +41,6 @@ #ifndef MACHINE_ARMREG_H #define MACHINE_ARMREG_H -#define INSN_SIZE 4 -#define INSN_COND_MASK 0xf0000000 /* Condition mask */ #define PSR_MODE 0x0000001f /* mode mask */ #define PSR_USR32_MODE 0x00000010 #define PSR_FIQ32_MODE 0x00000011 diff --git a/sys/compat/linuxkpi/common/include/asm/set_memory.h b/sys/compat/linuxkpi/common/include/asm/set_memory.h index 69f659001c60..1019aaf264a0 100644 --- a/sys/compat/linuxkpi/common/include/asm/set_memory.h +++ b/sys/compat/linuxkpi/common/include/asm/set_memory.h @@ -34,26 +34,20 @@ static inline int set_memory_uc(unsigned long addr, int numpages) { - vm_offset_t va; vm_size_t len; - va = PHYS_TO_DMAP(addr); - len = numpages << PAGE_SHIFT; - - return (-pmap_change_attr(va, len, VM_MEMATTR_UNCACHEABLE)); + len = (vm_size_t)numpages << PAGE_SHIFT; + return (-pmap_change_attr(addr, len, VM_MEMATTR_UNCACHEABLE)); } static inline int set_memory_wc(unsigned long addr, int numpages) { #ifdef VM_MEMATTR_WRITE_COMBINING - vm_offset_t va; vm_size_t len; - va = PHYS_TO_DMAP(addr); - len = numpages << PAGE_SHIFT; - - return (-pmap_change_attr(va, len, VM_MEMATTR_WRITE_COMBINING)); + len = (vm_size_t)numpages << PAGE_SHIFT; + return (-pmap_change_attr(addr, len, VM_MEMATTR_WRITE_COMBINING)); #else return (set_memory_uc(addr, numpages)); #endif @@ -62,13 +56,10 @@ set_memory_wc(unsigned long addr, int numpages) static inline int set_memory_wb(unsigned long addr, int numpages) { - vm_offset_t va; vm_size_t len; - va = PHYS_TO_DMAP(addr); - len = numpages << PAGE_SHIFT; - - return (-pmap_change_attr(va, len, VM_MEMATTR_WRITE_BACK)); + len = (vm_size_t)numpages << PAGE_SHIFT; + return (-pmap_change_attr(addr, len, VM_MEMATTR_WRITE_BACK)); } static inline int diff --git a/sys/compat/linuxkpi/common/include/linux/io.h b/sys/compat/linuxkpi/common/include/linux/io.h index bce70ed0cb8d..164347dbc4e7 100644 --- a/sys/compat/linuxkpi/common/include/linux/io.h +++ b/sys/compat/linuxkpi/common/include/linux/io.h @@ -541,30 +541,29 @@ void lkpi_arch_phys_wc_del(int); #define arch_phys_wc_index(x) \ (((x) < __MTRR_ID_BASE) ? -1 : ((x) - __MTRR_ID_BASE)) -#if defined(__amd64__) || defined(__i386__) || defined(__aarch64__) || defined(__powerpc__) || defined(__riscv) static inline int arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size) { +#if defined(__amd64__) vm_offset_t va; va = PHYS_TO_DMAP(start); - -#ifdef VM_MEMATTR_WRITE_COMBINING return (-pmap_change_attr(va, size, VM_MEMATTR_WRITE_COMBINING)); #else - return (-pmap_change_attr(va, size, VM_MEMATTR_UNCACHEABLE)); + return (0); #endif } static inline void arch_io_free_memtype_wc(resource_size_t start, resource_size_t size) { +#if defined(__amd64__) vm_offset_t va; va = PHYS_TO_DMAP(start); pmap_change_attr(va, size, VM_MEMATTR_WRITE_BACK); -} #endif +} #endif /* _LINUXKPI_LINUX_IO_H_ */ diff --git a/sys/conf/files b/sys/conf/files index c4e9f0698c4f..7d3c44893e09 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3060,7 +3060,6 @@ dev/smc/if_smc.c optional smc dev/smc/if_smc_acpi.c optional smc acpi dev/smc/if_smc_fdt.c optional smc fdt dev/snp/snp.c optional snp -dev/sound/unit.c optional sound dev/sound/pci/als4000.c optional snd_als4000 pci dev/sound/pci/atiixp.c optional snd_atiixp pci dev/sound/pci/cmi.c optional snd_cmi pci diff --git a/sys/dev/etherswitch/ip17x/ip17x.c b/sys/dev/etherswitch/ip17x/ip17x.c index 218c0c293662..65e548ba293b 100644 --- a/sys/dev/etherswitch/ip17x/ip17x.c +++ b/sys/dev/etherswitch/ip17x/ip17x.c @@ -556,7 +556,7 @@ ip17x_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr) static int ip17x_readreg(device_t dev, int addr) { - struct ip17x_softc *sc; + struct ip17x_softc *sc __diagused; sc = device_get_softc(dev); IP17X_LOCK_ASSERT(sc, MA_OWNED); @@ -568,7 +568,7 @@ ip17x_readreg(device_t dev, int addr) static int ip17x_writereg(device_t dev, int addr, int value) { - struct ip17x_softc *sc; + struct ip17x_softc *sc __diagused; sc = device_get_softc(dev); IP17X_LOCK_ASSERT(sc, MA_OWNED); diff --git a/sys/dev/etherswitch/ukswitch/ukswitch.c b/sys/dev/etherswitch/ukswitch/ukswitch.c index 6eff37bb118e..88726422bd01 100644 --- a/sys/dev/etherswitch/ukswitch/ukswitch.c +++ b/sys/dev/etherswitch/ukswitch/ukswitch.c @@ -514,7 +514,7 @@ ukswitch_writephy(device_t dev, int phy, int reg, int data) static int ukswitch_readreg(device_t dev, int addr) { - struct ukswitch_softc *sc; + struct ukswitch_softc *sc __diagused; sc = device_get_softc(dev); UKSWITCH_LOCK_ASSERT(sc, MA_OWNED); @@ -526,7 +526,7 @@ ukswitch_readreg(device_t dev, int addr) static int ukswitch_writereg(device_t dev, int addr, int value) { - struct ukswitch_softc *sc; + struct ukswitch_softc *sc __diagused; sc = device_get_softc(dev); UKSWITCH_LOCK_ASSERT(sc, MA_OWNED); diff --git a/sys/dev/iicbus/if_ic.c b/sys/dev/iicbus/if_ic.c index 4ca8f3960298..52ab5afb9c4e 100644 --- a/sys/dev/iicbus/if_ic.c +++ b/sys/dev/iicbus/if_ic.c @@ -363,8 +363,8 @@ icoutput(if_t ifp, struct mbuf *m, const struct sockaddr *dst, u_char *cp; u_int32_t hdr; - /* BPF writes need to be handled specially. */ - if (dst->sa_family == AF_UNSPEC) + /* BPF writes need to be handled specially. */ + if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT) bcopy(dst->sa_data, &hdr, sizeof(hdr)); else hdr = RO_GET_FAMILY(ro, dst); diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c index e1dbd02fcf3a..962705e6d258 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c @@ -3674,6 +3674,9 @@ out: /* Check if module is present before doing an access */ module_status = mlx5_query_module_status(priv->mdev, module_num); if (module_status != MLX5_MODULE_STATUS_PLUGGED_ENABLED) { + mlx5_en_err(ifp, + "Query module %d status: not plugged (%d), eeprom reading is not supported\n", + module_num, module_status); error = EINVAL; goto err_i2c; } diff --git a/sys/dev/sound/chip.h b/sys/dev/sound/chip.h deleted file mode 100644 index bb40d2809a00..000000000000 --- a/sys/dev/sound/chip.h +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 1999 Seigo Tanimura - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * These are the function codes assigned to the children of - * sound cards. - */ -enum { - SCF_PCM, - SCF_MIDI, - SCF_SYNTH, -}; - -/* - * This is the device information struct, used by - * a bridge device to pass the device function code - * to the children. - */ -struct sndcard_func { - int func; /* The function code. */ - void *varinfo; /* Bridge-specific information. */ -}; diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c index dcbf041f9605..eeb28bb08276 100644 --- a/sys/dev/sound/pci/atiixp.c +++ b/sys/dev/sound/pci/atiixp.c @@ -1168,12 +1168,12 @@ atiixp_release_resource(struct atiixp_info *sc) static int atiixp_pci_probe(device_t dev) { - int i; + size_t i; uint16_t devid, vendor; vendor = pci_get_vendor(dev); devid = pci_get_device(dev); - for (i = 0; i < sizeof(atiixp_hw) / sizeof(atiixp_hw[0]); i++) { + for (i = 0; i < nitems(atiixp_hw); i++) { if (vendor == atiixp_hw[i].vendor && devid == atiixp_hw[i].devid) { device_set_desc(dev, atiixp_hw[i].desc); diff --git a/sys/dev/sound/pci/csa.c b/sys/dev/sound/pci/csa.c index 7bb7967b74e7..662f0de80188 100644 --- a/sys/dev/sound/pci/csa.c +++ b/sys/dev/sound/pci/csa.c @@ -45,7 +45,6 @@ #endif #include <dev/sound/pcm/sound.h> -#include <dev/sound/chip.h> #include <dev/sound/pci/csareg.h> #include <dev/sound/pci/csavar.h> diff --git a/sys/dev/sound/pci/csamidi.c b/sys/dev/sound/pci/csamidi.c index df1699092990..29d5548b0954 100644 --- a/sys/dev/sound/pci/csamidi.c +++ b/sys/dev/sound/pci/csamidi.c @@ -43,7 +43,6 @@ #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> -#include <dev/sound/chip.h> #include <dev/sound/pcm/sound.h> #include <dev/sound/midi/midi.h> diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c index 71b9a0253cdb..c8424dd3e433 100644 --- a/sys/dev/sound/pci/csapcm.c +++ b/sys/dev/sound/pci/csapcm.c @@ -36,7 +36,6 @@ #include <dev/sound/pcm/sound.h> #include <dev/sound/pcm/ac97.h> -#include <dev/sound/chip.h> #include <dev/sound/pci/csareg.h> #include <dev/sound/pci/csavar.h> diff --git a/sys/dev/sound/pci/emu10kx-midi.c b/sys/dev/sound/pci/emu10kx-midi.c index 4ed8e6c1dd9c..2a98562f8f39 100644 --- a/sys/dev/sound/pci/emu10kx-midi.c +++ b/sys/dev/sound/pci/emu10kx-midi.c @@ -43,7 +43,6 @@ #include "opt_snd.h" #endif -#include <dev/sound/chip.h> #include <dev/sound/pcm/sound.h> #include <dev/sound/midi/midi.h> diff --git a/sys/dev/sound/pci/emu10kx-pcm.c b/sys/dev/sound/pci/emu10kx-pcm.c index 825a39fc4e63..bef6b596646e 100644 --- a/sys/dev/sound/pci/emu10kx-pcm.c +++ b/sys/dev/sound/pci/emu10kx-pcm.c @@ -43,7 +43,6 @@ #include "opt_snd.h" #endif -#include <dev/sound/chip.h> #include <dev/sound/pcm/sound.h> #include <dev/sound/pcm/ac97.h> diff --git a/sys/dev/sound/pci/emu10kx.c b/sys/dev/sound/pci/emu10kx.c index 6bbbfcc1df0e..0f938597e06c 100644 --- a/sys/dev/sound/pci/emu10kx.c +++ b/sys/dev/sound/pci/emu10kx.c @@ -49,7 +49,6 @@ #include "opt_snd.h" #endif -#include <dev/sound/chip.h> #include <dev/sound/pcm/sound.h> #include <dev/sound/pcm/ac97.h> @@ -2313,7 +2312,7 @@ emu10kx_dev_init(struct emu_sc_info *sc) mtx_init(&sc->emu10kx_lock, device_get_nameunit(sc->dev), "kxdevlock", 0); unit = device_get_unit(sc->dev); - sc->cdev = make_dev(&emu10kx_cdevsw, PCMMINOR(unit), UID_ROOT, GID_WHEEL, 0640, "emu10kx%d", unit); + sc->cdev = make_dev(&emu10kx_cdevsw, unit, UID_ROOT, GID_WHEEL, 0640, "emu10kx%d", unit); if (sc->cdev != NULL) { sc->cdev->si_drv1 = sc; return (0); diff --git a/sys/dev/sound/pci/hda/hdaa.c b/sys/dev/sound/pci/hda/hdaa.c index dcd10cb36510..e8d9ee12fffc 100644 --- a/sys/dev/sound/pci/hda/hdaa.c +++ b/sys/dev/sound/pci/hda/hdaa.c @@ -267,7 +267,8 @@ hdaa_channels_handler(struct hdaa_audio_as *as) struct hdaa_chan *ch = &devinfo->chans[as->chans[0]]; struct hdaa_widget *w; uint8_t *eld; - int i, total, sub, assume, channels; + int total, sub, assume, channels; + size_t i; uint16_t cpins, upins, tpins; cpins = upins = 0; @@ -347,7 +348,7 @@ hdaa_channels_handler(struct hdaa_audio_as *as) printf("\n"); ); /* Look for maximal fitting matrix. */ - for (i = 0; i < sizeof(matrixes) / sizeof(struct matrix); i++) { + for (i = 0; i < nitems(matrixes); i++) { if (as->pinset != 0 && matrixes[i].analog == 0) continue; if ((matrixes[i].m.mask & ~channels) == 0) { @@ -1252,7 +1253,8 @@ hdaa_sysctl_config(SYSCTL_HANDLER_ARGS) static void hdaa_config_fetch(const char *str, uint32_t *on, uint32_t *off) { - int i = 0, j, k, len, inv; + size_t k; + int i = 0, j, len, inv; for (;;) { while (str[i] != '\0' && @@ -1292,7 +1294,8 @@ static int hdaa_sysctl_quirks(SYSCTL_HANDLER_ARGS) { char buf[256]; - int error, n = 0, i; + int error, n = 0; + size_t i; uint32_t quirks, quirks_off; quirks = *(uint32_t *)oidp->oid_arg1; diff --git a/sys/dev/sound/pci/hda/hdaa_patches.c b/sys/dev/sound/pci/hda/hdaa_patches.c index 3a7dfc63637a..9f3532562252 100644 --- a/sys/dev/sound/pci/hda/hdaa_patches.c +++ b/sys/dev/sound/pci/hda/hdaa_patches.c @@ -318,7 +318,8 @@ hdac_pin_patch(struct hdaa_widget *w) } } else if (id == HDA_CODEC_ALC257 && (subid == LENOVO_L5AMD_SUBVENDOR || - subid == LENOVO_L5INTEL_SUBVENDOR)) { + subid == LENOVO_L5INTEL_SUBVENDOR || + subid == LENOVO_IDEAPAD3_SUBVENDOR)) { switch (nid) { case 20: patch_str = "as=1 seq=0"; @@ -339,7 +340,7 @@ hdac_pin_patch(struct hdaa_widget *w) break; } } else if (id == HDA_CODEC_ALC230 && - subid == LENOVO_I330_SUBVENDOR) { + subid == LENOVO_IDEAPAD330_SUBVENDOR) { switch (nid) { case 20: patch_str = "as=1 seq=0 device=Speaker"; diff --git a/sys/dev/sound/pci/hda/hdac.h b/sys/dev/sound/pci/hda/hdac.h index 4dd589ed2a09..6a3314280a22 100644 --- a/sys/dev/sound/pci/hda/hdac.h +++ b/sys/dev/sound/pci/hda/hdac.h @@ -382,7 +382,8 @@ #define LENOVO_L5AMD_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x381b) #define LENOVO_L5INTEL_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x380f) #define LENOVO_3000_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x384e) -#define LENOVO_I330_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3808) +#define LENOVO_IDEAPAD330_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3808) +#define LENOVO_IDEAPAD3_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0x3881) #define LENOVO_ALL_SUBVENDOR HDA_MODEL_CONSTRUCT(LENOVO, 0xffff) /* Samsung */ diff --git a/sys/dev/sound/pci/hdspe-pcm.c b/sys/dev/sound/pci/hdspe-pcm.c index db39b867879f..4bea6c65e087 100644 --- a/sys/dev/sound/pci/hdspe-pcm.c +++ b/sys/dev/sound/pci/hdspe-pcm.c @@ -34,7 +34,6 @@ #include <dev/sound/pcm/sound.h> #include <dev/sound/pci/hdspe.h> -#include <dev/sound/chip.h> #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> diff --git a/sys/dev/sound/pci/hdspe.c b/sys/dev/sound/pci/hdspe.c index e0197d1e981a..91d1f3ee1bf6 100644 --- a/sys/dev/sound/pci/hdspe.c +++ b/sys/dev/sound/pci/hdspe.c @@ -37,7 +37,6 @@ #include <dev/sound/pcm/sound.h> #include <dev/sound/pci/hdspe.h> -#include <dev/sound/chip.h> #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c index fbde0accfd28..910a371c6653 100644 --- a/sys/dev/sound/pci/ich.c +++ b/sys/dev/sound/pci/ich.c @@ -860,12 +860,12 @@ ich_init(struct sc_info *sc) static int ich_pci_probe(device_t dev) { - int i; + size_t i; uint16_t devid, vendor; vendor = pci_get_vendor(dev); devid = pci_get_device(dev); - for (i = 0; i < sizeof(ich_devs)/sizeof(ich_devs[0]); i++) { + for (i = 0; i < nitems(ich_devs); i++) { if (vendor == ich_devs[i].vendor && devid == ich_devs[i].devid) { device_set_desc(dev, ich_devs[i].name); diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c index 6dd54a66f683..4d6dca310eea 100644 --- a/sys/dev/sound/pci/maestro3.c +++ b/sys/dev/sound/pci/maestro3.c @@ -488,7 +488,7 @@ m3_pchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel DMAC_BLOCKF_SELECTOR); /* set an armload of static initializers */ - for(i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) { + for(i = 0 ; i < nitems(pv); i++) { m3_wr_assp_data(sc, ch->dac_data + pv[i].addr, pv[i].val); } @@ -862,7 +862,7 @@ m3_rchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR); /* set an armload of static initializers */ - for(i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) { + for(i = 0 ; i < nitems(rv); i++) { m3_wr_assp_data(sc, ch->adc_data + rv[i].addr, rv[i].val); } diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c index bee79e723696..82eabf3a4884 100644 --- a/sys/dev/sound/pci/solo.c +++ b/sys/dev/sound/pci/solo.c @@ -35,7 +35,6 @@ #include <dev/pci/pcivar.h> #include <dev/sound/isa/sb.h> -#include <dev/sound/chip.h> #include "mixer_if.h" diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index 1527d5ea3d2c..846885b9d729 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -1157,17 +1157,105 @@ chn_reset(struct pcm_channel *c, uint32_t fmt, uint32_t spd) return r; } -int -chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) +struct pcm_channel * +chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, + int dir, void *devinfo) { + struct pcm_channel *c; struct feeder_class *fc; struct snd_dbuf *b, *bs; - int i, ret; + char *dirs, *devname, buf[CHN_NAMELEN]; + int i, ret, direction, rpnum, *pnum, max, type, unit; - if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX) - chn_timeout = CHN_TIMEOUT; + PCM_BUSYASSERT(d); + PCM_LOCKASSERT(d); + switch (dir) { + case PCMDIR_PLAY: + dirs = "play"; + direction = PCMDIR_PLAY; + pnum = &d->playcount; + type = SND_DEV_DSPHW_PLAY; + max = SND_MAXHWCHAN; + break; + case PCMDIR_PLAY_VIRTUAL: + dirs = "virtual_play"; + direction = PCMDIR_PLAY; + pnum = &d->pvchancount; + type = SND_DEV_DSPHW_VPLAY; + max = SND_MAXVCHANS; + break; + case PCMDIR_REC: + dirs = "record"; + direction = PCMDIR_REC; + pnum = &d->reccount; + type = SND_DEV_DSPHW_REC; + max = SND_MAXHWCHAN; + break; + case PCMDIR_REC_VIRTUAL: + dirs = "virtual_record"; + direction = PCMDIR_REC; + pnum = &d->rvchancount; + type = SND_DEV_DSPHW_VREC; + max = SND_MAXVCHANS; + break; + default: + device_printf(d->dev, + "%s(): invalid channel direction: %d\n", + __func__, dir); + goto out1; + } + + unit = 0; + + if (*pnum >= max || unit >= max) { + device_printf(d->dev, "%s(): unit=%d or pnum=%d >= than " + "max=%d\n", __func__, unit, *pnum, max); + goto out1; + } + + rpnum = 0; + + CHN_FOREACH(c, d, channels.pcm) { + if (c->type != type) + continue; + unit++; + if (unit >= max) { + device_printf(d->dev, + "%s(): chan=%d >= max=%d\n", __func__, unit, max); + goto out1; + } + rpnum++; + } + + if (*pnum != rpnum) { + device_printf(d->dev, + "%s(): pnum screwed: dirs=%s pnum=%d rpnum=%d\n", + __func__, dirs, *pnum, rpnum); + goto out1; + } + + PCM_UNLOCK(d); + c = malloc(sizeof(*c), M_DEVBUF, M_WAITOK | M_ZERO); + c->methods = kobj_create(cls, M_DEVBUF, M_WAITOK | M_ZERO); + c->type = type; + c->unit = unit; + c->pid = -1; + strlcpy(c->comm, CHN_COMM_UNUSED, sizeof(c->comm)); + c->parentsnddev = d; + c->parentchannel = parent; + c->dev = d->dev; + c->trigger = PCMTRIG_STOP; chn_lockinit(c, dir); + devname = dsp_unit2name(buf, sizeof(buf), c); + if (devname == NULL) { + ret = EINVAL; + device_printf(d->dev, "%s(): failed to create channel name", + __func__); + goto out2; + } + snprintf(c->name, sizeof(c->name), "%s:%s:%s", + device_get_nameunit(c->dev), dirs, devname); b = NULL; bs = NULL; @@ -1180,20 +1268,31 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) ret = ENOMEM; b = sndbuf_create(c->dev, c->name, "primary", c); - if (b == NULL) - goto out; + if (b == NULL) { + device_printf(d->dev, "%s(): failed to create hardware buffer\n", + __func__); + goto out2; + } bs = sndbuf_create(c->dev, c->name, "secondary", c); - if (bs == NULL) - goto out; + if (bs == NULL) { + device_printf(d->dev, "%s(): failed to create software buffer\n", + __func__); + goto out2; + } CHN_LOCK(c); ret = EINVAL; fc = feeder_getclass(NULL); - if (fc == NULL) - goto out; - if (chn_addfeeder(c, fc, NULL)) - goto out; + if (fc == NULL) { + device_printf(d->dev, "%s(): failed to get feeder class\n", + __func__); + goto out2; + } + if (chn_addfeeder(c, fc, NULL)) { + device_printf(d->dev, "%s(): failed to add feeder\n", __func__); + goto out2; + } /* * XXX - sndbuf_setup() & sndbuf_resize() expect to be called @@ -1229,12 +1328,17 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) CHN_UNLOCK(c); /* XXX - Unlock for CHANNEL_INIT() malloc() call */ c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction); CHN_LOCK(c); - if (c->devinfo == NULL) - goto out; + if (c->devinfo == NULL) { + device_printf(d->dev, "%s(): NULL devinfo\n", __func__); + goto out2; + } ret = ENOMEM; - if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0)) - goto out; + if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0)) { + device_printf(d->dev, "%s(): hardware buffer's size is 0\n", + __func__); + goto out2; + } ret = 0; c->direction = direction; @@ -1254,12 +1358,14 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_NOWAIT); if (bs->shadbuf == NULL) { ret = ENOMEM; - goto out; + device_printf(d->dev, "%s(): failed to create shadow " + "buffer\n", __func__); + goto out2; } } - -out: - CHN_UNLOCK(c); +out2: + if (CHN_LOCKOWNED(c)) + CHN_UNLOCK(c); if (ret) { if (c->devinfo) { if (CHANNEL_FREE(c->methods, c->devinfo)) @@ -1273,17 +1379,28 @@ out: c->flags |= CHN_F_DEAD; chn_lockdestroy(c); - return ret; + PCM_LOCK(d); + + kobj_delete(c->methods, M_DEVBUF); + free(c, M_DEVBUF); + + return (NULL); } - return 0; + PCM_LOCK(d); + + return (c); +out1: + return (NULL); } -int +void chn_kill(struct pcm_channel *c) { - struct snd_dbuf *b = c->bufhard; - struct snd_dbuf *bs = c->bufsoft; + struct snd_dbuf *b = c->bufhard; + struct snd_dbuf *bs = c->bufsoft; + + PCM_BUSYASSERT(c->parentsnddev); if (CHN_STARTED(c)) { CHN_LOCK(c); @@ -1299,8 +1416,8 @@ chn_kill(struct pcm_channel *c) CHN_LOCK(c); c->flags |= CHN_F_DEAD; chn_lockdestroy(c); - - return (0); + kobj_delete(c->methods, M_DEVBUF); + free(c, M_DEVBUF); } void @@ -1312,6 +1429,34 @@ chn_shutdown(struct pcm_channel *c) c->flags |= CHN_F_DEAD; } +/* release a locked channel and unlock it */ +int +chn_release(struct pcm_channel *c) +{ + PCM_BUSYASSERT(c->parentsnddev); + CHN_LOCKASSERT(c); + + c->flags &= ~CHN_F_BUSY; + c->pid = -1; + strlcpy(c->comm, CHN_COMM_UNUSED, sizeof(c->comm)); + CHN_UNLOCK(c); + + return (0); +} + +int +chn_ref(struct pcm_channel *c, int ref) +{ + PCM_BUSYASSERT(c->parentsnddev); + CHN_LOCKASSERT(c); + KASSERT((c->refcount + ref) >= 0, + ("%s(): new refcount will be negative", __func__)); + + c->refcount += ref; + + return (c->refcount); +} + int chn_setvolume_multi(struct pcm_channel *c, int vc, int left, int right, int center) diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h index c8d33c583188..445882a62f0a 100644 --- a/sys/dev/sound/pcm/channel.h +++ b/sys/dev/sound/pcm/channel.h @@ -104,6 +104,7 @@ struct pcm_channel { void *devinfo; device_t dev; int unit; + int type; char name[CHN_NAMELEN]; char comm[MAXCOMLEN + 1]; struct mtx *lock; @@ -224,7 +225,7 @@ struct pcm_channel { #define CHN_INSERT_SORT(w, x, y, z) do { \ struct pcm_channel *t, *a = NULL; \ CHN_FOREACH(t, x, z) { \ - if ((y)->unit w t->unit) \ + if ((y)->type w t->type) \ a = t; \ else \ break; \ @@ -235,13 +236,9 @@ struct pcm_channel { CHN_INSERT_HEAD(x, y, z); \ } while (0) -#define CHN_INSERT_SORT_ASCEND(x, y, z) CHN_INSERT_SORT(>, x, y, z) +#define CHN_INSERT_SORT_ASCEND(x, y, z) CHN_INSERT_SORT(>=, x, y, z) #define CHN_INSERT_SORT_DESCEND(x, y, z) CHN_INSERT_SORT(<, x, y, z) -#define CHN_UNIT(x) (snd_unit2u((x)->unit)) -#define CHN_DEV(x) (snd_unit2d((x)->unit)) -#define CHN_CHAN(x) (snd_unit2c((x)->unit)) - #define CHN_BUF_PARENT(x, y) \ (((x) != NULL && (x)->parentchannel != NULL && \ (x)->parentchannel->bufhard != NULL) ? \ @@ -262,9 +259,12 @@ int chn_sync(struct pcm_channel *c, int threshold); int chn_flush(struct pcm_channel *c); int chn_poll(struct pcm_channel *c, int ev, struct thread *td); -int chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction); -int chn_kill(struct pcm_channel *c); +struct pcm_channel *chn_init(struct snddev_info *d, struct pcm_channel *parent, + kobj_class_t cls, int dir, void *devinfo); +void chn_kill(struct pcm_channel *c); void chn_shutdown(struct pcm_channel *c); +int chn_release(struct pcm_channel *c); +int chn_ref(struct pcm_channel *c, int ref); int chn_reset(struct pcm_channel *c, u_int32_t fmt, u_int32_t spd); int chn_setvolume_multi(struct pcm_channel *c, int vc, int left, int right, int center); diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index aa6c21f36601..6e5fad048d40 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -181,8 +181,8 @@ getchns(struct dsp_cdevpriv *priv, uint32_t prio) pcm_setflags(d->dev, flags); if (ch != NULL) { CHN_LOCK(ch); - pcm_chnref(ch, -1); - pcm_chnrelease(ch); + chn_ref(ch, -1); + chn_release(ch); } PCM_RELEASE(d); PCM_UNLOCK(d); @@ -203,13 +203,6 @@ relchns(struct dsp_cdevpriv *priv, uint32_t prio) CHN_UNLOCK(priv->wrch); } -/* duplex / simplex cdev type */ -enum { - DSP_CDEV_TYPE_RDONLY, /* simplex read-only (record) */ - DSP_CDEV_TYPE_WRONLY, /* simplex write-only (play) */ - DSP_CDEV_TYPE_RDWR /* duplex read, write, or both */ -}; - #define DSP_F_VALID(x) ((x) & (FREAD | FWRITE)) #define DSP_F_DUPLEX(x) (((x) & (FREAD | FWRITE)) == (FREAD | FWRITE)) #define DSP_F_SIMPLEX(x) (!DSP_F_DUPLEX(x)) @@ -221,48 +214,18 @@ static const struct { char *name; char *sep; char *alias; - int use_sep; - int hw; - int max; - int volctl; - uint32_t fmt, spd; - int query; } dsp_cdevs[] = { - { SND_DEV_DSP, "dsp", ".", NULL, 0, 0, 0, 0, - SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED, - DSP_CDEV_TYPE_RDWR }, - { SND_DEV_AUDIO, "audio", ".", NULL, 0, 0, 0, 0, - SND_FORMAT(AFMT_MU_LAW, 1, 0), DSP_DEFAULT_SPEED, - DSP_CDEV_TYPE_RDWR }, - { SND_DEV_DSP16, "dspW", ".", NULL, 0, 0, 0, 0, - SND_FORMAT(AFMT_S16_LE, 1, 0), DSP_DEFAULT_SPEED, - DSP_CDEV_TYPE_RDWR }, - { SND_DEV_DSPHW_PLAY, "dsp", ".p", NULL, 1, 1, SND_MAXHWCHAN, 1, - SND_FORMAT(AFMT_S16_LE, 2, 0), 48000, DSP_CDEV_TYPE_WRONLY }, - { SND_DEV_DSPHW_VPLAY, "dsp", ".vp", NULL, 1, 1, SND_MAXVCHANS, 1, - SND_FORMAT(AFMT_S16_LE, 2, 0), 48000, DSP_CDEV_TYPE_WRONLY }, - { SND_DEV_DSPHW_REC, "dsp", ".r", NULL, 1, 1, SND_MAXHWCHAN, 1, - SND_FORMAT(AFMT_S16_LE, 2, 0), 48000, DSP_CDEV_TYPE_RDONLY }, - { SND_DEV_DSPHW_VREC, "dsp", ".vr", NULL, 1, 1, SND_MAXVCHANS, 1, - SND_FORMAT(AFMT_S16_LE, 2, 0), 48000, DSP_CDEV_TYPE_RDONLY }, - { SND_DEV_DSPHW_CD, "dspcd", ".", NULL, 0, 0, 0, 0, - SND_FORMAT(AFMT_S16_LE, 2, 0), 44100, DSP_CDEV_TYPE_RDWR }, + { SND_DEV_DSP, "dsp", ".", NULL }, + { SND_DEV_DSPHW_PLAY, "dsp", ".p", NULL }, + { SND_DEV_DSPHW_VPLAY, "dsp", ".vp", NULL }, + { SND_DEV_DSPHW_REC, "dsp", ".r", NULL }, + { SND_DEV_DSPHW_VREC, "dsp", ".vr", NULL }, /* Low priority, OSSv4 aliases. */ - { SND_DEV_DSP, "dsp_ac3", ".", "dsp", 0, 0, 0, 0, - SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED, - DSP_CDEV_TYPE_RDWR }, - { SND_DEV_DSP, "dsp_mmap", ".", "dsp", 0, 0, 0, 0, - SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED, - DSP_CDEV_TYPE_RDWR }, - { SND_DEV_DSP, "dsp_multich", ".", "dsp", 0, 0, 0, 0, - SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED, - DSP_CDEV_TYPE_RDWR }, - { SND_DEV_DSP, "dsp_spdifout", ".", "dsp", 0, 0, 0, 0, - SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED, - DSP_CDEV_TYPE_RDWR }, - { SND_DEV_DSP, "dsp_spdifin", ".", "dsp", 0, 0, 0, 0, - SND_FORMAT(AFMT_U8, 1, 0), DSP_DEFAULT_SPEED, - DSP_CDEV_TYPE_RDWR }, + { SND_DEV_DSP, "dsp_ac3", ".", "dsp" }, + { SND_DEV_DSP, "dsp_mmap", ".", "dsp" }, + { SND_DEV_DSP, "dsp_multich", ".", "dsp" }, + { SND_DEV_DSP, "dsp_spdifout", ".", "dsp" }, + { SND_DEV_DSP, "dsp_spdifin", ".", "dsp" }, }; static void @@ -301,7 +264,7 @@ dsp_close(void *data) wdref--; else { CHN_LOCK(volch); - pcm_chnref(volch, -1); + chn_ref(volch, -1); CHN_UNLOCK(volch); } } @@ -332,12 +295,12 @@ dsp_close(void *data) free_unr(pcmsg_unrhdr, sg_ids); CHN_LOCK(rdch); - pcm_chnref(rdch, rdref); + chn_ref(rdch, rdref); chn_abort(rdch); /* won't sleep */ rdch->flags &= ~(CHN_F_RUNNING | CHN_F_MMAP | CHN_F_DEAD | CHN_F_EXCLUSIVE); chn_reset(rdch, 0, 0); - pcm_chnrelease(rdch); + chn_release(rdch); } if (wrch != NULL) { /* @@ -350,12 +313,12 @@ dsp_close(void *data) free_unr(pcmsg_unrhdr, sg_ids); CHN_LOCK(wrch); - pcm_chnref(wrch, wdref); + chn_ref(wrch, wdref); chn_flush(wrch); /* may sleep */ wrch->flags &= ~(CHN_F_RUNNING | CHN_F_MMAP | CHN_F_DEAD | CHN_F_EXCLUSIVE); chn_reset(wrch, 0, 0); - pcm_chnrelease(wrch); + chn_release(wrch); } PCM_LOCK(d); } @@ -444,14 +407,14 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) if (DSP_F_READ(flags)) { /* open for read */ rderror = pcm_chnalloc(d, &rdch, PCMDIR_REC, - td->td_proc->p_pid, td->td_proc->p_comm, -1); + td->td_proc->p_pid, td->td_proc->p_comm); if (rderror == 0 && chn_reset(rdch, fmt, spd) != 0) rderror = ENXIO; if (rderror != 0) { if (rdch != NULL) - pcm_chnrelease(rdch); + chn_release(rdch); if (!DSP_F_DUPLEX(flags)) { PCM_RELEASE_QUICK(d); PCM_GIANT_EXIT(d); @@ -463,7 +426,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) rdch->flags |= CHN_F_NBIO; if (flags & O_EXCL) rdch->flags |= CHN_F_EXCLUSIVE; - pcm_chnref(rdch, 1); + chn_ref(rdch, 1); chn_vpc_reset(rdch, SND_VOL_C_PCM, 0); CHN_UNLOCK(rdch); } @@ -472,14 +435,14 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) if (DSP_F_WRITE(flags)) { /* open for write */ wrerror = pcm_chnalloc(d, &wrch, PCMDIR_PLAY, - td->td_proc->p_pid, td->td_proc->p_comm, -1); + td->td_proc->p_pid, td->td_proc->p_comm); if (wrerror == 0 && chn_reset(wrch, fmt, spd) != 0) wrerror = ENXIO; if (wrerror != 0) { if (wrch != NULL) - pcm_chnrelease(wrch); + chn_release(wrch); if (!DSP_F_DUPLEX(flags)) { if (rdch != NULL) { /* @@ -487,8 +450,8 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) * created record channel */ CHN_LOCK(rdch); - pcm_chnref(rdch, -1); - pcm_chnrelease(rdch); + chn_ref(rdch, -1); + chn_release(rdch); } PCM_RELEASE_QUICK(d); PCM_GIANT_EXIT(d); @@ -500,7 +463,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) wrch->flags |= CHN_F_NBIO; if (flags & O_EXCL) wrch->flags |= CHN_F_EXCLUSIVE; - pcm_chnref(wrch, 1); + chn_ref(wrch, 1); chn_vpc_reset(wrch, SND_VOL_C_PCM, 0); CHN_UNLOCK(wrch); } @@ -630,68 +593,12 @@ dsp_write(struct cdev *i_dev, struct uio *buf, int flag) } static int -dsp_get_volume_channel(struct dsp_cdevpriv *priv, struct pcm_channel **volch) -{ - struct snddev_info *d; - struct pcm_channel *c; - int unit; - - KASSERT(volch != NULL, - ("%s(): NULL query priv=%p volch=%p", __func__, priv, volch)); - - d = priv->sc; - if (!PCM_REGISTERED(d)) { - *volch = NULL; - return (EINVAL); - } - - PCM_UNLOCKASSERT(d); - - *volch = NULL; - - c = priv->volch; - if (c != NULL) { - if (!(c->feederflags & (1 << FEEDER_VOLUME))) - return (-1); - *volch = c; - return (0); - } - - PCM_LOCK(d); - PCM_WAIT(d); - PCM_ACQUIRE(d); - - unit = dev2unit(d->dsp_dev); - - CHN_FOREACH(c, d, channels.pcm) { - CHN_LOCK(c); - if (c->unit != unit) { - CHN_UNLOCK(c); - continue; - } - *volch = c; - pcm_chnref(c, 1); - priv->volch = c; - CHN_UNLOCK(c); - PCM_RELEASE(d); - PCM_UNLOCK(d); - return ((c->feederflags & (1 << FEEDER_VOLUME)) ? 0 : -1); - } - - PCM_RELEASE(d); - PCM_UNLOCK(d); - - return (EINVAL); -} - -static int dsp_ioctl_channel(struct dsp_cdevpriv *priv, struct pcm_channel *volch, u_long cmd, caddr_t arg) { struct snddev_info *d; struct pcm_channel *rdch, *wrch; - int j, devtype, ret; - int left, right, center, mute; + int j, left, right, center, mute; d = priv->sc; if (!PCM_REGISTERED(d) || !(pcm_getflags(d->dev) & SD_F_VPC)) @@ -716,19 +623,6 @@ dsp_ioctl_channel(struct dsp_cdevpriv *priv, struct pcm_channel *volch, volch = wrch; } - devtype = PCMDEV(d->dsp_dev); - - /* Look super harder */ - if (volch == NULL && - (devtype == SND_DEV_DSPHW_PLAY || devtype == SND_DEV_DSPHW_VPLAY || - devtype == SND_DEV_DSPHW_REC || devtype == SND_DEV_DSPHW_VREC)) { - ret = dsp_get_volume_channel(priv, &volch); - if (ret != 0) - return (ret); - if (volch == NULL) - return (EINVAL); - } - /* Final validation */ if (volch == NULL) return (EINVAL); @@ -2072,7 +1966,7 @@ dsp_clone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev) { struct snddev_info *d; - int i; + size_t i; if (*dev != NULL) return; @@ -2105,8 +1999,6 @@ dsp_sysinit(void *p) { if (dsp_ehtag != NULL) return; - /* initialize unit numbering */ - snd_unit_init(); dsp_ehtag = EVENTHANDLER_REGISTER(dev_clone, dsp_clone, 0, 1000); } @@ -2123,20 +2015,19 @@ SYSINIT(dsp_sysinit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, dsp_sysinit, NULL); SYSUNINIT(dsp_sysuninit, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, dsp_sysuninit, NULL); char * -dsp_unit2name(char *buf, size_t len, int unit) +dsp_unit2name(char *buf, size_t len, struct pcm_channel *ch) { - int i, dtype; + size_t i; KASSERT(buf != NULL && len != 0, ("bogus buf=%p len=%ju", buf, (uintmax_t)len)); - dtype = snd_unit2d(unit); - for (i = 0; i < nitems(dsp_cdevs); i++) { - if (dtype != dsp_cdevs[i].type || dsp_cdevs[i].alias != NULL) + if (ch->type != dsp_cdevs[i].type || dsp_cdevs[i].alias != NULL) continue; - snprintf(buf, len, "%s%d%s%d", dsp_cdevs[i].name, - snd_unit2u(unit), dsp_cdevs[i].sep, snd_unit2c(unit)); + snprintf(buf, len, "%s%d%s%d", + dsp_cdevs[i].name, device_get_unit(ch->dev), + dsp_cdevs[i].sep, ch->unit); return (buf); } @@ -2185,7 +2076,7 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai) struct pcm_channel *ch; struct snddev_info *d; uint32_t fmts; - int i, nchan, *rates, minch, maxch; + int i, nchan, *rates, minch, maxch, unit; char *devname, buf[CHN_NAMELEN]; /* @@ -2205,9 +2096,9 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai) * Search for the requested audio device (channel). Start by * iterating over pcm devices. */ - for (i = 0; pcm_devclass != NULL && - i < devclass_get_maxunit(pcm_devclass); i++) { - d = devclass_get_softc(pcm_devclass, i); + for (unit = 0; pcm_devclass != NULL && + unit < devclass_get_maxunit(pcm_devclass); unit++) { + d = devclass_get_softc(pcm_devclass, unit); if (!PCM_REGISTERED(d)) continue; @@ -2224,12 +2115,10 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai) if (devfs_foreach_cdevpriv(i_dev, dsp_oss_audioinfo_cb, ch) != 0) { devname = dsp_unit2name(buf, - sizeof(buf), ch->unit); + sizeof(buf), ch); } - } else if (ai->dev == nchan) { - devname = dsp_unit2name(buf, sizeof(buf), - ch->unit); - } + } else if (ai->dev == nchan) + devname = dsp_unit2name(buf, sizeof(buf), ch); if (devname != NULL) break; CHN_UNLOCK(ch); @@ -2332,14 +2221,13 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai) * @todo @c port_number - routing information? */ ai->port_number = -1; - ai->mixer_dev = (d->mixer_dev != NULL) ? PCMUNIT(d->mixer_dev) : -1; + ai->mixer_dev = (d->mixer_dev != NULL) ? unit : -1; /** * @note - * @c real_device - OSSv4 docs: "Obsolete." + * @c legacy_device - OSSv4 docs: "Obsolete." */ - ai->real_device = -1; - snprintf(ai->devnode, sizeof(ai->devnode), - "/dev/dsp%d", device_get_unit(d->dev)); + ai->legacy_device = -1; + snprintf(ai->devnode, sizeof(ai->devnode), "/dev/dsp%d", unit); ai->enabled = device_is_attached(d->dev) ? 1 : 0; /** * @note diff --git a/sys/dev/sound/pcm/dsp.h b/sys/dev/sound/pcm/dsp.h index 6098c0641eb5..b81e60dc19b5 100644 --- a/sys/dev/sound/pcm/dsp.h +++ b/sys/dev/sound/pcm/dsp.h @@ -35,7 +35,7 @@ extern struct cdevsw dsp_cdevsw; int dsp_make_dev(device_t); void dsp_destroy_dev(device_t); -char *dsp_unit2name(char *, size_t, int); +char *dsp_unit2name(char *, size_t, struct pcm_channel *); int dsp_oss_audioinfo(struct cdev *, oss_audioinfo *); #endif /* !_PCMDSP_H_ */ diff --git a/sys/dev/sound/pcm/feeder.c b/sys/dev/sound/pcm/feeder.c index 8278a85948a8..0113299bd0d4 100644 --- a/sys/dev/sound/pcm/feeder.c +++ b/sys/dev/sound/pcm/feeder.c @@ -32,6 +32,7 @@ #endif #include <dev/sound/pcm/sound.h> +#include <dev/sound/pcm/vchan.h> #include "feeder_if.h" @@ -82,9 +83,7 @@ feeder_register(void *p) if (snd_verbose < 0 || snd_verbose > 4) snd_verbose = 1; - /* initialize unit numbering */ - snd_unit_init(); - if (snd_unit < 0 || snd_unit > PCMMAXUNIT) + if (snd_unit < 0) snd_unit = -1; if (snd_maxautovchans < 0 || diff --git a/sys/dev/sound/pcm/feeder_format.c b/sys/dev/sound/pcm/feeder_format.c index 1e18e3e07450..3bdd808df0ee 100644 --- a/sys/dev/sound/pcm/feeder_format.c +++ b/sys/dev/sound/pcm/feeder_format.c @@ -115,16 +115,13 @@ static const struct { } }; -#define FEEDFORMAT_TAB_SIZE \ - ((int32_t)(sizeof(feed_format_ops) / sizeof(feed_format_ops[0]))) - static int feed_format_init(struct pcm_feeder *f) { struct feed_format_info *info; intpcm_read_t *rd_op; intpcm_write_t *wr_op; - int i; + size_t i; if (f->desc->in == f->desc->out || AFMT_CHANNEL(f->desc->in) != AFMT_CHANNEL(f->desc->out)) @@ -133,7 +130,7 @@ feed_format_init(struct pcm_feeder *f) rd_op = NULL; wr_op = NULL; - for (i = 0; i < FEEDFORMAT_TAB_SIZE && + for (i = 0; i < nitems(feed_format_ops) && (rd_op == NULL || wr_op == NULL); i++) { if (rd_op == NULL && AFMT_ENCODING(f->desc->in) == feed_format_ops[i].format) @@ -276,9 +273,9 @@ FEEDER_DECLARE(feeder_format, NULL); intpcm_read_t * feeder_format_read_op(uint32_t format) { - int i; + size_t i; - for (i = 0; i < FEEDFORMAT_TAB_SIZE; i++) { + for (i = 0; i < nitems(feed_format_ops); i++) { if (AFMT_ENCODING(format) == feed_format_ops[i].format) return (feed_format_ops[i].read); } @@ -289,9 +286,9 @@ feeder_format_read_op(uint32_t format) intpcm_write_t * feeder_format_write_op(uint32_t format) { - int i; + size_t i; - for (i = 0; i < FEEDFORMAT_TAB_SIZE; i++) { + for (i = 0; i < nitems(feed_format_ops); i++) { if (AFMT_ENCODING(format) == feed_format_ops[i].format) return (feed_format_ops[i].write); } diff --git a/sys/dev/sound/pcm/feeder_matrix.c b/sys/dev/sound/pcm/feeder_matrix.c index f5f02e2bf4f5..97cf86585636 100644 --- a/sys/dev/sound/pcm/feeder_matrix.c +++ b/sys/dev/sound/pcm/feeder_matrix.c @@ -230,7 +230,7 @@ feed_matrix_reset(struct feed_matrix_info *info) { uint32_t i, j; - for (i = 0; i < (sizeof(info->matrix) / sizeof(info->matrix[0])); i++) { + for (i = 0; i < nitems(info->matrix); i++) { for (j = 0; j < (sizeof(info->matrix[i].chn) / sizeof(info->matrix[i].chn[0])); j++) { @@ -679,7 +679,7 @@ feeder_matrix_compare(struct pcmchan_matrix *m_in, struct pcmchan_matrix *m_out) m_in->mask != m_out->mask) return (1); - for (i = 0; i < (sizeof(m_in->map) / sizeof(m_in->map[0])); i++) { + for (i = 0; i < nitems(m_in->map); i++) { if (m_in->map[i].type != m_out->map[i].type) return (1); if (m_in->map[i].type == SND_CHN_T_MAX) diff --git a/sys/dev/sound/pcm/feeder_volume.c b/sys/dev/sound/pcm/feeder_volume.c index 452d8788a5a5..7e600c131afe 100644 --- a/sys/dev/sound/pcm/feeder_volume.c +++ b/sys/dev/sound/pcm/feeder_volume.c @@ -337,7 +337,7 @@ feeder_volume_apply_matrix(struct pcm_feeder *f, struct pcmchan_matrix *m) info = f->data; - for (i = 0; i < (sizeof(info->matrix) / sizeof(info->matrix[0])); i++) { + for (i = 0; i < nitems(info->matrix); i++) { if (i < m->channels) info->matrix[i] = m->map[i].type; else diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c index 0645089ac503..9811496853c8 100644 --- a/sys/dev/sound/pcm/mixer.c +++ b/sys/dev/sound/pcm/mixer.c @@ -650,7 +650,7 @@ mixer_obj_create(device_t dev, kobj_class_t cls, void *devinfo, int type, const char *desc) { struct snd_mixer *m; - int i; + size_t i; KASSERT(dev != NULL && cls != NULL && devinfo != NULL, ("%s(): NULL data dev=%p cls=%p devinfo=%p", @@ -671,7 +671,7 @@ mixer_obj_create(device_t dev, kobj_class_t cls, void *devinfo, m->devinfo = devinfo; m->busy = 0; m->dev = dev; - for (i = 0; i < (sizeof(m->parent) / sizeof(m->parent[0])); i++) { + for (i = 0; i < nitems(m->parent); i++) { m->parent[i] = SOUND_MIXER_NONE; m->child[i] = 0; m->realdev[i] = i; @@ -726,14 +726,17 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo) struct snd_mixer *m; u_int16_t v; struct cdev *pdev; - int i, unit, devunit, val; + const char *name; + int i, unit, val; snddev = device_get_softc(dev); if (snddev == NULL) return (-1); - if (resource_int_value(device_get_name(dev), - device_get_unit(dev), "eq", &val) == 0 && val != 0) { + name = device_get_name(dev); + unit = device_get_unit(dev); + if (resource_int_value(name, unit, "eq", &val) == 0 && + val != 0) { snddev->flags |= SD_F_EQ; if ((val & SD_F_EQ_MASK) == val) snddev->flags |= val; @@ -749,8 +752,8 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo) for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { v = snd_mixerdefaults[i]; - if (resource_int_value(device_get_name(dev), - device_get_unit(dev), snd_mixernames[i], &val) == 0) { + if (resource_int_value(name, unit, snd_mixernames[i], + &val) == 0) { if (val >= 0 && val <= 100) { v = (u_int16_t) val; } @@ -761,10 +764,8 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo) mixer_setrecsrc(m, 0); /* Set default input. */ - unit = device_get_unit(dev); - devunit = snd_mkunit(unit, SND_DEV_CTL, 0); - pdev = make_dev(&mixer_cdevsw, PCMMINOR(devunit), - UID_ROOT, GID_WHEEL, 0666, "mixer%d", unit); + pdev = make_dev(&mixer_cdevsw, SND_DEV_CTL, UID_ROOT, GID_WHEEL, 0666, + "mixer%d", unit); pdev->si_drv1 = m; snddev->mixer_dev = pdev; @@ -1430,7 +1431,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) { struct snddev_info *d; struct snd_mixer *m; - int nmix, i; + int i; /* * If probing the device handling the ioctl, make sure it's a mixer @@ -1441,7 +1442,6 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) d = NULL; m = NULL; - nmix = 0; /* * There's a 1:1 relationship between mixers and PCM devices, so @@ -1461,7 +1461,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) if (d->mixer_dev != NULL && d->mixer_dev->si_drv1 != NULL && ((mi->dev == -1 && d->mixer_dev == i_dev) || - mi->dev == nmix)) { + mi->dev == i)) { m = d->mixer_dev->si_drv1; mtx_lock(m->lock); @@ -1473,7 +1473,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) * sure to unlock when existing. */ bzero((void *)mi, sizeof(*mi)); - mi->dev = nmix; + mi->dev = i; snprintf(mi->id, sizeof(mi->id), "mixer%d", i); strlcpy(mi->name, m->name, sizeof(mi->name)); mi->modify_counter = m->modify_counter; @@ -1516,6 +1516,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) * Mixer extensions currently aren't supported, so * leave @sa oss_mixerinfo::nrext blank for now. */ + /** * @todo Fill in @sa oss_mixerinfo::priority (requires * touching drivers?) @@ -1529,16 +1530,13 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi) * default mixer. Other devices use values 1 to 9 * depending on the estimated probability of being the * default device. - * - * XXX Described by Hannu@4Front, but not found in - * soundcard.h. - strlcpy(mi->devnode, devtoname(d->mixer_dev), - sizeof(mi->devnode)); - mi->legacy_device = i; */ + + snprintf(mi->devnode, sizeof(mi->devnode), "/dev/mixer%d", i); + mi->legacy_device = i; + mtx_unlock(m->lock); - } else - ++nmix; + } PCM_UNLOCK(d); diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c index ef006a580d40..edb33e92ade9 100644 --- a/sys/dev/sound/pcm/sndstat.c +++ b/sys/dev/sound/pcm/sndstat.c @@ -51,7 +51,6 @@ #include <dev/sound/pcm/sound.h> #include <dev/sound/pcm/pcm.h> -#include <dev/sound/version.h> #include "feeder_if.h" @@ -1271,11 +1270,8 @@ sndstat_prepare(struct sndstat_file *pf_self) /* make sure buffer is reset */ sbuf_clear(s); - if (snd_verbose > 0) { - sbuf_printf(s, "FreeBSD Audio Driver (%ubit %d/%s)\n", - (u_int)sizeof(intpcm32_t) << 3, SND_DRV_VERSION, - MACHINE_ARCH); - } + if (snd_verbose > 0) + sbuf_printf(s, "FreeBSD Audio Driver\n"); /* generate list of installed devices */ k = 0; diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index 2057c7572ad6..e66462af2a71 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -41,7 +41,6 @@ #include <dev/sound/pcm/ac97.h> #include <dev/sound/pcm/vchan.h> #include <dev/sound/pcm/dsp.h> -#include <dev/sound/version.h> #include <sys/limits.h> #include <sys/sysctl.h> @@ -57,22 +56,11 @@ static int snd_unit_auto = -1; SYSCTL_INT(_hw_snd, OID_AUTO, default_auto, CTLFLAG_RWTUN, &snd_unit_auto, 0, "assign default unit to a newly attached device"); -int snd_maxautovchans = 16; - SYSCTL_NODE(_hw, OID_AUTO, snd, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "Sound driver"); static void pcm_sysinit(device_t); -/* - * XXX I've had enough with people not telling proper version/arch - * while reporting problems, not after 387397913213th questions/requests. - */ -static char snd_driver_version[] = - __XSTRING(SND_DRV_VERSION)"/"MACHINE_ARCH; -SYSCTL_STRING(_hw_snd, OID_AUTO, version, CTLFLAG_RD, &snd_driver_version, - 0, "driver version/arch"); - /** * @brief Unit number allocator for syncgroup IDs */ @@ -121,271 +109,71 @@ snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand return bus_setup_intr(dev, res, flags, NULL, hand, param, cookiep); } -int -pcm_setvchans(struct snddev_info *d, int direction, int newcnt, int num) -{ - struct pcm_channel *c, *ch, *nch; - struct pcmchan_caps *caps; - int i, err, vcnt; - - PCM_BUSYASSERT(d); - - if ((direction == PCMDIR_PLAY && d->playcount < 1) || - (direction == PCMDIR_REC && d->reccount < 1)) - return (ENODEV); - - if (!(d->flags & SD_F_AUTOVCHAN)) - return (EINVAL); - - if (newcnt < 0 || newcnt > SND_MAXVCHANS) - return (E2BIG); - - if (direction == PCMDIR_PLAY) - vcnt = d->pvchancount; - else if (direction == PCMDIR_REC) - vcnt = d->rvchancount; - else - return (EINVAL); - - if (newcnt > vcnt) { - KASSERT(num == -1 || - (num >= 0 && num < SND_MAXVCHANS && (newcnt - 1) == vcnt), - ("bogus vchan_create() request num=%d newcnt=%d vcnt=%d", - num, newcnt, vcnt)); - /* add new vchans - find a parent channel first */ - ch = NULL; - CHN_FOREACH(c, d, channels.pcm) { - CHN_LOCK(c); - if (c->direction == direction && - ((c->flags & CHN_F_HAS_VCHAN) || (vcnt == 0 && - c->refcount < 1 && - !(c->flags & (CHN_F_BUSY | CHN_F_VIRTUAL))))) { - /* - * Reuse hw channel with vchans already - * created. - */ - if (c->flags & CHN_F_HAS_VCHAN) { - ch = c; - break; - } - /* - * No vchans ever created, look for - * channels with supported formats. - */ - caps = chn_getcaps(c); - if (caps == NULL) { - CHN_UNLOCK(c); - continue; - } - for (i = 0; caps->fmtlist[i] != 0; i++) { - if (caps->fmtlist[i] & AFMT_CONVERTIBLE) - break; - } - if (caps->fmtlist[i] != 0) { - ch = c; - break; - } - } - CHN_UNLOCK(c); - } - if (ch == NULL) - return (EBUSY); - ch->flags |= CHN_F_BUSY; - err = 0; - while (err == 0 && newcnt > vcnt) { - err = vchan_create(ch, num); - if (err == 0) - vcnt++; - else if (err == E2BIG && newcnt > vcnt) - device_printf(d->dev, - "%s: err=%d Maximum channel reached.\n", - __func__, err); - } - if (vcnt == 0) - ch->flags &= ~CHN_F_BUSY; - CHN_UNLOCK(ch); - if (err != 0) - return (err); - } else if (newcnt < vcnt) { - KASSERT(num == -1, - ("bogus vchan_destroy() request num=%d", num)); - CHN_FOREACH(c, d, channels.pcm) { - CHN_LOCK(c); - if (c->direction != direction || - CHN_EMPTY(c, children) || - !(c->flags & CHN_F_HAS_VCHAN)) { - CHN_UNLOCK(c); - continue; - } - CHN_FOREACH_SAFE(ch, c, nch, children) { - CHN_LOCK(ch); - if (vcnt == 1 && c->refcount > 0) { - CHN_UNLOCK(ch); - break; - } - if (!(ch->flags & CHN_F_BUSY) && - ch->refcount < 1) { - err = vchan_destroy(ch); - if (err == 0) - vcnt--; - } else - CHN_UNLOCK(ch); - if (vcnt == newcnt) - break; - } - CHN_UNLOCK(c); - break; - } - } - - return (0); -} - /* return error status and a locked channel */ int pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction, - pid_t pid, char *comm, int devunit) + pid_t pid, char *comm) { struct pcm_channel *c; int err, vchancount, vchan_num; + bool retry; - KASSERT(d != NULL && ch != NULL && (devunit == -1 || - !(devunit & ~(SND_U_MASK | SND_D_MASK | SND_C_MASK))) && + KASSERT(d != NULL && ch != NULL && (direction == PCMDIR_PLAY || direction == PCMDIR_REC), - ("%s(): invalid d=%p ch=%p direction=%d pid=%d devunit=%d", - __func__, d, ch, direction, pid, devunit)); + ("%s(): invalid d=%p ch=%p direction=%d pid=%d", + __func__, d, ch, direction, pid)); PCM_BUSYASSERT(d); - /* Double check again. */ - if (devunit != -1) { - switch (snd_unit2d(devunit)) { - case SND_DEV_DSPHW_PLAY: - case SND_DEV_DSPHW_VPLAY: - if (direction != PCMDIR_PLAY) - return (ENOTSUP); - break; - case SND_DEV_DSPHW_REC: - case SND_DEV_DSPHW_VREC: - if (direction != PCMDIR_REC) - return (ENOTSUP); - break; - default: - if (!(direction == PCMDIR_PLAY || - direction == PCMDIR_REC)) - return (ENOTSUP); - break; - } - } - *ch = NULL; vchan_num = 0; vchancount = (direction == PCMDIR_PLAY) ? d->pvchancount : d->rvchancount; + retry = false; retry_chnalloc: err = ENOTSUP; /* scan for a free channel */ CHN_FOREACH(c, d, channels.pcm) { CHN_LOCK(c); - if (devunit == -1 && c->direction == direction && - (c->flags & CHN_F_VIRTUAL)) { + if (c->direction == direction && (c->flags & CHN_F_VIRTUAL)) { if (vchancount < snd_maxautovchans && - vchan_num < CHN_CHAN(c)) { + vchan_num < c->unit) { CHN_UNLOCK(c); goto vchan_alloc; } vchan_num++; } - if (c->direction == direction && !(c->flags & CHN_F_BUSY) && - (devunit == -1 || devunit == -2 || c->unit == devunit)) { + if (c->direction == direction && !(c->flags & CHN_F_BUSY)) { c->flags |= CHN_F_BUSY; c->pid = pid; strlcpy(c->comm, (comm != NULL) ? comm : CHN_COMM_UNKNOWN, sizeof(c->comm)); *ch = c; return (0); - } else if (c->unit == devunit) { - if (c->direction != direction) - err = ENOTSUP; - else if (c->flags & CHN_F_BUSY) - err = EBUSY; - else - err = EINVAL; - CHN_UNLOCK(c); - return (err); - } else if ((devunit == -1 || devunit == -2) && - c->direction == direction && (c->flags & CHN_F_BUSY)) + } else if (c->direction == direction && (c->flags & CHN_F_BUSY)) err = EBUSY; CHN_UNLOCK(c); } - if (devunit == -2) + /* + * We came from retry_chnalloc and still didn't find a free channel. + */ + if (retry) return (err); vchan_alloc: /* no channel available */ - if (devunit == -1 || snd_unit2d(devunit) == SND_DEV_DSPHW_VPLAY || - snd_unit2d(devunit) == SND_DEV_DSPHW_VREC) { - if (!(vchancount > 0 && vchancount < snd_maxautovchans) && - (devunit == -1 || snd_unit2c(devunit) < snd_maxautovchans)) - return (err); - err = pcm_setvchans(d, direction, vchancount + 1, - (devunit == -1) ? -1 : snd_unit2c(devunit)); - if (err == 0) { - if (devunit == -1) - devunit = -2; - goto retry_chnalloc; - } + if (!(vchancount > 0 && vchancount < snd_maxautovchans)) + return (err); + err = vchan_setnew(d, direction, vchancount + 1); + if (err == 0) { + retry = true; + goto retry_chnalloc; } return (err); } -/* release a locked channel and unlock it */ -int -pcm_chnrelease(struct pcm_channel *c) -{ - PCM_BUSYASSERT(c->parentsnddev); - CHN_LOCKASSERT(c); - - c->flags &= ~CHN_F_BUSY; - c->pid = -1; - strlcpy(c->comm, CHN_COMM_UNUSED, sizeof(c->comm)); - CHN_UNLOCK(c); - - return (0); -} - -int -pcm_chnref(struct pcm_channel *c, int ref) -{ - PCM_BUSYASSERT(c->parentsnddev); - CHN_LOCKASSERT(c); - - c->refcount += ref; - - return (c->refcount); -} - -static void -pcm_setmaxautovchans(struct snddev_info *d, int num) -{ - PCM_BUSYASSERT(d); - - if (num < 0) - return; - - if (num >= 0 && d->pvchancount > num) - (void)pcm_setvchans(d, PCMDIR_PLAY, num, -1); - else if (num > 0 && d->pvchancount == 0) - (void)pcm_setvchans(d, PCMDIR_PLAY, 1, -1); - - if (num >= 0 && d->rvchancount > num) - (void)pcm_setvchans(d, PCMDIR_REC, num, -1); - else if (num > 0 && d->rvchancount == 0) - (void)pcm_setvchans(d, PCMDIR_REC, 1, -1); -} - static int sysctl_hw_snd_default_unit(SYSCTL_HANDLER_ARGS) { @@ -409,173 +197,7 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, default_unit, sizeof(int), sysctl_hw_snd_default_unit, "I", "default sound device"); -static int -sysctl_hw_snd_maxautovchans(SYSCTL_HANDLER_ARGS) -{ - struct snddev_info *d; - int i, v, error; - - v = snd_maxautovchans; - error = sysctl_handle_int(oidp, &v, 0, req); - if (error == 0 && req->newptr != NULL) { - if (v < 0) - v = 0; - if (v > SND_MAXVCHANS) - v = SND_MAXVCHANS; - snd_maxautovchans = v; - for (i = 0; pcm_devclass != NULL && - i < devclass_get_maxunit(pcm_devclass); i++) { - d = devclass_get_softc(pcm_devclass, i); - if (!PCM_REGISTERED(d)) - continue; - PCM_ACQUIRE_QUICK(d); - pcm_setmaxautovchans(d, v); - PCM_RELEASE_QUICK(d); - } - } - return (error); -} -SYSCTL_PROC(_hw_snd, OID_AUTO, maxautovchans, - CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, 0, sizeof(int), - sysctl_hw_snd_maxautovchans, "I", - "maximum virtual channel"); - -struct pcm_channel * -pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, int num, void *devinfo) -{ - struct pcm_channel *ch; - int direction, err, rpnum, *pnum, max; - int udc, device, chan; - char *dirs, *devname, buf[CHN_NAMELEN]; - - PCM_BUSYASSERT(d); - PCM_LOCKASSERT(d); - KASSERT(num >= -1, ("invalid num=%d", num)); - - switch (dir) { - case PCMDIR_PLAY: - dirs = "play"; - direction = PCMDIR_PLAY; - pnum = &d->playcount; - device = SND_DEV_DSPHW_PLAY; - max = SND_MAXHWCHAN; - break; - case PCMDIR_PLAY_VIRTUAL: - dirs = "virtual"; - direction = PCMDIR_PLAY; - pnum = &d->pvchancount; - device = SND_DEV_DSPHW_VPLAY; - max = SND_MAXVCHANS; - break; - case PCMDIR_REC: - dirs = "record"; - direction = PCMDIR_REC; - pnum = &d->reccount; - device = SND_DEV_DSPHW_REC; - max = SND_MAXHWCHAN; - break; - case PCMDIR_REC_VIRTUAL: - dirs = "virtual"; - direction = PCMDIR_REC; - pnum = &d->rvchancount; - device = SND_DEV_DSPHW_VREC; - max = SND_MAXVCHANS; - break; - default: - return (NULL); - } - - chan = (num == -1) ? 0 : num; - - if (*pnum >= max || chan >= max) - return (NULL); - - rpnum = 0; - - CHN_FOREACH(ch, d, channels.pcm) { - if (CHN_DEV(ch) != device) - continue; - if (chan == CHN_CHAN(ch)) { - if (num != -1) { - device_printf(d->dev, - "channel num=%d allocated!\n", chan); - return (NULL); - } - chan++; - if (chan >= max) { - device_printf(d->dev, - "chan=%d > %d\n", chan, max); - return (NULL); - } - } - rpnum++; - } - - if (*pnum != rpnum) { - device_printf(d->dev, - "%s(): WARNING: pnum screwed : dirs=%s pnum=%d rpnum=%d\n", - __func__, dirs, *pnum, rpnum); - return (NULL); - } - - udc = snd_mkunit(device_get_unit(d->dev), device, chan); - devname = dsp_unit2name(buf, sizeof(buf), udc); - - if (devname == NULL) { - device_printf(d->dev, - "Failed to query device name udc=0x%08x\n", udc); - return (NULL); - } - - PCM_UNLOCK(d); - ch = malloc(sizeof(*ch), M_DEVBUF, M_WAITOK | M_ZERO); - ch->methods = kobj_create(cls, M_DEVBUF, M_WAITOK | M_ZERO); - ch->unit = udc; - ch->pid = -1; - strlcpy(ch->comm, CHN_COMM_UNUSED, sizeof(ch->comm)); - ch->parentsnddev = d; - ch->parentchannel = parent; - ch->dev = d->dev; - ch->trigger = PCMTRIG_STOP; - snprintf(ch->name, sizeof(ch->name), "%s:%s:%s", - device_get_nameunit(ch->dev), dirs, devname); - - err = chn_init(ch, devinfo, dir, direction); - PCM_LOCK(d); - if (err) { - device_printf(d->dev, "chn_init(%s) failed: err = %d\n", - ch->name, err); - kobj_delete(ch->methods, M_DEVBUF); - free(ch, M_DEVBUF); - return (NULL); - } - - return (ch); -} - -int -pcm_chn_destroy(struct pcm_channel *ch) -{ - struct snddev_info *d __diagused; - int err; - - d = ch->parentsnddev; - PCM_BUSYASSERT(d); - - err = chn_kill(ch); - if (err) { - device_printf(ch->dev, "chn_kill(%s) failed, err = %d\n", - ch->name, err); - return (err); - } - - kobj_delete(ch->methods, M_DEVBUF); - free(ch, M_DEVBUF); - - return (0); -} - -int +void pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch) { PCM_BUSYASSERT(d); @@ -585,7 +207,7 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch) CHN_INSERT_SORT_ASCEND(d, ch, channels.pcm); - switch (CHN_DEV(ch)) { + switch (ch->type) { case SND_DEV_DSPHW_PLAY: d->playcount++; break; @@ -599,12 +221,8 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch) d->rvchancount++; break; default: - break; + __assert_unreachable(); } - - d->devcount++; - - return (0); } int @@ -627,7 +245,7 @@ pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch) CHN_REMOVE(d, ch, channels.pcm); - switch (CHN_DEV(ch)) { + switch (ch->type) { case SND_DEV_DSPHW_PLAY: d->playcount--; break; @@ -641,11 +259,9 @@ pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch) d->rvchancount--; break; default: - break; + __assert_unreachable(); } - d->devcount--; - return (0); } @@ -654,28 +270,22 @@ pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo) { struct snddev_info *d = device_get_softc(dev); struct pcm_channel *ch; - int err; PCM_BUSYASSERT(d); PCM_LOCK(d); - ch = pcm_chn_create(d, NULL, cls, dir, -1, devinfo); + ch = chn_init(d, NULL, cls, dir, devinfo); if (!ch) { - device_printf(d->dev, "pcm_chn_create(%s, %d, %p) failed\n", + device_printf(d->dev, "chn_init(%s, %d, %p) failed\n", cls->name, dir, devinfo); PCM_UNLOCK(d); return (ENODEV); } - err = pcm_chn_add(d, ch); + pcm_chn_add(d, ch); PCM_UNLOCK(d); - if (err) { - device_printf(d->dev, "pcm_chn_add(%s) failed, err=%d\n", - ch->name, err); - pcm_chn_destroy(ch); - } - return (err); + return (0); } static void @@ -720,7 +330,7 @@ pcm_killchans(struct snddev_info *d) error = pcm_chn_remove(d, ch); PCM_UNLOCK(d); if (error == 0) - pcm_chn_destroy(ch); + chn_kill(ch); } while (!CHN_EMPTY(d, channels.pcm)); } @@ -767,7 +377,7 @@ pcm_setstatus(device_t dev, char *str) if (d->playcount > 0 || d->reccount > 0) d->flags |= SD_F_AUTOVCHAN; - pcm_setmaxautovchans(d, snd_maxautovchans); + vchan_setmaxauto(d, snd_maxautovchans); strlcpy(d->status, str, SND_STATUSLEN); @@ -943,14 +553,6 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec) return EINVAL; } - if (device_get_unit(dev) > PCMMAXUNIT) { - device_printf(dev, "PCMMAXUNIT reached : unit=%d > %d\n", - device_get_unit(dev), PCMMAXUNIT); - device_printf(dev, - "Use 'hw.snd.maxunit' tunable to raise the limit.\n"); - return ENODEV; - } - d = device_get_softc(dev); d->dev = dev; d->lock = snd_mtxcreate(device_get_nameunit(dev), "sound cdev"); @@ -974,7 +576,6 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec) d->flags |= SD_F_BITPERFECT; d->devinfo = devinfo; - d->devcount = 0; d->reccount = 0; d->playcount = 0; d->pvchancount = 0; @@ -1107,9 +708,8 @@ sound_oss_sysinfo(oss_sysinfo *si) struct snddev_info *d; struct pcm_channel *c; - int i, j, ncards; - - ncards = 0; + int j; + size_t i; strlcpy(si->product, si_product, sizeof(si->product)); strlcpy(si->version, si_version, sizeof(si->version)); @@ -1118,7 +718,7 @@ sound_oss_sysinfo(oss_sysinfo *si) /* * Iterate over PCM devices and their channels, gathering up data - * for the numaudios, ncards, and openedaudio fields. + * for the numaudios and openedaudio fields. */ si->numaudios = 0; bzero((void *)&si->openedaudio, sizeof(si->openedaudio)); @@ -1137,8 +737,7 @@ sound_oss_sysinfo(oss_sysinfo *si) PCM_UNLOCKASSERT(d); PCM_LOCK(d); - si->numaudios += d->devcount; - ++ncards; + si->numaudios += PCM_CHANCOUNT(d); CHN_FOREACH(c, d, channels.pcm) { CHN_UNLOCKASSERT(c); @@ -1169,7 +768,7 @@ sound_oss_sysinfo(oss_sysinfo *si) si->nummidis = 0; si->numtimers = 0; si->nummixers = mixer_count; - si->numcards = ncards; + si->numcards = devclass_get_maxunit(pcm_devclass); /* OSSv4 docs: Intended only for test apps; API doesn't really have much of a concept of cards. Shouldn't be used by applications. */ @@ -1185,7 +784,7 @@ sound_oss_sysinfo(oss_sysinfo *si) * Si->filler is a reserved array, but according to docs each * element should be set to -1. */ - for (i = 0; i < sizeof(si->filler)/sizeof(si->filler[0]); i++) + for (i = 0; i < nitems(si->filler); i++) si->filler[i] = -1; } @@ -1193,9 +792,7 @@ int sound_oss_card_info(oss_card_info *si) { struct snddev_info *d; - int i, ncards; - - ncards = 0; + int i; for (i = 0; pcm_devclass != NULL && i < devclass_get_maxunit(pcm_devclass); i++) { @@ -1203,7 +800,7 @@ sound_oss_card_info(oss_card_info *si) if (!PCM_REGISTERED(d)) continue; - if (ncards++ != si->card) + if (i != si->card) continue; PCM_UNLOCKASSERT(d); diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h index b48aed7c2d6e..e4a3ba41ee7f 100644 --- a/sys/dev/sound/pcm/sound.h +++ b/sys/dev/sound/pcm/sound.h @@ -88,7 +88,6 @@ struct snd_mixer; #include <dev/sound/pcm/feeder.h> #include <dev/sound/pcm/mixer.h> #include <dev/sound/pcm/dsp.h> -#include <dev/sound/unit.h> #define PCM_SOFTC_SIZE (sizeof(struct snddev_info)) @@ -101,24 +100,6 @@ struct snd_mixer; #define SOUND_MAXVER SOUND_MODVER /* - * We're abusing the fact that MAXMINOR still have enough room - * for our bit twiddling and nobody ever need 512 unique soundcards, - * 32 unique device types and 1024 unique cloneable devices for the - * next 100 years... - */ - -#define PCMMAXUNIT (snd_max_u()) -#define PCMMAXDEV (snd_max_d()) -#define PCMMAXCHAN (snd_max_c()) - -#define PCMUNIT(x) (snd_unit2u(dev2unit(x))) -#define PCMDEV(x) (snd_unit2d(dev2unit(x))) -#define PCMCHAN(x) (snd_unit2c(dev2unit(x))) - -/* XXX unit2minor compat */ -#define PCMMINOR(x) (x) - -/* * By design, limit possible channels for each direction. */ #define SND_MAXHWCHAN 256 @@ -175,6 +156,9 @@ struct snd_mixer; #define PCM_DETACHING(x) ((x)->flags & SD_F_DETACHING) +#define PCM_CHANCOUNT(d) \ + (d->playcount + d->pvchancount + d->reccount + d->rvchancount) + /* many variables should be reduced to a range. Here define a macro */ #define RANGE(var, low, high) (var) = \ (((var)<(low))? (low) : ((var)>(high))? (high) : (var)) @@ -244,45 +228,17 @@ struct snd_mixer; #define AFMT_NE (AFMT_SIGNED_NE | AFMT_U8_NE | AFMT_U16_NE | \ AFMT_U24_NE | AFMT_U32_NE) -/* - * Minor numbers for the sound driver. - * - * Unfortunately Creative called the codec chip of SB as a DSP. For this - * reason the /dev/dsp is reserved for digitized audio use. There is a - * device for true DSP processors but it will be called something else. - * In v3.0 it's /dev/sndproc but this could be a temporary solution. - */ - -#define SND_DEV_CTL 0 /* Control port /dev/mixer */ -#define SND_DEV_SEQ 1 /* Sequencer /dev/sequencer */ -#define SND_DEV_MIDIN 2 /* Raw midi access */ -#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */ -#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */ -#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */ -#define SND_DEV_STATUS 6 /* /dev/sndstat */ - /* #7 not in use now. */ -#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */ -#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */ -#define SND_DEV_PSS SND_DEV_SNDPROC /* ? */ -#define SND_DEV_NORESET 10 - -#define SND_DEV_DSPHW_PLAY 11 /* specific playback channel */ -#define SND_DEV_DSPHW_VPLAY 12 /* specific virtual playback channel */ -#define SND_DEV_DSPHW_REC 13 /* specific record channel */ -#define SND_DEV_DSPHW_VREC 14 /* specific virtual record channel */ - -#define SND_DEV_DSPHW_CD 15 /* s16le/stereo 44100Hz CD */ - -/* - * OSSv4 compatible device. For now, it serve no purpose and - * the cloning itself will forward the request to ordinary /dev/dsp - * instead. - */ -#define SND_DEV_DSP_MMAP 16 /* /dev/dsp_mmap */ -#define SND_DEV_DSP_AC3 17 /* /dev/dsp_ac3 */ -#define SND_DEV_DSP_MULTICH 18 /* /dev/dsp_multich */ -#define SND_DEV_DSP_SPDIFOUT 19 /* /dev/dsp_spdifout */ -#define SND_DEV_DSP_SPDIFIN 20 /* /dev/dsp_spdifin */ +enum { + SND_DEV_CTL = 0, /* Control port /dev/mixer */ + SND_DEV_SEQ, /* Sequencer /dev/sequencer */ + SND_DEV_MIDIN, /* Raw midi access */ + SND_DEV_DSP, /* Digitized voice /dev/dsp */ + SND_DEV_STATUS, /* /dev/sndstat */ + SND_DEV_DSPHW_PLAY, /* specific playback channel */ + SND_DEV_DSPHW_VPLAY, /* specific virtual playback channel */ + SND_DEV_DSPHW_REC, /* specific record channel */ + SND_DEV_DSPHW_VREC, /* specific virtual record channel */ +}; #define DSP_DEFAULT_SPEED 8000 @@ -291,7 +247,6 @@ struct snd_mixer; extern int pcm_veto_load; extern int snd_unit; -extern int snd_maxautovchans; extern int snd_verbose; extern devclass_t pcm_devclass; extern struct unrhdr *pcmsg_unrhdr; @@ -309,15 +264,10 @@ extern struct unrhdr *pcmsg_unrhdr; SYSCTL_DECL(_hw_snd); -int pcm_setvchans(struct snddev_info *d, int direction, int newcnt, int num); int pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction, - pid_t pid, char *comm, int devunit); -int pcm_chnrelease(struct pcm_channel *c); -int pcm_chnref(struct pcm_channel *c, int ref); + pid_t pid, char *comm); -struct pcm_channel *pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, int num, void *devinfo); -int pcm_chn_destroy(struct pcm_channel *ch); -int pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch); +void pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch); int pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch); int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo); @@ -341,13 +291,21 @@ void snd_mtxassert(void *m); int sndstat_register(device_t dev, char *str); int sndstat_unregister(device_t dev); -/* usage of flags in device config entry (config file) */ -#define DV_F_DRQ_MASK 0x00000007 /* mask for secondary drq */ -#define DV_F_DUAL_DMA 0x00000010 /* set to use secondary dma channel */ +/* These are the function codes assigned to the children of sound cards. */ +enum { + SCF_PCM, + SCF_MIDI, + SCF_SYNTH, +}; -/* ought to be made obsolete but still used by mss */ -#define DV_F_DEV_MASK 0x0000ff00 /* force device type/class */ -#define DV_F_DEV_SHIFT 8 /* force device type/class */ +/* + * This is the device information struct, used by a bridge device to pass the + * device function code to the children. + */ +struct sndcard_func { + int func; /* The function code. */ + void *varinfo; /* Bridge-specific information. */ +}; /* * this is rather kludgey- we need to duplicate these struct def'ns from sound.c @@ -367,7 +325,7 @@ struct snddev_info { } opened; } pcm; } channels; - unsigned devcount, playcount, reccount, pvchancount, rvchancount ; + unsigned playcount, reccount, pvchancount, rvchancount; unsigned flags; unsigned int bufsz; void *devinfo; diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c index d10c3ff4aabb..528c6fa62621 100644 --- a/sys/dev/sound/pcm/vchan.c +++ b/sys/dev/sound/pcm/vchan.c @@ -4,6 +4,10 @@ * Copyright (c) 2006-2009 Ariff Abdullah <ariff@FreeBSD.org> * Copyright (c) 2001 Cameron Grant <cg@FreeBSD.org> * All rights reserved. + * Copyright (c) 2024 The FreeBSD Foundation + * + * Portions of this software were developed by Christos Margiolis + * <christos@FreeBSD.org> under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -57,6 +61,8 @@ struct vchan_info { int trigger; }; +int snd_maxautovchans = 16; + static void * vchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) @@ -249,7 +255,7 @@ static kobj_method_t vchan_methods[] = { CHANNEL_DECLARE(vchan); static void -pcm_getparentchannel(struct snddev_info *d, +vchan_getparentchannel(struct snddev_info *d, struct pcm_channel **wrch, struct pcm_channel **rdch) { struct pcm_channel **ch, *wch, *rch, *c; @@ -337,7 +343,7 @@ sysctl_dev_pcm_vchans(SYSCTL_HANDLER_ARGS) cnt = 0; if (cnt > SND_MAXVCHANS) cnt = SND_MAXVCHANS; - err = pcm_setvchans(d, direction, cnt, -1); + err = vchan_setnew(d, direction, cnt); } PCM_RELEASE_QUICK(d); @@ -378,9 +384,9 @@ sysctl_dev_pcm_vchanmode(SYSCTL_HANDLER_ARGS) PCM_UNLOCK(d); if (direction == PCMDIR_PLAY) - pcm_getparentchannel(d, &c, NULL); + vchan_getparentchannel(d, &c, NULL); else - pcm_getparentchannel(d, NULL, &c); + vchan_getparentchannel(d, NULL, &c); if (c == NULL) { PCM_RELEASE_QUICK(d); @@ -480,9 +486,9 @@ sysctl_dev_pcm_vchanrate(SYSCTL_HANDLER_ARGS) PCM_UNLOCK(d); if (direction == PCMDIR_PLAY) - pcm_getparentchannel(d, &c, NULL); + vchan_getparentchannel(d, &c, NULL); else - pcm_getparentchannel(d, NULL, &c); + vchan_getparentchannel(d, NULL, &c); if (c == NULL) { PCM_RELEASE_QUICK(d); @@ -589,9 +595,9 @@ sysctl_dev_pcm_vchanformat(SYSCTL_HANDLER_ARGS) PCM_UNLOCK(d); if (direction == PCMDIR_PLAY) - pcm_getparentchannel(d, &c, NULL); + vchan_getparentchannel(d, &c, NULL); else - pcm_getparentchannel(d, NULL, &c); + vchan_getparentchannel(d, NULL, &c); if (c == NULL) { PCM_RELEASE_QUICK(d); @@ -662,7 +668,7 @@ sysctl_dev_pcm_vchanformat(SYSCTL_HANDLER_ARGS) "play.vchanrate" : "rec.vchanrate" int -vchan_create(struct pcm_channel *parent, int num) +vchan_create(struct pcm_channel *parent) { struct snddev_info *d; struct pcm_channel *ch; @@ -698,7 +704,7 @@ vchan_create(struct pcm_channel *parent, int num) } /* create a new playback channel */ - ch = pcm_chn_create(d, parent, &vchan_class, direction, num, parent); + ch = chn_init(d, parent, &vchan_class, direction, parent); if (ch == NULL) { PCM_UNLOCK(d); CHN_LOCK(parent); @@ -706,13 +712,8 @@ vchan_create(struct pcm_channel *parent, int num) } /* add us to our grandparent's channel list */ - ret = pcm_chn_add(d, ch); + pcm_chn_add(d, ch); PCM_UNLOCK(d); - if (ret != 0) { - pcm_chn_destroy(ch); - CHN_LOCK(parent); - return (ret); - } CHN_LOCK(parent); /* @@ -727,6 +728,7 @@ vchan_create(struct pcm_channel *parent, int num) parent->flags |= CHN_F_HAS_VCHAN; + ret = 0; parent_caps = chn_getcaps(parent); if (parent_caps == NULL) ret = EINVAL; @@ -837,7 +839,7 @@ vchan_create(struct pcm_channel *parent, int num) PCM_LOCK(d); if (pcm_chn_remove(d, ch) == 0) { PCM_UNLOCK(d); - pcm_chn_destroy(ch); + chn_kill(ch); } else PCM_UNLOCK(d); CHN_LOCK(parent); @@ -890,7 +892,7 @@ vchan_destroy(struct pcm_channel *c) /* destroy ourselves */ if (ret == 0) - ret = pcm_chn_destroy(c); + chn_kill(c); CHN_LOCK(parent); @@ -923,7 +925,7 @@ vchan_sync(struct pcm_channel *c) if (snd_passthrough_verbose != 0) { char *devname, buf[CHN_NAMELEN]; - devname = dsp_unit2name(buf, sizeof(buf), c->unit); + devname = dsp_unit2name(buf, sizeof(buf), c); device_printf(c->dev, "%s(%s/%s) %s() -> re-sync err=%d\n", __func__, (devname != NULL) ? devname : "dspX", c->comm, @@ -934,6 +936,172 @@ vchan_sync(struct pcm_channel *c) return (ret); } +int +vchan_setnew(struct snddev_info *d, int direction, int newcnt) +{ + struct pcm_channel *c, *ch, *nch; + struct pcmchan_caps *caps; + int i, err, vcnt; + + PCM_BUSYASSERT(d); + + if ((direction == PCMDIR_PLAY && d->playcount < 1) || + (direction == PCMDIR_REC && d->reccount < 1)) + return (ENODEV); + + if (!(d->flags & SD_F_AUTOVCHAN)) + return (EINVAL); + + if (newcnt < 0 || newcnt > SND_MAXVCHANS) + return (E2BIG); + + if (direction == PCMDIR_PLAY) + vcnt = d->pvchancount; + else if (direction == PCMDIR_REC) + vcnt = d->rvchancount; + else + return (EINVAL); + + if (newcnt > vcnt) { + KASSERT((newcnt - 1) == vcnt, + ("bogus vchan_create() request newcnt=%d vcnt=%d", + newcnt, vcnt)); + /* add new vchans - find a parent channel first */ + ch = NULL; + CHN_FOREACH(c, d, channels.pcm) { + CHN_LOCK(c); + if (c->direction == direction && + ((c->flags & CHN_F_HAS_VCHAN) || (vcnt == 0 && + c->refcount < 1 && + !(c->flags & (CHN_F_BUSY | CHN_F_VIRTUAL))))) { + /* + * Reuse hw channel with vchans already + * created. + */ + if (c->flags & CHN_F_HAS_VCHAN) { + ch = c; + break; + } + /* + * No vchans ever created, look for + * channels with supported formats. + */ + caps = chn_getcaps(c); + if (caps == NULL) { + CHN_UNLOCK(c); + continue; + } + for (i = 0; caps->fmtlist[i] != 0; i++) { + if (caps->fmtlist[i] & AFMT_CONVERTIBLE) + break; + } + if (caps->fmtlist[i] != 0) { + ch = c; + break; + } + } + CHN_UNLOCK(c); + } + if (ch == NULL) + return (EBUSY); + ch->flags |= CHN_F_BUSY; + err = 0; + while (err == 0 && newcnt > vcnt) { + err = vchan_create(ch); + if (err == 0) + vcnt++; + else if (err == E2BIG && newcnt > vcnt) + device_printf(d->dev, + "%s: err=%d Maximum channel reached.\n", + __func__, err); + } + if (vcnt == 0) + ch->flags &= ~CHN_F_BUSY; + CHN_UNLOCK(ch); + if (err != 0) + return (err); + } else if (newcnt < vcnt) { + CHN_FOREACH(c, d, channels.pcm) { + CHN_LOCK(c); + if (c->direction != direction || + CHN_EMPTY(c, children) || + !(c->flags & CHN_F_HAS_VCHAN)) { + CHN_UNLOCK(c); + continue; + } + CHN_FOREACH_SAFE(ch, c, nch, children) { + CHN_LOCK(ch); + if (vcnt == 1 && c->refcount > 0) { + CHN_UNLOCK(ch); + break; + } + if (!(ch->flags & CHN_F_BUSY) && + ch->refcount < 1) { + err = vchan_destroy(ch); + if (err == 0) + vcnt--; + } else + CHN_UNLOCK(ch); + if (vcnt == newcnt) + break; + } + CHN_UNLOCK(c); + break; + } + } + + return (0); +} + +void +vchan_setmaxauto(struct snddev_info *d, int num) +{ + PCM_BUSYASSERT(d); + + if (num < 0) + return; + + if (num >= 0 && d->pvchancount > num) + (void)vchan_setnew(d, PCMDIR_PLAY, num); + else if (num > 0 && d->pvchancount == 0) + (void)vchan_setnew(d, PCMDIR_PLAY, 1); + + if (num >= 0 && d->rvchancount > num) + (void)vchan_setnew(d, PCMDIR_REC, num); + else if (num > 0 && d->rvchancount == 0) + (void)vchan_setnew(d, PCMDIR_REC, 1); +} + +static int +sysctl_hw_snd_maxautovchans(SYSCTL_HANDLER_ARGS) +{ + struct snddev_info *d; + int i, v, error; + + v = snd_maxautovchans; + error = sysctl_handle_int(oidp, &v, 0, req); + if (error == 0 && req->newptr != NULL) { + if (v < 0) + v = 0; + if (v > SND_MAXVCHANS) + v = SND_MAXVCHANS; + snd_maxautovchans = v; + for (i = 0; pcm_devclass != NULL && + i < devclass_get_maxunit(pcm_devclass); i++) { + d = devclass_get_softc(pcm_devclass, i); + if (!PCM_REGISTERED(d)) + continue; + PCM_ACQUIRE_QUICK(d); + vchan_setmaxauto(d, v); + PCM_RELEASE_QUICK(d); + } + } + return (error); +} +SYSCTL_PROC(_hw_snd, OID_AUTO, maxautovchans, + CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, 0, sizeof(int), + sysctl_hw_snd_maxautovchans, "I", "maximum virtual channel"); + void vchan_initsys(device_t dev) { diff --git a/sys/dev/sound/pcm/vchan.h b/sys/dev/sound/pcm/vchan.h index e2dcc9761261..1f0fa058cf71 100644 --- a/sys/dev/sound/pcm/vchan.h +++ b/sys/dev/sound/pcm/vchan.h @@ -30,7 +30,9 @@ #ifndef _SND_VCHAN_H_ #define _SND_VCHAN_H_ -int vchan_create(struct pcm_channel *, int); +extern int snd_maxautovchans; + +int vchan_create(struct pcm_channel *); int vchan_destroy(struct pcm_channel *); #ifdef SND_DEBUG @@ -45,6 +47,9 @@ int vchan_sync(struct pcm_channel *); sndbuf_getfmt((c)->bufhard) != (c)->parentchannel->format || \ sndbuf_getspd((c)->bufhard) != (c)->parentchannel->speed)) +int vchan_setnew(struct snddev_info *, int, int); +void vchan_setmaxauto(struct snddev_info *, int); + void vchan_initsys(device_t); /* diff --git a/sys/dev/sound/unit.c b/sys/dev/sound/unit.c deleted file mode 100644 index 28ffbde1f7ec..000000000000 --- a/sys/dev/sound/unit.c +++ /dev/null @@ -1,188 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2007 Ariff Abdullah <ariff@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> - -#ifdef HAVE_KERNEL_OPTION_HEADERS -#include "opt_snd.h" -#endif - -#include <dev/sound/unit.h> - -/* - * Unit magic allocator for sound driver. - * - * 'u' = Unit of attached soundcards - * 'd' = Device type - * 'c' = Channel number - * - * eg: dsp0.p1 - u=0, d=p, c=1 - * dsp1.vp0 - u=1, d=vp, c=0 - * - * Maximum unit of soundcards can be tuned through "hw.snd.maxunit", which is - * between SND_UNIT_UMIN (16) and SND_UNIT_UMAX (2048). By design, the maximum - * allowable allocated channel is 256. - */ - -/* Default width */ -static int snd_u_shift = 9; /* 0 - 0x1ff : 512 distinct soundcards */ -static int snd_d_shift = 5; /* 0 - 0x1f : 32 distinct device types */ -static int snd_c_shift = 10; /* 0 - 0x3ff : 1024 distinct channels - (256 limit "by design") */ - -static int snd_unit_initialized = 0; - -#ifdef SND_DIAGNOSTIC -#define SND_UNIT_ASSERT() do { \ - if (snd_unit_initialized == 0) \ - panic("%s(): Uninitialized sound unit!", __func__); \ -} while (0) -#else -#define SND_UNIT_ASSERT() KASSERT(snd_unit_initialized != 0, \ - ("%s(): Uninitialized sound unit!", \ - __func__)) -#endif - -#define MKMASK(x) ((1 << snd_##x##_shift) - 1) - -int -snd_max_u(void) -{ - SND_UNIT_ASSERT(); - - return (MKMASK(u)); -} - -int -snd_max_d(void) -{ - SND_UNIT_ASSERT(); - - return (MKMASK(d)); -} - -int -snd_max_c(void) -{ - SND_UNIT_ASSERT(); - - return (MKMASK(c)); -} - -int -snd_unit2u(int unit) -{ - SND_UNIT_ASSERT(); - - return ((unit >> (snd_c_shift + snd_d_shift)) & MKMASK(u)); -} - -int -snd_unit2d(int unit) -{ - SND_UNIT_ASSERT(); - - return ((unit >> snd_c_shift) & MKMASK(d)); -} - -int -snd_unit2c(int unit) -{ - SND_UNIT_ASSERT(); - - return (unit & MKMASK(c)); -} - -int -snd_u2unit(int u) -{ - SND_UNIT_ASSERT(); - - return ((u & MKMASK(u)) << (snd_c_shift + snd_d_shift)); -} - -int -snd_d2unit(int d) -{ - SND_UNIT_ASSERT(); - - return ((d & MKMASK(d)) << snd_c_shift); -} - -int -snd_c2unit(int c) -{ - SND_UNIT_ASSERT(); - - return (c & MKMASK(c)); -} - -int -snd_mkunit(int u, int d, int c) -{ - SND_UNIT_ASSERT(); - - return ((c & MKMASK(c)) | ((d & MKMASK(d)) << snd_c_shift) | - ((u & MKMASK(u)) << (snd_c_shift + snd_d_shift))); -} - -/* - * This *must* be called first before any of the functions above!!! - */ -void -snd_unit_init(void) -{ - int i; - - if (snd_unit_initialized != 0) - return; - - snd_unit_initialized = 1; - - if (getenv_int("hw.snd.maxunit", &i) != 0) { - if (i < SND_UNIT_UMIN) - i = SND_UNIT_UMIN; - else if (i > SND_UNIT_UMAX) - i = SND_UNIT_UMAX; - else - i = roundup2(i, 2); - - for (snd_u_shift = 0; (i >> (snd_u_shift + 1)) != 0; - snd_u_shift++) - ; - - /* Make room for channels to fit within 24bit MAXMINOR limit. */ - snd_c_shift = 24 - snd_u_shift - snd_d_shift; - } - - if (bootverbose != 0) - printf("%s() u=0x%08x [%d] d=0x%08x [%d] c=0x%08x [%d]\n", - __func__, SND_U_MASK, snd_max_u() + 1, - SND_D_MASK, snd_max_d() + 1, SND_C_MASK, snd_max_c() + 1); -} diff --git a/sys/dev/sound/unit.h b/sys/dev/sound/unit.h deleted file mode 100644 index 9ddd68a2fe04..000000000000 --- a/sys/dev/sound/unit.h +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2007 Ariff Abdullah <ariff@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _SND_UNIT_H_ -#define _SND_UNIT_H_ - -#define SND_UNIT_UMIN 16 -#define SND_UNIT_UMAX 2048 - -int snd_max_u(void); -int snd_max_d(void); -int snd_max_c(void); -int snd_unit2u(int); -int snd_unit2d(int); -int snd_unit2c(int); -int snd_u2unit(int); -int snd_d2unit(int); -int snd_c2unit(int); -int snd_mkunit(int, int, int); - -void snd_unit_init(void); - -#define SND_U_MASK (snd_u2unit(snd_max_u())) -#define SND_D_MASK (snd_d2unit(snd_max_d())) -#define SND_C_MASK (snd_c2unit(snd_max_c())) - -#endif /* !_SND_UNIT_H_ */ diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 2351c2522021..d47eb86ed271 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -90,7 +90,6 @@ #include <dev/sound/pcm/sound.h> #include <dev/sound/usb/uaudioreg.h> #include <dev/sound/usb/uaudio.h> -#include <dev/sound/chip.h> #include "feeder_if.h" static int uaudio_default_rate = 0; /* use rate list */ diff --git a/sys/dev/sound/usb/uaudio_pcm.c b/sys/dev/sound/usb/uaudio_pcm.c index 9b17cb232907..0b3da9b20440 100644 --- a/sys/dev/sound/usb/uaudio_pcm.c +++ b/sys/dev/sound/usb/uaudio_pcm.c @@ -32,7 +32,6 @@ #endif #include <dev/sound/pcm/sound.h> -#include <dev/sound/chip.h> #include <dev/sound/usb/uaudio.h> #include "mixer_if.h" diff --git a/sys/dev/sound/version.h b/sys/dev/sound/version.h deleted file mode 100644 index b816bbf964e8..000000000000 --- a/sys/dev/sound/version.h +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2007 Ariff Abdullah <ariff@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _SND_VERSION_H_ -#define _SND_VERSION_H_ - -/* - * FreeBSD sound driver internal versioning, nothing to do - * with OSS whatsoever. Dear future maintainer, please revisit - * this _before_ Jan 1 2148 - * - * Last 2 decimal places reserved for daily versioning, starting - * with 0. - */ -#define SND_DRV_VERSION 2009061500 - -#endif /* !_SND_VERSION_H_ */ diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c index a59501b6bbff..58809de4ad3a 100644 --- a/sys/dev/usb/net/if_smsc.c +++ b/sys/dev/usb/net/if_smsc.c @@ -28,7 +28,7 @@ #include <sys/cdefs.h> /* - * SMSC LAN9xxx devices (http://www.smsc.com/) + * Microchip LAN9xxx devices (https://www.microchip.com/en-us/product/lan9500a) * * The LAN9500 & LAN9500A devices are stand-alone USB to Ethernet chips that * support USB 2.0 and 10/100 Mbps Ethernet. @@ -38,7 +38,7 @@ * supports the hub part. * * This driver is closely modelled on the Linux driver written and copyrighted - * by SMSC. + * by SMSC (later acquired by Microchip). * * * diff --git a/sys/dev/wg/if_wg.c b/sys/dev/wg/if_wg.c index 2c867956912a..30429c3725cd 100644 --- a/sys/dev/wg/if_wg.c +++ b/sys/dev/wg/if_wg.c @@ -2194,7 +2194,8 @@ wg_output(if_t ifp, struct mbuf *m, const struct sockaddr *dst, struct route *ro int ret; struct mbuf *defragged; - if (dst->sa_family == AF_UNSPEC) + /* BPF writes need to be handled specially. */ + if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT) memcpy(&af, dst->sa_data, sizeof(af)); else af = dst->sa_family; diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 578fb3ce1340..950e0c097457 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -713,7 +713,7 @@ int nfsvno_rmdirsub(struct nameidata *, int, struct ucred *, NFSPROC_T *, struct nfsexstuff *); int nfsvno_rename(struct nameidata *, struct nameidata *, u_int32_t, u_int32_t, struct ucred *, NFSPROC_T *); -int nfsvno_link(struct nameidata *, vnode_t, struct ucred *, +int nfsvno_link(struct nameidata *, vnode_t, nfsquad_t, struct ucred *, NFSPROC_T *, struct nfsexstuff *); int nfsvno_fsync(vnode_t, u_int64_t, int, struct ucred *, NFSPROC_T *); int nfsvno_statfs(vnode_t, struct statfs *); diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index f8c2ddfd2a59..f4679309657b 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -1656,8 +1656,8 @@ out1: * Link vnode op. */ int -nfsvno_link(struct nameidata *ndp, struct vnode *vp, struct ucred *cred, - struct thread *p, struct nfsexstuff *exp) +nfsvno_link(struct nameidata *ndp, struct vnode *vp, nfsquad_t clientid, + struct ucred *cred, struct thread *p, struct nfsexstuff *exp) { struct vnode *xp; int error = 0; @@ -1672,9 +1672,11 @@ nfsvno_link(struct nameidata *ndp, struct vnode *vp, struct ucred *cred, } if (!error) { NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); - if (!VN_IS_DOOMED(vp)) - error = VOP_LINK(ndp->ni_dvp, vp, &ndp->ni_cnd); - else + if (!VN_IS_DOOMED(vp)) { + error = nfsrv_checkremove(vp, 0, NULL, clientid, p); + if (error == 0) + error = VOP_LINK(ndp->ni_dvp, vp, &ndp->ni_cnd); + } else error = EPERM; if (ndp->ni_dvp == vp) { vrele(ndp->ni_dvp); diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 8141ee6cbdb6..0c8bda6dc6a6 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -1797,6 +1797,7 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram, char *bufp; u_long *hashp; struct thread *p = curthread; + nfsquad_t clientid; if (nd->nd_repstat) { nfsrv_postopattr(nd, getret, &at); @@ -1858,8 +1859,14 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram, NULL); } } - if (!nd->nd_repstat) - nd->nd_repstat = nfsvno_link(&named, vp, nd->nd_cred, p, exp); + if (!nd->nd_repstat) { + clientid.qval = 0; + if ((nd->nd_flag & (ND_IMPLIEDCLID | ND_NFSV41)) == + (ND_IMPLIEDCLID | ND_NFSV41)) + clientid.qval = nd->nd_clientid.qval; + nd->nd_repstat = nfsvno_link(&named, vp, clientid, nd->nd_cred, + p, exp); + } if (nd->nd_flag & ND_NFSV3) getret = nfsvno_getattr(vp, &at, nd, p, 0, NULL); if (dirp) { diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 16b38e628e35..400734c10596 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -101,11 +101,13 @@ SYSCTL_BOOL(_kern_geom_eli, OID_AUTO, blocking_malloc, CTLFLAG_RWTUN, static bool g_eli_unmapped_io = true; SYSCTL_BOOL(_kern_geom_eli, OID_AUTO, unmapped_io, CTLFLAG_RDTUN, &g_eli_unmapped_io, 0, "Enable support for unmapped I/O"); +static int g_eli_alloc_sz; +SYSCTL_UINT(_kern_geom_eli, OID_AUTO, use_uma_bytes, CTLFLAG_RD, + &g_eli_alloc_sz, 0, "Use uma(9) for allocations of this size or smaller."); static struct sx g_eli_umalock; /* Controls changes to UMA zone. */ SX_SYSINIT(g_eli_umalock, &g_eli_umalock, "GELI UMA"); static uma_zone_t g_eli_uma = NULL; -static int g_eli_alloc_sz; static volatile int g_eli_umaoutstanding; static volatile int g_eli_devs; diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c index 1634041daf2a..3a7b7c2f6c71 100644 --- a/sys/i386/i386/sys_machdep.c +++ b/sys/i386/i386/sys_machdep.c @@ -154,26 +154,24 @@ sysarch(struct thread *td, struct sysarch_args *uap) * explicitly indicate whether or not the operation is safe to * perform in capability mode. */ - if (IN_CAPABILITY_MODE(td)) { - switch (uap->op) { - case I386_GET_LDT: - case I386_SET_LDT: - case I386_GET_IOPERM: - case I386_GET_FSBASE: - case I386_SET_FSBASE: - case I386_GET_GSBASE: - case I386_SET_GSBASE: - case I386_GET_XFPUSTATE: - break; + switch (uap->op) { + case I386_GET_LDT: + case I386_SET_LDT: + case I386_GET_IOPERM: + case I386_GET_FSBASE: + case I386_SET_FSBASE: + case I386_GET_GSBASE: + case I386_SET_GSBASE: + case I386_GET_XFPUSTATE: + break; - case I386_SET_IOPERM: - default: -#ifdef KTRACE - if (KTRPOINT(td, KTR_CAPFAIL)) - ktrcapfail(CAPFAIL_SYSCALL, NULL, NULL); -#endif + case I386_SET_IOPERM: + default: + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_SYSCALL, &uap->op); + if (IN_CAPABILITY_MODE(td)) return (ECAPMODE); - } + break; } #endif diff --git a/sys/kern/kern_boottrace.c b/sys/kern/kern_boottrace.c index 86fee4f47fbe..1b097e7378ad 100644 --- a/sys/kern/kern_boottrace.c +++ b/sys/kern/kern_boottrace.c @@ -613,4 +613,4 @@ boottrace_init(void) st.table = malloc(st.size * sizeof(struct bt_event), M_BOOTTRACE, M_WAITOK | M_ZERO); } -SYSINIT(boottrace, SI_SUB_CPU, SI_ORDER_ANY, boottrace_init, 0); +SYSINIT(boottrace, SI_SUB_CPU, SI_ORDER_ANY, boottrace_init, NULL); diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c index 17176afa6ad3..5d9e2f2f326b 100644 --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -1762,22 +1762,38 @@ cpuset_setproc_update_set(struct proc *p, struct cpuset *set) * In Capability mode, the only accesses that are permitted are to the current * thread and process' CPU and domain sets. */ +static bool +cpuset_capmode_allowed(struct thread *td, cpulevel_t level, cpuwhich_t which, + id_t id) +{ + if (level != CPU_LEVEL_WHICH) + return (false); + if (which != CPU_WHICH_TID && which != CPU_WHICH_PID && + which != CPU_WHICH_TIDPID) + return (false); + if (id != -1 && which == CPU_WHICH_TIDPID && + id != td->td_tid && id != td->td_proc->p_pid) + return (false); + if (id != -1 && + !(which == CPU_WHICH_TID && id == td->td_tid) && + !(which == CPU_WHICH_PID && id == td->td_proc->p_pid)) + return (false); + return (true); +} + +/* + * Check for capability violations and record them if ktrace(2) is active. + */ static int cpuset_check_capabilities(struct thread *td, cpulevel_t level, cpuwhich_t which, id_t id) { - if (IN_CAPABILITY_MODE(td)) { - if (level != CPU_LEVEL_WHICH) - return (ECAPMODE); - if (which != CPU_WHICH_TID && which != CPU_WHICH_PID && - which != CPU_WHICH_TIDPID) - return (ECAPMODE); - if (id != -1 && which == CPU_WHICH_TIDPID && - id != td->td_tid && id != td->td_proc->p_pid) - return (ECAPMODE); - if (id != -1 && - !(which == CPU_WHICH_TID && id == td->td_tid) && - !(which == CPU_WHICH_PID && id == td->td_proc->p_pid)) + if (IN_CAPABILITY_MODE(td) || CAP_TRACING(td)) { + if (cpuset_capmode_allowed(td, level, which, id)) + return (0); + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_CPUSET, NULL); + if (IN_CAPABILITY_MODE(td)) return (ECAPMODE); } return (0); diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 30d82f74d725..35e9afea4625 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -877,6 +877,8 @@ revert_f_setfl: case F_KINFO: #ifdef CAPABILITY_MODE + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_SYSCALL, &cmd); if (IN_CAPABILITY_MODE(td)) { error = ECAPMODE; break; @@ -3054,7 +3056,7 @@ fgetvp_lookup_smr(struct nameidata *ndp, struct vnode **vpp, bool *fsearch) ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL || ndp->ni_filecaps.fc_nioctls != -1) { #ifdef notyet - ndp->ni_lcf |= NI_LCF_STRICTRELATIVE; + ndp->ni_lcf |= NI_LCF_STRICTREL; #else return (EAGAIN); #endif @@ -3146,7 +3148,7 @@ fgetvp_lookup(struct nameidata *ndp, struct vnode **vpp) if (!cap_rights_contains(&ndp->ni_filecaps.fc_rights, &rights) || ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL || ndp->ni_filecaps.fc_nioctls != -1) { - ndp->ni_lcf |= NI_LCF_STRICTRELATIVE; + ndp->ni_lcf |= NI_LCF_STRICTREL; ndp->ni_resflags |= NIRES_STRICTREL; } #endif diff --git a/sys/kern/kern_devctl.c b/sys/kern/kern_devctl.c index 12d4f9ebfc4d..0dd05a49c9ad 100644 --- a/sys/kern/kern_devctl.c +++ b/sys/kern/kern_devctl.c @@ -89,6 +89,9 @@ static int sysctl_devctl_queue(SYSCTL_HANDLER_ARGS); static int devctl_queue_length = DEVCTL_DEFAULT_QUEUE_LEN; SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_queue, CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, NULL, 0, sysctl_devctl_queue, "I", "devctl queue length"); +static bool nomatch_enabled = false; +SYSCTL_BOOL(_hw_bus, OID_AUTO, devctl_nomatch_enabled, CTLFLAG_RWTUN, + &nomatch_enabled, 0, "enable nomatch events"); static void devctl_attach_handler(void *arg __unused, device_t dev); static void devctl_detach_handler(void *arg __unused, device_t dev, @@ -208,7 +211,8 @@ devctl_detach_handler(void *arg __unused, device_t dev, enum evhdev_detach state static void devctl_nomatch_handler(void *arg __unused, device_t dev) { - devaddq("?", "", dev); + if (nomatch_enabled) + devaddq("?", "", dev); } static int diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index ae2b624c2659..6727872b5b10 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -454,6 +454,8 @@ do_execve(struct thread *td, struct image_args *args, struct mac *mac_p, interpret: if (args->fname != NULL) { #ifdef CAPABILITY_MODE + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_NAMEI, args->fname); /* * While capability mode can't reach this point via direct * path arguments to execve(), we also don't allow diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 4c1936edc301..555762185411 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -925,14 +925,17 @@ ktrstructarray(const char *name, enum uio_seg seg, const void *data, } void -ktrcapfail(enum ktr_cap_fail_type type, const cap_rights_t *needed, - const cap_rights_t *held) +ktrcapfail(enum ktr_cap_violation type, const void *data) { struct thread *td = curthread; struct ktr_request *req; struct ktr_cap_fail *kcf; + union ktr_cap_data *kcd; - if (__predict_false(curthread->td_pflags & TDP_INKTRACE)) + if (__predict_false(td->td_pflags & TDP_INKTRACE)) + return; + if (type != CAPFAIL_SYSCALL && + (td->td_sa.callp->sy_flags & SYF_CAPENABLED) == 0) return; req = ktr_getrequest(KTR_CAPFAIL); @@ -940,14 +943,32 @@ ktrcapfail(enum ktr_cap_fail_type type, const cap_rights_t *needed, return; kcf = &req->ktr_data.ktr_cap_fail; kcf->cap_type = type; - if (needed != NULL) - kcf->cap_needed = *needed; - else - cap_rights_init(&kcf->cap_needed); - if (held != NULL) - kcf->cap_held = *held; - else - cap_rights_init(&kcf->cap_held); + kcf->cap_code = td->td_sa.code; + kcf->cap_svflags = td->td_proc->p_sysent->sv_flags; + if (data != NULL) { + kcd = &kcf->cap_data; + switch (type) { + case CAPFAIL_NOTCAPABLE: + case CAPFAIL_INCREASE: + kcd->cap_needed = *(const cap_rights_t *)data; + kcd->cap_held = *((const cap_rights_t *)data + 1); + break; + case CAPFAIL_SYSCALL: + case CAPFAIL_SIGNAL: + case CAPFAIL_PROTO: + kcd->cap_int = *(const int *)data; + break; + case CAPFAIL_SOCKADDR: + kcd->cap_sockaddr = *(const struct sockaddr *)data; + break; + case CAPFAIL_NAMEI: + strlcpy(kcd->cap_path, data, MAXPATHLEN); + break; + case CAPFAIL_CPUSET: + default: + break; + } + } ktr_enqueuerequest(td, req); ktrace_exit(td); } diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c index 9e860e7c80a5..23b3403fec4f 100644 --- a/sys/kern/kern_procctl.c +++ b/sys/kern/kern_procctl.c @@ -28,6 +28,8 @@ */ #include <sys/cdefs.h> +#include "opt_ktrace.h" + #include <sys/param.h> #include <sys/_unrhdr.h> #include <sys/systm.h> @@ -543,6 +545,8 @@ reap_kill(struct thread *td, struct proc *p, void *data) rk = data; sx_assert(&proctree_lock, SX_LOCKED); + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_SIGNAL, &rk->rk_sig); if (IN_CAPABILITY_MODE(td)) return (ECAPMODE); if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG || diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 2f2ec7edfb12..802231767762 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1907,8 +1907,12 @@ kern_kill(struct thread *td, pid_t pid, int signum) * The main rationale behind this is that abort(3) is implemented as * kill(getpid(), SIGABRT). */ - if (IN_CAPABILITY_MODE(td) && pid != td->td_proc->p_pid) - return (ECAPMODE); + if (pid != td->td_proc->p_pid) { + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_SIGNAL, &signum); + if (IN_CAPABILITY_MODE(td)) + return (ECAPMODE); + } AUDIT_ARG_SIGNUM(signum); AUDIT_ARG_PID(pid); @@ -2690,10 +2694,16 @@ ptrace_syscallreq(struct thread *td, struct proc *p, &td->td_proc->p_cowgen))) thread_cow_update(td); + td->td_sa = tsr->ts_sa; + #ifdef CAPABILITY_MODE - if (IN_CAPABILITY_MODE(td) && (se->sy_flags & SYF_CAPENABLED) == 0) { - tsr->ts_ret.sr_error = ECAPMODE; - return; + if ((se->sy_flags & SYF_CAPENABLED) == 0) { + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_SYSCALL, NULL); + if (IN_CAPABILITY_MODE(td)) { + tsr->ts_ret.sr_error = ECAPMODE; + return; + } } #endif diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 814579a80f5a..53b61c08713f 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -634,17 +634,15 @@ sysctl_ctx_free(struct sysctl_ctx_list *clist) return(EBUSY); } /* Now really delete the entries */ - e = TAILQ_FIRST(clist); - while (e != NULL) { - e1 = TAILQ_NEXT(e, link); + TAILQ_FOREACH_SAFE(e, clist, link, e1) { error = sysctl_remove_oid_locked(e->entry, 1, 0); if (error) panic("sysctl_remove_oid: corrupt tree, entry: %s", e->entry->oid_name); free(e, M_SYSCTLOID); - e = e1; } SYSCTL_WUNLOCK(); + TAILQ_INIT(clist); return (error); } diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 57ff74f5421e..092fcade9d19 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -2520,7 +2520,8 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags, struct umtx_pi *pi; uint32_t ceiling; uint32_t owner, id; - int error, pri, old_inherited_pri, su, rv; + int error, pri, old_inherited_pri, new_pri, rv; + bool su; id = td->td_tid; uq = td->td_umtxq; @@ -2549,21 +2550,23 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags, error = EINVAL; goto out; } + new_pri = PRI_MIN_REALTIME + ceiling; - mtx_lock(&umtx_lock); - if (UPRI(td) < PRI_MIN_REALTIME + ceiling) { - mtx_unlock(&umtx_lock); + if (td->td_base_user_pri < new_pri) { error = EINVAL; goto out; } - if (su && PRI_MIN_REALTIME + ceiling < uq->uq_inherited_pri) { - uq->uq_inherited_pri = PRI_MIN_REALTIME + ceiling; - thread_lock(td); - if (uq->uq_inherited_pri < UPRI(td)) - sched_lend_user_prio(td, uq->uq_inherited_pri); - thread_unlock(td); + if (su) { + mtx_lock(&umtx_lock); + if (new_pri < uq->uq_inherited_pri) { + uq->uq_inherited_pri = new_pri; + thread_lock(td); + if (new_pri < UPRI(td)) + sched_lend_user_prio(td, new_pri); + thread_unlock(td); + } + mtx_unlock(&umtx_lock); } - mtx_unlock(&umtx_lock); rv = casueword32(&m->m_owner, UMUTEX_CONTESTED, &owner, id | UMUTEX_CONTESTED); @@ -2684,7 +2687,8 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags, bool rb) struct umtx_q *uq, *uq2; struct umtx_pi *pi; uint32_t id, owner, rceiling; - int error, pri, new_inherited_pri, su; + int error, pri, new_inherited_pri; + bool su; id = td->td_tid; uq = td->td_umtxq; @@ -2739,7 +2743,7 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags, bool rb) error = EFAULT; else { mtx_lock(&umtx_lock); - if (su != 0) + if (su || new_inherited_pri == PRI_MAX) uq->uq_inherited_pri = new_inherited_pri; pri = PRI_MAX; TAILQ_FOREACH(pi, &uq->uq_pi_contested, pi_link) { diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index f0fffeb08e2d..ff1e57746404 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -981,15 +981,9 @@ void sched_lend_user_prio_cond(struct thread *td, u_char prio) { - if (td->td_lend_user_pri != prio) - goto lend; - if (td->td_user_pri != min(prio, td->td_base_user_pri)) - goto lend; - if (td->td_priority != td->td_user_pri) - goto lend; - return; - -lend: + if (td->td_lend_user_pri == prio) + return; + thread_lock(td); sched_lend_user_prio(td, prio); thread_unlock(td); diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index ee1e0ab0b955..4b99f1c486bf 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -2007,15 +2007,9 @@ void sched_lend_user_prio_cond(struct thread *td, u_char prio) { - if (td->td_lend_user_pri != prio) - goto lend; - if (td->td_user_pri != min(prio, td->td_base_user_pri)) - goto lend; - if (td->td_priority != td->td_user_pri) - goto lend; - return; + if (td->td_lend_user_pri == prio) + return; -lend: thread_lock(td); sched_lend_user_prio(td, prio); thread_unlock(td); diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c index 49fe20cdc890..6535c42f2404 100644 --- a/sys/kern/subr_intr.c +++ b/sys/kern/subr_intr.c @@ -175,11 +175,11 @@ intr_irq_init(void *dummy __unused) /* * - 2 counters for each I/O interrupt. - * - mp_maxid + 1 counters for each IPI counters for SMP. + * - MAXCPU counters for each IPI counters for SMP. */ nintrcnt = intr_nirq * 2; #ifdef SMP - nintrcnt += INTR_IPI_COUNT * (mp_maxid + 1); + nintrcnt += INTR_IPI_COUNT * MAXCPU; #endif intrcnt = mallocarray(nintrcnt, sizeof(u_long), M_INTRNG, @@ -312,18 +312,18 @@ intr_ipi_setup_counters(const char *name) mtx_lock(&isrc_table_lock); /* - * We should never have a problem finding mp_maxid + 1 contiguous - * counters, in practice. Interrupts will be allocated sequentially - * during boot, so the array should fill from low to high index. Once - * reserved, the IPI counters will never be released. Similarly, we - * will not need to allocate more IPIs once the system is running. + * We should never have a problem finding MAXCPU contiguous counters, + * in practice. Interrupts will be allocated sequentially during boot, + * so the array should fill from low to high index. Once reserved, the + * IPI counters will never be released. Similarly, we will not need to + * allocate more IPIs once the system is running. */ - bit_ffc_area(intrcnt_bitmap, nintrcnt, mp_maxid + 1, &index); + bit_ffc_area(intrcnt_bitmap, nintrcnt, MAXCPU, &index); if (index == -1) panic("Failed to allocate %d counters. Array exhausted?", - mp_maxid + 1); - bit_nset(intrcnt_bitmap, index, index + mp_maxid); - for (i = 0; i < mp_maxid + 1; i++) { + MAXCPU); + bit_nset(intrcnt_bitmap, index, index + MAXCPU - 1); + for (i = 0; i < MAXCPU; i++) { snprintf(str, INTRNAME_LEN, "cpu%d:%s", i, name); intrcnt_setname(str, index + i); } diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c index ff13672501b2..725467e1215f 100644 --- a/sys/kern/subr_syscall.c +++ b/sys/kern/subr_syscall.c @@ -120,10 +120,13 @@ syscallenter(struct thread *td) * In capability mode, we only allow access to system calls * flagged with SYF_CAPENABLED. */ - if (__predict_false(IN_CAPABILITY_MODE(td) && - (se->sy_flags & SYF_CAPENABLED) == 0)) { - td->td_errno = error = ECAPMODE; - goto retval; + if ((se->sy_flags & SYF_CAPENABLED) == 0) { + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_SYSCALL, NULL); + if (IN_CAPABILITY_MODE(td)) { + td->td_errno = error = ECAPMODE; + goto retval; + } } #endif diff --git a/sys/kern/sys_capability.c b/sys/kern/sys_capability.c index fac264a78531..d59ad37f35ec 100644 --- a/sys/kern/sys_capability.c +++ b/sys/kern/sys_capability.c @@ -154,14 +154,13 @@ MALLOC_DECLARE(M_FILECAPS); static inline int _cap_check(const cap_rights_t *havep, const cap_rights_t *needp, - enum ktr_cap_fail_type type) + enum ktr_cap_violation type) { + const cap_rights_t rights[] = { *needp, *havep }; if (!cap_rights_contains(havep, needp)) { -#ifdef KTRACE - if (KTRPOINT(curthread, KTR_CAPFAIL)) - ktrcapfail(type, needp, havep); -#endif + if (CAP_TRACING(curthread)) + ktrcapfail(type, rights); return (ENOTCAPABLE); } return (0); @@ -180,11 +179,10 @@ cap_check(const cap_rights_t *havep, const cap_rights_t *needp) int cap_check_failed_notcapable(const cap_rights_t *havep, const cap_rights_t *needp) { + const cap_rights_t rights[] = { *needp, *havep }; -#ifdef KTRACE - if (KTRPOINT(curthread, KTR_CAPFAIL)) - ktrcapfail(CAPFAIL_NOTCAPABLE, needp, havep); -#endif + if (CAP_TRACING(curthread)) + ktrcapfail(CAPFAIL_NOTCAPABLE, rights); return (ENOTCAPABLE); } diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c index 1b9434aa438c..0bfbc636e405 100644 --- a/sys/kern/uipc_shm.c +++ b/sys/kern/uipc_shm.c @@ -1172,14 +1172,6 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, if ((shmflags & SHM_ALLOW_SEALING) != 0) initial_seals &= ~F_SEAL_SEAL; -#ifdef CAPABILITY_MODE - /* - * shm_open(2) is only allowed for anonymous objects. - */ - if (IN_CAPABILITY_MODE(td) && (userpath != SHM_ANON)) - return (ECAPMODE); -#endif - AUDIT_ARG_FFLAGS(flags); AUDIT_ARG_MODE(mode); @@ -1204,6 +1196,28 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, if ((initial_seals & ~F_SEAL_SEAL) != 0) return (EINVAL); + if (userpath != SHM_ANON) { + error = shm_copyin_path(td, userpath, &path); + if (error != 0) + return (error); + +#ifdef CAPABILITY_MODE + /* + * shm_open(2) is only allowed for anonymous objects. + */ + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_NAMEI, path); + if (IN_CAPABILITY_MODE(td)) { + free(path, M_SHMFD); + return (ECAPMODE); + } +#endif + + AUDIT_ARG_UPATH1_CANON(path); + } else { + path = NULL; + } + pdp = td->td_proc->p_pd; cmode = (mode & ~pdp->pd_cmask) & ACCESSPERMS; @@ -1215,8 +1229,10 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, * in sys_shm_open() to keep this implementation compliant. */ error = falloc_caps(td, &fp, &fd, flags & O_CLOEXEC, fcaps); - if (error) + if (error) { + free(path, M_SHMFD); return (error); + } /* A SHM_ANON path pointer creates an anonymous object. */ if (userpath == SHM_ANON) { @@ -1230,14 +1246,6 @@ kern_shm_open2(struct thread *td, const char *userpath, int flags, mode_t mode, shmfd->shm_seals = initial_seals; shmfd->shm_flags = shmflags; } else { - error = shm_copyin_path(td, userpath, &path); - if (error != 0) { - fdclose(td, fp, fd); - fdrop(fp, td); - return (error); - } - - AUDIT_ARG_UPATH1_CANON(path); fnv = fnv_32_str(path, FNV1_32_INIT); sx_xlock(&shm_dict_lock); shmfd = shm_lookup(path, fnv); diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 5faf018dca11..32a6ff14bb43 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -106,6 +106,7 @@ #include "opt_inet.h" #include "opt_inet6.h" #include "opt_kern_tls.h" +#include "opt_ktrace.h" #include "opt_sctp.h" #include <sys/param.h> @@ -524,8 +525,12 @@ socreate(int dom, struct socket **aso, int type, int proto, MPASS(prp->pr_attach); - if (IN_CAPABILITY_MODE(td) && (prp->pr_flags & PR_CAPATTACH) == 0) - return (ECAPMODE); + if ((prp->pr_flags & PR_CAPATTACH) == 0) { + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_PROTO, &proto); + if (IN_CAPABILITY_MODE(td)) + return (ECAPMODE); + } if (prison_check_af(cred, prp->pr_domain->dom_family) != 0) return (EPROTONOSUPPORT); diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 85b2214eaeb9..6c13740d8094 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -201,8 +201,12 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) int error; #ifdef CAPABILITY_MODE - if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD)) - return (ECAPMODE); + if (dirfd == AT_FDCWD) { + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_NAMEI, "AT_FDCWD"); + if (IN_CAPABILITY_MODE(td)) + return (ECAPMODE); + } #endif AUDIT_ARG_FD(fd); @@ -487,8 +491,12 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) int error; #ifdef CAPABILITY_MODE - if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD)) - return (ECAPMODE); + if (dirfd == AT_FDCWD) { + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_NAMEI, "AT_FDCWD"); + if (IN_CAPABILITY_MODE(td)) + return (ECAPMODE); + } #endif AUDIT_ARG_FD(fd); @@ -665,11 +673,6 @@ sendit(struct thread *td, int s, struct msghdr *mp, int flags) struct sockaddr *to; int error; -#ifdef CAPABILITY_MODE - if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL)) - return (ECAPMODE); -#endif - if (mp->msg_name != NULL) { error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); if (error != 0) { @@ -677,6 +680,14 @@ sendit(struct thread *td, int s, struct msghdr *mp, int flags) goto bad; } mp->msg_name = to; +#ifdef CAPABILITY_MODE + if (CAP_TRACING(td)) + ktrcapfail(CAPFAIL_SOCKADDR, mp->msg_name); + if (IN_CAPABILITY_MODE(td)) { + error = ECAPMODE; + goto bad; + } +#endif } else { to = NULL; } diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index e3ab80f94482..70c4dbc01c98 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -4396,7 +4396,7 @@ cache_can_fplookup(struct cache_fpl *fpl) cache_fpl_aborted_early(fpl); return (false); } - if (IN_CAPABILITY_MODE(td)) { + if (IN_CAPABILITY_MODE(td) || CAP_TRACING(td)) { cache_fpl_aborted_early(fpl); return (false); } diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 6c83746eaf8b..b7f751a364ce 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -88,6 +88,17 @@ static void NDVALIDATE_impl(struct nameidata *, int); ndp->ni_cnd.cn_flags |= ISRESTARTED; \ } while (0) +#ifdef KTRACE +#define NIKTRCAPFAIL(path) ktrcapfail(CAPFAIL_NAMEI, (path)) +#else +#define NIKTRCAPFAIL(path) +#endif + +#define NI_CAP_VIOLATION(ndp, path) do { \ + NIKTRCAPFAIL(path); \ + (ndp)->ni_lcf &= ~NI_LCF_KTR_FLAGS; \ +} while (0) + SDT_PROVIDER_DEFINE(vfs); SDT_PROBE_DEFINE4(vfs, namei, lookup, entry, "struct vnode *", "char *", "unsigned long", "bool"); @@ -238,14 +249,17 @@ nameicap_check_dotdot(struct nameidata *ndp, struct vnode *dp) struct mount *mp; if (dp == NULL || dp->v_type != VDIR || (ndp->ni_lcf & - NI_LCF_STRICTRELATIVE) == 0) + NI_LCF_STRICTREL) == 0) return (0); + if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL_KTR | + NI_LCF_CAP_DOTDOT_KTR)) == NI_LCF_STRICTREL_KTR)) + NI_CAP_VIOLATION(ndp, ndp->ni_cnd.cn_pnbuf); if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0) return (ENOTCAPABLE); mp = dp->v_mount; if (lookup_cap_dotdot_nonlocal == 0 && mp != NULL && (mp->mnt_flag & MNT_LOCAL) == 0) - return (ENOTCAPABLE); + goto capfail; TAILQ_FOREACH_REVERSE(nt, &ndp->ni_cap_tracker, nameicap_tracker_head, nm_link) { if (dp == nt->dp) { @@ -255,6 +269,10 @@ nameicap_check_dotdot(struct nameidata *ndp, struct vnode *dp) return (0); } } + +capfail: + if (__predict_false((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0)) + NI_CAP_VIOLATION(ndp, ndp->ni_cnd.cn_pnbuf); return (ENOTCAPABLE); } @@ -273,12 +291,12 @@ namei_handle_root(struct nameidata *ndp, struct vnode **dpp) struct componentname *cnp; cnp = &ndp->ni_cnd; - if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0) { -#ifdef KTRACE - if (KTRPOINT(curthread, KTR_CAPFAIL)) - ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL); -#endif - return (ENOTCAPABLE); + if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL | + NI_LCF_STRICTREL_KTR)) != 0)) { + if ((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0) + NI_CAP_VIOLATION(ndp, cnp->cn_pnbuf); + if ((ndp->ni_lcf & NI_LCF_STRICTREL) != 0) + return (ENOTCAPABLE); } while (*(cnp->cn_nameptr) == '/') { cnp->cn_nameptr++; @@ -319,15 +337,17 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp) * previously walked by us, which prevents an escape from * the relative root. */ - if (IN_CAPABILITY_MODE(td) && (cnp->cn_flags & NOCAPCHECK) == 0) { - ndp->ni_lcf |= NI_LCF_STRICTRELATIVE; - ndp->ni_resflags |= NIRES_STRICTREL; - if (ndp->ni_dirfd == AT_FDCWD) { -#ifdef KTRACE - if (KTRPOINT(td, KTR_CAPFAIL)) - ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL); -#endif - return (ECAPMODE); + if ((cnp->cn_flags & NOCAPCHECK) == 0) { + if (CAP_TRACING(td)) { + ndp->ni_lcf |= NI_LCF_STRICTREL_KTR; + if (ndp->ni_dirfd == AT_FDCWD) + NI_CAP_VIOLATION(ndp, "AT_FDCWD"); + } + if (IN_CAPABILITY_MODE(td)) { + ndp->ni_lcf |= NI_LCF_STRICTREL; + ndp->ni_resflags |= NIRES_STRICTREL; + if (ndp->ni_dirfd == AT_FDCWD) + return (ECAPMODE); } } #endif @@ -370,8 +390,8 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp) if (error == 0 && (cnp->cn_flags & RBENEATH) != 0) { if (cnp->cn_pnbuf[0] == '/') { error = ENOTCAPABLE; - } else if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) == 0) { - ndp->ni_lcf |= NI_LCF_STRICTRELATIVE | + } else if ((ndp->ni_lcf & NI_LCF_STRICTREL) == 0) { + ndp->ni_lcf |= NI_LCF_STRICTREL | NI_LCF_CAP_DOTDOT; } } @@ -393,9 +413,12 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp) pwd_drop(pwd); return (error); } - if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0 && - lookup_cap_dotdot != 0) - ndp->ni_lcf |= NI_LCF_CAP_DOTDOT; + if (lookup_cap_dotdot != 0) { + if ((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0) + ndp->ni_lcf |= NI_LCF_CAP_DOTDOT_KTR; + if ((ndp->ni_lcf & NI_LCF_STRICTREL) != 0) + ndp->ni_lcf |= NI_LCF_CAP_DOTDOT; + } SDT_PROBE4(vfs, namei, lookup, entry, *dpp, cnp->cn_pnbuf, cnp->cn_flags, false); *pwdp = pwd; @@ -1170,12 +1193,11 @@ dirloop: * result of dotdot lookup. */ if (cnp->cn_flags & ISDOTDOT) { - if ((ndp->ni_lcf & (NI_LCF_STRICTRELATIVE | NI_LCF_CAP_DOTDOT)) - == NI_LCF_STRICTRELATIVE) { -#ifdef KTRACE - if (KTRPOINT(curthread, KTR_CAPFAIL)) - ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL); -#endif + if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL_KTR | + NI_LCF_CAP_DOTDOT_KTR)) == NI_LCF_STRICTREL_KTR)) + NI_CAP_VIOLATION(ndp, cnp->cn_pnbuf); + if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL | + NI_LCF_CAP_DOTDOT)) == NI_LCF_STRICTREL)) { error = ENOTCAPABLE; goto bad; } @@ -1192,10 +1214,14 @@ dirloop: bool isroot = dp == ndp->ni_rootdir || dp == ndp->ni_topdir || dp == rootvnode || pr != NULL; - if (isroot && (ndp->ni_lcf & - NI_LCF_STRICTRELATIVE) != 0) { - error = ENOTCAPABLE; - goto capdotdot; + if (__predict_false(isroot && (ndp->ni_lcf & + (NI_LCF_STRICTREL | NI_LCF_STRICTREL_KTR)) != 0)) { + if ((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0) + NI_CAP_VIOLATION(ndp, cnp->cn_pnbuf); + if ((ndp->ni_lcf & NI_LCF_STRICTREL) != 0) { + error = ENOTCAPABLE; + goto capdotdot; + } } if (isroot || ((dp->v_vflag & VV_ROOT) != 0 && (cnp->cn_flags & NOCROSSMOUNT) != 0)) { @@ -1220,10 +1246,6 @@ dirloop: error = nameicap_check_dotdot(ndp, dp); if (error != 0) { capdotdot: -#ifdef KTRACE - if (KTRPOINT(curthread, KTR_CAPFAIL)) - ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL); -#endif goto bad; } } @@ -1376,13 +1398,8 @@ nextname: } if (cnp->cn_flags & ISDOTDOT) { error = nameicap_check_dotdot(ndp, ndp->ni_vp); - if (error != 0) { -#ifdef KTRACE - if (KTRPOINT(curthread, KTR_CAPFAIL)) - ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL); -#endif + if (error != 0) goto bad2; - } } if (*ndp->ni_next == '/') { cnp->cn_nameptr = ndp->ni_next; diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 51386d0e9581..1171b72a3a96 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -3341,7 +3341,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, off_t startoff, endoff, xfer, xfer2; u_long blksize; int error, interrupted; - bool cantseek, readzeros, eof, lastblock, holetoeof, sparse; + bool cantseek, readzeros, eof, first, lastblock, holetoeof, sparse; ssize_t aresid, r = 0; size_t copylen, len, savlen; off_t outsize; @@ -3482,6 +3482,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, endts.tv_sec++; } else timespecclear(&endts); + first = true; holetoeof = eof = false; while (len > 0 && error == 0 && !eof && interrupted == 0) { endoff = 0; /* To shut up compilers. */ @@ -3583,10 +3584,17 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, */ xfer -= (*inoffp % blksize); } - /* Loop copying the data block. */ - while (copylen > 0 && error == 0 && !eof && interrupted == 0) { + + /* + * Loop copying the data block. If this was our first attempt + * to copy anything, allow a zero-length block so that the VOPs + * get a chance to update metadata, specifically the atime. + */ + while (error == 0 && ((copylen > 0 && !eof) || first) && + interrupted == 0) { if (copylen < xfer) xfer = copylen; + first = false; error = vn_lock(invp, LK_SHARED); if (error != 0) goto out; @@ -3596,7 +3604,7 @@ vn_generic_copy_file_range(struct vnode *invp, off_t *inoffp, curthread); VOP_UNLOCK(invp); lastblock = false; - if (error == 0 && aresid > 0) { + if (error == 0 && (xfer == 0 || aresid > 0)) { /* Stop the copy at EOF on the input file. */ xfer -= aresid; eof = true; diff --git a/sys/modules/sound/sound/Makefile b/sys/modules/sound/sound/Makefile index 833330ef9b26..1c3685715503 100644 --- a/sys/modules/sound/sound/Makefile +++ b/sys/modules/sound/sound/Makefile @@ -17,7 +17,7 @@ SRCS+= feeder_eq_gen.h feeder_rate_gen.h snd_fxdiv_gen.h SRCS+= mpu_if.h mpufoi_if.h synth_if.h SRCS+= mpu_if.c mpufoi_if.c synth_if.c SRCS+= ac97.c ac97_patch.c buffer.c channel.c dsp.c -SRCS+= mixer.c sndstat.c sound.c unit.c vchan.c +SRCS+= mixer.c sndstat.c sound.c vchan.c SRCS+= midi.c mpu401.c sequencer.c feeder_eq_gen.h: ${SYSDIR}/tools/sound/feeder_eq_mkfilter.awk diff --git a/sys/net/if.c b/sys/net/if.c index 0128fb8039ee..1ca0893eb724 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -4873,6 +4873,9 @@ if_resolvemulti(if_t ifp, struct sockaddr **srcs, struct sockaddr *dst) int if_ioctl(if_t ifp, u_long cmd, void *data) { + if (ifp->if_ioctl == NULL) + return (EOPNOTSUPP); + return (ifp->if_ioctl(ifp, cmd, data)); } diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 1b4ac92b62a3..1e6f9b578ee3 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -403,12 +403,14 @@ static int bridge_ioctl_sproto(struct bridge_softc *, void *); static int bridge_ioctl_stxhc(struct bridge_softc *, void *); static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *, int); +#ifdef INET static int bridge_ip_checkbasic(struct mbuf **mp); +static int bridge_fragment(struct ifnet *, struct mbuf **mp, + struct ether_header *, int, struct llc *); +#endif /* INET */ #ifdef INET6 static int bridge_ip6_checkbasic(struct mbuf **mp); #endif /* INET6 */ -static int bridge_fragment(struct ifnet *, struct mbuf **mp, - struct ether_header *, int, struct llc *); static void bridge_linkstate(struct ifnet *ifp); static void bridge_linkcheck(struct bridge_softc *sc); @@ -3390,12 +3392,15 @@ bridge_state_change(struct ifnet *ifp, int state) static int bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) { - int snap, error, i, hlen; + int snap, error, i; struct ether_header *eh1, eh2; - struct ip *ip; struct llc llc1; u_int16_t ether_type; pfil_return_t rv; +#ifdef INET + struct ip *ip = NULL; + int hlen = 0; +#endif snap = 0; error = -1; /* Default error if not error == 0 */ @@ -3436,31 +3441,36 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) } /* - * If we're trying to filter bridge traffic, don't look at anything - * other than IP and ARP traffic. If the filter doesn't understand - * IPv6, don't allow IPv6 through the bridge either. This is lame - * since if we really wanted, say, an AppleTalk filter, we are hosed, - * but of course we don't have an AppleTalk filter to begin with. - * (Note that since pfil doesn't understand ARP it will pass *ALL* - * ARP traffic.) + * If we're trying to filter bridge traffic, only look at traffic for + * protocols available in the kernel (IPv4 and/or IPv6) to avoid + * passing traffic for an unsupported protocol to the filter. This is + * lame since if we really wanted, say, an AppleTalk filter, we are + * hosed, but of course we don't have an AppleTalk filter to begin + * with. (Note that since pfil doesn't understand ARP it will pass + * *ALL* ARP traffic.) */ switch (ether_type) { +#ifdef INET case ETHERTYPE_ARP: case ETHERTYPE_REVARP: if (V_pfil_ipfw_arp == 0) return (0); /* Automatically pass */ - break; + /* FALLTHROUGH */ case ETHERTYPE_IP: +#endif #ifdef INET6 case ETHERTYPE_IPV6: #endif /* INET6 */ break; + default: /* - * Check to see if the user wants to pass non-ip - * packets, these will not be checked by pfil(9) and - * passed unconditionally so the default is to drop. + * We get here if the packet isn't from a supported + * protocol. Check to see if the user wants to pass + * non-IP packets, these will not be checked by pfil(9) + * and passed unconditionally so the default is to + * drop. */ if (V_pfil_onlyip) goto bad; @@ -3492,9 +3502,11 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) */ if (dir == PFIL_IN) { switch (ether_type) { +#ifdef INET case ETHERTYPE_IP: error = bridge_ip_checkbasic(mp); break; +#endif #ifdef INET6 case ETHERTYPE_IPV6: error = bridge_ip6_checkbasic(mp); @@ -3514,6 +3526,7 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) */ rv = PFIL_PASS; switch (ether_type) { +#ifdef INET case ETHERTYPE_IP: /* * Run pfil on the member interface and the bridge, both can @@ -3571,6 +3584,7 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) ip->ip_sum = in_cksum(*mp, hlen); break; +#endif /* INET */ #ifdef INET6 case ETHERTYPE_IPV6: if (V_pfil_bridge && dir == PFIL_OUT && bifp != NULL && (rv = @@ -3628,6 +3642,7 @@ bad: return (error); } +#ifdef INET /* * Perform basic checks on header size since * pfil assumes ip_input has already processed @@ -3728,6 +3743,7 @@ bad: *mp = m; return (-1); } +#endif /* INET */ #ifdef INET6 /* @@ -3783,6 +3799,7 @@ bad: } #endif /* INET6 */ +#ifdef INET /* * bridge_fragment: * @@ -3859,6 +3876,7 @@ dropit: } return (error); } +#endif /* INET */ static void bridge_linkstate(struct ifnet *ifp) diff --git a/sys/net/if_disc.c b/sys/net/if_disc.c index 02f3bbbfdaf1..193bb31d138f 100644 --- a/sys/net/if_disc.c +++ b/sys/net/if_disc.c @@ -182,7 +182,7 @@ discoutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, M_ASSERTPKTHDR(m); /* BPF writes need to be handled specially. */ - if (dst->sa_family == AF_UNSPEC) + if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT) bcopy(dst->sa_data, &af, sizeof(af)); else af = RO_GET_FAMILY(ro, dst); diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index e5065889d732..ef64c15074ed 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -408,7 +408,8 @@ gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, KASSERT(ifp->if_bridge == NULL, ("%s: unexpectedly called with bridge attached", __func__)); - if (dst->sa_family == AF_UNSPEC) + /* BPF writes need to be handled specially. */ + if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT) memcpy(&af, dst->sa_data, sizeof(af)); else af = RO_GET_FAMILY(ro, dst); diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 55163416f807..ca9c4835daf6 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -609,7 +609,8 @@ gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, { uint32_t af; - if (dst->sa_family == AF_UNSPEC) + /* BPF writes need to be handled specially. */ + if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT) bcopy(dst->sa_data, &af, sizeof(af)); else af = RO_GET_FAMILY(ro, dst); diff --git a/sys/net/if_me.c b/sys/net/if_me.c index e9bcd345b5c5..80c2816b808a 100644 --- a/sys/net/if_me.c +++ b/sys/net/if_me.c @@ -539,7 +539,8 @@ me_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, { uint32_t af; - if (dst->sa_family == AF_UNSPEC) + /* BPF writes need to be handled specially. */ + if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT) bcopy(dst->sa_data, &af, sizeof(af)); else af = RO_GET_FAMILY(ro, dst); diff --git a/sys/net/if_tuntap.c b/sys/net/if_tuntap.c index 4cb219dc92b6..5d37879e87b9 100644 --- a/sys/net/if_tuntap.c +++ b/sys/net/if_tuntap.c @@ -1442,7 +1442,7 @@ tunoutput(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst, } /* BPF writes need to be handled specially. */ - if (dst->sa_family == AF_UNSPEC) + if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT) bcopy(dst->sa_data, &af, sizeof(af)); else af = RO_GET_FAMILY(ro, dst); diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index 8ae4707b7abd..e9f97ff0fdec 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -367,7 +367,7 @@ ng_iface_output(struct ifnet *ifp, struct mbuf *m, } /* BPF writes need to be handled specially. */ - if (dst->sa_family == AF_UNSPEC) + if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT) bcopy(dst->sa_data, &af, sizeof(af)); else af = RO_GET_FAMILY(ro, dst); diff --git a/sys/netgraph/ng_pipe.c b/sys/netgraph/ng_pipe.c index a2966c9a0349..42a5991e8dc7 100644 --- a/sys/netgraph/ng_pipe.c +++ b/sys/netgraph/ng_pipe.c @@ -34,7 +34,7 @@ * This node permits simple traffic shaping by emulating bandwidth * and delay, as well as random packet losses. * The node has two hooks, upper and lower. Traffic flowing from upper to - * lower hook is referenced as downstream, and vice versa. Parameters for + * lower hook is referenced as downstream, and vice versa. Parameters for * both directions can be set separately, except for delay. */ @@ -44,6 +44,7 @@ #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/mbuf.h> +#include <sys/prng.h> #include <sys/time.h> #include <vm/uma.h> @@ -195,8 +196,8 @@ static const struct ng_cmdlist ngp_cmds[] = { { .cookie = NGM_PIPE_COOKIE, .cmd = NGM_PIPE_GET_STATS, - .name = "getstats", - .respType = &ng_pipe_stats_type + .name = "getstats", + .respType = &ng_pipe_stats_type }, { .cookie = NGM_PIPE_COOKIE, @@ -494,7 +495,7 @@ parse_cfg(struct ng_pipe_hookcfg *current, struct ng_pipe_hookcfg *new, if (new->qin_size_limit == -1) current->qin_size_limit = 0; - else if (new->qin_size_limit >= 5) + else if (new->qin_size_limit >= 5) current->qin_size_limit = new->qin_size_limit; if (new->qout_size_limit == -1) @@ -547,7 +548,7 @@ parse_cfg(struct ng_pipe_hookcfg *current, struct ng_pipe_hookcfg *new, } else if (new->bandwidth >= 100 && new->bandwidth <= 1000000000) current->bandwidth = new->bandwidth; - if (current->bandwidth | priv->delay | + if (current->bandwidth | priv->delay | current->duplicate | current->ber) hinfo->noqueue = 0; else @@ -640,12 +641,14 @@ ngp_rcvdata(hook_p hook, item_p item) } /* Populate the packet header */ - ngp_h = uma_zalloc(ngp_zone, M_NOWAIT); - KASSERT((ngp_h != NULL), ("ngp_h zalloc failed (1)")); NGI_GET_M(item, m); - KASSERT(m != NULL, ("NGI_GET_M failed")); - ngp_h->m = m; NG_FREE_ITEM(item); + ngp_h = uma_zalloc(ngp_zone, M_NOWAIT); + if (ngp_h == NULL) { + NG_FREE_M(m); + return (ENOMEM); + } + ngp_h->m = m; if (hinfo->cfg.fifo) hash = 0; /* all packets go into a single FIFO queue */ @@ -658,7 +661,11 @@ ngp_rcvdata(hook_p hook, item_p item) break; if (ngp_f == NULL) { ngp_f = uma_zalloc(ngp_zone, M_NOWAIT); - KASSERT(ngp_h != NULL, ("ngp_h zalloc failed (2)")); + if (ngp_f == NULL) { + NG_FREE_M(ngp_h->m); + uma_zfree(ngp_zone, ngp_h); + return (ENOMEM); + } TAILQ_INIT(&ngp_f->packet_head); ngp_f->hash = hash; ngp_f->packets = 1; @@ -686,9 +693,9 @@ ngp_rcvdata(hook_p hook, item_p item) } /* Drop a frame from the queue head/tail, depending on cfg */ - if (hinfo->cfg.drophead) + if (hinfo->cfg.drophead) ngp_h = TAILQ_FIRST(&ngp_f->packet_head); - else + else ngp_h = TAILQ_LAST(&ngp_f->packet_head, p_head); TAILQ_REMOVE(&ngp_f->packet_head, ngp_h, ngp_link); m1 = ngp_h->m; @@ -732,7 +739,7 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) { const priv_p priv = NG_NODE_PRIVATE(node); struct hookinfo *dest; struct ngp_fifo *ngp_f, *ngp_f1; - struct ngp_hdr *ngp_h; + struct ngp_hdr *ngp_h, *ngp_dup; struct timeval *when; struct mbuf *m; int plen, error = 0; @@ -767,23 +774,34 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) { } /* - * Either create a duplicate and pass it on, or dequeue - * the original packet... + * Either create a duplicate and pass it on, or + * dequeue the original packet. When any of the + * memory allocations for the duplicate package fail, + * simply do not duplicate it at all. */ + ngp_dup = NULL; if (hinfo->cfg.duplicate && - random() % 100 <= hinfo->cfg.duplicate) { - ngp_h = uma_zalloc(ngp_zone, M_NOWAIT); - KASSERT(ngp_h != NULL, ("ngp_h zalloc failed (3)")); - m = m_dup(m, M_NOWAIT); - KASSERT(m != NULL, ("m_dup failed")); - ngp_h->m = m; + prng32_bounded(100) <= hinfo->cfg.duplicate) { + ngp_dup = uma_zalloc(ngp_zone, M_NOWAIT); + if (ngp_dup != NULL) { + ngp_dup->m = m_dup(m, M_NOWAIT); + if (ngp_dup->m == NULL) { + uma_zfree(ngp_zone, ngp_dup); + ngp_dup = NULL; + } + } + } + + if (ngp_dup != NULL) { + ngp_h = ngp_dup; + m = ngp_h->m; } else { TAILQ_REMOVE(&ngp_f->packet_head, ngp_h, ngp_link); hinfo->run.qin_frames--; hinfo->run.qin_octets -= m->m_pkthdr.len; ngp_f->packets--; } - + /* Calculate the serialization delay */ if (hinfo->cfg.bandwidth) { hinfo->qin_utime.tv_usec += @@ -814,7 +832,7 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) { /* Randomly discard the frame, according to BER setting */ if (hinfo->cfg.ber) { oldrand = rand; - rand = random(); + rand = prng32_bounded(1U << 31); if (((oldrand ^ rand) << 17) >= hinfo->ber_p[priv->overhead + m->m_pkthdr.len]) { hinfo->stats.out_disc_frames++; @@ -936,6 +954,7 @@ ngp_disconnect(hook_p hook) struct hookinfo *const hinfo = NG_HOOK_PRIVATE(hook); struct ngp_fifo *ngp_f; struct ngp_hdr *ngp_h; + priv_p priv; KASSERT(hinfo != NULL, ("%s: null info", __FUNCTION__)); hinfo->hook = NULL; @@ -962,6 +981,12 @@ ngp_disconnect(hook_p hook) if (hinfo->ber_p) free(hinfo->ber_p, M_NG_PIPE); + /* Destroy the node if all hooks are disconnected */ + priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); + + if (priv->upper.hook == NULL && priv->lower.hook == NULL) + ng_rmnode_self(NG_HOOK_NODE(hook)); + return (0); } @@ -975,8 +1000,6 @@ ngp_modevent(module_t mod, int type, void *unused) ngp_zone = uma_zcreate("ng_pipe", max(sizeof(struct ngp_hdr), sizeof (struct ngp_fifo)), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); - if (ngp_zone == NULL) - panic("ng_pipe: couldn't allocate descriptor zone"); break; case MOD_UNLOAD: uma_zdestroy(ngp_zone); diff --git a/sys/netinet/in_fib_dxr.c b/sys/netinet/in_fib_dxr.c index e7eede53ea51..82245ecf6e66 100644 --- a/sys/netinet/in_fib_dxr.c +++ b/sys/netinet/in_fib_dxr.c @@ -474,8 +474,7 @@ chunk_ref(struct dxr_aux *da, uint32_t chunk) cdp->cd_max_size = size; cdp->cd_base = fdesc->base; LIST_INSERT_HEAD(&da->all_chunks, cdp, cd_all_le); - KASSERT(cdp->cd_base + cdp->cd_max_size == da->rtbl_top, - ("dxr: %s %d", __FUNCTION__, __LINE__)); + MPASS(cdp->cd_base + cdp->cd_max_size == da->rtbl_top); } cdp->cd_hash = hash; @@ -497,8 +496,11 @@ chunk_ref(struct dxr_aux *da, uint32_t chunk) da->range_tbl = realloc(da->range_tbl, sizeof(*da->range_tbl) * da->rtbl_size + FRAGS_PREF_SHORT, M_DXRAUX, M_NOWAIT); - if (da->range_tbl == NULL) + if (da->range_tbl == NULL) { + FIB_PRINTF(LOG_NOTICE, da->fd, + "Unable to allocate DXR range table"); return (1); + } } return (0); @@ -522,7 +524,7 @@ chunk_unref(struct dxr_aux *da, uint32_t chunk) sizeof(struct range_entry_long) * size) == 0) break; - KASSERT(cdp != NULL, ("dxr: dangling chunk")); + MPASS(cdp != NULL); if (--cdp->cd_refcnt > 0) return; @@ -533,8 +535,7 @@ chunk_unref(struct dxr_aux *da, uint32_t chunk) /* Attempt to merge with the preceding chunk, if empty */ cdp2 = LIST_NEXT(cdp, cd_all_le); if (cdp2 != NULL && cdp2->cd_cur_size == 0) { - KASSERT(cdp2->cd_base + cdp2->cd_max_size == cdp->cd_base, - ("dxr: %s %d", __FUNCTION__, __LINE__)); + MPASS(cdp2->cd_base + cdp2->cd_max_size == cdp->cd_base); LIST_REMOVE(cdp, cd_all_le); LIST_REMOVE(cdp2, cd_hash_le); cdp2->cd_max_size += cdp->cd_max_size; @@ -545,8 +546,7 @@ chunk_unref(struct dxr_aux *da, uint32_t chunk) /* Attempt to merge with the subsequent chunk, if empty */ cdp2 = LIST_PREV(cdp, &da->all_chunks, chunk_desc, cd_all_le); if (cdp2 != NULL && cdp2->cd_cur_size == 0) { - KASSERT(cdp->cd_base + cdp->cd_max_size == cdp2->cd_base, - ("dxr: %s %d", __FUNCTION__, __LINE__)); + MPASS(cdp->cd_base + cdp->cd_max_size == cdp2->cd_base); LIST_REMOVE(cdp, cd_all_le); LIST_REMOVE(cdp2, cd_hash_le); cdp2->cd_max_size += cdp->cd_max_size; @@ -557,8 +557,7 @@ chunk_unref(struct dxr_aux *da, uint32_t chunk) if (cdp->cd_base + cdp->cd_max_size == da->rtbl_top) { /* Free the chunk on the top of the range heap, trim the heap */ - KASSERT(cdp == LIST_FIRST(&da->all_chunks), - ("dxr: %s %d", __FUNCTION__, __LINE__)); + MPASS(cdp == LIST_FIRST(&da->all_chunks)); da->rtbl_top -= cdp->cd_max_size; da->unused_chunks_size -= cdp->cd_max_size; LIST_REMOVE(cdp, cd_all_le); @@ -632,8 +631,11 @@ trie_ref(struct dxr_aux *da, uint32_t index) da->xtbl_size += XTBL_SIZE_INCR; da->x_tbl = realloc(da->x_tbl, sizeof(*da->x_tbl) * da->xtbl_size, M_DXRAUX, M_NOWAIT); - if (da->x_tbl == NULL) + if (da->x_tbl == NULL) { + FIB_PRINTF(LOG_NOTICE, da->fd, + "Unable to allocate DXR extension table"); return (-1); + } } return(tp->td_index); } @@ -869,14 +871,18 @@ dxr_build(struct dxr *dxr) uint32_t trie_frag; #endif - KASSERT(dxr->d == NULL, ("dxr: d not free")); + MPASS(dxr->d == NULL); if (da == NULL) { da = malloc(sizeof(*dxr->aux), M_DXRAUX, M_NOWAIT); - if (da == NULL) + if (da == NULL) { + FIB_PRINTF(LOG_NOTICE, dxr->fd, + "Unable to allocate DXR aux struct"); return; + } dxr->aux = da; da->fibnum = dxr->fibnum; + da->fd = dxr->fd; da->refcnt = 1; LIST_INIT(&da->all_chunks); LIST_INIT(&da->all_trie); @@ -894,20 +900,25 @@ dxr_build(struct dxr *dxr) if (da->range_tbl == NULL) { da->range_tbl = malloc(sizeof(*da->range_tbl) * da->rtbl_size + FRAGS_PREF_SHORT, M_DXRAUX, M_NOWAIT); - if (da->range_tbl == NULL) + if (da->range_tbl == NULL) { + FIB_PRINTF(LOG_NOTICE, da->fd, + "Unable to allocate DXR range table"); return; + } range_rebuild = 1; } #ifdef DXR2 if (da->x_tbl == NULL) { da->x_tbl = malloc(sizeof(*da->x_tbl) * da->xtbl_size, M_DXRAUX, M_NOWAIT); - if (da->x_tbl == NULL) + if (da->x_tbl == NULL) { + FIB_PRINTF(LOG_NOTICE, da->fd, + "Unable to allocate DXR extension table"); return; + } trie_rebuild = 1; } #endif - da->fd = dxr->fd; microuptime(&t0); @@ -1039,8 +1050,11 @@ dxr2_try_squeeze: #endif dxr->d = malloc(dxr_tot_size, M_DXRLPM, M_NOWAIT); - if (dxr->d == NULL) + if (dxr->d == NULL) { + FIB_PRINTF(LOG_NOTICE, da->fd, + "Unable to allocate DXR lookup table"); return; + } #ifdef DXR2 memcpy(dxr->d, da->d_tbl, d_size); dxr->x = ((char *) dxr->d) + d_size; @@ -1098,7 +1112,7 @@ dxr2_try_squeeze: } /* - * Glue functions for attaching to FreeBSD 13 fib_algo infrastructure. + * Glue functions for attaching to the FIB_ALGO infrastructure. */ static struct nhop_object * @@ -1118,8 +1132,11 @@ dxr_init(uint32_t fibnum, struct fib_data *fd, void *old_data, void **data) struct dxr *dxr; dxr = malloc(sizeof(*dxr), M_DXRAUX, M_NOWAIT); - if (dxr == NULL) + if (dxr == NULL) { + FIB_PRINTF(LOG_NOTICE, fd, + "Unable to allocate DXR container struct"); return (FLM_REBUILD); + } /* Check whether we may reuse the old auxiliary structures */ if (old_dxr != NULL && old_dxr->aux != NULL) { @@ -1140,14 +1157,11 @@ static void dxr_destroy(void *data) { struct dxr *dxr = data; - struct dxr_aux *da; + struct dxr_aux *da = dxr->aux; struct chunk_desc *cdp; struct trie_desc *tp; - if (dxr->d != NULL) - free(dxr->d, M_DXRLPM); - - da = dxr->aux; + free(dxr->d, M_DXRLPM); free(dxr, M_DXRAUX); if (da == NULL || atomic_fetchadd_int(&da->refcnt, -1) > 1) @@ -1213,17 +1227,12 @@ dxr_dump_end(void *data, struct fib_dp *dp) dxr_build(dxr); da = dxr->aux; - if (da == NULL) + if (da == NULL || dxr->d == NULL) return (FLM_REBUILD); - /* Structural limit exceeded, hard error */ if (da->rtbl_top >= BASE_MAX) return (FLM_ERROR); - /* A malloc(,, M_NOWAIT) failed somewhere, retry later */ - if (dxr->d == NULL) - return (FLM_REBUILD); - dp->f = choose_lookup_fn(da); dp->arg = dxr; @@ -1260,13 +1269,14 @@ dxr_change_rib_batch(struct rib_head *rnh, struct fib_change_queue *q, int update_delta = 0; #endif - KASSERT(data != NULL, ("%s: NULL data", __FUNCTION__)); - KASSERT(q != NULL, ("%s: NULL q", __FUNCTION__)); - KASSERT(q->count < q->size, ("%s: q->count %d q->size %d", - __FUNCTION__, q->count, q->size)); + MPASS(data != NULL); + MPASS(q != NULL); + MPASS(q->count < q->size); da = dxr->aux; - KASSERT(da != NULL, ("%s: NULL dxr->aux", __FUNCTION__)); + MPASS(da != NULL); + MPASS(da->fd != NULL); + MPASS(da->refcnt > 0); FIB_PRINTF(LOG_INFO, da->fd, "processing %d update(s)", q->count); for (ui = 0; ui < q->count; ui++) { @@ -1299,8 +1309,7 @@ dxr_change_rib_batch(struct rib_head *rnh, struct fib_change_queue *q, #ifdef INVARIANTS fib_get_rtable_info(fib_get_rh(da->fd), &rinfo); - KASSERT(da->prefixes + update_delta == rinfo.num_prefixes, - ("%s: update count mismatch", __FUNCTION__)); + MPASS(da->prefixes + update_delta == rinfo.num_prefixes); #endif res = dxr_init(0, dxr->fd, data, (void **) &new_dxr); @@ -1310,12 +1319,9 @@ dxr_change_rib_batch(struct rib_head *rnh, struct fib_change_queue *q, dxr_build(new_dxr); /* Structural limit exceeded, hard error */ - if (da->rtbl_top >= BASE_MAX) { - dxr_destroy(new_dxr); + if (da->rtbl_top >= BASE_MAX) return (FLM_ERROR); - } - /* A malloc(,, M_NOWAIT) failed somewhere, retry later */ if (new_dxr->d == NULL) { dxr_destroy(new_dxr); return (FLM_REBUILD); @@ -1329,6 +1335,7 @@ dxr_change_rib_batch(struct rib_head *rnh, struct fib_change_queue *q, return (FLM_SUCCESS); } + FIB_PRINTF(LOG_NOTICE, dxr->fd, "fib_set_datapath_ptr() failed"); dxr_destroy(new_dxr); return (FLM_REBUILD); } diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 95e162e60f53..0fffd285fb17 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -657,6 +657,10 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo) #if defined(IPSEC) || defined(IPSEC_SUPPORT) || defined(MAC) out: + crfree(inp->inp_cred); +#ifdef INVARIANTS + inp->inp_cred = NULL; +#endif uma_zfree_smr(pcbinfo->ipi_zone, inp); return (error); #endif diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h index 2b59e46b5bcc..937dc8fbbbc2 100644 --- a/sys/netinet/ip_fw.h +++ b/sys/netinet/ip_fw.h @@ -979,7 +979,7 @@ typedef struct _ipfw_range_tlv { #define IPFW_RCFLAG_USER (IPFW_RCFLAG_RANGE | IPFW_RCFLAG_ALL | \ IPFW_RCFLAG_SET | IPFW_RCFLAG_DYNAMIC) /* Internally used flags */ -#define IPFW_RCFLAG_DEFAULT 0x0100 /* Do not skip defaul rule */ +#define IPFW_RCFLAG_DEFAULT 0x0100 /* Do not skip default rule */ typedef struct _ipfw_ta_tinfo { uint32_t flags; /* Format flags */ diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 78c9cd56ed60..ce3bbea6b8e6 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -102,7 +102,13 @@ struct in6_addr { }; #define s6_addr __u6_addr.__u6_addr8 -#if defined(_KERNEL) || defined(_STANDALONE) /* XXX nonstandard */ +#if __BSD_VISIBLE +/* + * s6_addr is the only in6_addr element specified in RFCs 2553 and 3493, + * also in POSIX 1003.1-2017. The following three definitions were not + * exposed to user programs in FreeBSD before 14.1, or in other BSDs, + * and are thus less portable than s6_addr. + */ #define s6_addr8 __u6_addr.__u6_addr8 #define s6_addr16 __u6_addr.__u6_addr16 #define s6_addr32 __u6_addr.__u6_addr32 diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 5fc234c5aca9..6874dd59c1f7 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -1325,6 +1325,7 @@ keyattach: sk : NULL); printf("\n"); } + s->timeout = PFTM_UNLINKED; PF_HASHROW_UNLOCK(ih); KEYS_UNLOCK(); uma_zfree(V_pf_state_key_z, sk); @@ -1392,6 +1393,8 @@ pf_detach_state(struct pf_kstate *s) struct pf_state_key *sks = s->key[PF_SK_STACK]; struct pf_keyhash *kh; + MPASS(s->timeout >= PFTM_MAX); + pf_sctp_multihome_detach_addr(s); if (sks != NULL) { @@ -1517,6 +1520,7 @@ pf_state_insert(struct pfi_kkif *kif, struct pfi_kkif *orig_kif, break; if (cur != NULL) { + s->timeout = PFTM_UNLINKED; PF_HASHROW_UNLOCK(ih); if (V_pf_status.debug >= PF_DEBUG_MISC) { printf("pf: state ID collision: " diff --git a/sys/sys/bitset.h b/sys/sys/bitset.h index 5ff2bb76a4ab..4afac9b172e8 100644 --- a/sys/sys/bitset.h +++ b/sys/sys/bitset.h @@ -135,6 +135,18 @@ (d)->__bits[__i] = (s1)->__bits[__i] | (s2)->__bits[__i];\ } while (0) +#define __BIT_ORNOT(_s, d, s) do { \ + __size_t __i; \ + for (__i = 0; __i < __bitset_words((_s)); __i++) \ + (d)->__bits[__i] |= ~(s)->__bits[__i]; \ +} while (0) + +#define __BIT_ORNOT2(_s, d, s1, s2) do { \ + __size_t __i; \ + for (__i = 0; __i < __bitset_words((_s)); __i++) \ + (d)->__bits[__i] = (s1)->__bits[__i] | ~(s2)->__bits[__i];\ +} while (0) + #define __BIT_AND(_s, d, s) do { \ __size_t __i; \ for (__i = 0; __i < __bitset_words((_s)); __i++) \ @@ -330,6 +342,8 @@ #define BIT_ISSET(_s, n, p) __BIT_ISSET(_s, n, p) #define BIT_OR(_s, d, s) __BIT_OR(_s, d, s) #define BIT_OR2(_s, d, s1, s2) __BIT_OR2(_s, d, s1, s2) +#define BIT_ORNOT(_s, d, s) __BIT_ORNOT(_s, d, s) +#define BIT_ORNOT2(_s, d, s1, s2) __BIT_ORNOT2(_s, d, s1, s2) #define BIT_OR_ATOMIC(_s, d, s) __BIT_OR_ATOMIC(_s, d, s) #define BIT_OVERLAP(_s, p, c) __BIT_OVERLAP(_s, p, c) #define BIT_SET(_s, n, p) __BIT_SET(_s, n, p) diff --git a/sys/sys/capsicum.h b/sys/sys/capsicum.h index 93c5f0c9c390..e2f305462f0d 100644 --- a/sys/sys/capsicum.h +++ b/sys/sys/capsicum.h @@ -417,6 +417,13 @@ __END_DECLS #ifdef _KERNEL #include <sys/systm.h> +#include <sys/ktrace.h> + +#ifdef KTRACE +#define CAP_TRACING(td) KTRPOINT((td), KTR_CAPFAIL) +#else +#define CAP_TRACING(td) 0 +#endif #define IN_CAPABILITY_MODE(td) (((td)->td_ucred->cr_flags & CRED_FLAG_CAPMODE) != 0) diff --git a/sys/sys/cpuset.h b/sys/sys/cpuset.h index 219e190f0b37..b036b45da283 100644 --- a/sys/sys/cpuset.h +++ b/sys/sys/cpuset.h @@ -56,6 +56,7 @@ #define CPU_OVERLAP(p, c) __BIT_OVERLAP(CPU_SETSIZE, p, c) #define CPU_CMP(p, c) __BIT_CMP(CPU_SETSIZE, p, c) #define CPU_OR(d, s1, s2) __BIT_OR2(CPU_SETSIZE, d, s1, s2) +#define CPU_ORNOT(d, s1, s2) __BIT_ORNOT2(CPU_SETSIZE, d, s1, s2) #define CPU_AND(d, s1, s2) __BIT_AND2(CPU_SETSIZE, d, s1, s2) #define CPU_ANDNOT(d, s1, s2) __BIT_ANDNOT2(CPU_SETSIZE, d, s1, s2) #define CPU_XOR(d, s1, s2) __BIT_XOR2(CPU_SETSIZE, d, s1, s2) diff --git a/sys/sys/domainset.h b/sys/sys/domainset.h index 42891263b81b..f98b175e9bc8 100644 --- a/sys/sys/domainset.h +++ b/sys/sys/domainset.h @@ -54,6 +54,7 @@ #define DOMAINSET_OVERLAP(p, c) __BIT_OVERLAP(DOMAINSET_SETSIZE, p, c) #define DOMAINSET_CMP(p, c) __BIT_CMP(DOMAINSET_SETSIZE, p, c) #define DOMAINSET_OR(d, s) __BIT_OR(DOMAINSET_SETSIZE, d, s) +#define DOMAINSET_ORNOT(d, s) __BIT_ORNOT(DOMAINSET_SETSIZE, d, s) #define DOMAINSET_AND(d, s) __BIT_AND(DOMAINSET_SETSIZE, d, s) #define DOMAINSET_ANDNOT(d, s) __BIT_ANDNOT(DOMAINSET_SETSIZE, d, s) #define DOMAINSET_CLR_ATOMIC(n, p) __BIT_CLR_ATOMIC(DOMAINSET_SETSIZE, n, p) diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h index 594f912b02ef..6d8280c415a6 100644 --- a/sys/sys/ktrace.h +++ b/sys/sys/ktrace.h @@ -34,8 +34,10 @@ #ifndef _SYS_KTRACE_H_ #define _SYS_KTRACE_H_ +#include <sys/param.h> #include <sys/caprights.h> #include <sys/signal.h> +#include <sys/socket.h> #include <sys/_uio.h> /* @@ -207,16 +209,31 @@ struct ktr_proc_ctor { * KTR_CAPFAIL - trace capability check failures */ #define KTR_CAPFAIL 12 -enum ktr_cap_fail_type { +enum ktr_cap_violation { CAPFAIL_NOTCAPABLE, /* insufficient capabilities in cap_check() */ - CAPFAIL_INCREASE, /* attempt to increase capabilities */ + CAPFAIL_INCREASE, /* attempt to increase rights on a capability */ CAPFAIL_SYSCALL, /* disallowed system call */ - CAPFAIL_LOOKUP, /* disallowed VFS lookup */ + CAPFAIL_SIGNAL, /* sent signal to process other than self */ + CAPFAIL_PROTO, /* disallowed protocol */ + CAPFAIL_SOCKADDR, /* restricted address lookup */ + CAPFAIL_NAMEI, /* restricted namei lookup */ + CAPFAIL_CPUSET, /* restricted CPU set modification */ }; + +union ktr_cap_data { + cap_rights_t cap_rights[2]; +#define cap_needed cap_rights[0] +#define cap_held cap_rights[1] + int cap_int; + struct sockaddr cap_sockaddr; + char cap_path[MAXPATHLEN]; +}; + struct ktr_cap_fail { - enum ktr_cap_fail_type cap_type; - cap_rights_t cap_needed; - cap_rights_t cap_held; + enum ktr_cap_violation cap_type; + short cap_code; + u_int cap_svflags; + union ktr_cap_data cap_data; }; /* @@ -319,8 +336,7 @@ void ktruserret(struct thread *); void ktrstruct(const char *, const void *, size_t); void ktrstruct_error(const char *, const void *, size_t, int); void ktrstructarray(const char *, enum uio_seg, const void *, int, size_t); -void ktrcapfail(enum ktr_cap_fail_type, const cap_rights_t *, - const cap_rights_t *); +void ktrcapfail(enum ktr_cap_violation, const void *); #define ktrcaprights(s) \ ktrstruct("caprights", (s), sizeof(cap_rights_t)) #define ktritimerval(s) \ diff --git a/sys/sys/namei.h b/sys/sys/namei.h index 8ffa87aa3d7e..f6279700e735 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -198,8 +198,12 @@ int cache_fplookup(struct nameidata *ndp, enum cache_fpl_status *status, /* * Flags in ni_lcf, valid for the duration of the namei call. */ -#define NI_LCF_STRICTRELATIVE 0x0001 /* relative lookup only */ +#define NI_LCF_STRICTREL 0x0001 /* relative lookup only */ #define NI_LCF_CAP_DOTDOT 0x0002 /* ".." in strictrelative case */ +/* Track capability restrictions seperately for violation ktracing. */ +#define NI_LCF_STRICTREL_KTR 0x0004 /* trace relative lookups */ +#define NI_LCF_CAP_DOTDOT_KTR 0x0008 /* ".." in strictrelative case */ +#define NI_LCF_KTR_FLAGS (NI_LCF_STRICTREL_KTR | NI_LCF_CAP_DOTDOT_KTR) /* * Initialization of a nameidata structure. diff --git a/sys/sys/sdt.h b/sys/sys/sdt.h index ba3dcfa15762..20be685ad081 100644 --- a/sys/sys/sdt.h +++ b/sys/sys/sdt.h @@ -147,36 +147,41 @@ SET_DECLARE(sdt_providers_set, struct sdt_provider); SET_DECLARE(sdt_probes_set, struct sdt_probe); SET_DECLARE(sdt_argtypes_set, struct sdt_argtype); +#define _SDT_PROBE_NAME(prov, mod, func, name) \ + sdt_##prov##_##mod##_##func##_##name +#define _SDT_PROVIDER_NAME(prov) \ + sdt_provider_##prov + #define SDT_PROVIDER_DEFINE(_prov) \ - struct sdt_provider sdt_provider_##_prov[1] = { \ + struct sdt_provider _SDT_PROVIDER_NAME(_prov)[1] = { \ [0] = { .name = #_prov }, \ }; \ - DATA_SET(sdt_providers_set, sdt_provider_##_prov); + DATA_SET(sdt_providers_set, _SDT_PROVIDER_NAME(_prov)) -#define SDT_PROVIDER_DECLARE(prov) \ - extern struct sdt_provider sdt_provider_##prov[1] +#define SDT_PROVIDER_DECLARE(prov) \ + extern struct sdt_provider _SDT_PROVIDER_NAME(prov)[1] #define SDT_PROBE_DEFINE(_prov, _mod, _func, _name) \ - struct sdt_probe sdt_##_prov##_##_mod##_##_func##_##_name[1] = {\ + struct sdt_probe _SDT_PROBE_NAME(_prov, _mod, _func, _name)[1] = { \ [0] = { \ .version = sizeof(struct sdt_probe), \ - .prov = sdt_provider_##_prov, \ + .prov = _SDT_PROVIDER_NAME(_prov), \ .mod = #_mod, \ .func = #_func, \ .name = #_name, \ }, \ }; \ - DATA_SET(sdt_probes_set, sdt_##_prov##_##_mod##_##_func##_##_name) + DATA_SET(sdt_probes_set, _SDT_PROBE_NAME(_prov, _mod, _func, _name)) -#define SDT_PROBE_DECLARE(prov, mod, func, name) \ - extern struct sdt_probe sdt_##prov##_##mod##_##func##_##name[1] +#define SDT_PROBE_DECLARE(prov, mod, func, name) \ + extern struct sdt_probe _SDT_PROBE_NAME(prov, mod, func, name)[1] #define SDT_PROBES_ENABLED() __predict_false(sdt_probes_enabled) #define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) do { \ if (SDT_PROBES_ENABLED()) { \ - if (__predict_false(sdt_##prov##_##mod##_##func##_##name->id)) \ - (*sdt_probe_func)(sdt_##prov##_##mod##_##func##_##name->id, \ + if (__predict_false(_SDT_PROBE_NAME(prov, mod, func, name)->id)) \ + (*sdt_probe_func)(_SDT_PROBE_NAME(prov, mod, func, name)->id, \ (uintptr_t) arg0, (uintptr_t) arg1, (uintptr_t) arg2, \ (uintptr_t) arg3, (uintptr_t) arg4); \ } \ @@ -189,7 +194,7 @@ SET_DECLARE(sdt_argtypes_set, struct sdt_argtype); .ndx = _num, \ .type = _type, \ .xtype = _xtype, \ - .probe = sdt_##_prov##_##_mod##_##_func##_##_name, \ + .probe = _SDT_PROBE_NAME(_prov, _mod, _func, _name), \ }, \ }; \ DATA_SET(sdt_argtypes_set, \ @@ -322,21 +327,21 @@ SET_DECLARE(sdt_argtypes_set, struct sdt_argtype); SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) #define SDT_PROBE6(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4, arg5) \ do { \ - if (sdt_##prov##_##mod##_##func##_##name->id) \ + if (_SDT_PROBE_NAME(prov, mod, func, name)->id) \ (*(void (*)(uint32_t, uintptr_t, uintptr_t, uintptr_t, \ uintptr_t, uintptr_t, uintptr_t))sdt_probe_func)( \ - sdt_##prov##_##mod##_##func##_##name->id, \ + _SDT_PROBE_NAME(prov, mod, func, name)->id, \ (uintptr_t)arg0, (uintptr_t)arg1, (uintptr_t)arg2, \ (uintptr_t)arg3, (uintptr_t)arg4, (uintptr_t)arg5);\ } while (0) #define SDT_PROBE7(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4, arg5, \ arg6) \ do { \ - if (sdt_##prov##_##mod##_##func##_##name->id) \ + if (_SDT_PROBE_NAME(prov, mod, func, name)->id) \ (*(void (*)(uint32_t, uintptr_t, uintptr_t, uintptr_t, \ uintptr_t, uintptr_t, uintptr_t, uintptr_t)) \ sdt_probe_func)( \ - sdt_##prov##_##mod##_##func##_##name->id, \ + _SDT_PROBE_NAME(prov, mod, func, name)->id, \ (uintptr_t)arg0, (uintptr_t)arg1, (uintptr_t)arg2, \ (uintptr_t)arg3, (uintptr_t)arg4, (uintptr_t)arg5, \ (uintptr_t)arg6); \ diff --git a/sys/sys/soundcard.h b/sys/sys/soundcard.h index ddd8a51d29a5..b5434b930215 100644 --- a/sys/sys/soundcard.h +++ b/sys/sys/soundcard.h @@ -1878,7 +1878,7 @@ typedef struct oss_audioinfo int card_number; int port_number; int mixer_dev; - int real_device; /* Obsolete field. Replaced by devnode */ + int legacy_device; /* Obsolete field. Replaced by devnode */ int enabled; /* 1=enabled, 0=device not ready at this moment */ int flags; /* For internal use only - no practical @@ -1925,7 +1925,9 @@ typedef struct oss_mixerinfo * as the default mixer. */ int priority; - int filler[254]; /* Reserved */ + oss_devnode_t devnode; + int legacy_device; + int filler[245]; /* Reserved */ } oss_mixerinfo; typedef struct oss_midi_info diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h index 10016e291b9b..ac6a82659e34 100644 --- a/sys/x86/include/apicvar.h +++ b/sys/x86/include/apicvar.h @@ -78,7 +78,12 @@ #define MAX_APIC_ID 0x800 #define APIC_ID_ALL 0xffffffff -#define IOAPIC_MAX_ID xAPIC_MAX_APIC_ID +/* + * The 0xff ID is used for broadcast IPIs for local APICs when not using + * x2APIC. IPIs are not sent to I/O APICs so it's acceptable for an I/O APIC + * to use that ID. + */ +#define IOAPIC_MAX_ID 0xff /* I/O Interrupts are used for external devices such as ISA, PCI, etc. */ #define APIC_IO_INTS (IDT_IO_INTS + 16) diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile index b95be12d9665..d78c761feaac 100644 --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -21,6 +21,7 @@ ATF_TESTS_C+= kill_zombie .if ${MK_OPENSSL} != "no" ATF_TESTS_C+= ktls_test .endif +ATF_TESTS_C+= ktrace_test ATF_TESTS_C+= module_test ATF_TESTS_C+= ptrace_test TEST_METADATA.ptrace_test+= timeout="15" @@ -79,6 +80,7 @@ LIBADD.socket_msg_waitall+= pthread LIBADD.sendfile_helper+= pthread LIBADD.fdgrowtable_test+= util pthread kvm procstat LIBADD.sigwait+= rt +LIBADD.ktrace_test+= sysdecode NETBSD_ATF_TESTS_C+= lockf_test NETBSD_ATF_TESTS_C+= mqueue_test diff --git a/tests/sys/kern/ktrace_test.c b/tests/sys/kern/ktrace_test.c new file mode 100644 index 000000000000..21868441c687 --- /dev/null +++ b/tests/sys/kern/ktrace_test.c @@ -0,0 +1,522 @@ +/*- + * Copyright (c) 2015 John Baldwin <jhb@FreeBSD.org> + * Copyright (c) 2023 The FreeBSD Foundation + * + * This software was developed by Jake Freeland <jfree@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/capsicum.h> +#include <sys/cpuset.h> +#include <sys/ktrace.h> +#include <sys/mman.h> +#include <sys/socket.h> +#include <sys/sysent.h> +#include <sys/time.h> +#include <sys/uio.h> +#include <sys/user.h> +#include <sys/wait.h> + +#include <machine/sysarch.h> +#include <netinet/in.h> + +#include <atf-c.h> +#include <capsicum_helpers.h> +#include <errno.h> +#include <fcntl.h> +#include <netdb.h> +#include <signal.h> +#include <sysdecode.h> + +/* + * A variant of ATF_REQUIRE that is suitable for use in child + * processes. This only works if the parent process is tripped up by + * the early exit and fails some requirement itself. + */ +#define CHILD_REQUIRE(exp) do { \ + if (!(exp)) \ + child_fail_require(__FILE__, __LINE__, \ + #exp " not met\n"); \ +} while (0) +#define CHILD_REQUIRE_EQ(actual, expected) do { \ + __typeof__(expected) _e = expected; \ + __typeof__(actual) _a = actual; \ + if (_e != _a) \ + child_fail_require(__FILE__, __LINE__, #actual \ + " (%jd) == " #expected " (%jd) not met\n", \ + (intmax_t)_a, (intmax_t)_e); \ +} while (0) + +static __dead2 void +child_fail_require(const char *file, int line, const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + + /* Use write() not fprintf() to avoid possible duplicate output. */ + snprintf(buf, sizeof(buf), "%s:%d: ", file, line); + write(STDERR_FILENO, buf, strlen(buf)); + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + write(STDERR_FILENO, buf, strlen(buf)); + va_end(ap); + + _exit(32); +} + +/* + * Determine sysdecode ABI based on proc's ABI in sv_flags. + */ +static enum sysdecode_abi +syscallabi(u_int sv_flags) +{ + switch (sv_flags & SV_ABI_MASK) { + case SV_ABI_FREEBSD: + return (SYSDECODE_ABI_FREEBSD); + case SV_ABI_LINUX: +#ifdef __LP64__ + if ((sv_flags & SV_ILP32) != 0) + return (SYSDECODE_ABI_LINUX32); +#endif + return (SYSDECODE_ABI_LINUX); + } + return (SYSDECODE_ABI_UNKNOWN); +} + +/* + * Start tracing capability violations and notify child that it can execute. + * Return @numv capability violations from child in @v. + */ +static void +cap_trace_child(int cpid, struct ktr_cap_fail *v, int numv) +{ + struct ktr_header header; + int error, fd, i; + + ATF_REQUIRE((fd = open("ktrace.out", + O_RDONLY | O_CREAT | O_TRUNC)) != -1); + ATF_REQUIRE(ktrace("ktrace.out", KTROP_SET, + KTRFAC_CAPFAIL, cpid) != -1); + /* Notify child that we've starting tracing. */ + ATF_REQUIRE(kill(cpid, SIGUSR1) != -1); + /* Wait for child to raise violation and exit. */ + ATF_REQUIRE(waitpid(cpid, &error, 0) != -1); + ATF_REQUIRE(WIFEXITED(error)); + ATF_REQUIRE_EQ(WEXITSTATUS(error), 0); + /* Read ktrace header and ensure violation occurred. */ + for (i = 0; i < numv; ++i) { + ATF_REQUIRE((error = read(fd, &header, sizeof(header))) != -1); + ATF_REQUIRE_EQ(error, sizeof(header)); + ATF_REQUIRE_EQ(header.ktr_len, sizeof(*v)); + ATF_REQUIRE_EQ(header.ktr_pid, cpid); + /* Read the capability violation. */ + ATF_REQUIRE((error = read(fd, v + i, + sizeof(*v))) != -1); + ATF_REQUIRE_EQ(error, sizeof(*v)); + } + ATF_REQUIRE(close(fd) != -1); +} + +/* + * Test if ktrace will record an operation that is done with + * insufficient rights. + */ +ATF_TC_WITHOUT_HEAD(ktrace__cap_not_capable); +ATF_TC_BODY(ktrace__cap_not_capable, tc) +{ + struct ktr_cap_fail violation; + cap_rights_t rights; + sigset_t set = { }; + pid_t pid; + int error; + + /* Block SIGUSR1 so child does not terminate. */ + ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1); + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1); + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + /* Limit fd rights to CAP_READ. */ + cap_rights_init(&rights, CAP_READ); + CHILD_REQUIRE(caph_rights_limit(STDIN_FILENO, &rights) != -1); + CHILD_REQUIRE(caph_enter() != -1); + /* Wait until ktrace has started. */ + CHILD_REQUIRE(sigwait(&set, &error) != -1); + CHILD_REQUIRE_EQ(error, SIGUSR1); + /* Write without CAP_WRITE. */ + CHILD_REQUIRE(write(STDIN_FILENO, &pid, sizeof(pid)) == -1); + CHILD_REQUIRE_EQ(errno, ENOTCAPABLE); + exit(0); + } + + cap_trace_child(pid, &violation, 1); + ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_NOTCAPABLE); + ATF_REQUIRE(cap_rights_is_set(&violation.cap_data.cap_needed, + CAP_WRITE)); +} + +/* + * Test if ktrace will record an attempt to increase rights. + */ +ATF_TC_WITHOUT_HEAD(ktrace__cap_increase_rights); +ATF_TC_BODY(ktrace__cap_increase_rights, tc) +{ + struct ktr_cap_fail violation; + cap_rights_t rights; + sigset_t set = { }; + pid_t pid; + int error; + + /* Block SIGUSR1 so child does not terminate. */ + ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1); + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1); + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + /* Limit fd rights to CAP_READ. */ + cap_rights_init(&rights, CAP_READ); + CHILD_REQUIRE(caph_rights_limit(STDIN_FILENO, &rights) != -1); + CHILD_REQUIRE(caph_enter() != -1); + /* Wait until ktrace has started. */ + CHILD_REQUIRE(sigwait(&set, &error) != -1); + CHILD_REQUIRE_EQ(error, SIGUSR1); + /* Increase fd rights to include CAP_WRITE. */ + cap_rights_set(&rights, CAP_WRITE); + CHILD_REQUIRE(caph_rights_limit(STDIN_FILENO, &rights) == -1); + CHILD_REQUIRE_EQ(errno, ENOTCAPABLE); + exit(0); + } + + cap_trace_child(pid, &violation, 1); + ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_INCREASE); + ATF_REQUIRE(cap_rights_is_set(&violation.cap_data.cap_needed, + CAP_WRITE)); +} + +/* + * Test if disallowed syscalls are reported as capability violations. + */ +ATF_TC_WITHOUT_HEAD(ktrace__cap_syscall); +ATF_TC_BODY(ktrace__cap_syscall, tc) +{ + struct kinfo_file kinf; + struct ktr_cap_fail violation[2]; + sigset_t set = { }; + pid_t pid; + int error; + + /* Block SIGUSR1 so child does not terminate. */ + ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1); + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1); + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + /* Wait until ktrace has started. */ + CHILD_REQUIRE(sigwait(&set, &error) != -1); + CHILD_REQUIRE_EQ(error, SIGUSR1); + /* chdir() is not permitted in capability mode. */ + CHILD_REQUIRE(chdir(".") != -1); + kinf.kf_structsize = sizeof(struct kinfo_file); + /* + * fcntl() is permitted in capability mode, + * but the F_KINFO cmd is not. + */ + CHILD_REQUIRE(fcntl(STDIN_FILENO, F_KINFO, &kinf) != -1); + exit(0); + } + + cap_trace_child(pid, violation, 2); + ATF_REQUIRE_EQ(violation[0].cap_type, CAPFAIL_SYSCALL); + error = syscallabi(violation[0].cap_svflags); + ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation[0].cap_code), + "chdir"); + + ATF_REQUIRE_EQ(violation[1].cap_type, CAPFAIL_SYSCALL); + error = syscallabi(violation[1].cap_svflags); + ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation[1].cap_code), + "fcntl"); + ATF_REQUIRE_EQ(violation[1].cap_data.cap_int, F_KINFO); +} + +/* + * Test if sending a signal to another process is reported as + * a signal violation. + */ +ATF_TC_WITHOUT_HEAD(ktrace__cap_signal); +ATF_TC_BODY(ktrace__cap_signal, tc) +{ + struct ktr_cap_fail violation; + sigset_t set = { }; + pid_t pid; + int error; + + /* Block SIGUSR1 so child does not terminate. */ + ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1); + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1); + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + /* Wait until ktrace has started. */ + CHILD_REQUIRE(sigwait(&set, &error) != -1); + CHILD_REQUIRE_EQ(error, SIGUSR1); + /* + * Signals may only be sent to ourself. Sending signals + * to other processes is not allowed in capability mode. + */ + CHILD_REQUIRE(kill(getppid(), SIGCONT) != -1); + exit(0); + } + + cap_trace_child(pid, &violation, 1); + ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_SIGNAL); + error = syscallabi(violation.cap_svflags); + ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code), + "kill"); + ATF_REQUIRE_EQ(violation.cap_data.cap_int, SIGCONT); +} + +/* + * Test if opening a socket with a restricted protocol is reported + * as a protocol violation. + */ +ATF_TC_WITHOUT_HEAD(ktrace__cap_proto); +ATF_TC_BODY(ktrace__cap_proto, tc) +{ + struct ktr_cap_fail violation; + sigset_t set = { }; + pid_t pid; + int error; + + /* Block SIGUSR1 so child does not terminate. */ + ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1); + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1); + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + /* Wait until ktrace has started. */ + CHILD_REQUIRE(sigwait(&set, &error) != -1); + CHILD_REQUIRE_EQ(error, SIGUSR1); + /* + * Certain protocols may not be used in capability mode. + * ICMP's raw-protocol interface is not allowed. + */ + CHILD_REQUIRE(close(socket(AF_INET, SOCK_RAW, + IPPROTO_ICMP)) != -1); + exit(0); + } + + cap_trace_child(pid, &violation, 1); + ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_PROTO); + error = syscallabi(violation.cap_svflags); + ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code), + "socket"); + ATF_REQUIRE_EQ(violation.cap_data.cap_int, IPPROTO_ICMP); +} + +/* + * Test if sending data to an address using a socket is + * reported as a sockaddr violation. + */ +ATF_TC_WITHOUT_HEAD(ktrace__cap_sockaddr); +ATF_TC_BODY(ktrace__cap_sockaddr, tc) +{ + struct sockaddr_in addr = { }, *saddr; + struct ktr_cap_fail violation; + sigset_t set = { }; + pid_t pid; + int error, sfd; + + /* Block SIGUSR1 so child does not terminate. */ + ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1); + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1); + + CHILD_REQUIRE((sfd = socket(AF_INET, SOCK_DGRAM, + IPPROTO_UDP)) != -1); + addr.sin_family = AF_INET; + addr.sin_port = htons(5000); + addr.sin_addr.s_addr = INADDR_ANY; + CHILD_REQUIRE(bind(sfd, (const struct sockaddr *)&addr, + sizeof(addr)) != -1); + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + /* Wait until ktrace has started. */ + CHILD_REQUIRE(sigwait(&set, &error) != -1); + CHILD_REQUIRE_EQ(error, SIGUSR1); + /* + * Sending data to an address is not permitted. + * In this case, sending data to @addr causes a + * violation. + */ + CHILD_REQUIRE(sendto(sfd, NULL, 0, 0, + (const struct sockaddr *)&addr, sizeof(addr)) != -1); + exit(0); + } + + cap_trace_child(pid, &violation, 1); + ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_SOCKADDR); + error = syscallabi(violation.cap_svflags); + ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code), + "sendto"); + saddr = (struct sockaddr_in *)&violation.cap_data.cap_sockaddr; + ATF_REQUIRE_EQ(saddr->sin_family, AF_INET); + ATF_REQUIRE_EQ(saddr->sin_port, htons(5000)); + ATF_REQUIRE_EQ(saddr->sin_addr.s_addr, INADDR_ANY); + close(sfd); +} + +/* + * Test if openat() with AT_FDCWD and absolute path are reported + * as namei violations. + */ +ATF_TC_WITHOUT_HEAD(ktrace__cap_namei); +ATF_TC_BODY(ktrace__cap_namei, tc) +{ + struct ktr_cap_fail violation[2]; + sigset_t set = { }; + pid_t pid; + int error; + + /* Block SIGUSR1 so child does not terminate. */ + ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1); + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1); + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + /* Wait until ktrace has started. */ + CHILD_REQUIRE(sigwait(&set, &error) != -1); + CHILD_REQUIRE_EQ(error, SIGUSR1); + /* + * The AT_FDCWD file descriptor has not been opened + * and will be inaccessible in capability mode. + */ + CHILD_REQUIRE(close(openat(AT_FDCWD, "ktrace.out", + O_RDONLY | O_CREAT)) != -1); + /* + * Absolute paths are inaccessible in capability mode. + */ + CHILD_REQUIRE(close(openat(-1, "/", O_RDONLY)) != -1); + exit(0); + } + + cap_trace_child(pid, violation, 2); + ATF_REQUIRE_EQ(violation[0].cap_type, CAPFAIL_NAMEI); + error = syscallabi(violation[0].cap_svflags); + ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation[0].cap_code), + "openat"); + ATF_REQUIRE_STREQ(violation[0].cap_data.cap_path, "AT_FDCWD"); + + ATF_REQUIRE_EQ(violation[1].cap_type, CAPFAIL_NAMEI); + error = syscallabi(violation[1].cap_svflags); + ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation[1].cap_code), + "openat"); + ATF_REQUIRE_STREQ(violation[1].cap_data.cap_path, "/"); +} + +/* + * Test if changing another process's cpu set is recorded as + * a cpuset violation. + */ +ATF_TC_WITHOUT_HEAD(ktrace__cap_cpuset); +ATF_TC_BODY(ktrace__cap_cpuset, tc) +{ + struct ktr_cap_fail violation; + cpuset_t cpuset_mask = { }; + sigset_t set = { }; + pid_t pid; + int error; + + /* Block SIGUSR1 so child does not terminate. */ + ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1); + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1); + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + /* Wait until ktrace has started. */ + CHILD_REQUIRE(sigwait(&set, &error) != -1); + CHILD_REQUIRE_EQ(error, SIGUSR1); + /* + * Set cpu 0 affinity for parent process. + * Other process's cpu sets are restricted in capability + * mode, so this will raise a violation. + */ + CPU_SET(0, &cpuset_mask); + CHILD_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, + getppid(), sizeof(cpuset_mask), &cpuset_mask) != -1); + exit(0); + } + + cap_trace_child(pid, &violation, 1); + ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_CPUSET); + error = syscallabi(violation.cap_svflags); + ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code), + "cpuset_setaffinity"); +} + +ATF_TC_WITHOUT_HEAD(ktrace__cap_shm_open); +ATF_TC_BODY(ktrace__cap_shm_open, tc) +{ + struct ktr_cap_fail violation; + sigset_t set = { }; + pid_t pid; + int error; + + /* Block SIGUSR1 so child does not terminate. */ + ATF_REQUIRE(sigaddset(&set, SIGUSR1) != -1); + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &set, NULL) != -1); + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + /* Wait until ktrace has started. */ + CHILD_REQUIRE(sigwait(&set, &error) != -1); + CHILD_REQUIRE_EQ(error, SIGUSR1); + + CHILD_REQUIRE(shm_open("/ktrace_shm", O_RDWR | O_CREAT, + 0600) != -1); + CHILD_REQUIRE(shm_unlink("/ktrace_shm") != -1); + exit(0); + } + + cap_trace_child(pid, &violation, 1); + ATF_REQUIRE_EQ(violation.cap_type, CAPFAIL_NAMEI); + error = syscallabi(violation.cap_svflags); + ATF_REQUIRE_STREQ(sysdecode_syscallname(error, violation.cap_code), + "shm_open2"); + ATF_REQUIRE_STREQ(violation.cap_data.cap_path, "/ktrace_shm"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, ktrace__cap_not_capable); + ATF_TP_ADD_TC(tp, ktrace__cap_increase_rights); + ATF_TP_ADD_TC(tp, ktrace__cap_syscall); + ATF_TP_ADD_TC(tp, ktrace__cap_signal); + ATF_TP_ADD_TC(tp, ktrace__cap_proto); + ATF_TP_ADD_TC(tp, ktrace__cap_sockaddr); + ATF_TP_ADD_TC(tp, ktrace__cap_namei); + ATF_TP_ADD_TC(tp, ktrace__cap_cpuset); + ATF_TP_ADD_TC(tp, ktrace__cap_shm_open); + return (atf_no_error()); +} diff --git a/tools/regression/iscsi/initiator-instructions.txt b/tools/regression/iscsi/initiator-instructions.txt index 11c3311cddb2..e99ff87fe379 100644 --- a/tools/regression/iscsi/initiator-instructions.txt +++ b/tools/regression/iscsi/initiator-instructions.txt @@ -3,9 +3,9 @@ How to prepare initiator virtual machines for iSCSI target testing 1. Install operating systems. - - FreeBSD: Use default settings for everything. Don't install - ports from the system installer, use "portsnap fetch extract" - after installation instead. + - FreeBSD: Use default settings for everything. Don't install ports + from the system installer, fetch a new ports tree after + installation instead. - Fedora: Change the environment to "Minimal install". diff --git a/usr.bin/ctags/C.c b/usr.bin/ctags/C.c index 25c5db5d405b..725336d33e01 100644 --- a/usr.bin/ctags/C.c +++ b/usr.bin/ctags/C.c @@ -43,10 +43,10 @@ static char sccsid[] = "@(#)C.c 8.4 (Berkeley) 4/2/94"; #include "ctags.h" -static int func_entry(void); +static bool func_entry(void); static void hash_entry(void); static void skip_string(int); -static int str_entry(int); +static bool str_entry(int); /* * c_entries -- @@ -58,13 +58,13 @@ c_entries(void) int c; /* current character */ int level; /* brace level */ int token; /* if reading a token */ - int t_def; /* if reading a typedef */ + bool t_def; /* if reading a typedef */ int t_level; /* typedef's brace level */ char *sp; /* buffer pointer */ char tok[MAXTOKEN]; /* token buffer */ lineftell = ftell(inf); - sp = tok; token = t_def = NO; t_level = -1; level = 0; lineno = 1; + sp = tok; token = t_def = false; t_level = -1; level = 0; lineno = 1; while (GETC(!=, EOF)) { switch (c) { /* @@ -98,11 +98,11 @@ c_entries(void) */ endtok: if (sp > tok) { *sp = EOS; - token = YES; + token = true; sp = tok; } else - token = NO; + token = false; continue; /* @@ -180,7 +180,7 @@ c_entries(void) */ case ';': if (t_def && level == t_level) { - t_def = NO; + t_def = false; get_line(); if (sp != tok) *sp = EOS; @@ -213,7 +213,7 @@ c_entries(void) /* no typedefs inside typedefs */ if (!t_def && !memcmp(tok, "typedef",8)) { - t_def = YES; + t_def = true; t_level = level; break; } @@ -239,15 +239,15 @@ c_entries(void) if (sp == tok + sizeof tok - 1) /* Too long -- truncate it */ *sp = EOS; - else + else *sp++ = c; - token = YES; + token = true; } continue; } sp = tok; - token = NO; + token = false; } } @@ -255,7 +255,7 @@ c_entries(void) * func_entry -- * handle a function reference */ -static int +static bool func_entry(void) { int c; /* current character */ @@ -293,7 +293,7 @@ func_entry(void) SETLINE; } } - return (NO); + return (false); fnd: /* * we assume that the character after a function's right paren @@ -305,7 +305,7 @@ fnd: if (c == '\n') SETLINE; if (c == EOF) - return NO; + return false; /* * Recognize the gnu __attribute__ extension, which would * otherwise make the heuristic test DTWT @@ -317,7 +317,7 @@ fnd: } } else { if (intoken(c)) { - if (anext - maybe_attribute + if (anext - maybe_attribute < (ptrdiff_t)(sizeof attribute - 1)) *anext++ = c; else break; @@ -326,7 +326,7 @@ fnd: *anext++ = '\0'; if (strcmp(maybe_attribute, attribute) == 0) { (void)ungetc(c, inf); - return NO; + return false; } break; } @@ -337,12 +337,12 @@ fnd: skip_comment(c); else { /* don't ever "read" '/' */ (void)ungetc(c, inf); - return (NO); + return (false); } } if (c != '{') (void)skip_key('{'); - return (YES); + return (true); } /* @@ -371,7 +371,7 @@ hash_entry(void) if (sp == tok + sizeof tok - 1) /* Too long -- truncate it */ *sp = EOS; - else + else *sp++ = c; } *sp = EOS; @@ -387,7 +387,7 @@ hash_entry(void) if (sp == tok + sizeof tok - 1) /* Too long -- truncate it */ *sp = EOS; - else + else *sp++ = c; if (GETC(==, EOF)) return; @@ -415,7 +415,7 @@ skip: if (c == '\n') { /* get rid of rest of define */ * str_entry -- * handle a struct, union or enum entry */ -static int +static bool str_entry(int c) /* c is current character */ { int curline; /* line started on */ @@ -425,17 +425,17 @@ str_entry(int c) /* c is current character */ curline = lineno; while (iswhite(c)) if (GETC(==, EOF)) - return (NO); + return (false); if (c == '{') /* it was "struct {" */ - return (YES); + return (true); for (sp = tok;;) { /* get next token */ if (sp == tok + sizeof tok - 1) /* Too long -- truncate it */ *sp = EOS; - else + else *sp++ = c; if (GETC(==, EOF)) - return (NO); + return (false); if (!intoken(c)) break; } @@ -452,12 +452,12 @@ str_entry(int c) /* c is current character */ break; if (c != '{') { (void)ungetc(c, inf); - return (NO); + return (false); } } *sp = EOS; pfnote(tok, curline); - return (YES); + return (true); } /* @@ -474,7 +474,7 @@ skip_comment(int t) /* t is comment character */ switch(c) { /* comments don't nest, nor can they be escaped. */ case '*': - star = YES; + star = true; break; case '/': if (star && t == '*') @@ -486,7 +486,7 @@ skip_comment(int t) /* t is comment character */ return; /*FALLTHROUGH*/ default: - star = NO; + star = false; break; } } @@ -501,7 +501,7 @@ skip_string(int key) int c, skip; - for (skip = NO; GETC(!=, EOF); ) + for (skip = false; GETC(!=, EOF); ) switch (c) { case '\\': /* a backslash escapes anything */ skip = !skip; /* we toggle in case it's "\\" */ @@ -512,7 +512,7 @@ skip_string(int key) default: if (c == key && !skip) return; - skip = NO; + skip = false; } } @@ -520,21 +520,21 @@ skip_string(int key) * skip_key -- * skip to next char "key" */ -int +bool skip_key(int key) { - int c, - skip, - retval; + int c; + bool skip; + bool retval; - for (skip = retval = NO; GETC(!=, EOF);) + for (skip = retval = false; GETC(!=, EOF);) switch(c) { case '\\': /* a backslash escapes anything */ skip = !skip; /* we toggle in case it's "\\" */ break; case ';': /* special case for yacc; if one */ case '|': /* of these chars occurs, we may */ - retval = YES; /* have moved out of the rule */ + retval = true; /* have moved out of the rule */ break; /* not used by C */ case '\'': case '"': @@ -557,7 +557,7 @@ skip_key(int key) norm: if (c == key && !skip) return (retval); - skip = NO; + skip = false; } return (retval); } diff --git a/usr.bin/ctags/ctags.c b/usr.bin/ctags/ctags.c index 6053a52f32da..686acd0f9cdf 100644 --- a/usr.bin/ctags/ctags.c +++ b/usr.bin/ctags/ctags.c @@ -99,8 +99,8 @@ main(int argc, char **argv) setlocale(LC_ALL, ""); - aflag = uflag = NO; - tflag = YES; + aflag = uflag = false; + tflag = true; while ((ch = getopt(argc, argv, "BFTadf:tuwvx")) != -1) switch(ch) { case 'B': @@ -110,7 +110,7 @@ main(int argc, char **argv) searchar = '/'; break; case 'T': - tflag = NO; + tflag = false; break; case 'a': aflag++; @@ -122,7 +122,7 @@ main(int argc, char **argv) outfile = optarg; break; case 't': - tflag = YES; + tflag = true; break; case 'u': uflag++; @@ -264,24 +264,24 @@ init(void) const unsigned char *sp; for (i = 0; i < 256; i++) { - _wht[i] = _etk[i] = _itk[i] = _btk[i] = NO; - _gd[i] = YES; + _wht[i] = _etk[i] = _itk[i] = _btk[i] = false; + _gd[i] = true; } #define CWHITE " \f\t\n" for (sp = CWHITE; *sp; sp++) /* white space chars */ - _wht[*sp] = YES; + _wht[*sp] = true; #define CTOKEN " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?" for (sp = CTOKEN; *sp; sp++) /* token ending chars */ - _etk[*sp] = YES; + _etk[*sp] = true; #define CINTOK "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz0123456789" for (sp = CINTOK; *sp; sp++) /* valid in-token chars */ - _itk[*sp] = YES; + _itk[*sp] = true; #define CBEGIN "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" for (sp = CBEGIN; *sp; sp++) /* token starting chars */ - _btk[*sp] = YES; + _btk[*sp] = true; #define CNOTGD ",;" for (sp = CNOTGD; *sp; sp++) /* invalid after-function chars */ - _gd[*sp] = NO; + _gd[*sp] = false; } /* diff --git a/usr.bin/ctags/ctags.h b/usr.bin/ctags/ctags.h index 8892733d650f..5079353a8136 100644 --- a/usr.bin/ctags/ctags.h +++ b/usr.bin/ctags/ctags.h @@ -32,10 +32,9 @@ * */ -#define bool char +/* This header requires bool for some externed symbols. */ +#include <stdbool.h> -#define YES 1 -#define NO 0 #define EOS '\0' #define ENDLINE 50 /* max length of pattern */ @@ -83,14 +82,14 @@ extern char lbuf[LINE_MAX]; extern char *lbp; extern char searchar; /* ex search character */ -extern int cicmp(const char *); +extern bool cicmp(const char *); extern void get_line(void); extern void pfnote(const char *, int); -extern int skip_key(int); +extern bool skip_key(int); extern void put_entries(NODE *); extern void toss_yysec(void); extern void l_entries(void); extern void y_entries(void); -extern int PF_funcs(void); +extern bool PF_funcs(void); extern void c_entries(void); extern void skip_comment(int); diff --git a/usr.bin/ctags/fortran.c b/usr.bin/ctags/fortran.c index 7fa6ec3823d9..56ae3b66458b 100644 --- a/usr.bin/ctags/fortran.c +++ b/usr.bin/ctags/fortran.c @@ -47,14 +47,14 @@ static void takeprec(void); char *lbp; /* line buffer pointer */ -int +bool PF_funcs(void) { bool pfcnt; /* pascal/fortran functions found */ char *cp; char tok[MAXTOKEN]; - for (pfcnt = NO;;) { + for (pfcnt = false;;) { lineftell = ftell(inf); if (!fgets(lbuf, sizeof(lbuf), inf)) return (pfcnt); @@ -126,7 +126,7 @@ PF_funcs(void) (void)strlcpy(tok, lbp, sizeof(tok)); /* possible trunc */ get_line(); /* process line for ex(1) */ pfnote(tok, lineno); - pfcnt = YES; + pfcnt = true; } /*NOTREACHED*/ } @@ -135,7 +135,7 @@ PF_funcs(void) * cicmp -- * do case-independent strcmp */ -int +bool cicmp(const char *cp) { int len; @@ -146,9 +146,9 @@ cicmp(const char *cp) continue; if (!*cp) { lbp += len; - return (YES); + return (true); } - return (NO); + return (false); } static void diff --git a/usr.bin/ctags/lisp.c b/usr.bin/ctags/lisp.c index d167c82e7c69..bd6100709299 100644 --- a/usr.bin/ctags/lisp.c +++ b/usr.bin/ctags/lisp.c @@ -50,7 +50,7 @@ static char sccsid[] = "@(#)lisp.c 8.3 (Berkeley) 4/2/94"; void l_entries(void) { - int special; + bool special; char *cp; char savedc; char tok[MAXTOKEN]; @@ -63,15 +63,15 @@ l_entries(void) lbp = lbuf; if (!cicmp("(def")) continue; - special = NO; + special = false; switch(*lbp | ' ') { case 'm': if (cicmp("method")) - special = YES; + special = true; break; case 'w': if (cicmp("wrapper") || cicmp("whopper")) - special = YES; + special = true; } for (; !isspace(*lbp); ++lbp) continue; diff --git a/usr.bin/ctags/tree.c b/usr.bin/ctags/tree.c index 15291f4a5e80..c3cfabc6e25f 100644 --- a/usr.bin/ctags/tree.c +++ b/usr.bin/ctags/tree.c @@ -106,7 +106,7 @@ add_node(NODE *node, NODE *cur_node) if (!cur_node->been_warned) if (!wflag) fprintf(stderr, "Duplicate entry in files %s and %s: %s (Warning only)\n", node->file, cur_node->file, node->entry); - cur_node->been_warned = YES; + cur_node->been_warned = true; } else if (dif < 0) if (cur_node->left) diff --git a/usr.bin/ctags/yacc.c b/usr.bin/ctags/yacc.c index 0fd8537fb74f..e30ea0eacad0 100644 --- a/usr.bin/ctags/yacc.c +++ b/usr.bin/ctags/yacc.c @@ -54,7 +54,7 @@ y_entries(void) bool in_rule; char tok[MAXTOKEN]; - in_rule = NO; + in_rule = false; while (GETC(!=, EOF)) switch (c) { @@ -68,12 +68,12 @@ y_entries(void) break; case '{': if (skip_key('}')) - in_rule = NO; + in_rule = false; break; case '\'': case '"': if (skip_key(c)) - in_rule = NO; + in_rule = false; break; case '%': if (GETC(==, '%')) @@ -88,7 +88,7 @@ y_entries(void) break; case '|': case ';': - in_rule = NO; + in_rule = false; break; default: if (in_rule || (!isalpha(c) && c != '.' && c != '_')) @@ -107,7 +107,7 @@ y_entries(void) } if (c == ':') { pfnote(tok, lineno); - in_rule = YES; + in_rule = true; } else (void)ungetc(c, inf); diff --git a/usr.bin/expand/expand.1 b/usr.bin/expand/expand.1 index 9a49deb1a948..c1e19891b1ab 100644 --- a/usr.bin/expand/expand.1 +++ b/usr.bin/expand/expand.1 @@ -80,9 +80,15 @@ If the .Fl a option is given, then tabs are inserted whenever they would compress the resultant file by replacing two or more characters. -.It Fl t \&Sm Ar tab1 , tab2 , ... , tabn \&Sm +.It Fl t Xo +.Sm off +.Ar tab1 , tab2 , ... , tabn +.Sm on +.Xc Set tab stops at column positions +.Sm off .Ar tab1 , tab2 , ... , tabn . +.Sm on If only a single number is given, tab stops are set that number of column positions apart instead of the default number of 8. .El diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index d69c019bd6be..abbe57b0b75e 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -2137,35 +2137,74 @@ invalid: void ktrcapfail(struct ktr_cap_fail *ktr) { + union ktr_cap_data *kcd = &ktr->cap_data; + switch (ktr->cap_type) { case CAPFAIL_NOTCAPABLE: /* operation on fd with insufficient capabilities */ printf("operation requires "); - sysdecode_cap_rights(stdout, &ktr->cap_needed); + sysdecode_cap_rights(stdout, &kcd->cap_needed); printf(", descriptor holds "); - sysdecode_cap_rights(stdout, &ktr->cap_held); + sysdecode_cap_rights(stdout, &kcd->cap_held); break; case CAPFAIL_INCREASE: /* requested more capabilities than fd already has */ printf("attempt to increase capabilities from "); - sysdecode_cap_rights(stdout, &ktr->cap_held); + sysdecode_cap_rights(stdout, &kcd->cap_held); printf(" to "); - sysdecode_cap_rights(stdout, &ktr->cap_needed); + sysdecode_cap_rights(stdout, &kcd->cap_needed); break; case CAPFAIL_SYSCALL: /* called restricted syscall */ - printf("disallowed system call"); + printf("system call not allowed: "); + syscallname(ktr->cap_code, ktr->cap_svflags); + if (syscallabi(ktr->cap_svflags) == SYSDECODE_ABI_FREEBSD) { + switch (ktr->cap_code) { + case SYS_sysarch: + printf(", op: "); + print_integer_arg(sysdecode_sysarch_number, + kcd->cap_int); + break; + case SYS_fcntl: + printf(", cmd: "); + print_integer_arg(sysdecode_fcntl_cmd, + kcd->cap_int); + break; + } + } break; - case CAPFAIL_LOOKUP: - /* absolute or AT_FDCWD path, ".." path, etc. */ - printf("restricted VFS lookup"); + case CAPFAIL_SIGNAL: + /* sent signal to proc other than self */ + syscallname(ktr->cap_code, ktr->cap_svflags); + printf(": signal delivery not allowed: "); + print_integer_arg(sysdecode_signal, kcd->cap_int); break; - default: - printf("unknown capability failure: "); - sysdecode_cap_rights(stdout, &ktr->cap_needed); - printf(" "); - sysdecode_cap_rights(stdout, &ktr->cap_held); + case CAPFAIL_PROTO: + /* created socket with restricted protocol */ + syscallname(ktr->cap_code, ktr->cap_svflags); + printf(": protocol not allowed: "); + print_integer_arg(sysdecode_ipproto, kcd->cap_int); break; + case CAPFAIL_SOCKADDR: + /* unable to look up address */ + syscallname(ktr->cap_code, ktr->cap_svflags); + printf(": restricted address lookup: "); + ktrsockaddr(&kcd->cap_sockaddr); + return; + case CAPFAIL_NAMEI: + /* absolute or AT_FDCWD path, ".." path, etc. */ + syscallname(ktr->cap_code, ktr->cap_svflags); + printf(": restricted VFS lookup: %s\n", kcd->cap_path); + return; + case CAPFAIL_CPUSET: + /* modification of an external cpuset */ + syscallname(ktr->cap_code, ktr->cap_svflags); + printf(": restricted cpuset operation\n"); + return; + default: + syscallname(ktr->cap_code, ktr->cap_svflags); + printf(": unknown capability failure\n"); + return; } printf("\n"); } diff --git a/usr.bin/ktrace/ktrace.1 b/usr.bin/ktrace/ktrace.1 index a6a07bb93caf..1b287af7a611 100644 --- a/usr.bin/ktrace/ktrace.1 +++ b/usr.bin/ktrace/ktrace.1 @@ -27,7 +27,7 @@ .\" .\" @(#)ktrace.1 8.1 (Berkeley) 6/6/93 .\" -.Dd August 26, 2019 +.Dd April 20, 2024 .Dt KTRACE 1 .Os .Sh NAME @@ -139,7 +139,7 @@ trace requests .It Cm + trace the default set of trace points - -.Cm c , i , n , p , s , t , u , y +.Cm c , i , n , s , t , u , y .El .It Ar command Execute @@ -153,6 +153,21 @@ The and .Ar command options are mutually exclusive. +.Sh CAPABILITY VIOLATION TRACING +When the +.Cm p +trace point is specified, +.Nm +will record +.Xr capsicum 4 +capability mode violations made by the traced process. +Violations will be logged regardless of whether the process has actually +entered capability mode. +.Pp +For developers that are interested in Capsicumizing their programs, the +.Cm c , n , p +trace points can help quickly identify any system calls and path lookups that +are triggering violations. .Sh EXAMPLES Run "make", then trace it and any child processes: .Dl $ ktrace -i make @@ -185,7 +200,8 @@ Disable tracing of all user-owned processes: .Xr kdump 1 , .Xr truss 1 , .Xr ktrace 2 , -.Xr utrace 2 +.Xr utrace 2 , +.Xr capsicum 4 .Sh HISTORY The .Nm diff --git a/usr.bin/ktrace/ktrace.h b/usr.bin/ktrace/ktrace.h index cecd0adc7321..1d96c6faa2b7 100644 --- a/usr.bin/ktrace/ktrace.h +++ b/usr.bin/ktrace/ktrace.h @@ -33,13 +33,12 @@ #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \ KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER | \ - KTRFAC_STRUCT | KTRFAC_SYSCTL | KTRFAC_CAPFAIL | \ - KTRFAC_STRUCT_ARRAY) + KTRFAC_STRUCT | KTRFAC_SYSCTL | KTRFAC_STRUCT_ARRAY) #define PROC_ABI_POINTS (KTRFAC_PROCCTOR | KTRFAC_PROCDTOR) -#define ALL_POINTS (DEF_POINTS | KTRFAC_CSW | PROC_ABI_POINTS | \ - KTRFAC_FAULT | KTRFAC_FAULTEND) +#define ALL_POINTS (DEF_POINTS | KTRFAC_CAPFAIL | KTRFAC_CSW | \ + PROC_ABI_POINTS | KTRFAC_FAULT | KTRFAC_FAULTEND) #define DEF_TRACEFILE "ktrace.out" diff --git a/usr.bin/locate/locate/locate.rc b/usr.bin/locate/locate/locate.rc index 404af4cc4a64..f004dea19508 100644 --- a/usr.bin/locate/locate/locate.rc +++ b/usr.bin/locate/locate/locate.rc @@ -15,7 +15,7 @@ #SEARCHPATHS="/" # paths unwanted in output -#PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/db/portsnap /var/db/freebsd-update" +#PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/db/freebsd-update" # directories unwanted in output #PRUNEDIRS=".zfs" diff --git a/usr.bin/locate/locate/updatedb.sh b/usr.bin/locate/locate/updatedb.sh index e874700afdb8..ff7ec7f6c18e 100644 --- a/usr.bin/locate/locate/updatedb.sh +++ b/usr.bin/locate/locate/updatedb.sh @@ -52,7 +52,7 @@ PATH=$LIBEXECDIR:/bin:/usr/bin:$PATH; export PATH : ${mklocatedb:=locate.mklocatedb} # make locate database program : ${FCODES:=/var/db/locate.database} # the database : ${SEARCHPATHS="/"} # directories to be put in the database -: ${PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/db/portsnap /var/db/freebsd-update"} # unwanted directories +: ${PRUNEPATHS="/tmp /usr/tmp /var/tmp /var/db/freebsd-update"} # unwanted directories : ${PRUNEDIRS=".zfs"} # unwanted directories, in any parent : ${FILESYSTEMS="$(lsvfs | tail -n +3 | \ egrep -vw "loopback|network|synthetic|read-only|0" | \ diff --git a/usr.bin/split/split.c b/usr.bin/split/split.c index e246a0d4adfc..52374c93efca 100644 --- a/usr.bin/split/split.c +++ b/usr.bin/split/split.c @@ -401,6 +401,10 @@ newfile(void) */ if (!dflag && autosfx && (fpnt[0] == 'y') && strspn(fpnt+1, "z") == strlen(fpnt+1)) { + /* Ensure the generated filenames will fit into the buffer. */ + if (strlen(fname) + 2 >= sizeof(fname)) + errx(EX_USAGE, "combined filenames would be too long"); + fpnt = fname + strlen(fname) - sufflen; fpnt[sufflen + 2] = '\0'; fpnt[0] = end; diff --git a/usr.sbin/adduser/adduser.sh b/usr.sbin/adduser/adduser.sh index e9027b6b7876..7c3fdb418179 100644 --- a/usr.sbin/adduser/adduser.sh +++ b/usr.sbin/adduser/adduser.sh @@ -53,7 +53,7 @@ info() { # by pw(8). # get_nextuid () { - local _uid=$1 _nextuid + local _uid=$1 _nextuid= if [ -z "$_uid" ]; then _nextuid="$(${PWCMD} usernext | cut -f1 -d:)" @@ -101,7 +101,7 @@ show_usage() { # basename of the shell is output. # valid_shells() { - local _prefix + local _prefix= ${GREPCMD} '^[^#]' ${ETCSHELLS} | while read _path _junk ; do @@ -119,7 +119,7 @@ valid_shells() { # full path to the shell from the /etc/shells file. # fullpath_from_shell() { - local _shell=$1 _fullpath + local _shell=$1 _fullpath= if [ -z "$_shell" ]; then return @@ -154,7 +154,7 @@ fullpath_from_shell() { # will emit an informational message saying so. # shell_exists() { - local _sh="$1" + local _sh=$1 if [ -z "$(fullpath_from_shell "$_sh")" ] ; then err "Invalid shell ($_sh) for user $username." @@ -193,8 +193,9 @@ save_config() { # message or lock the account, do so. # add_user() { - local _uid _name _comment _gecos _home _group _grouplist _shell _class - local _dotdir _expire _pwexpire _passwd _upasswd _passwdmethod + local _uid= _name= _comment= _gecos= _home= _group= _grouplist= + local _shell= _class= _dotdir= _expire= _pwexpire= _passwd= _upasswd= + local _passwdmethod= _pwcmd= # Is this a configuration run? If so, don't modify user database. # @@ -299,7 +300,7 @@ add_user() { fi fi - local _line _owner _perms _file _dir + local _line= _owner= _perms= _file= _dir= if [ -n "$msgflag" ]; then if [ -r "$msgfile" ]; then # We're evaluating the contents of an external file. @@ -331,7 +332,7 @@ add_user() { # a file it will output an error message and return to the caller. # get_user() { - local _input + local _input= # No need to take down user names if this is a configuration saving run. [ -n "$configflag" ] && return @@ -366,7 +367,7 @@ get_user() { # and batch (from file) mode. # get_gecos() { - local _input + local _input= # No need to take down additional user information for a configuration run. [ -n "$configflag" ] && return @@ -386,7 +387,7 @@ get_gecos() { # If an invalid shell is entered it will simply use the default shell. # get_shell() { - local _input _fullpath + local _input= _fullpath= ushell="$defaultshell" # Make sure the current value of the shell is a valid one @@ -424,7 +425,7 @@ get_shell() { # and batch input. # get_homedir() { - _input= + local _input= if [ -z "$fflag" ]; then echo -n "Home directory [${homeprefix}/${username}]: " read _input @@ -450,7 +451,7 @@ get_homedir() { # Reads the account's home directory permissions. # get_homeperm() { - local _input _prompt + local _input= _prompt= uhomeperm=$defaultHomePerm if [ -n "$uhomeperm" ]; then @@ -473,7 +474,7 @@ get_homeperm() { # so, enable ZFS home dataset creation. # get_zfs_home() { - local _prefix + local _prefix= # check if zfs kernel module is loaded before attempting to run zfs to # prevent loading the kernel module on systems that don't use ZFS @@ -494,7 +495,7 @@ get_zfs_home() { # allocates one if it is not specified. # get_uid() { - local _input _prompt + local _input= _prompt= uuid=${uidstart} if [ -n "$uuid" ]; then @@ -519,7 +520,7 @@ get_uid() { # Reads login class of account. Can be used in interactive or batch mode. # get_class() { - local _input _uclass + local _input= _class= uclass="$defaultclass" _class=${uclass:-"default"} @@ -541,7 +542,7 @@ get_class() { # will then provide a login group with the same name as the username. # get_logingroup() { - local _input + local _input= ulogingroup="$defaultLgroup" if [ -z "$fflag" ]; then @@ -560,7 +561,7 @@ get_logingroup() { # and batch modes. # get_groups() { - local _input _group + local _input= _group= ugroups="$defaultgroups" _group=${ulogingroup:-"${username}"} @@ -626,7 +627,7 @@ get_password() { # Ask user if they want to enable encryption on their ZFS home dataset. # get_zfs_encryption() { - local _input _prompt + local _input= _prompt= _prompt="Enable ZFS encryption? (yes/no) [${Zencrypt}]: " while : ; do echo -n "$_prompt" @@ -702,7 +703,7 @@ set_zfs_perms() { # adds it to the user database. # input_from_file() { - local _field + local _field= while read -r fileline ; do case "$fileline" in @@ -733,14 +734,13 @@ input_from_file() { # the user database. # input_interactive() { - local _disable _pass _passconfirm _input + local _disable= _pass= _passconfirm= _input= local _random="no" local _emptypass="no" local _usepass="yes" local _logingroup_ok="no" local _groups_ok="no" local _all_ok="yes" - local _another_user="no" case $passwdtype in none) _emptypass="yes" @@ -1129,6 +1129,7 @@ if [ -n "$fflag" ]; then else input_interactive while : ; do + _another_user="no" if [ -z "$configflag" ]; then echo -n "Add another user? (yes/no) [$_another_user]: " else diff --git a/usr.sbin/bhyve/gdb.c b/usr.sbin/bhyve/gdb.c index 2a075cd10ca6..0319aaf0a9cd 100644 --- a/usr.sbin/bhyve/gdb.c +++ b/usr.sbin/bhyve/gdb.c @@ -193,7 +193,6 @@ static const struct gdb_reg { { .id = VM_REG_GUEST_EFER, .size = 8 }, }; -#define GDB_LOG #ifdef GDB_LOG #include <stdarg.h> #include <stdio.h> diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index 4a6a8d78330b..77b12a3756c2 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -1052,10 +1052,10 @@ IDS_check_params () { # a useful answer, use the server name specified by the user. # Put another way... look up _http._tcp.${SERVERNAME} and pick a server # from that; or if no servers are returned, use ${SERVERNAME}. -# This allows a user to specify "portsnap.freebsd.org" (in which case -# portsnap will select one of the mirrors) or "portsnap5.tld.freebsd.org" -# (in which case portsnap will use that particular server, since there -# won't be an SRV entry for that name). +# This allows a user to specify "update.FreeBSD.org" (in which case +# freebsd-update will select one of the mirrors) or "update1.freebsd.org" +# (in which case freebsd-update will use that particular server, since +# there won't be an SRV entry for that name). # # We ignore the Port field, since we are always going to use port 80. diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index 063553dd084f..fc17f6dba022 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -101,13 +101,16 @@ static int (*cmdfunc[W_NUM][M_NUM])(int argc, char **argv, char *_name) = { struct pwconf conf; +static int mode = -1; +static int which = -1; + static int getindex(const char *words[], const char *word); static void cmdhelp(int mode, int which); int main(int argc, char *argv[]) { - int mode = -1, which = -1, tmp; + int tmp; struct stat st; char arg, *arg1; bool relocated, nis; @@ -375,5 +378,11 @@ cmdhelp(int mode, int which) fprintf(stderr, "%s", help[which][mode]); } - exit(EXIT_FAILURE); + exit(EX_USAGE); +} + +void +usage(void) +{ + cmdhelp(mode, which); } diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h index 5de333ce5e71..c3725693f91d 100644 --- a/usr.sbin/pw/pw.h +++ b/usr.sbin/pw/pw.h @@ -36,14 +36,14 @@ enum _mode { - M_ADD, - M_DELETE, - M_UPDATE, - M_PRINT, + M_ADD, + M_DELETE, + M_MODIFY, + M_SHOW, M_NEXT, M_LOCK, M_UNLOCK, - M_NUM + M_NUM }; enum _passmode @@ -56,13 +56,13 @@ enum _passmode enum _which { - W_USER, - W_GROUP, - W_NUM + W_USER, + W_GROUP, + W_NUM }; -#define _DEF_DIRMODE (S_IRWXU | S_IRWXG | S_IRWXO) -#define _PW_CONF "pw.conf" +#define _DEF_DIRMODE (S_IRWXU | S_IRWXG | S_IRWXO) +#define _PW_CONF "pw.conf" #define _UC_MAXLINE 1024 #define _UC_MAXSHELLS 32 @@ -114,3 +114,5 @@ uintmax_t strtounum(const char * __restrict, uintmax_t, uintmax_t, const char ** __restrict); bool grp_has_member(struct group *grp, const char *name); + +void usage(void); diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c index 32dec769fb1a..1941c03aa2c5 100644 --- a/usr.sbin/pw/pw_group.c +++ b/usr.sbin/pw/pw_group.c @@ -273,9 +273,13 @@ pw_group_next(int argc, char **argv, char *arg1 __unused) quiet = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); if (quiet) freopen(_PATH_DEVNULL, "w", stderr); @@ -332,9 +336,13 @@ pw_group_show(int argc, char **argv, char *arg1) all = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); if (quiet) freopen(_PATH_DEVNULL, "w", stderr); @@ -391,9 +399,13 @@ pw_group_del(int argc, char **argv, char *arg1) nis = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); if (quiet) freopen(_PATH_DEVNULL, "w", stderr); @@ -551,9 +563,13 @@ pw_group_add(int argc, char **argv, char *arg1) nis = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); if (quiet) freopen(_PATH_DEVNULL, "w", stderr); @@ -645,9 +661,14 @@ pw_group_mod(int argc, char **argv, char *arg1) nis = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); + if (quiet) freopen(_PATH_DEVNULL, "w", stderr); cnf = get_userconfig(cfg); @@ -697,11 +718,11 @@ pw_group_mod(int argc, char **argv, char *arg1) if ((grp = GETGRNAM(name)) == NULL) errx(EX_SOFTWARE, "group disappeared during update"); - pw_log(cnf, M_UPDATE, W_GROUP, "%s(%ju)", grp->gr_name, + pw_log(cnf, M_MODIFY, W_GROUP, "%s(%ju)", grp->gr_name, (uintmax_t)grp->gr_gid); if (nis && nis_update() == 0) - pw_log(cnf, M_UPDATE, W_GROUP, "NIS maps updated"); + pw_log(cnf, M_MODIFY, W_GROUP, "NIS maps updated"); return (EXIT_SUCCESS); } diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 6875d931a1d2..89354b249935 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -146,7 +146,7 @@ create_and_populate_homedir(struct userconf *cnf, struct passwd *pwd, copymkdir(conf.rootfd, pwd->pw_dir, skelfd, homemode, pwd->pw_uid, pwd->pw_gid, 0); - pw_log(cnf, update ? M_UPDATE : M_ADD, W_USER, "%s(%ju) home %s made", + pw_log(cnf, update ? M_MODIFY : M_ADD, W_USER, "%s(%ju) home %s made", pwd->pw_name, (uintmax_t)pwd->pw_uid, pwd->pw_dir); } @@ -708,9 +708,13 @@ pw_user_next(int argc, char **argv, char *name __unused) quiet = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); if (quiet) freopen(_PATH_DEVNULL, "w", stderr); @@ -772,9 +776,13 @@ pw_user_show(int argc, char **argv, char *arg1) v7 = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); if (quiet) freopen(_PATH_DEVNULL, "w", stderr); @@ -855,9 +863,13 @@ pw_user_del(int argc, char **argv, char *arg1) nis = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); if (quiet) freopen(_PATH_DEVNULL, "w", stderr); @@ -1003,9 +1015,13 @@ pw_user_lock(int argc, char **argv, char *arg1) /* compatibility */ break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); return (pw_userlock(arg1, M_LOCK)); } @@ -1022,9 +1038,13 @@ pw_user_unlock(int argc, char **argv, char *arg1) /* compatibility */ break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); return (pw_userlock(arg1, M_UNLOCK)); } @@ -1291,9 +1311,13 @@ pw_user_add(int argc, char **argv, char *arg1) nis = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); if (geteuid() != 0 && ! dryrun) errx(EX_NOPERM, "you must be root"); @@ -1604,9 +1628,13 @@ pw_user_mod(int argc, char **argv, char *arg1) nis = true; break; default: - exit(EX_USAGE); + usage(); } } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); if (geteuid() != 0 && ! dryrun) errx(EX_NOPERM, "you must be root"); @@ -1787,7 +1815,7 @@ pw_user_mod(int argc, char **argv, char *arg1) if (pwd == NULL) errx(EX_NOUSER, "user '%s' disappeared during update", name); grp = GETGRGID(pwd->pw_gid); - pw_log(cnf, M_UPDATE, W_USER, "%s(%ju):%s(%ju):%s:%s:%s", + pw_log(cnf, M_MODIFY, W_USER, "%s(%ju):%s(%ju):%s:%s:%s", pwd->pw_name, (uintmax_t)pwd->pw_uid, grp ? grp->gr_name : "unknown", (uintmax_t)(grp ? grp->gr_gid : (uid_t)-1), @@ -1808,7 +1836,7 @@ pw_user_mod(int argc, char **argv, char *arg1) } if (nis && nis_update() == 0) - pw_log(cnf, M_UPDATE, W_USER, "NIS maps updated"); + pw_log(cnf, M_MODIFY, W_USER, "NIS maps updated"); return (EXIT_SUCCESS); } diff --git a/usr.sbin/pw/tests/pw_useradd_test.sh b/usr.sbin/pw/tests/pw_useradd_test.sh index 3b495482eb05..b4efa42bada7 100755 --- a/usr.sbin/pw/tests/pw_useradd_test.sh +++ b/usr.sbin/pw/tests/pw_useradd_test.sh @@ -313,6 +313,22 @@ user_add_R_intermed_body() { test -d ${HOME}/a/b/c/foo || atf_fail "user directory not created" } +atf_test_case user_add_dir +user_add_dir_body() { + populate_root_etc_skel + + atf_check -s exit:0 ${RPW} useradd foo -M 0705 -m + atf_check grep -q '^foo:' $HOME/etc/master.passwd + atf_check test -d ${HOME}/home/foo + atf_check -o save:ugid \ + awk -F: '$1 == "foo" { print $3, $4 }' \ + $HOME/etc/master.passwd + atf_check -o file:ugid \ + stat -f '%u %g' ${HOME}/home/foo + atf_check -o inline:"40705\n" \ + stat -f '%p' ${HOME}/home/foo +} + atf_test_case user_add_skel user_add_skel_body() { populate_root_etc_skel @@ -511,6 +527,7 @@ atf_init_test_cases() { atf_add_test_case user_add_R atf_add_test_case user_add_R_no_symlink atf_add_test_case user_add_R_intermed + atf_add_test_case user_add_dir atf_add_test_case user_add_skel atf_add_test_case user_add_uid0 atf_add_test_case user_add_uid_too_large diff --git a/usr.sbin/rpc.lockd/lockd.c b/usr.sbin/rpc.lockd/lockd.c index 7e0652d26533..0ac7ddfeea5c 100644 --- a/usr.sbin/rpc.lockd/lockd.c +++ b/usr.sbin/rpc.lockd/lockd.c @@ -188,7 +188,8 @@ main(int argc, char **argv) kernel_lockd_client = FALSE; if (modfind("nfslockd") < 0) { if (kldload("nfslockd") < 0) { - fprintf(stderr, "Can't find or load kernel support for rpc.lockd - using non-kernel implementation\n"); + fprintf(stderr, "Unable to load nfslockd(4), " + "using userland implementation\n"); } else { kernel_lockd = TRUE; } diff --git a/usr.sbin/rpc.lockd/rpc.lockd.8 b/usr.sbin/rpc.lockd/rpc.lockd.8 index 89f55087901d..89592a1cceaf 100644 --- a/usr.sbin/rpc.lockd/rpc.lockd.8 +++ b/usr.sbin/rpc.lockd/rpc.lockd.8 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 21, 2019 +.Dd May 8, 2024 .Dt RPC.LOCKD 8 .Os .Sh NAME @@ -44,7 +44,7 @@ The .Nm utility provides monitored and unmonitored file and record locking services -in an NFS environment. +in an NFSv3 environment. To monitor the status of hosts requesting locks, the locking daemon typically operates in conjunction with @@ -137,6 +137,7 @@ RPC protocol specification for the network lock manager protocol. .El .Sh SEE ALSO .Xr syslog 3 , +.Xr nfslockd 4 , .Xr rc.conf 5 , .Xr rpc.statd 8 .Sh STANDARDS |