From 10b80543807e3fc5af5f8bcfd8bb6e219bb3cecc Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Tue, 18 Feb 2025 08:00:00 +0000 Subject: [PATCH] pam_inline: introduce pam_asprintf(), pam_snprintf(), and pam_sprintf() pam_asprintf() is essentially asprintf() with the following semantic difference: it returns the string itself instead of its length. pam_snprintf() is essentially snprintf() with the following semantic difference: it returns -1 in case of truncation. pam_sprintf() is essentially snprintf() but with a check that the buffer is an array, and with an automatically calculated buffer size. Use of these helpers would make error checking simpler. (cherry picked from commit 10b80543807e3fc5af5f8bcfd8bb6e219bb3cecc) Signed-off-by: Dmitry V. Levin Upstream-Status: Backport [https://github.com/linux-pam/linux-pam/commit/10b80543807e3fc5af5f8bcfd8bb6e219bb3cecc] Signed-off-by: Hitendra Prajapati --- libpam/include/pam_cc_compat.h | 6 ++++++ libpam/include/pam_inline.h | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/libpam/include/pam_cc_compat.h b/libpam/include/pam_cc_compat.h index 6919036..45c74b5 100644 --- a/libpam/include/pam_cc_compat.h +++ b/libpam/include/pam_cc_compat.h @@ -21,6 +21,12 @@ # define PAM_ATTRIBUTE_ALIGNED(arg) /* empty */ #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 --git a/libpam/include/pam_inline.h b/libpam/include/pam_inline.h index ec2f3bf..666a028 100644 --- a/libpam/include/pam_inline.h +++ b/libpam/include/pam_inline.h @@ -9,6 +9,9 @@ #define PAM_INLINE_H #include "pam_cc_compat.h" +#include +#include +#include #include #include #include @@ -66,6 +69,40 @@ pam_str_skip_icase_prefix_len(const char *str, const char *prefix, size_t prefix #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__) + + static inline int pam_read_passwords(int fd, int npass, char **passwords) { -- 2.50.1