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>
146 lines
3.9 KiB
C
146 lines
3.9 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
|
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
|
|
* SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko
|
|
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
/* $Id$ */
|
|
#ifndef COMMONIO_H
|
|
#define COMMONIO_H
|
|
|
|
#include "defines.h" /* bool */
|
|
|
|
/*
|
|
* Linked list entry.
|
|
*/
|
|
struct commonio_entry {
|
|
/*@null@*/char *line;
|
|
/*@null@*/void *eptr; /* struct passwd, struct spwd, ... */
|
|
/*@dependent@*/ /*@null@*/struct commonio_entry *prev;
|
|
/*@owned@*/ /*@null@*/struct commonio_entry *next;
|
|
bool changed:1;
|
|
};
|
|
|
|
/*
|
|
* Operations depending on database type: passwd, group, shadow etc.
|
|
*/
|
|
struct commonio_ops {
|
|
/*
|
|
* Make a copy of the object (for example, struct passwd)
|
|
* and all strings pointed by it, in malloced memory.
|
|
*/
|
|
/*@null@*/ /*@only@*/void *(*dup) (const void *);
|
|
|
|
/*
|
|
* free() the object including any strings pointed by it.
|
|
*/
|
|
void (*free)(/*@only@*/void *);
|
|
|
|
/*
|
|
* Return the name of the object (for example, pw_name
|
|
* for struct passwd).
|
|
*/
|
|
const char *(*getname) (const void *);
|
|
|
|
/*
|
|
* Parse a string, return object (in static area -
|
|
* should be copied using the dup operation above).
|
|
*/
|
|
void *(*parse) (const char *);
|
|
|
|
/*
|
|
* Write the object to the file (this calls putpwent()
|
|
* for struct passwd, for example).
|
|
*/
|
|
int (*put) (const void *, FILE *);
|
|
|
|
/*
|
|
* fgets and fputs (can be replaced by versions that
|
|
* understand line continuation conventions).
|
|
*/
|
|
/*@null@*/char *(*fgets) (/*@returned@*/ /*@out@*/char *s, int n, FILE *stream);
|
|
int (*fputs) (const char *, FILE *);
|
|
|
|
/*
|
|
* open_hook and close_hook.
|
|
* If non NULL, these functions will be called after the database
|
|
* is open or before it is closed.
|
|
* They return 0 on failure and 1 on success.
|
|
*/
|
|
/*@null@*/int (*open_hook) (void);
|
|
/*@null@*/int (*close_hook) (void);
|
|
};
|
|
|
|
/*
|
|
* Database structure.
|
|
*/
|
|
struct commonio_db {
|
|
/*
|
|
* Name of the data file.
|
|
*/
|
|
char filename[1024];
|
|
|
|
/*
|
|
* Operations from above.
|
|
*/
|
|
/*@observer@*/const struct commonio_ops *ops;
|
|
|
|
/*
|
|
* Currently open file stream.
|
|
*/
|
|
/*@dependent@*/ /*@null@*/FILE *fp;
|
|
|
|
#ifdef WITH_SELINUX
|
|
/*@null@*/char *scontext;
|
|
#endif
|
|
/*
|
|
* Default permissions and owner for newly created data file.
|
|
*/
|
|
mode_t st_mode;
|
|
uid_t st_uid;
|
|
gid_t st_gid;
|
|
/*
|
|
* Head, tail, current position in linked list.
|
|
*/
|
|
/*@owned@*/ /*@null@*/struct commonio_entry *head;
|
|
/*@dependent@*/ /*@null@*/struct commonio_entry *tail;
|
|
/*@dependent@*/ /*@null@*/struct commonio_entry *cursor;
|
|
|
|
/*
|
|
* Various flags.
|
|
*/
|
|
bool changed:1;
|
|
bool isopen:1;
|
|
bool locked:1;
|
|
bool readonly:1;
|
|
bool setname:1;
|
|
};
|
|
|
|
extern int commonio_setname (struct commonio_db *, const char *);
|
|
extern bool commonio_present (const struct commonio_db *db);
|
|
extern int commonio_lock (struct commonio_db *);
|
|
extern int commonio_lock_nowait (struct commonio_db *, bool log);
|
|
extern int do_fcntl_lock (const char *file, bool log, short type);
|
|
extern int commonio_open (struct commonio_db *, int);
|
|
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
|
|
extern int commonio_update (struct commonio_db *, const void *);
|
|
#ifdef ENABLE_SUBIDS
|
|
extern int commonio_append (struct commonio_db *, const void *);
|
|
#endif /* ENABLE_SUBIDS */
|
|
extern int commonio_remove (struct commonio_db *, const char *);
|
|
extern int commonio_rewind (struct commonio_db *);
|
|
extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *);
|
|
extern int commonio_close (struct commonio_db *);
|
|
extern int commonio_unlock (struct commonio_db *);
|
|
extern void commonio_del_entry (struct commonio_db *,
|
|
const struct commonio_entry *);
|
|
extern int commonio_sort_wrt (struct commonio_db *shadow,
|
|
const struct commonio_db *passwd);
|
|
extern int commonio_sort (struct commonio_db *db,
|
|
int (*cmp) (const void *, const void *));
|
|
|
|
#endif
|