diff -up Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h.pam-inline-pam-asprintf Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h --- Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h.pam-inline-pam-asprintf 2025-06-17 10:12:31.039519165 +0200 +++ Linux-PAM-1.3.1/libpam/include/pam_cc_compat.h 2025-06-17 10:17:40.313892315 +0200 @@ -15,6 +15,12 @@ # define PAM_CLANG_PREREQ(maj, min) 0 #endif +#if PAM_GNUC_PREREQ(3, 0) +# define PAM_ATTRIBUTE_MALLOC __attribute__((__malloc__)) +#else +# define PAM_ATTRIBUTE_MALLOC /* empty */ +#endif + #if PAM_GNUC_PREREQ(4, 6) # define DIAG_PUSH_IGNORE_CAST_QUAL \ _Pragma("GCC diagnostic push"); \ diff -up Linux-PAM-1.3.1/libpam/include/pam_inline.h.pam-inline-pam-asprintf Linux-PAM-1.3.1/libpam/include/pam_inline.h --- Linux-PAM-1.3.1/libpam/include/pam_inline.h.pam-inline-pam-asprintf 2025-06-17 10:12:31.039639983 +0200 +++ Linux-PAM-1.3.1/libpam/include/pam_inline.h 2025-06-17 10:19:03.453146173 +0200 @@ -9,6 +9,9 @@ #define PAM_INLINE_H #include "pam_cc_compat.h" +#include +#include +#include #include /* @@ -64,4 +67,37 @@ pam_str_skip_icase_prefix_len(const char #define pam_str_skip_icase_prefix(str_, prefix_) \ pam_str_skip_icase_prefix_len((str_), (prefix_), sizeof(prefix_) - 1 + PAM_MUST_BE_ARRAY(prefix_)) +static inline char * PAM_FORMAT((printf, 1, 2)) PAM_NONNULL((1)) PAM_ATTRIBUTE_MALLOC +pam_asprintf(const char *fmt, ...) +{ + int rc; + char *res; + va_list ap; + + va_start(ap, fmt); + rc = vasprintf(&res, fmt, ap); + va_end(ap); + + return rc < 0 ? NULL : res; +} + +static inline int PAM_FORMAT((printf, 3, 4)) PAM_NONNULL((3)) +pam_snprintf(char *str, size_t size, const char *fmt, ...) +{ + int rc; + va_list ap; + + va_start(ap, fmt); + rc = vsnprintf(str, size, fmt, ap); + va_end(ap); + + if (rc < 0 || (unsigned int) rc >= size) + return -1; + return rc; +} + +#define pam_sprintf(str_, fmt_, ...) \ + pam_snprintf((str_), sizeof(str_) + PAM_MUST_BE_ARRAY(str_), (fmt_), \ + ##__VA_ARGS__) + #endif /* PAM_INLINE_H */