lib/: Remove incorrect /*@out@*/ comment from functions that read the pointee

These functions (e.g., gr_free()), explicitly dereference the pointer
and read the pointee.

The /@out@/ comment, which is (almost) analogous to the
[[gnu::access(write_only, ...)]] attribute, means that the pointee can
be uninitialized, since it won't read it.  There's a difference between
/@out@/ and the GCC attribute: the attribute doesn't require that the
call writes to the pointee, while /@out@/ requires that the pointee be
fully initialized after the call, so it _must_ write to it.

A guess of why it was used is that these functions are similar to
free(3), which does not read the memory it frees, and so one would
assume that if it doesn't read, write_only (or equivalents) are good.
That's wrong in several ways:

-  free(3) does not read _nor_ write to the memory, so it would
   be slightly inappropriate to use write_only with it.  It wouldn't be
   "wrong", but [[gnu::access(none, ...)]] would be more appropriate.

-  Because /@out@/ requires that the call writes to the pointee, it
   would be wrong to use it in free(3), which doesn't write to the
   pointee.

-  Our functions are similar to free(3) conceptually, but they don't
   behave like free(3), since they do read the memory (pointee) (and
   also write to it), and thus they're actually read_write.

Link: <https://splint.org/manual/manual.html#undefined>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
This commit is contained in:
Alejandro Colomar
2023-12-11 14:01:38 +01:00
committed by Serge Hallyn
parent f1b9f8d829
commit 9ca6b71e76
10 changed files with 23 additions and 14 deletions

View File

@@ -37,7 +37,7 @@ struct commonio_ops {
/*
* free() the object including any strings pointed by it.
*/
void (*free) (/*@out@*/ /*@only@*/void *);
void (*free)(/*@only@*/void *);
/*
* Return the name of the object (for example, pw_name

View File

@@ -36,7 +36,8 @@ static /*@null@*/ /*@only@*/void *group_dup (const void *ent)
return __gr_dup (gr);
}
static void group_free (/*@out@*/ /*@only@*/void *ent)
static void
group_free(/*@only@*/void *ent)
{
struct group *gr = ent;

View File

@@ -77,7 +77,8 @@ void gr_free_members (struct group *grent)
}
}
void gr_free (/*@out@*/ /*@only@*/struct group *grent)
void
gr_free(/*@only@*/struct group *grent)
{
free (grent->gr_name);
if (NULL != grent->gr_passwd) {

View File

@@ -188,7 +188,7 @@ extern void __gr_set_changed (void);
/* groupmem.c */
extern /*@null@*/ /*@only@*/struct group *__gr_dup (const struct group *grent);
extern void gr_free_members (struct group *grent);
extern void gr_free (/*@out@*/ /*@only@*/struct group *grent);
extern void gr_free(/*@only@*/struct group *grent);
/* hushed.c */
extern bool hushed (const char *username);
@@ -355,7 +355,7 @@ extern /*@dependent@*/ /*@null@*/struct commonio_entry *__pw_get_head (void);
/* pwmem.c */
extern /*@null@*/ /*@only@*/struct passwd *__pw_dup (const struct passwd *pwent);
extern void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent);
extern void pw_free(/*@only@*/struct passwd *pwent);
/* csrand.c */
unsigned long csrand (void);
@@ -418,7 +418,7 @@ extern struct spwd *sgetspent (const char *string);
/* sgroupio.c */
extern void __sgr_del_entry (const struct commonio_entry *ent);
extern /*@null@*/ /*@only@*/struct sgrp *__sgr_dup (const struct sgrp *sgent);
extern void sgr_free (/*@out@*/ /*@only@*/struct sgrp *sgent);
extern void sgr_free(/*@only@*/struct sgrp *sgent);
extern /*@dependent@*/ /*@null@*/struct commonio_entry *__sgr_get_head (void);
extern void __sgr_set_changed (void);
@@ -428,7 +428,7 @@ extern void __spw_del_entry (const struct commonio_entry *ent);
/* shadowmem.c */
extern /*@null@*/ /*@only@*/struct spwd *__spw_dup (const struct spwd *spent);
extern void spw_free (/*@out@*/ /*@only@*/struct spwd *spent);
extern void spw_free(/*@only@*/struct spwd *spent);
/* shell.c */
extern int shell (const char *file, /*@null@*/const char *arg, char *const envp[]);

View File

@@ -26,7 +26,8 @@ static /*@null@*/ /*@only@*/void *passwd_dup (const void *ent)
return __pw_dup (pw);
}
static void passwd_free (/*@out@*/ /*@only@*/void *ent)
static void
passwd_free(/*@only@*/void *ent)
{
struct passwd *pw = ent;

View File

@@ -70,7 +70,8 @@
return pw;
}
void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent)
void
pw_free(/*@only@*/struct passwd *pwent)
{
if (pwent != NULL) {
free (pwent->pw_name);

View File

@@ -117,14 +117,16 @@ static /*@null@*/ /*@only@*/void *gshadow_dup (const void *ent)
return __sgr_dup (sg);
}
static void gshadow_free (/*@out@*/ /*@only@*/void *ent)
static void
gshadow_free(/*@only@*/void *ent)
{
struct sgrp *sg = ent;
sgr_free (sg);
}
void sgr_free (/*@out@*/ /*@only@*/struct sgrp *sgent)
void
sgr_free(/*@only@*/struct sgrp *sgent)
{
size_t i;
free (sgent->sg_name);

View File

@@ -31,7 +31,8 @@ static /*@null@*/ /*@only@*/void *shadow_dup (const void *ent)
return __spw_dup (sp);
}
static void shadow_free (/*@out@*//*@only@*/void *ent)
static void
shadow_free(/*@only@*/void *ent)
{
struct spwd *sp = ent;

View File

@@ -56,7 +56,8 @@
return sp;
}
void spw_free (/*@out@*/ /*@only@*/struct spwd *spent)
void
spw_free(/*@only@*/struct spwd *spent)
{
if (spent != NULL) {
free (spent->sp_namp);

View File

@@ -56,7 +56,8 @@ static /*@null@*/ /*@only@*/void *subordinate_dup (const void *ent)
*
* @ent: pointer to a subordinate_range struct to free.
*/
static void subordinate_free (/*@out@*/ /*@only@*/void *ent)
static void
subordinate_free(/*@only@*/void *ent)
{
struct subordinate_range *rangeent = ent;