Re: [RFC PATCH 1/9] libselinux: annotate interfaces with compiler attributes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, May 12, 2023 at 6:25 AM Christian Göttsche
<cgzones@xxxxxxxxxxxxxx> wrote:
>
> libselinux is used widely, in object managers, like systemd or dbus, and
> essential utilities, like coreutils or package managers.
>
> Help compilers and static analyzers to find suspicious usages of
> interfaces of libselinux by annotating them with function attributes.
> This includes potentially passing NULL to non-NULL parameters, no error
> handling by ignoring return values.
>
> Function attributes are GNU extensions and supported by GCC[1] and
> Clang[2].
>
> [1]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
> [2]: https://clang.llvm.org/docs/AttributeReference.html#function-attributes

So all of this is supported by clang?

>
> Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx>
> ---
>  libselinux/include/selinux/_private.h         |  76 ++++
>  libselinux/include/selinux/avc.h              |  66 ++--
>  libselinux/include/selinux/context.h          |  22 +-
>  libselinux/include/selinux/get_context_list.h |  16 +-
>  libselinux/include/selinux/get_default_type.h |   6 +-
>  libselinux/include/selinux/label.h            |  24 +-
>  libselinux/include/selinux/restorecon.h       |  16 +-
>  libselinux/include/selinux/selinux.h          | 354 ++++++++----------
>  libselinux/src/exception.sh                   |   4 +-
>  libselinux/src/selinuxswig.i                  |   1 +
>  scripts/run-scan-build                        |   2 +-
>  11 files changed, 308 insertions(+), 279 deletions(-)
>  create mode 100644 libselinux/include/selinux/_private.h
>
> diff --git a/libselinux/include/selinux/_private.h b/libselinux/include/selinux/_private.h

I don't like the name "_private.h". Maybe something like
"compiler_attributes.h" or something like that.

> new file mode 100644
> index 00000000..ddbe9798
> --- /dev/null
> +++ b/libselinux/include/selinux/_private.h
> @@ -0,0 +1,76 @@
> +#if defined __INCLUDE_LEVEL__ && __INCLUDE_LEVEL__ < 2 && ! defined NO_INCLUDE_ERROR
> +# error This file should not be included directly!
> +#endif
> +
> +
> +#ifndef _SELINUX_PRIVATE_H_
> +#define _SELINUX_PRIVATE_H_
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +
> +/* helper macro to check GCC version */
> +#if defined __GNUC__ && defined __GNUC_MINOR__
> +# define REQUIRE_GNUC(major, minor)    (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
> +#else
> +# define REQUIRE_GNUC(major, minor)    0
> +#endif
> +
> +
> +/* format */
> +#ifndef selinux_format
> +# ifdef __GNUC__
> +#  define selinux_format(opts)         __attribute__((__format__ opts))
> +# else
> +#  define selinux_format(opts)
> +# endif
> +#endif
> +
> +
> +/* nonnull */
> +#ifndef selinux_nonnull
> +# if REQUIRE_GNUC(3,3)
> +#  define selinux_nonnull(params)      __attribute__((__nonnull__ params))
> +# else
> +#  define selinux_nonnull(params)
> +# endif
> +#endif
> +

I am just going to comment here for this attribute. I really don't
want to see every function that takes a pointer marked with this
attribute.

> +
> +/* nodiscard / warn-unused-result */
> +#ifndef selinux_nodiscard
> +# if REQUIRE_GNUC(3,4)
> +#  define selinux_nodiscard            __attribute__((__warn_unused_result__))
> +# else
> +#  define selinux_nodiscard
> +# endif
> +#endif
> +

I most definitely do not want to see every function that returns a
value marked with this attribute. It is fine to mark functions where
ignoring the return value is very dangerous (for example, only a
truncated result has been returned).

Thanks,
Jim


