LCOV - code coverage report
Current view: top level - lib/dpkg - db-fsys-override.c (source / functions) Coverage Total Hit
Test: dpkg 1.22.7-3-g89f48 C code coverage Lines: 0.0 % 99 0
Test Date: 2024-07-17 02:53:43 Functions: 0.0 % 4 0
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0.0 % 74 0

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * libdpkg - Debian packaging suite library routines
       3                 :             :  * db-fsys-override.c - management of filesystem stat overrides database
       4                 :             :  *
       5                 :             :  * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
       6                 :             :  * Copyright © 2000, 2001 Wichert Akkerman <wakkerma@debian.org>
       7                 :             :  * Copyright © 2008-2012 Guillem Jover <guillem@debian.org>
       8                 :             :  *
       9                 :             :  * This is free software; you can redistribute it and/or modify
      10                 :             :  * it under the terms of the GNU General Public License as published by
      11                 :             :  * the Free Software Foundation; either version 2 of the License, or
      12                 :             :  * (at your option) any later version.
      13                 :             :  *
      14                 :             :  * This is distributed in the hope that it will be useful,
      15                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17                 :             :  * GNU General Public License for more details.
      18                 :             :  *
      19                 :             :  * You should have received a copy of the GNU General Public License
      20                 :             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21                 :             :  */
      22                 :             : 
      23                 :             : #include <config.h>
      24                 :             : #include <compat.h>
      25                 :             : 
      26                 :             : #include <sys/types.h>
      27                 :             : 
      28                 :             : #include <errno.h>
      29                 :             : #include <string.h>
      30                 :             : #include <pwd.h>
      31                 :             : #include <grp.h>
      32                 :             : #include <fcntl.h>
      33                 :             : #include <unistd.h>
      34                 :             : #include <stdlib.h>
      35                 :             : 
      36                 :             : #include <dpkg/i18n.h>
      37                 :             : #include <dpkg/dpkg.h>
      38                 :             : #include <dpkg/dpkg-db.h>
      39                 :             : #include <dpkg/fdio.h>
      40                 :             : #include <dpkg/debug.h>
      41                 :             : #include <dpkg/db-fsys.h>
      42                 :             : 
      43                 :             : uid_t
      44                 :           0 : statdb_parse_uid(const char *str)
      45                 :             : {
      46                 :             :         char *endptr;
      47                 :             :         uid_t uid;
      48                 :             : 
      49         [ #  # ]:           0 :         if (str[0] == '#') {
      50                 :             :                 long int value;
      51                 :             : 
      52                 :           0 :                 errno = 0;
      53                 :           0 :                 value = strtol(str + 1, &endptr, 10);
      54   [ #  #  #  #  :           0 :                 if (str + 1 == endptr || *endptr || value < 0 || errno != 0)
             #  #  #  # ]
      55                 :           0 :                         ohshit(_("invalid statoverride uid %s"), str);
      56                 :           0 :                 uid = (uid_t)value;
      57                 :             :         } else {
      58                 :           0 :                 const struct passwd *pw = getpwnam(str);
      59                 :             : 
      60         [ #  # ]:           0 :                 if (pw == NULL)
      61                 :           0 :                         uid = (uid_t)-1;
      62                 :             :                 else
      63                 :           0 :                         uid = pw->pw_uid;
      64                 :             :         }
      65                 :             : 
      66                 :           0 :         return uid;
      67                 :             : }
      68                 :             : 
      69                 :             : gid_t
      70                 :           0 : statdb_parse_gid(const char *str)
      71                 :             : {
      72                 :             :         char *endptr;
      73                 :             :         gid_t gid;
      74                 :             : 
      75         [ #  # ]:           0 :         if (str[0] == '#') {
      76                 :             :                 long int value;
      77                 :             : 
      78                 :           0 :                 errno = 0;
      79                 :           0 :                 value = strtol(str + 1, &endptr, 10);
      80   [ #  #  #  #  :           0 :                 if (str + 1 == endptr || *endptr || value < 0 || errno != 0)
             #  #  #  # ]
      81                 :           0 :                         ohshit(_("invalid statoverride gid %s"), str);
      82                 :           0 :                 gid = (gid_t)value;
      83                 :             :         } else {
      84                 :           0 :                 const struct group *gr = getgrnam(str);
      85                 :             : 
      86         [ #  # ]:           0 :                 if (gr == NULL)
      87                 :           0 :                         gid = (gid_t)-1;
      88                 :             :                 else
      89                 :           0 :                         gid = gr->gr_gid;
      90                 :             :         }
      91                 :             : 
      92                 :           0 :         return gid;
      93                 :             : }
      94                 :             : 
      95                 :             : mode_t
      96                 :           0 : statdb_parse_mode(const char *str)
      97                 :             : {
      98                 :             :         char *endptr;
      99                 :             :         long int mode;
     100                 :             : 
     101                 :           0 :         mode = strtol(str, &endptr, 8);
     102   [ #  #  #  #  :           0 :         if (str == endptr || *endptr || mode < 0 || mode > 07777)
             #  #  #  # ]
     103                 :           0 :                 ohshit(_("invalid statoverride mode %s"), str);
     104                 :             : 
     105                 :           0 :         return (mode_t)mode;
     106                 :             : }
     107                 :             : 
     108                 :             : void
     109                 :           0 : ensure_statoverrides(enum statdb_parse_flags flags)
     110                 :             : {
     111                 :             :         static struct dpkg_db db = {
     112                 :             :                 .name = STATOVERRIDEFILE,
     113                 :             :         };
     114                 :             :         enum dpkg_db_error rc;
     115                 :             :         char *loaded_list, *loaded_list_end, *thisline, *nextline, *ptr;
     116                 :             :         struct file_stat *fso;
     117                 :             :         struct fsys_namenode *fnn;
     118                 :             :         struct fsys_hash_iter *iter;
     119                 :             : 
     120                 :           0 :         rc = dpkg_db_reopen(&db);
     121         [ #  # ]:           0 :         if (rc == DPKG_DB_SAME)
     122                 :           0 :                 return;
     123                 :             : 
     124                 :           0 :         onerr_abort++;
     125                 :             : 
     126                 :             :         /* Reset statoverride information. */
     127                 :           0 :         iter = fsys_hash_iter_new();
     128         [ #  # ]:           0 :         while ((fnn = fsys_hash_iter_next(iter)))
     129                 :           0 :                 fnn->statoverride = NULL;
     130                 :           0 :         fsys_hash_iter_free(iter);
     131                 :             : 
     132                 :           0 :         onerr_abort--;
     133                 :             : 
     134         [ #  # ]:           0 :         if (rc == DPKG_DB_NONE)
     135                 :           0 :                 return;
     136                 :             : 
     137                 :             :         /* If the statoverride list is empty we don't need to bother
     138                 :             :          * reading it. */
     139         [ #  # ]:           0 :         if (!db.st.st_size)
     140                 :           0 :                 return;
     141                 :             : 
     142                 :           0 :         onerr_abort++;
     143                 :             : 
     144                 :           0 :         loaded_list = m_malloc(db.st.st_size);
     145                 :           0 :         loaded_list_end = loaded_list + db.st.st_size;
     146                 :             : 
     147         [ #  # ]:           0 :         if (fd_read(fileno(db.file), loaded_list, db.st.st_size) < 0)
     148                 :           0 :                 ohshite(_("reading statoverride file '%.250s'"), db.pathname);
     149                 :             : 
     150                 :           0 :         thisline = loaded_list;
     151         [ #  # ]:           0 :         while (thisline < loaded_list_end) {
     152                 :           0 :                 fso = nfmalloc(sizeof(*fso));
     153                 :             : 
     154                 :           0 :                 ptr = memchr(thisline, '\n', loaded_list_end - thisline);
     155         [ #  # ]:           0 :                 if (ptr == NULL)
     156                 :           0 :                         ohshit(_("statoverride file is missing final newline"));
     157                 :             :                 /* Where to start next time around. */
     158                 :           0 :                 nextline = ptr + 1;
     159         [ #  # ]:           0 :                 if (ptr == thisline)
     160                 :           0 :                         ohshit(_("statoverride file contains empty line"));
     161                 :           0 :                 *ptr = '\0';
     162                 :             : 
     163                 :             :                 /* Extract the uid. */
     164                 :           0 :                 ptr = memchr(thisline, ' ', nextline - thisline);
     165         [ #  # ]:           0 :                 if (ptr == NULL)
     166                 :           0 :                         ohshit(_("syntax error in statoverride file"));
     167                 :           0 :                 *ptr = '\0';
     168                 :             : 
     169                 :           0 :                 fso->uid = statdb_parse_uid(thisline);
     170         [ #  # ]:           0 :                 if (fso->uid == (uid_t)-1)
     171                 :           0 :                         fso->uname = nfstrsave(thisline);
     172                 :             :                 else
     173                 :           0 :                         fso->uname = NULL;
     174                 :             : 
     175   [ #  #  #  # ]:           0 :                 if (fso->uid == (uid_t)-1 && !(flags & STATDB_PARSE_LAX))
     176                 :           0 :                         ohshit(_("unknown system user '%s' in statoverride file; the system user got removed\n"
     177                 :             :                                  "before the override, which is most probably a packaging bug, to recover you\n"
     178                 :             :                                  "can remove the override manually with %s"), thisline, DPKGSTAT);
     179                 :             : 
     180                 :             :                 /* Move to the next bit */
     181                 :           0 :                 thisline = ptr + 1;
     182         [ #  # ]:           0 :                 if (thisline >= loaded_list_end)
     183                 :           0 :                         ohshit(_("unexpected end of line in statoverride file"));
     184                 :             : 
     185                 :             :                 /* Extract the gid */
     186                 :           0 :                 ptr = memchr(thisline, ' ', nextline - thisline);
     187         [ #  # ]:           0 :                 if (ptr == NULL)
     188                 :           0 :                         ohshit(_("syntax error in statoverride file"));
     189                 :           0 :                 *ptr = '\0';
     190                 :             : 
     191                 :           0 :                 fso->gid = statdb_parse_gid(thisline);
     192         [ #  # ]:           0 :                 if (fso->gid == (gid_t)-1)
     193                 :           0 :                         fso->gname = nfstrsave(thisline);
     194                 :             :                 else
     195                 :           0 :                         fso->gname = NULL;
     196                 :             : 
     197   [ #  #  #  # ]:           0 :                 if (fso->gid == (gid_t)-1 && !(flags & STATDB_PARSE_LAX))
     198                 :           0 :                         ohshit(_("unknown system group '%s' in statoverride file; the system group got removed\n"
     199                 :             :                                  "before the override, which is most probably a packaging bug, to recover you\n"
     200                 :             :                                  "can remove the override manually with %s"), thisline, DPKGSTAT);
     201                 :             : 
     202                 :             :                 /* Move to the next bit */
     203                 :           0 :                 thisline = ptr + 1;
     204         [ #  # ]:           0 :                 if (thisline >= loaded_list_end)
     205                 :           0 :                         ohshit(_("unexpected end of line in statoverride file"));
     206                 :             : 
     207                 :             :                 /* Extract the mode */
     208                 :           0 :                 ptr = memchr(thisline, ' ', nextline - thisline);
     209         [ #  # ]:           0 :                 if (ptr == NULL)
     210                 :           0 :                         ohshit(_("syntax error in statoverride file"));
     211                 :           0 :                 *ptr = '\0';
     212                 :             : 
     213                 :           0 :                 fso->mode = statdb_parse_mode(thisline);
     214                 :             : 
     215                 :             :                 /* Move to the next bit */
     216                 :           0 :                 thisline = ptr + 1;
     217         [ #  # ]:           0 :                 if (thisline >= loaded_list_end)
     218                 :           0 :                         ohshit(_("unexpected end of line in statoverride file"));
     219                 :             : 
     220                 :           0 :                 fnn = fsys_hash_find_node(thisline, FHFF_NONE);
     221         [ #  # ]:           0 :                 if (fnn->statoverride)
     222                 :           0 :                         ohshit(_("multiple statoverrides present for file '%.250s'"),
     223                 :             :                                thisline);
     224                 :           0 :                 fnn->statoverride = fso;
     225                 :             : 
     226                 :             :                 /* Moving on... */
     227                 :           0 :                 thisline = nextline;
     228                 :             :         }
     229                 :             : 
     230                 :           0 :         free(loaded_list);
     231                 :             : 
     232                 :           0 :         onerr_abort--;
     233                 :             : }
        

Generated by: LCOV version 2.0-1