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:
committed by
Serge Hallyn
parent
f1b9f8d829
commit
9ca6b71e76
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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[]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user