> +
> +/* deprecated */
> +#ifndef selinux_deprecated
> +# if REQUIRE_GNUC(4,5)
> +#  define selinux_deprecated(msg)      __attribute__((__deprecated__ (msg)))
> +# else
> +#  define selinux_deprecated(msg)
> +# endif
> +#endif
> +
> +
> +/* access */
> +#ifndef selinux_access
> +# if REQUIRE_GNUC(10,0)
> +#  define selinux_access(opts)         __attribute__((__access__ opts))
> +# else
> +#  define selinux_access(opts)
> +# endif
> +#endif
> +
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _SELINUX_PRIVATE_H_ */
> diff --git a/libselinux/include/selinux/avc.h b/libselinux/include/selinux/avc.h
> index 4bbd2382..92c79988 100644
> --- a/libselinux/include/selinux/avc.h
> +++ b/libselinux/include/selinux/avc.h
> @@ -37,8 +37,8 @@ typedef struct security_id *security_id_t;
>   * failure, with @errno set to %ENOMEM if insufficient memory was
>   * available to make the copy, or %EINVAL if the input SID is invalid.
>   */
> -extern int avc_sid_to_context(security_id_t sid, char ** ctx);
> -extern int avc_sid_to_context_raw(security_id_t sid, char ** ctx);
> +extern int avc_sid_to_context(security_id_t sid, char ** ctx) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int avc_sid_to_context_raw(security_id_t sid, char ** ctx) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /**
>   * avc_context_to_sid - get SID for context.
> @@ -51,8 +51,8 @@ extern int avc_sid_to_context_raw(security_id_t sid, char ** ctx);
>   * to the SID structure into the memory referenced by @sid,
>   * returning %0 on success or -%1 on error with @errno set.
>   */
> -extern int avc_context_to_sid(const char * ctx, security_id_t * sid);
> -extern int avc_context_to_sid_raw(const char * ctx, security_id_t * sid);
> +extern int avc_context_to_sid(const char * ctx, security_id_t * sid) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int avc_context_to_sid_raw(const char * ctx, security_id_t * sid) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /**
>   * sidget - increment SID reference counter.
> @@ -64,11 +64,7 @@ extern int avc_context_to_sid_raw(const char * ctx, security_id_t * sid);
>   * reference count).  Note that avc_context_to_sid() also
>   * increments reference counts.
>   */
> -extern int sidget(security_id_t sid)
> -#ifdef __GNUC__
> -__attribute__ ((deprecated))
> -#endif
> -;
> +extern int sidget(security_id_t sid) selinux_deprecated("SID refcounting has been removed");
>
>  /**
>   * sidput - decrement SID reference counter.
> @@ -80,11 +76,7 @@ __attribute__ ((deprecated))
>   * zero, the SID is invalid, and avc_context_to_sid() must
>   * be called to obtain a new SID for the security context.
>   */
> -extern int sidput(security_id_t sid)
> -#ifdef __GNUC__
> -__attribute__ ((deprecated))
> -#endif
> -;
> +extern int sidput(security_id_t sid) selinux_deprecated("SID refcounting has been removed");
>
>  /**
>   * avc_get_initial_sid - get SID for an initial kernel security identifier
> @@ -95,7 +87,7 @@ __attribute__ ((deprecated))
>   * @name using security_get_initial_context() and then call
>   * avc_context_to_sid() to get the corresponding SID.
>   */
> -extern int avc_get_initial_sid(const char *name, security_id_t * sid);
> +extern int avc_get_initial_sid(const char *name, security_id_t * sid) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /*
>   * AVC entry
> @@ -139,9 +131,7 @@ struct avc_memory_callback {
>  struct avc_log_callback {
>         /* log the printf-style format and arguments. */
>         void
> -#ifdef __GNUC__
> -__attribute__ ((format(printf, 1, 2)))
> -#endif
> +       selinux_format((printf, 1, 2))
>         (*func_log) (const char *fmt, ...);
>         /* store a string representation of auditdata (corresponding
>            to the given security class) into msgbuf. */
> @@ -200,11 +190,7 @@ extern int avc_init(const char *msgprefix,
>                     const struct avc_memory_callback *mem_callbacks,
>                     const struct avc_log_callback *log_callbacks,
>                     const struct avc_thread_callback *thread_callbacks,
> -                   const struct avc_lock_callback *lock_callbacks)
> -#ifdef __GNUC__
> -       __attribute__ ((deprecated("Use avc_open and selinux_set_callback")))
> -#endif
> -;
> +                   const struct avc_lock_callback *lock_callbacks) selinux_nodiscard selinux_deprecated("Use avc_open(3) and selinux_set_callback(3)");
>
>  /**
>   * avc_open - Initialize the AVC.
> @@ -215,7 +201,7 @@ extern int avc_init(const char *msgprefix,
>   * is set to "avc" and any callbacks desired should be specified via
>   * selinux_set_callback().  Available options are listed above.
>   */
> -extern int avc_open(struct selinux_opt *opts, unsigned nopts);
> +extern int avc_open(struct selinux_opt *opts, unsigned nopts) selinux_access((read_only, 1, 2)) selinux_nodiscard;
>
>  /**
>   * avc_cleanup - Remove unused SIDs and AVC entries.
> @@ -235,7 +221,7 @@ extern void avc_cleanup(void);
>   * The SID mapping is not affected.  Return %0 on success,
>   * -%1 with @errno set on error.
>   */
> -extern int avc_reset(void);
> +extern int avc_reset(void) selinux_nodiscard;
>
>  /**
>   * avc_destroy - Free all AVC structures.
> @@ -273,7 +259,7 @@ extern int avc_has_perm_noaudit(security_id_t ssid,
>                                 security_id_t tsid,
>                                 security_class_t tclass,
>                                 access_vector_t requested,
> -                               struct avc_entry_ref *aeref, struct av_decision *avd);
> +                               struct avc_entry_ref *aeref, struct av_decision *avd) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /**
>   * avc_has_perm - Check permissions and perform any appropriate auditing.
> @@ -295,7 +281,7 @@ extern int avc_has_perm_noaudit(security_id_t ssid,
>   */
>  extern int avc_has_perm(security_id_t ssid, security_id_t tsid,
>                         security_class_t tclass, access_vector_t requested,
> -                       struct avc_entry_ref *aeref, void *auditdata);
> +                       struct avc_entry_ref *aeref, void *auditdata) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /**
>   * avc_audit - Audit the granting or denial of permissions.
> @@ -318,7 +304,7 @@ extern int avc_has_perm(security_id_t ssid, security_id_t tsid,
>   */
>  extern void avc_audit(security_id_t ssid, security_id_t tsid,
>                       security_class_t tclass, access_vector_t requested,
> -                     struct av_decision *avd, int result, void *auditdata);
> +                     struct av_decision *avd, int result, void *auditdata) selinux_nonnull((1,2,5));
>
>  /**
>   * avc_compute_create - Compute SID for labeling a new object.
> @@ -336,7 +322,7 @@ extern void avc_audit(security_id_t ssid, security_id_t tsid,
>   */
>  extern int avc_compute_create(security_id_t ssid,
>                               security_id_t tsid,
> -                             security_class_t tclass, security_id_t * newsid);
> +                             security_class_t tclass, security_id_t * newsid) selinux_nonnull((1,2,4)) selinux_nodiscard;
>
>  /**
>   * avc_compute_member - Compute SID for polyinstantation.
> @@ -354,7 +340,7 @@ extern int avc_compute_create(security_id_t ssid,
>   */
>  extern int avc_compute_member(security_id_t ssid,
>                               security_id_t tsid,
> -                             security_class_t tclass, security_id_t * newsid);
> +                             security_class_t tclass, security_id_t * newsid) selinux_nonnull((1,2,4)) selinux_nodiscard;
>
>  /*
>   * security event callback facility
> @@ -392,7 +378,7 @@ extern int avc_add_callback(int (*callback)
>                               access_vector_t * out_retained),
>                             uint32_t events, security_id_t ssid,
>                             security_id_t tsid, security_class_t tclass,
> -                           access_vector_t perms);
> +                           access_vector_t perms) selinux_nonnull((1,3,4)) selinux_nodiscard;
>
>  /*
>   * AVC statistics
> @@ -423,7 +409,7 @@ struct avc_cache_stats {
>   * avc_reset().  See the structure definition for
>   * details.
>   */
> -extern void avc_cache_stats(struct avc_cache_stats *stats);
> +extern void avc_cache_stats(struct avc_cache_stats *stats) selinux_nonnull((1));
>
>  /**
>   * avc_av_stats - log av table statistics.
> @@ -446,7 +432,7 @@ extern void avc_sid_stats(void);
>  /**
>   * avc_netlink_open - Create a netlink socket and connect to the kernel.
>   */
> -extern int avc_netlink_open(int blocking);
> +extern int avc_netlink_open(int blocking) selinux_nodiscard;
>
>  /**
>   * avc_netlink_loop - Wait for netlink messages from the kernel
> @@ -464,7 +450,7 @@ extern void avc_netlink_close(void);
>   * Allows the application to manage messages from the netlink socket in
>   * its own main loop.
>   */
> -extern int avc_netlink_acquire_fd(void);
> +extern int avc_netlink_acquire_fd(void) selinux_nodiscard;
>
>  /**
>   * avc_netlink_release_fd - Release netlink socket fd.
> @@ -479,13 +465,13 @@ extern void avc_netlink_release_fd(void);
>   * Called by the application when using avc_netlink_acquire_fd() to
>   * process kernel netlink events.
>   */
> -extern int avc_netlink_check_nb(void);
> +extern int avc_netlink_check_nb(void) selinux_nodiscard;
>
>  /**
>   * selinux_status_open - Open and map SELinux kernel status page
>   *
>   */
> -extern int selinux_status_open(int fallback);
> +extern int selinux_status_open(int fallback) selinux_nodiscard;
>
>  /**
>   * selinux_status_close - Unmap and close SELinux kernel status page
> @@ -497,25 +483,25 @@ extern void selinux_status_close(void);
>   * selinux_status_updated - Inform us whether the kernel status has been updated
>   *
>   */
> -extern int selinux_status_updated(void);
> +extern int selinux_status_updated(void) selinux_nodiscard;
>
>  /**
>   * selinux_status_getenforce - Get the enforce flag value
>   *
>   */
> -extern int selinux_status_getenforce(void);
> +extern int selinux_status_getenforce(void) selinux_nodiscard;
>
>  /**
>   * selinux_status_policyload - Get the number of policy reloaded
>   *
>   */
> -extern int selinux_status_policyload(void);
> +extern int selinux_status_policyload(void) selinux_nodiscard;
>
>  /**
>   * selinux_status_deny_unknown - Get the  behavior for undefined classes/permissions
>   *
>   */
> -extern int selinux_status_deny_unknown(void);
> +extern int selinux_status_deny_unknown(void) selinux_nodiscard;
>
>  #ifdef __cplusplus
>  }
> diff --git a/libselinux/include/selinux/context.h b/libselinux/include/selinux/context.h
> index 59d9bb69..e3c99191 100644
> --- a/libselinux/include/selinux/context.h
> +++ b/libselinux/include/selinux/context.h
> @@ -1,6 +1,8 @@
>  #ifndef _SELINUX_CONTEXT_H_
>  #define _SELINUX_CONTEXT_H_
>
> +#include <selinux/_private.h>
> +
>  #ifdef __cplusplus
>  extern "C" {
>  #endif
> @@ -17,7 +19,7 @@ extern "C" {
>
>  /* Return a new context initialized to a context string */
>
> -       extern context_t context_new(const char *str);
> +       extern context_t context_new(const char *str) selinux_nonnull((1)) selinux_nodiscard;
>
>  /*
>   * Return a pointer to the string value of the context_t
> @@ -25,24 +27,24 @@ extern "C" {
>   * for the same context_t*
>   */
>
> -       extern const char *context_str(context_t con);
> +       extern const char *context_str(context_t con) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Free the storage used by a context */
>         extern void context_free(context_t con);
>
>  /* Get a pointer to the string value of a context component */
>
> -       extern const char *context_type_get(context_t con);
> -       extern const char *context_range_get(context_t con);
> -       extern const char *context_role_get(context_t con);
> -       extern const char *context_user_get(context_t con);
> +       extern const char *context_type_get(context_t con) selinux_nonnull((1)) selinux_nodiscard;
> +       extern const char *context_range_get(context_t con) selinux_nonnull((1)) selinux_nodiscard;
> +       extern const char *context_role_get(context_t con) selinux_nonnull((1)) selinux_nodiscard;
> +       extern const char *context_user_get(context_t con) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Set a context component.  Returns nonzero if unsuccessful */
>
> -       extern int context_type_set(context_t con, const char *type);
> -       extern int context_range_set(context_t con, const char *range);
> -       extern int context_role_set(context_t con, const char *role);
> -       extern int context_user_set(context_t con, const char *user);
> +       extern int context_type_set(context_t con, const char *type) selinux_nonnull((1)) selinux_nodiscard;
> +       extern int context_range_set(context_t con, const char *range) selinux_nonnull((1)) selinux_nodiscard;
> +       extern int context_role_set(context_t con, const char *role) selinux_nonnull((1)) selinux_nodiscard;
> +       extern int context_user_set(context_t con, const char *user) selinux_nonnull((1)) selinux_nodiscard;
>
>  #ifdef __cplusplus
>  }
> diff --git a/libselinux/include/selinux/get_context_list.h b/libselinux/include/selinux/get_context_list.h
> index 6b2f14f3..6146e4fe 100644
> --- a/libselinux/include/selinux/get_context_list.h
> +++ b/libselinux/include/selinux/get_context_list.h
> @@ -18,14 +18,14 @@ extern "C" {
>     Caller must free via freeconary. */
>         extern int get_ordered_context_list(const char *user,
>                                             const char *fromcon,
> -                                           char *** list);
> +                                           char *** list) selinux_nonnull((1,3)) selinux_nodiscard;
>
>  /* As above, but use the provided MLS level rather than the
>     default level for the user. */
>         extern int get_ordered_context_list_with_level(const char *user,
>                                                        const char *level,
>                                                        const char *fromcon,
> -                                                      char *** list);
> +                                                      char *** list) selinux_nonnull((1,4)) selinux_nodiscard;
>
>  /* Get the default security context for a user session for 'user'
>     spawned by 'fromcon' and set *newcon to refer to it.  The context
> @@ -36,14 +36,14 @@ extern "C" {
>     Caller must free via freecon. */
>         extern int get_default_context(const char *user,
>                                        const char *fromcon,
> -                                      char ** newcon);
> +                                      char ** newcon) selinux_nonnull((1,3)) selinux_nodiscard;
>
>  /* As above, but use the provided MLS level rather than the
>     default level for the user. */
>         extern int get_default_context_with_level(const char *user,
>                                                   const char *level,
>                                                   const char *fromcon,
> -                                                 char ** newcon);
> +                                                 char ** newcon) selinux_nonnull((1,4)) selinux_nodiscard;
>
>  /* Same as get_default_context, but only return a context
>     that has the specified role.  If no reachable context exists
> @@ -51,7 +51,7 @@ extern "C" {
>         extern int get_default_context_with_role(const char *user,
>                                                  const char *role,
>                                                  const char *fromcon,
> -                                                char ** newcon);
> +                                                char ** newcon) selinux_nonnull((1,2,4)) selinux_nodiscard;
>
>  /* Same as get_default_context, but only return a context
>     that has the specified role and level.  If no reachable context exists
> @@ -60,21 +60,21 @@ extern "C" {
>                                                       const char *role,
>                                                       const char *level,
>                                                       const char *fromcon,
> -                                                     char ** newcon);
> +                                                     char ** newcon) selinux_nonnull((1,2,5)) selinux_nodiscard;
>
>  /* Given a list of authorized security contexts for the user,
>     query the user to select one and set *newcon to refer to it.
>     Caller must free via freecon.
>     Returns 0 on success or -1 otherwise. */
>         extern int query_user_context(char ** list,
> -                                     char ** newcon);
> +                                     char ** newcon) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /* Allow the user to manually enter a context as a fallback
>     if a list of authorized contexts could not be obtained.
>     Caller must free via freecon.
>     Returns 0 on success or -1 otherwise. */
>         extern int manual_user_enter_context(const char *user,
> -                                            char ** newcon);
> +                                            char ** newcon) selinux_nonnull((2)) selinux_nodiscard;
>
>  #ifdef __cplusplus
>  }
> diff --git a/libselinux/include/selinux/get_default_type.h b/libselinux/include/selinux/get_default_type.h
> index 93f5b276..dccb715b 100644
> --- a/libselinux/include/selinux/get_default_type.h
> +++ b/libselinux/include/selinux/get_default_type.h
> @@ -5,17 +5,19 @@
>  #ifndef _SELINUX_GET_DEFAULT_TYPE_H_
>  #define _SELINUX_GET_DEFAULT_TYPE_H_
>
> +#include <selinux/_private.h>
> +
>  #ifdef __cplusplus
>  extern "C" {
>  #endif
>
>  /* Return path to default type file. */
> -       extern const char *selinux_default_type_path(void);
> +       extern const char *selinux_default_type_path(void) selinux_nodiscard;
>
>  /* Get the default type (domain) for 'role' and set 'type' to refer to it.
>     Caller must free via free().
>     Return 0 on success or -1 otherwise. */
> -       extern int get_default_type(const char *role, char **type);
> +       extern int get_default_type(const char *role, char **type) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  #ifdef __cplusplus
>  }
> diff --git a/libselinux/include/selinux/label.h b/libselinux/include/selinux/label.h
> index e8983606..f12a5803 100644
> --- a/libselinux/include/selinux/label.h
> +++ b/libselinux/include/selinux/label.h
> @@ -75,7 +75,7 @@ struct selabel_handle;
>   */
>  extern struct selabel_handle *selabel_open(unsigned int backend,
>                                            const struct selinux_opt *opts,
> -                                          unsigned nopts);
> +                                          unsigned nopts) selinux_access((read_only, 2, 3)) selinux_nodiscard;
>
>  /**
>   * selabel_close - Close a labeling handle.
> @@ -84,7 +84,7 @@ extern struct selabel_handle *selabel_open(unsigned int backend,
>   * Destroy the specified handle, closing files, freeing allocated memory,
>   * etc.  The handle may not be further used after it has been closed.
>   */
> -extern void selabel_close(struct selabel_handle *handle);
> +extern void selabel_close(struct selabel_handle *handle) selinux_nonnull((1));
>
>  /**
>   * selabel_lookup - Perform labeling lookup operation.
> @@ -100,24 +100,24 @@ extern void selabel_close(struct selabel_handle *handle);
>   * by the user with freecon().
>   */
>  extern int selabel_lookup(struct selabel_handle *handle, char **con,
> -                         const char *key, int type);
> +                         const char *key, int type) selinux_nonnull((1,2)) selinux_nodiscard;
>  extern int selabel_lookup_raw(struct selabel_handle *handle, char **con,
> -                             const char *key, int type);
> +                             const char *key, int type) selinux_nonnull((1,2)) selinux_nodiscard;
>
> -extern bool selabel_partial_match(struct selabel_handle *handle, const char *key);
> +extern bool selabel_partial_match(struct selabel_handle *handle, const char *key) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  extern bool selabel_get_digests_all_partial_matches(struct selabel_handle *rec,
>                                                     const char *key,
>                                                     uint8_t **calculated_digest,
>                                                     uint8_t **xattr_digest,
> -                                                   size_t *digest_len);
> +                                                   size_t *digest_len) selinux_nonnull((1,2,3,4,5)) selinux_nodiscard;
>  extern bool selabel_hash_all_partial_matches(struct selabel_handle *rec,
> -                                            const char *key, uint8_t* digest);
> +                                            const char *key, uint8_t* digest) selinux_nonnull((1,2,3)) selinux_nodiscard;
>
>  extern int selabel_lookup_best_match(struct selabel_handle *rec, char **con,
> -                                    const char *key, const char **aliases, int type);
> +                                    const char *key, const char **aliases, int type) selinux_nonnull((1,2,3)) selinux_nodiscard;
>  extern int selabel_lookup_best_match_raw(struct selabel_handle *rec, char **con,
> -                                        const char *key, const char **aliases, int type);
> +                                        const char *key, const char **aliases, int type) selinux_nonnull((1,2,3)) selinux_nodiscard;
>
>  /**
>   * selabel_digest - Retrieve the SHA1 digest and the list of specfiles used to
> @@ -134,7 +134,7 @@ extern int selabel_lookup_best_match_raw(struct selabel_handle *rec, char **con,
>   */
>  extern int selabel_digest(struct selabel_handle *rec,
>                           unsigned char **digest, size_t *digest_len,
> -                         char ***specfiles, size_t *num_specfiles);
> +                         char ***specfiles, size_t *num_specfiles) selinux_nonnull((1,2,3,4,5)) selinux_nodiscard;
>
>  enum selabel_cmp_result {
>         SELABEL_SUBSET,
> @@ -154,7 +154,7 @@ enum selabel_cmp_result {
>   * of @h2, and %SELABEL_INCOMPARABLE if @h1 and @h2 are incomparable.
>   */
>  extern enum selabel_cmp_result selabel_cmp(struct selabel_handle *h1,
> -                                          struct selabel_handle *h2);
> +                                          struct selabel_handle *h2) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /**
>   * selabel_stats - log labeling operation statistics.
> @@ -164,7 +164,7 @@ extern enum selabel_cmp_result selabel_cmp(struct selabel_handle *h1,
>   * number of unused matching entries, or other operational statistics.
>   * Message is backend-specific, some backends may not output a message.
>   */
> -extern void selabel_stats(struct selabel_handle *handle);
> +extern void selabel_stats(struct selabel_handle *handle) selinux_nonnull((1));
>
>  /*
>   * Type codes used by specific backends
> diff --git a/libselinux/include/selinux/restorecon.h b/libselinux/include/selinux/restorecon.h
> index b10fe684..aa53c706 100644
> --- a/libselinux/include/selinux/restorecon.h
> +++ b/libselinux/include/selinux/restorecon.h
> @@ -5,6 +5,8 @@
>  #include <stddef.h>
>  #include <stdarg.h>
>
> +#include <selinux/_private.h>
> +
>  #ifdef __cplusplus
>  extern "C" {
>  #endif
> @@ -23,7 +25,7 @@ extern "C" {
>   * selinux_restorecon_set_sehandle(3).
>   */
>  extern int selinux_restorecon(const char *pathname,
> -                                   unsigned int restorecon_flags);
> +                                   unsigned int restorecon_flags) selinux_nonnull((1)) selinux_nodiscard;
>  /**
>   * selinux_restorecon_parallel - Relabel files, optionally use more threads.
>   * @pathname: specifies file/directory to relabel.
> @@ -36,7 +38,7 @@ extern int selinux_restorecon(const char *pathname,
>   */
>  extern int selinux_restorecon_parallel(const char *pathname,
>                                        unsigned int restorecon_flags,
> -                                      size_t nthreads);
> +                                      size_t nthreads) selinux_nonnull((1)) selinux_nodiscard;
>  /*
>   * restorecon_flags options
>   */
> @@ -144,7 +146,7 @@ extern void selinux_restorecon_set_sehandle(struct selabel_handle *hndl);
>   * Return value is the created handle on success or NULL with @errno set on
>   * failure.
>   */
> -extern struct selabel_handle *selinux_restorecon_default_handle(void);
> +extern struct selabel_handle *selinux_restorecon_default_handle(void) selinux_nodiscard;
>
>  /**
>   * selinux_restorecon_set_exclude_list - Add a list of directories that are
> @@ -152,7 +154,7 @@ extern struct selabel_handle *selinux_restorecon_default_handle(void);
>   * @exclude_list: containing a NULL terminated list of one or more
>   *               directories not to be relabeled.
>   */
> -extern void selinux_restorecon_set_exclude_list(const char **exclude_list);
> +extern void selinux_restorecon_set_exclude_list(const char **exclude_list) selinux_nonnull((1));
>
>  /**
>   * selinux_restorecon_set_alt_rootpath - Use alternate rootpath.
> @@ -160,7 +162,7 @@ extern void selinux_restorecon_set_exclude_list(const char **exclude_list);
>   *
>   * Return %0 on success, -%1 with @errno set on failure.
>   */
> -extern int selinux_restorecon_set_alt_rootpath(const char *alt_rootpath);
> +extern int selinux_restorecon_set_alt_rootpath(const char *alt_rootpath) selinux_nonnull((1)) selinux_nodiscard;
>
>  /**
>   * selinux_restorecon_xattr - Read/remove security.sehash xattr entries.
> @@ -196,7 +198,7 @@ struct dir_xattr {
>
>  extern int selinux_restorecon_xattr(const char *pathname,
>                                     unsigned int xattr_flags,
> -                                   struct dir_xattr ***xattr_list);
> +                                   struct dir_xattr ***xattr_list) selinux_nonnull((1,3)) selinux_nodiscard;
>
>  /*
>   * xattr_flags options
> @@ -218,7 +220,7 @@ extern int selinux_restorecon_xattr(const char *pathname,
>   * (i.e., with a zero return value), then this function returns the number of
>   * errors ignored during the file tree walk.
>   */
> -extern long unsigned selinux_restorecon_get_skipped_errors(void);
> +extern long unsigned selinux_restorecon_get_skipped_errors(void) selinux_nodiscard;
>
>  #ifdef __cplusplus
>  }
> diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h
> index a0948853..7f8deb65 100644
> --- a/libselinux/include/selinux/selinux.h
> +++ b/libselinux/include/selinux/selinux.h
> @@ -4,21 +4,19 @@
>  #include <sys/types.h>
>  #include <stdarg.h>
>
> +#include <selinux/_private.h>
> +
>  #ifdef __cplusplus
>  extern "C" {
>  #endif
>
>  /* Return 1 if we are running on a SELinux kernel, or 0 otherwise. */
> -extern int is_selinux_enabled(void);
> +extern int is_selinux_enabled(void) selinux_nodiscard;
>  /* Return 1 if we are running on a SELinux MLS kernel, or 0 otherwise. */
> -extern int is_selinux_mls_enabled(void);
> +extern int is_selinux_mls_enabled(void) selinux_nodiscard;
>
>  /* No longer used; here for compatibility with legacy callers. */
> -typedef char *security_context_t
> -#ifdef __GNUC__
> -__attribute__ ((deprecated))
> -#endif
> -;
> +typedef char *security_context_t selinux_deprecated("Use literal char*");
>
>  /* Free the memory allocated for a context by any of the below get* calls. */
>  extern void freecon(char * con);
> @@ -30,8 +28,8 @@ extern void freeconary(char ** con);
>
>  /* Get current context, and set *con to refer to it.
>     Caller must free via freecon. */
> -extern int getcon(char ** con);
> -extern int getcon_raw(char ** con);
> +extern int getcon(char ** con) selinux_nonnull((1)) selinux_nodiscard;
> +extern int getcon_raw(char ** con) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Set the current security context to con.
>     Note that use of this function requires that the entire application
> @@ -41,18 +39,18 @@ extern int getcon_raw(char ** con);
>     instead. Note that the application may lose access to its open descriptors
>     as a result of a setcon() unless policy allows it to use descriptors opened
>     by the old context. */
> -extern int setcon(const char * con);
> -extern int setcon_raw(const char * con);
> +extern int setcon(const char * con) selinux_nodiscard;
> +extern int setcon_raw(const char * con) selinux_nodiscard;
>
>  /* Get context of process identified by pid, and
>     set *con to refer to it.  Caller must free via freecon. */
> -extern int getpidcon(pid_t pid, char ** con);
> -extern int getpidcon_raw(pid_t pid, char ** con);
> +extern int getpidcon(pid_t pid, char ** con) selinux_nonnull((2)) selinux_nodiscard;
> +extern int getpidcon_raw(pid_t pid, char ** con) selinux_nonnull((2)) selinux_nodiscard;
>
>  /* Get previous context (prior to last exec), and set *con to refer to it.
>     Caller must free via freecon. */
> -extern int getprevcon(char ** con);
> -extern int getprevcon_raw(char ** con);
> +extern int getprevcon(char ** con) selinux_nonnull((1)) selinux_nodiscard;
> +extern int getprevcon_raw(char ** con) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Get previous context (prior to last exec) of process identified by pid, and
>     set *con to refer to it.  Caller must free via freecon. */
> @@ -62,72 +60,72 @@ extern int getpidprevcon_raw(pid_t pid, char ** con);
>  /* Get exec context, and set *con to refer to it.
>     Sets *con to NULL if no exec context has been set, i.e. using default.
>     If non-NULL, caller must free via freecon. */
> -extern int getexeccon(char ** con);
> -extern int getexeccon_raw(char ** con);
> +extern int getexeccon(char ** con) selinux_nonnull((1)) selinux_nodiscard;
> +extern int getexeccon_raw(char ** con) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Set exec security context for the next execve.
>     Call with NULL if you want to reset to the default. */
> -extern int setexeccon(const char * con);
> -extern int setexeccon_raw(const char * con);
> +extern int setexeccon(const char * con) selinux_nodiscard;
> +extern int setexeccon_raw(const char * con) selinux_nodiscard;
>
>  /* Get fscreate context, and set *con to refer to it.
>     Sets *con to NULL if no fs create context has been set, i.e. using default.
>     If non-NULL, caller must free via freecon. */
> -extern int getfscreatecon(char ** con);
> -extern int getfscreatecon_raw(char ** con);
> +extern int getfscreatecon(char ** con) selinux_nonnull((1)) selinux_nodiscard;
> +extern int getfscreatecon_raw(char ** con) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Set the fscreate security context for subsequent file creations.
>     Call with NULL if you want to reset to the default. */
> -extern int setfscreatecon(const char * context);
> -extern int setfscreatecon_raw(const char * context);
> +extern int setfscreatecon(const char * context) selinux_nodiscard;
> +extern int setfscreatecon_raw(const char * context) selinux_nodiscard;
>
>  /* Get keycreate context, and set *con to refer to it.
>     Sets *con to NULL if no key create context has been set, i.e. using default.
>     If non-NULL, caller must free via freecon. */
> -extern int getkeycreatecon(char ** con);
> -extern int getkeycreatecon_raw(char ** con);
> +extern int getkeycreatecon(char ** con) selinux_nonnull((1)) selinux_nodiscard;
> +extern int getkeycreatecon_raw(char ** con) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Set the keycreate security context for subsequent key creations.
>     Call with NULL if you want to reset to the default. */
> -extern int setkeycreatecon(const char * context);
> -extern int setkeycreatecon_raw(const char * context);
> +extern int setkeycreatecon(const char * context) selinux_nodiscard;
> +extern int setkeycreatecon_raw(const char * context) selinux_nodiscard;
>
>  /* Get sockcreate context, and set *con to refer to it.
>     Sets *con to NULL if no socket create context has been set, i.e. using default.
>     If non-NULL, caller must free via freecon. */
> -extern int getsockcreatecon(char ** con);
> -extern int getsockcreatecon_raw(char ** con);
> +extern int getsockcreatecon(char ** con) selinux_nonnull((1)) selinux_nodiscard;
> +extern int getsockcreatecon_raw(char ** con) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Set the sockcreate security context for subsequent socket creations.
>     Call with NULL if you want to reset to the default. */
> -extern int setsockcreatecon(const char * context);
> -extern int setsockcreatecon_raw(const char * context);
> +extern int setsockcreatecon(const char * context) selinux_nodiscard;
> +extern int setsockcreatecon_raw(const char * context) selinux_nodiscard;
>
>  /* Wrappers for the xattr API. */
>
>  /* Get file context, and set *con to refer to it.
>     Caller must free via freecon. */
> -extern int getfilecon(const char *path, char ** con);
> -extern int getfilecon_raw(const char *path, char ** con);
> -extern int lgetfilecon(const char *path, char ** con);
> -extern int lgetfilecon_raw(const char *path, char ** con);
> -extern int fgetfilecon(int fd, char ** con);
> -extern int fgetfilecon_raw(int fd, char ** con);
> +extern int getfilecon(const char *path, char ** con) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int getfilecon_raw(const char *path, char ** con) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int lgetfilecon(const char *path, char ** con) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int lgetfilecon_raw(const char *path, char ** con) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int fgetfilecon(int fd, char ** con) selinux_nonnull((2)) selinux_nodiscard;
> +extern int fgetfilecon_raw(int fd, char ** con) selinux_nonnull((2)) selinux_nodiscard;
>
>  /* Set file context */
> -extern int setfilecon(const char *path, const char * con);
> -extern int setfilecon_raw(const char *path, const char * con);
> -extern int lsetfilecon(const char *path, const char * con);
> -extern int lsetfilecon_raw(const char *path, const char * con);
> -extern int fsetfilecon(int fd, const char * con);
> -extern int fsetfilecon_raw(int fd, const char * con);
> +extern int setfilecon(const char *path, const char * con) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int setfilecon_raw(const char *path, const char * con) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int lsetfilecon(const char *path, const char * con) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int lsetfilecon_raw(const char *path, const char * con) selinux_nonnull((1,2)) selinux_nodiscard;
> +extern int fsetfilecon(int fd, const char * con) selinux_nonnull((2)) selinux_nodiscard;
> +extern int fsetfilecon_raw(int fd, const char * con) selinux_nonnull((2)) selinux_nodiscard;
>
>  /* Wrappers for the socket API */
>
>  /* Get context of peer socket, and set *con to refer to it.
>     Caller must free via freecon. */
> -extern int getpeercon(int fd, char ** con);
> -extern int getpeercon_raw(int fd, char ** con);
> +extern int getpeercon(int fd, char ** con) selinux_nonnull((2)) selinux_nodiscard;
> +extern int getpeercon_raw(int fd, char ** con) selinux_nonnull((2)) selinux_nodiscard;
>
>  /* Wrappers for the selinuxfs (policy) API. */
>
> @@ -156,10 +154,8 @@ struct selinux_opt {
>  union selinux_callback {
>         /* log the printf-style format and arguments,
>            with the type code indicating the type of message */
> -       int
> -#ifdef __GNUC__
> -__attribute__ ((format(printf, 2, 3)))
> -#endif
> +       int
> +       selinux_format((printf, 2, 3))
>         (*func_log) (int type, const char *fmt, ...);
>         /* store a string representation of auditdata (corresponding
>            to the given security class) into msgbuf. */
> @@ -179,7 +175,7 @@ __attribute__ ((format(printf, 2, 3)))
>  #define SELINUX_CB_SETENFORCE  3
>  #define SELINUX_CB_POLICYLOAD  4
>
> -extern union selinux_callback selinux_get_callback(int type);
> +extern union selinux_callback selinux_get_callback(int type) selinux_nodiscard;
>  extern void selinux_set_callback(int type, union selinux_callback cb);
>
>         /* Logging type codes, passed to the logging callback */
> @@ -196,66 +192,66 @@ extern int security_compute_av(const char * scon,
>                                const char * tcon,
>                                security_class_t tclass,
>                                access_vector_t requested,
> -                              struct av_decision *avd);
> +                              struct av_decision *avd) selinux_nonnull((1,2,5)) selinux_nodiscard;
>  extern int security_compute_av_raw(const char * scon,
>                                    const char * tcon,
>                                    security_class_t tclass,
>                                    access_vector_t requested,
> -                                  struct av_decision *avd);
> +                                  struct av_decision *avd) selinux_nonnull((1,2,5)) selinux_nodiscard;
>
>  extern int security_compute_av_flags(const char * scon,
>                                      const char * tcon,
>                                      security_class_t tclass,
>                                      access_vector_t requested,
> -                                    struct av_decision *avd);
> +                                    struct av_decision *avd) selinux_nonnull((1,2,5)) selinux_nodiscard;
>  extern int security_compute_av_flags_raw(const char * scon,
>                                          const char * tcon,
>                                          security_class_t tclass,
>                                          access_vector_t requested,
> -                                        struct av_decision *avd);
> +                                        struct av_decision *avd) selinux_nonnull((1,2,5)) selinux_nodiscard;
>
>  /* Compute a labeling decision and set *newcon to refer to it.
>     Caller must free via freecon. */
>  extern int security_compute_create(const char * scon,
>                                    const char * tcon,
>                                    security_class_t tclass,
> -                                  char ** newcon);
> +                                  char ** newcon) selinux_nonnull((1,2,4)) selinux_nodiscard;
>  extern int security_compute_create_raw(const char * scon,
>                                        const char * tcon,
>                                        security_class_t tclass,
> -                                      char ** newcon);
> +                                      char ** newcon) selinux_nonnull((1,2,4)) selinux_nodiscard;
>  extern int security_compute_create_name(const char * scon,
>                                         const char * tcon,
>                                         security_class_t tclass,
>                                         const char *objname,
> -                                       char ** newcon);
> +                                       char ** newcon) selinux_nonnull((1,2,5)) selinux_nodiscard;
>  extern int security_compute_create_name_raw(const char * scon,
>                                             const char * tcon,
>                                             security_class_t tclass,
>                                             const char *objname,
> -                                           char ** newcon);
> +                                           char ** newcon) selinux_nonnull((1,2,5)) selinux_nodiscard;
>
>  /* Compute a relabeling decision and set *newcon to refer to it.
>     Caller must free via freecon. */
>  extern int security_compute_relabel(const char * scon,
>                                     const char * tcon,
>                                     security_class_t tclass,
> -                                   char ** newcon);
> +                                   char ** newcon) selinux_nonnull((1,2,4)) selinux_nodiscard;
>  extern int security_compute_relabel_raw(const char * scon,
>                                         const char * tcon,
>                                         security_class_t tclass,
> -                                       char ** newcon);
> +                                       char ** newcon) selinux_nonnull((1,2,4)) selinux_nodiscard;
>
>  /* Compute a polyinstantiation member decision and set *newcon to refer to it.
>     Caller must free via freecon. */
>  extern int security_compute_member(const char * scon,
>                                    const char * tcon,
>                                    security_class_t tclass,
> -                                  char ** newcon);
> +                                  char ** newcon) selinux_nonnull((1,2,4)) selinux_nodiscard;
>  extern int security_compute_member_raw(const char * scon,
>                                        const char * tcon,
>                                        security_class_t tclass,
> -                                      char ** newcon);
> +                                      char ** newcon) selinux_nonnull((1,2,4)) selinux_nodiscard;
>
>  /*
>   * Compute the set of reachable user contexts and set *con to refer to
> @@ -265,10 +261,10 @@ extern int security_compute_member_raw(const char * scon,
>   */
>  extern int security_compute_user(const char * scon,
>                                  const char *username,
> -                                char *** con);
> +                                char *** con) selinux_nonnull((1,2,3)) selinux_nodiscard;
>  extern int security_compute_user_raw(const char * scon,
>                                      const char *username,
> -                                    char *** con);
> +                                    char *** con) selinux_nonnull((1,2,3)) selinux_nodiscard;
>
>  /* Validate a transition. This determines whether a transition from scon to newcon
>     using tcon as the target for object class tclass is valid in the loaded policy.
> @@ -277,21 +273,21 @@ extern int security_compute_user_raw(const char * scon,
>  extern int security_validatetrans(const char *scon,
>                                   const char *tcon,
>                                   security_class_t tclass,
> -                                 const char *newcon);
> +                                 const char *newcon) selinux_nonnull((1,2,4)) selinux_nodiscard;
>  extern int security_validatetrans_raw(const char *scon,
>                                       const char *tcon,
>                                       security_class_t tclass,
> -                                     const char *newcon);
> +                                     const char *newcon) selinux_nonnull((1,2,4)) selinux_nodiscard;
>
>  /* Load a policy configuration. */
> -extern int security_load_policy(const void *data, size_t len);
> +extern int security_load_policy(const void *data, size_t len) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Get the context of an initial kernel security identifier by name.
>     Caller must free via freecon */
>  extern int security_get_initial_context(const char *name,
> -                                       char ** con);
> +                                       char ** con) selinux_nonnull((1,2)) selinux_nodiscard;
>  extern int security_get_initial_context_raw(const char *name,
> -                                           char ** con);
> +                                           char ** con) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /*
>   * Make a policy image and load it.
> @@ -303,7 +299,7 @@ extern int security_get_initial_context_raw(const char *name,
>   *
>   * 'preservebools' is no longer supported, set to 0.
>   */
> -extern int selinux_mkload_policy(int preservebools);
> +extern int selinux_mkload_policy(int preservebools) selinux_nodiscard;
>
>  /*
>   * Perform the initial policy load.
> @@ -320,7 +316,7 @@ extern int selinux_mkload_policy(int preservebools);
>   * determine how to proceed.  If enforcing (*enforce > 0), then init should
>   * halt the system.  Otherwise, init may proceed normally without a re-exec.
>   */
> -extern int selinux_init_load_policy(int *enforce);
> +extern int selinux_init_load_policy(int *enforce) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Translate boolean strict to name value pair. */
>  typedef struct {
> @@ -331,62 +327,58 @@ typedef struct {
>   * longer supported, set to 0.
>   */
>  extern int security_set_boolean_list(size_t boolcnt,
> -                                    SELboolean * boollist, int permanent);
> +                                    SELboolean * boollist, int permanent) selinux_nonnull((2)) selinux_nodiscard;
>
>  /* Load policy boolean settings. Deprecated as local policy booleans no
>   * longer supported. Will always return -1.
>   */
> -extern int security_load_booleans(char *path)
> -#ifdef __GNUC__
> -__attribute__ ((deprecated))
> -#endif
> -;
> +extern int security_load_booleans(char *path) selinux_deprecated("Local booleans are no longer supported");
>
>  /* Check the validity of a security context. */
> -extern int security_check_context(const char * con);
> -extern int security_check_context_raw(const char * con);
> +extern int security_check_context(const char * con) selinux_nonnull((1)) selinux_nodiscard;
> +extern int security_check_context_raw(const char * con) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Canonicalize a security context. */
>  extern int security_canonicalize_context(const char * con,
> -                                        char ** canoncon);
> +                                        char ** canoncon) selinux_nonnull((1,2)) selinux_nodiscard;
>  extern int security_canonicalize_context_raw(const char * con,
> -                                            char ** canoncon);
> +                                            char ** canoncon) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /* Get the enforce flag value. */
> -extern int security_getenforce(void);
> +extern int security_getenforce(void) selinux_nodiscard;
>
>  /* Set the enforce flag value. */
> -extern int security_setenforce(int value);
> +extern int security_setenforce(int value) selinux_nodiscard;
>
>  /* Get the load-time behavior for undefined classes/permissions */
> -extern int security_reject_unknown(void);
> +extern int security_reject_unknown(void) selinux_nodiscard;
>
>  /* Get the runtime behavior for undefined classes/permissions */
> -extern int security_deny_unknown(void);
> +extern int security_deny_unknown(void); selinux_nodiscard
>
>  /* Get the checkreqprot value */
> -extern int security_get_checkreqprot(void);
> +extern int security_get_checkreqprot(void) selinux_nodiscard;
>
>  /* Disable SELinux at runtime (must be done prior to initial policy load). */
> -extern int security_disable(void);
> +extern int security_disable(void) selinux_nodiscard;
>
>  /* Get the policy version number. */
> -extern int security_policyvers(void);
> +extern int security_policyvers(void) selinux_nodiscard;
>
>  /* Get the boolean names */
> -extern int security_get_boolean_names(char ***names, int *len);
> +extern int security_get_boolean_names(char ***names, int *len) selinux_nodiscard;
>
>  /* Get the pending value for the boolean */
> -extern int security_get_boolean_pending(const char *name);
> +extern int security_get_boolean_pending(const char *name) selinux_nodiscard;
>
>  /* Get the active value for the boolean */
> -extern int security_get_boolean_active(const char *name);
> +extern int security_get_boolean_active(const char *name) selinux_nodiscard;
>
>  /* Set the pending value for the boolean */
> -extern int security_set_boolean(const char *name, int value);
> +extern int security_set_boolean(const char *name, int value) selinux_nodiscard;
>
>  /* Commit the pending values for the booleans */
> -extern int security_commit_booleans(void);
> +extern int security_commit_booleans(void) selinux_nodiscard;
>
>  /* Userspace class mapping support */
>  struct security_class_mapping {
> @@ -413,26 +405,26 @@ struct security_class_mapping {
>   * starting at 1, and have one security_class_mapping structure entry
>   * per define.
>   */
> -extern int selinux_set_mapping(struct security_class_mapping *map);
> +extern int selinux_set_mapping(struct security_class_mapping *map) selinux_nodiscard;
>
>  /* Common helpers */
>
>  /* Convert between mode and security class values */
> -extern security_class_t mode_to_security_class(mode_t mode);
> +extern security_class_t mode_to_security_class(mode_t mode) selinux_nodiscard;
>  /* Convert between security class values and string names */
> -extern security_class_t string_to_security_class(const char *name);
> -extern const char *security_class_to_string(security_class_t cls);
> +extern security_class_t string_to_security_class(const char *name) selinux_nonnull((1)) selinux_nodiscard;
> +extern const char *security_class_to_string(security_class_t cls) selinux_nodiscard;
>
>  /* Convert between individual access vector permissions and string names */
>  extern const char *security_av_perm_to_string(security_class_t tclass,
> -                                             access_vector_t perm);
> +                                             access_vector_t perm) selinux_nodiscard;
>  extern access_vector_t string_to_av_perm(security_class_t tclass,
> -                                        const char *name);
> +                                        const char *name) selinux_nonnull((2)) selinux_nodiscard;
>
>  /* Returns an access vector in a string representation.  User must free the
>   * returned string via free(). */
>  extern int security_av_string(security_class_t tclass,
> -                             access_vector_t av, char **result);
> +                             access_vector_t av, char **result) selinux_nonnull((3)) selinux_nodiscard;
>
>  /* Display an access vector in a string representation. */
>  extern void print_access_vector(security_class_t tclass, access_vector_t av);
> @@ -476,27 +468,19 @@ extern void set_matchpathcon_flags(unsigned int flags);
>     function also checks for a 'path'.homedirs file and
>     a 'path'.local file and loads additional specifications
>     from them if present. */
> -extern int matchpathcon_init(const char *path)
> -#ifdef __GNUC__
> -   __attribute__ ((deprecated("Use selabel_open with backend SELABEL_CTX_FILE")))
> -#endif
> -;
> +extern int matchpathcon_init(const char *path) selinux_nodiscard selinux_deprecated("Use selabel_open(3) with backend SELABEL_CTX_FILE");
>
>  /* Same as matchpathcon_init, but only load entries with
>     regexes that have stems that are prefixes of 'prefix'. */
> -extern int matchpathcon_init_prefix(const char *path, const char *prefix);
> +extern int matchpathcon_init_prefix(const char *path, const char *prefix) selinux_nodiscard;
>
>  /* Free the memory allocated by matchpathcon_init. */
> -extern void matchpathcon_fini(void)
> -#ifdef __GNUC__
> -   __attribute__ ((deprecated("Use selabel_close")))
> -#endif
> -;
> +extern void matchpathcon_fini(void) selinux_deprecated("Use selabel_close(3)");
>
>  /* Resolve all of the symlinks and relative portions of a pathname, but NOT
>   * the final component (same a realpath() unless the final component is a
>   * symlink.  Resolved path must be a path of size PATH_MAX + 1 */
> -extern int realpath_not_final(const char *name, char *resolved_path);
> +extern int realpath_not_final(const char *name, char *resolved_path) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /* Match the specified pathname and mode against the file contexts
>     configuration and set *con to refer to the resulting context.
> @@ -505,23 +489,19 @@ extern int realpath_not_final(const char *name, char *resolved_path);
>     If matchpathcon_init has not already been called, then this function
>     will call it upon its first invocation with a NULL path. */
>  extern int matchpathcon(const char *path,
> -                       mode_t mode, char ** con)
> -#ifdef __GNUC__
> -       __attribute__ ((deprecated("Use selabel_lookup instead")))
> -#endif
> -;
> +                       mode_t mode, char ** con) selinux_nonnull((1,3)) selinux_nodiscard selinux_deprecated("Use selabel_lookup(3)");
>
>  /* Same as above, but return a specification index for
>     later use in a matchpathcon_filespec_add() call - see below. */
>  extern int matchpathcon_index(const char *path,
> -                             mode_t mode, char ** con);
> +                             mode_t mode, char ** con) selinux_nonnull((1,3)) selinux_nodiscard;
>
>  /* Maintain an association between an inode and a specification index,
>     and check whether a conflicting specification is already associated
>     with the same inode (e.g. due to multiple hard links).  If so, then
>     use the latter of the two specifications based on their order in the
>     file contexts configuration.  Return the used specification index. */
> -extern int matchpathcon_filespec_add(ino_t ino, int specind, const char *file);
> +extern int matchpathcon_filespec_add(ino_t ino, int specind, const char *file) selinux_nonnull((3)) selinux_nodiscard;
>
>  /* Destroy any inode associations that have been added, e.g. to restart
>     for a new filesystem. */
> @@ -537,14 +517,14 @@ extern void matchpathcon_checkmatches(char *str);
>  /* Match the specified media and against the media contexts
>     configuration and set *con to refer to the resulting context.
>     Caller must free con via freecon. */
> -extern int matchmediacon(const char *media, char ** con);
> +extern int matchmediacon(const char *media, char ** con) selinux_nonnull((1,2)) selinux_nodiscard;
>
>  /*
>    selinux_getenforcemode reads the /etc/selinux/config file and determines
>    whether the machine should be started in enforcing (1), permissive (0) or
>    disabled (-1) mode.
>   */
> -extern int selinux_getenforcemode(int *enforce);
> +extern int selinux_getenforcemode(int *enforce) selinux_nonnull((1)) selinux_nodiscard;
>
>  /*
>    selinux_boolean_sub reads the /etc/selinux/TYPE/booleans.subs_dist file
> @@ -552,73 +532,65 @@ extern int selinux_getenforcemode(int *enforce);
>    returns the translated name otherwise it returns the original name.
>    The returned value needs to be freed. On failure NULL will be returned.
>   */
> -extern char *selinux_boolean_sub(const char *boolean_name);
> +extern char *selinux_boolean_sub(const char *boolean_name) selinux_nodiscard;
>
>  /*
>    selinux_getpolicytype reads the /etc/selinux/config file and determines
>    what the default policy for the machine is.  Calling application must
>    free policytype.
>   */
> -extern int selinux_getpolicytype(char **policytype);
> +extern int selinux_getpolicytype(char **policytype) selinux_nonnull((1)) selinux_nodiscard;
>
>  /*
>    selinux_policy_root reads the /etc/selinux/config file and returns
>    the directory path under which the compiled policy file and context
>    configuration files exist.
>   */
> -extern const char *selinux_policy_root(void);
> +extern const char *selinux_policy_root(void) selinux_nodiscard;
>
>  /*
>    selinux_set_policy_root sets an alternate policy root directory path under
>    which the compiled policy file and context configuration files exist.
>   */
> -extern int selinux_set_policy_root(const char *rootpath);
> +extern int selinux_set_policy_root(const char *rootpath) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* These functions return the paths to specific files under the
>     policy root directory. */
> -extern const char *selinux_current_policy_path(void);
> -extern const char *selinux_binary_policy_path(void);
> -extern const char *selinux_failsafe_context_path(void);
> -extern const char *selinux_removable_context_path(void);
> -extern const char *selinux_default_context_path(void);
> -extern const char *selinux_user_contexts_path(void);
> -extern const char *selinux_file_context_path(void);
> -extern const char *selinux_file_context_homedir_path(void);
> -extern const char *selinux_file_context_local_path(void);
> -extern const char *selinux_file_context_subs_path(void);
> -extern const char *selinux_file_context_subs_dist_path(void);
> -extern const char *selinux_homedir_context_path(void);
> -extern const char *selinux_media_context_path(void);
> -extern const char *selinux_virtual_domain_context_path(void);
> -extern const char *selinux_virtual_image_context_path(void);
> -extern const char *selinux_lxc_contexts_path(void);
> -extern const char *selinux_x_context_path(void);
> -extern const char *selinux_sepgsql_context_path(void);
> -extern const char *selinux_openrc_contexts_path(void);
> -extern const char *selinux_openssh_contexts_path(void);
> -extern const char *selinux_snapperd_contexts_path(void);
> -extern const char *selinux_systemd_contexts_path(void);
> -extern const char *selinux_contexts_path(void);
> -extern const char *selinux_securetty_types_path(void);
> -extern const char *selinux_booleans_subs_path(void);
> +extern const char *selinux_current_policy_path(void) selinux_nodiscard;
> +extern const char *selinux_binary_policy_path(void) selinux_nodiscard;
> +extern const char *selinux_failsafe_context_path(void) selinux_nodiscard;
> +extern const char *selinux_removable_context_path(void) selinux_nodiscard;
> +extern const char *selinux_default_context_path(void) selinux_nodiscard;
> +extern const char *selinux_user_contexts_path(void) selinux_nodiscard;
> +extern const char *selinux_file_context_path(void) selinux_nodiscard;
> +extern const char *selinux_file_context_homedir_path(void) selinux_nodiscard;
> +extern const char *selinux_file_context_local_path(void) selinux_nodiscard;
> +extern const char *selinux_file_context_subs_path(void) selinux_nodiscard;
> +extern const char *selinux_file_context_subs_dist_path(void) selinux_nodiscard;
> +extern const char *selinux_homedir_context_path(void) selinux_nodiscard;
> +extern const char *selinux_media_context_path(void) selinux_nodiscard;
> +extern const char *selinux_virtual_domain_context_path(void) selinux_nodiscard;
> +extern const char *selinux_virtual_image_context_path(void) selinux_nodiscard;
> +extern const char *selinux_lxc_contexts_path(void) selinux_nodiscard;
> +extern const char *selinux_x_context_path(void) selinux_nodiscard;
> +extern const char *selinux_sepgsql_context_path(void) selinux_nodiscard;
> +extern const char *selinux_openrc_contexts_path(void) selinux_nodiscard;
> +extern const char *selinux_openssh_contexts_path(void) selinux_nodiscard;
> +extern const char *selinux_snapperd_contexts_path(void) selinux_nodiscard;
> +extern const char *selinux_systemd_contexts_path(void) selinux_nodiscard;
> +extern const char *selinux_contexts_path(void) selinux_nodiscard;
> +extern const char *selinux_securetty_types_path(void) selinux_nodiscard;
> +extern const char *selinux_booleans_subs_path(void) selinux_nodiscard;
>  /* Deprecated as local policy booleans no longer supported. */
> -extern const char *selinux_booleans_path(void)
> -#ifdef __GNUC__
> -__attribute__ ((deprecated))
> -#endif
> -;
> -extern const char *selinux_customizable_types_path(void);
> +extern const char *selinux_booleans_path(void) selinux_nodiscard selinux_deprecated("Local booleans are no longer supported");
> +extern const char *selinux_customizable_types_path(void) selinux_nodiscard;
>  /* Deprecated as policy ./users no longer supported. */
> -extern const char *selinux_users_path(void)
> -#ifdef __GNUC__
> -__attribute__ ((deprecated))
> -#endif
> -;
> -extern const char *selinux_usersconf_path(void);
> -extern const char *selinux_translations_path(void);
> -extern const char *selinux_colors_path(void);
> -extern const char *selinux_netfilter_context_path(void);
> -extern const char *selinux_path(void);
> +extern const char *selinux_users_path(void) selinux_nodiscard selinux_deprecated("Local users are no longer supported");
> +extern const char *selinux_usersconf_path(void) selinux_nodiscard;
> +extern const char *selinux_translations_path(void) selinux_nodiscard;
> +extern const char *selinux_colors_path(void) selinux_nodiscard;
> +extern const char *selinux_netfilter_context_path(void) selinux_nodiscard;
> +extern const char *selinux_path(void) selinux_nodiscard;
>
>  /**
>   * selinux_check_access - Check permissions and perform appropriate auditing.
> @@ -637,56 +609,43 @@ extern const char *selinux_path(void);
>   * If auditing or logging is configured the appropriate callbacks will be called
>   * and passed the auditdata field
>   */
> -extern int selinux_check_access(const char * scon, const char * tcon, const char *tclass, const char *perm, void *auditdata);
> +extern int selinux_check_access(const char * scon, const char * tcon, const char *tclass, const char *perm, void *auditdata) selinux_nonnull((1,2,3,4)) selinux_nodiscard;
>
>  /* Check a permission in the passwd class.
>     Return 0 if granted or -1 otherwise. */
> -extern int selinux_check_passwd_access(access_vector_t requested)
> -#ifdef __GNUC__
> -  __attribute__ ((deprecated("Use selinux_check_access")))
> -#endif
> -;
> -
> -extern int checkPasswdAccess(access_vector_t requested)
> -#ifdef __GNUC__
> -   __attribute__ ((deprecated("Use selinux_check_access")))
> -#endif
> -;
> +extern int selinux_check_passwd_access(access_vector_t requested) selinux_nodiscard selinux_deprecated("Use selinux_check_access(3)");
> +extern int checkPasswdAccess(access_vector_t requested) selinux_nodiscard selinux_deprecated("Use selinux_check_access(3)");
>
>  /* Check if the tty_context is defined as a securetty
>     Return 0 if secure, < 0 otherwise. */
> -extern int selinux_check_securetty_context(const char * tty_context);
> +extern int selinux_check_securetty_context(const char * tty_context) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Set the path to the selinuxfs mount point explicitly.
>     Normally, this is determined automatically during libselinux
>     initialization, but this is not always possible, e.g. for /sbin/init
>     which performs the initial mount of selinuxfs. */
> -extern void set_selinuxmnt(const char *mnt);
> +extern void set_selinuxmnt(const char *mnt) selinux_nonnull((1));
>
>  /* Check if selinuxfs exists as a kernel filesystem */
> -extern int selinuxfs_exists(void);
> +extern int selinuxfs_exists(void) selinux_nodiscard;
>
>  /* clear selinuxmnt variable and free allocated memory */
>  extern void fini_selinuxmnt(void);
>
>  /* Set an appropriate security context based on the filename of a helper
>   * program, falling back to a new context with the specified type. */
> -extern int setexecfilecon(const char *filename, const char *fallback_type);
> +extern int setexecfilecon(const char *filename, const char *fallback_type) selinux_nonnull((1)) selinux_nodiscard;
>
>  #ifndef DISABLE_RPM
>  /* Execute a helper for rpm in an appropriate security context. */
>  extern int rpm_execcon(unsigned int verified,
>                        const char *filename,
> -                      char *const argv[], char *const envp[])
> -#ifdef __GNUC__
> -       __attribute__((deprecated("Use setexecfilecon and execve")))
> -#endif
> -;
> +                      char *const argv[], char *const envp[]) selinux_deprecated("Use setexecfilecon(3) and execve(2)");
>  #endif
>
>  /* Returns whether a file context is customizable, and should not
>     be relabeled . */
> -extern int is_context_customizable(const char * scontext);
> +extern int is_context_customizable(const char * scontext) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* Perform context translation between the human-readable format
>     ("translated") and the internal system format ("raw").
> @@ -694,9 +653,9 @@ extern int is_context_customizable(const char * scontext);
>     Returns -1 upon an error or 0 otherwise.
>     If passed NULL, sets the returned context to NULL and returns 0. */
>  extern int selinux_trans_to_raw_context(const char * trans,
> -                                       char ** rawp);
> +                                       char ** rawp) selinux_nonnull((2)) selinux_nodiscard;
>  extern int selinux_raw_to_trans_context(const char * raw,
> -                                       char ** transp);
> +                                       char ** transp) selinux_nonnull((2)) selinux_nodiscard;
>
>  /* Perform context translation between security contexts
>     and display colors.  Returns a space-separated list of ten
> @@ -704,14 +663,14 @@ extern int selinux_raw_to_trans_context(const char * raw,
>     Caller must free the resulting string via free.
>     Returns -1 upon an error or 0 otherwise. */
>  extern int selinux_raw_context_to_color(const char * raw,
> -                                       char **color_str);
> +                                       char **color_str) selinux_nonnull((2)) selinux_nodiscard;
>
>  /* Get the SELinux username and level to use for a given Linux username.
>     These values may then be passed into the get_ordered_context_list*
>     and get_default_context* functions to obtain a context for the user.
>     Returns 0 on success or -1 otherwise.
>     Caller must free the returned strings via free. */
> -extern int getseuserbyname(const char *linuxuser, char **seuser, char **level);
> +extern int getseuserbyname(const char *linuxuser, char **seuser, char **level) selinux_nonnull((1,2,3)) selinux_nodiscard;
>
>  /* Get the SELinux username and level to use for a given Linux username and service.
>     These values may then be passed into the get_ordered_context_list*
> @@ -719,20 +678,21 @@ extern int getseuserbyname(const char *linuxuser, char **seuser, char **level);
>     Returns 0 on success or -1 otherwise.
>     Caller must free the returned strings via free. */
>  extern int getseuser(const char *username, const char *service,
> -                    char **r_seuser, char **r_level);
> +                    char **r_seuser, char **r_level) selinux_nonnull((1,3,4)) selinux_nodiscard;
>
> -/* Compare two file contexts, return 0 if equivalent. */
> +/* Compare two contexts to see if their differences are "significant",
> + * or whether the only difference is in the user. Return 0 if equivalent. */
>  extern int selinux_file_context_cmp(const char * a,
> -                            const char * b);
> +                            const char * b) selinux_nodiscard;
>
>  /*
>   * Verify the context of the file 'path' against policy.
>   * Return 1 if match, 0 if not and -1 on error.
>   */
> -extern int selinux_file_context_verify(const char *path, mode_t mode);
> +extern int selinux_file_context_verify(const char *path, mode_t mode) selinux_nonnull((1)) selinux_nodiscard;
>
>  /* This function sets the file context on to the system defaults returns 0 on success */
> -extern int selinux_lsetfilecon_default(const char *path);
> +extern int selinux_lsetfilecon_default(const char *path) selinux_nonnull((1)) selinux_nodiscard;
>
>  /*
>   * Force a reset of the loaded configuration
> diff --git a/libselinux/src/exception.sh b/libselinux/src/exception.sh
> index 3b7f2450..15413c7a 100755
> --- a/libselinux/src/exception.sh
> +++ b/libselinux/src/exception.sh
> @@ -28,10 +28,10 @@ FILE_LIST=(
>      ../include/selinux/label.h
>      ../include/selinux/restorecon.h
>  )
> -if ! cat "${FILE_LIST[@]}" | ${CC:-gcc} -x c -c -I../include -o temp.o - -aux-info temp.aux
> +if ! cat "${FILE_LIST[@]}" | ${CC:-gcc} -x c -c -I../include -DNO_INCLUDE_ERROR -o temp.o - -aux-info temp.aux
>  then
>      # clang does not support -aux-info so fall back to gcc
> -    cat "${FILE_LIST[@]}" | gcc -x c -c -I../include -o temp.o - -aux-info temp.aux
> +    cat "${FILE_LIST[@]}" | gcc -x c -c -I../include -DNO_INCLUDE_ERROR -o temp.o - -aux-info temp.aux
>  fi
>  for i in `awk '/<stdin>.*extern int/ { print $6 }' temp.aux`; do except $i ; done
>  rm -f -- temp.aux temp.o
> diff --git a/libselinux/src/selinuxswig.i b/libselinux/src/selinuxswig.i
> index dbdb4c3d..42e31e10 100644
> --- a/libselinux/src/selinuxswig.i
> +++ b/libselinux/src/selinuxswig.i
> @@ -57,6 +57,7 @@
>  %ignore avc_netlink_release_fd;
>  %ignore avc_netlink_check_nb;
>
> +%include "../include/selinux/_private.h"
>  %include "../include/selinux/avc.h"
>  %include "../include/selinux/context.h"
>  %include "../include/selinux/get_context_list.h"
> diff --git a/scripts/run-scan-build b/scripts/run-scan-build
> index 931ffd2a..5a79c8bc 100755
> --- a/scripts/run-scan-build
> +++ b/scripts/run-scan-build
> @@ -32,7 +32,7 @@ fi
>  make -C .. clean distclean -j"$(nproc)"
>  $SCAN_BUILD -analyze-headers -o "$OUTPUTDIR" make -C .. \
>      DESTDIR="$DESTDIR" \
> -    CFLAGS="-O2 -Wall -Wextra -D_FORTIFY_SOURCE=2 -D__CHECKER__ -I$DESTDIR/usr/include" \
> +    CFLAGS="-O2 -Wall -Wextra -D_FORTIFY_SOURCE=2 -D__CHECKER__ -DNO_INCLUDE_ERROR -I$DESTDIR/usr/include" \
>      -j"$(nproc)" \
>      install install-pywrap install-rubywrap all test
>
> --
> 2.40.1
>




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux