Coverage Report

Created: 2025-06-24 07:00

/src/boringssl/crypto/bio/fd.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/bio.h>
16
17
#if !defined(OPENSSL_NO_POSIX_IO)
18
19
#include <errno.h>
20
#include <string.h>
21
22
#if !defined(OPENSSL_WINDOWS)
23
#include <unistd.h>
24
#else
25
#include <io.h>
26
#endif
27
28
#include <openssl/err.h>
29
#include <openssl/mem.h>
30
31
#include "internal.h"
32
#include "../internal.h"
33
34
35
#if defined(OPENSSL_WINDOWS)
36
  #define BORINGSSL_CLOSE _close
37
  #define BORINGSSL_LSEEK _lseek
38
  #define BORINGSSL_READ _read
39
  #define BORINGSSL_WRITE _write
40
#else
41
0
  #define BORINGSSL_CLOSE close
42
0
  #define BORINGSSL_LSEEK lseek
43
0
  #define BORINGSSL_READ read
44
0
  #define BORINGSSL_WRITE write
45
#endif
46
47
0
BIO *BIO_new_fd(int fd, int close_flag) {
48
0
  BIO *ret = BIO_new(BIO_s_fd());
49
0
  if (ret == NULL) {
50
0
    return NULL;
51
0
  }
52
0
  BIO_set_fd(ret, fd, close_flag);
53
0
  return ret;
54
0
}
55
56
0
static int fd_new(BIO *bio) {
57
  // num is used to store the file descriptor.
58
0
  bio->num = -1;
59
0
  return 1;
60
0
}
61
62
0
static int fd_free(BIO *bio) {
63
0
  if (bio->shutdown) {
64
0
    if (bio->init) {
65
0
      BORINGSSL_CLOSE(bio->num);
66
0
    }
67
0
    bio->init = 0;
68
0
  }
69
0
  return 1;
70
0
}
71
72
0
static int fd_read(BIO *b, char *out, int outl) {
73
0
  int ret = 0;
74
75
0
  ret = (int)BORINGSSL_READ(b->num, out, outl);
76
0
  BIO_clear_retry_flags(b);
77
0
  if (ret <= 0) {
78
0
    if (bio_errno_should_retry(ret)) {
79
0
      BIO_set_retry_read(b);
80
0
    }
81
0
  }
82
83
0
  return ret;
84
0
}
85
86
0
static int fd_write(BIO *b, const char *in, int inl) {
87
0
  int ret = (int)BORINGSSL_WRITE(b->num, in, inl);
88
0
  BIO_clear_retry_flags(b);
89
0
  if (ret <= 0) {
90
0
    if (bio_errno_should_retry(ret)) {
91
0
      BIO_set_retry_write(b);
92
0
    }
93
0
  }
94
95
0
  return ret;
96
0
}
97
98
0
static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) {
99
0
  switch (cmd) {
100
0
    case BIO_CTRL_RESET:
101
0
      num = 0;
102
0
      [[fallthrough]];
103
0
    case BIO_C_FILE_SEEK:
104
0
      if (b->init) {
105
0
        return (long)BORINGSSL_LSEEK(b->num, num, SEEK_SET);
106
0
      }
107
0
      return 0;
108
0
    case BIO_C_FILE_TELL:
109
0
    case BIO_CTRL_INFO:
110
0
      if (b->init) {
111
0
        return (long)BORINGSSL_LSEEK(b->num, 0, SEEK_CUR);
112
0
      }
113
0
      return 0;
114
0
    case BIO_C_SET_FD:
115
0
      fd_free(b);
116
0
      b->num = *static_cast<int *>(ptr);
117
0
      b->shutdown = static_cast<int>(num);
118
0
      b->init = 1;
119
0
      return 1;
120
0
    case BIO_C_GET_FD:
121
0
      if (b->init) {
122
0
        int *out = static_cast<int *>(ptr);
123
0
        if (out != nullptr) {
124
0
          *out = b->num;
125
0
        }
126
0
        return b->num;
127
0
      } else {
128
0
        return -1;
129
0
      }
130
0
    case BIO_CTRL_GET_CLOSE:
131
0
      return b->shutdown;
132
0
    case BIO_CTRL_SET_CLOSE:
133
0
      b->shutdown = static_cast<int>(num);
134
0
      return 1;
135
0
    case BIO_CTRL_FLUSH:
136
0
      return 1;
137
0
    default:
138
0
      return 0;
139
0
  }
140
0
}
141
142
0
static int fd_gets(BIO *bp, char *buf, int size) {
143
0
  if (size <= 0) {
144
0
    return 0;
145
0
  }
146
147
0
  char *ptr = buf;
148
0
  char *end = buf + size - 1;
149
0
  while (ptr < end && fd_read(bp, ptr, 1) > 0) {
150
0
    char c = ptr[0];
151
0
    ptr++;
152
0
    if (c == '\n') {
153
0
      break;
154
0
    }
155
0
  }
156
157
0
  ptr[0] = '\0';
158
159
  // The output length is bounded by |size|.
160
0
  return (int)(ptr - buf);
161
0
}
162
163
static const BIO_METHOD methods_fdp = {
164
    BIO_TYPE_FD, "file descriptor", fd_write,
165
    fd_read,     fd_gets,           fd_ctrl,
166
    fd_new,      fd_free,           /*callback_ctrl=*/nullptr,
167
};
168
169
0
const BIO_METHOD *BIO_s_fd(void) { return &methods_fdp; }
170
171
#endif  // OPENSSL_NO_POSIX_IO
172
173
0
int BIO_set_fd(BIO *bio, int fd, int close_flag) {
174
0
  return (int)BIO_int_ctrl(bio, BIO_C_SET_FD, close_flag, fd);
175
0
}
176
177
0
int BIO_get_fd(BIO *bio, int *out_fd) {
178
0
  return (int)BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *) out_fd);
179
0
}