Coverage Report

Created: 2025-10-28 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/sudo/lib/util/locking.c
Line
Count
Source
1
/*
2
 * SPDX-License-Identifier: ISC
3
 *
4
 * Copyright (c) 1999-2005, 2007, 2009-2015
5
 *  Todd C. Miller <Todd.Miller@sudo.ws>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 *
19
 * Sponsored in part by the Defense Advanced Research Projects
20
 * Agency (DARPA) and Air Force Research Laboratory, Air Force
21
 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
22
 */
23
24
#include <config.h>
25
26
#include <stdlib.h>
27
#include <string.h>
28
#ifdef HAVE_STDBOOL_H
29
# include <stdbool.h>
30
#else
31
# include <compat/stdbool.h>
32
#endif
33
#include <errno.h>
34
#include <fcntl.h>
35
#include <unistd.h>
36
37
#include <sudo_compat.h>
38
#include <sudo_util.h>
39
#include <sudo_debug.h>
40
41
bool
42
sudo_lock_file_v1(int fd, int type)
43
0
{
44
0
    return sudo_lock_region_v1(fd, type, 0);
45
0
}
46
47
/*
48
 * Lock/unlock all or part of a file.
49
 */
50
#ifdef HAVE_LOCKF
51
bool
52
sudo_lock_region_v1(int fd, int type, off_t len)
53
0
{
54
0
    int op, rc;
55
0
    off_t oldpos = -1;
56
0
    debug_decl(sudo_lock_region, SUDO_DEBUG_UTIL);
57
58
0
    switch (type) {
59
0
  case SUDO_LOCK:
60
0
      sudo_debug_printf(SUDO_DEBUG_INFO, "%s: lock %d:%lld",
61
0
    __func__, fd, (long long)len);
62
0
      op = F_LOCK;
63
0
      break;
64
0
  case SUDO_TLOCK:
65
0
      sudo_debug_printf(SUDO_DEBUG_INFO, "%s: tlock %d:%lld",
66
0
    __func__, fd, (long long)len);
67
0
      op = F_TLOCK;
68
0
      break;
69
0
  case SUDO_UNLOCK:
70
0
      sudo_debug_printf(SUDO_DEBUG_INFO, "%s: unlock %d:%lld",
71
0
    __func__, fd, (long long)len);
72
0
      op = F_ULOCK;
73
      /* Must seek to start of file to unlock the entire thing. */
74
0
      if (len == 0 && (oldpos = lseek(fd, 0, SEEK_CUR)) != -1) {
75
0
    if (lseek(fd, 0, SEEK_SET) == -1) {
76
0
        sudo_debug_printf(
77
0
      SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
78
0
      "unable to seek to beginning");
79
0
    }
80
0
      }
81
0
      break;
82
0
  default:
83
0
      sudo_debug_printf(SUDO_DEBUG_INFO, "%s: bad lock type %d",
84
0
    __func__, type);
85
0
      errno = EINVAL;
86
0
      debug_return_bool(false);
87
0
    }
88
0
    rc = lockf(fd, op, len);
89
0
    if (oldpos != -1) {
90
0
  if (lseek(fd, oldpos, SEEK_SET) == -1) {
91
0
      sudo_debug_printf(
92
0
    SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
93
0
    "unable to restore offset");
94
0
  }
95
0
    }
96
    debug_return_bool(rc == 0);
97
0
}
98
#else
99
bool
100
sudo_lock_region_v1(int fd, int type, off_t len)
101
{
102
    struct flock lock;
103
    int func;
104
    debug_decl(sudo_lock_file, SUDO_DEBUG_UTIL);
105
106
    switch (type) {
107
  case SUDO_LOCK:
108
      sudo_debug_printf(SUDO_DEBUG_INFO, "%s: lock %d:%lld",
109
    __func__, fd, (long long)len);
110
      lock.l_type = F_WRLCK;
111
      func = F_SETLKW;
112
      break;
113
  case SUDO_TLOCK:
114
      sudo_debug_printf(SUDO_DEBUG_INFO, "%s: tlock %d:%lld",
115
    __func__, fd, (long long)len);
116
      lock.l_type = F_WRLCK;
117
      func = F_SETLK;
118
      break;
119
  case SUDO_UNLOCK:
120
      sudo_debug_printf(SUDO_DEBUG_INFO, "%s: unlock %d:%lld",
121
    __func__, fd, (long long)len);
122
      lock.l_type = F_UNLCK;
123
      func = F_SETLK;
124
      break;
125
  default:
126
      sudo_debug_printf(SUDO_DEBUG_INFO, "%s: bad lock type %d",
127
    __func__, type);
128
      errno = EINVAL;
129
      debug_return_bool(false);
130
    }
131
    lock.l_start = 0;
132
    lock.l_len = len;
133
    lock.l_pid = 0;
134
    lock.l_whence = len ? SEEK_CUR : SEEK_SET;
135
136
    debug_return_bool(fcntl(fd, func, &lock) == 0);
137
}
138
#endif