Coverage Report

Created: 2025-11-16 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/lib/util_ea.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   SMB Extended attribute buffer handling
4
   Copyright (C) Jeremy Allison                 2005-2013
5
   Copyright (C) Tim Prouty     2008
6
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
*/
20
21
#include "includes.h"
22
#include "lib/util_ea.h"
23
24
/****************************************************************************
25
 Read one EA list entry from the buffer.
26
****************************************************************************/
27
28
struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
29
0
{
30
0
  struct ea_list *eal = talloc_zero(ctx, struct ea_list);
31
0
  uint16_t val_len;
32
0
  unsigned int namelen;
33
0
  size_t converted_size;
34
35
0
  if (!eal) {
36
0
    goto fail;
37
0
  }
38
39
0
  if (data_size < 6) {
40
0
    goto fail;
41
0
  }
42
43
0
  eal->ea.flags = CVAL(pdata,0);
44
0
  namelen = CVAL(pdata,1);
45
0
  val_len = SVAL(pdata,2);
46
47
0
  if (4 + namelen + 1 + val_len > data_size) {
48
0
    goto fail;
49
0
  }
50
51
  /* Ensure the name is null terminated. */
52
0
  if (pdata[namelen + 4] != '\0') {
53
0
    goto fail;
54
0
  }
55
0
  if (!pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4, &converted_size)) {
56
0
    DBG_ERR("pull_ascii_talloc failed: %s\n", strerror(errno));
57
0
  }
58
0
  if (!eal->ea.name) {
59
0
    goto fail;
60
0
  }
61
62
0
  eal->ea.value = data_blob_talloc(eal, NULL, (size_t)val_len + 1);
63
0
  if (!eal->ea.value.data) {
64
0
    goto fail;
65
0
  }
66
67
0
  memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
68
69
  /* Ensure we're null terminated just in case we print the value. */
70
0
  eal->ea.value.data[val_len] = '\0';
71
  /* But don't count the null. */
72
0
  eal->ea.value.length--;
73
74
0
  if (pbytes_used) {
75
0
    *pbytes_used = 4 + namelen + 1 + val_len;
76
0
  }
77
78
0
  DBG_DEBUG("read ea name %s\n", eal->ea.name);
79
0
  dump_data(10, eal->ea.value.data, eal->ea.value.length);
80
81
0
  return eal;
82
0
fail:
83
0
  TALLOC_FREE(eal);
84
0
  return NULL;
85
0
}
86
87
/****************************************************************************
88
 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
89
****************************************************************************/
90
91
struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
92
0
{
93
0
  struct ea_list *ea_list_head = NULL;
94
0
  size_t offset = 0;
95
96
0
  if (data_size < 4) {
97
0
    return NULL;
98
0
  }
99
100
0
  while (offset + 4 <= data_size) {
101
0
    size_t next_offset = IVAL(pdata,offset);
102
0
    struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);
103
104
0
    if (!eal) {
105
0
      return NULL;
106
0
    }
107
108
0
    DLIST_ADD_END(ea_list_head, eal);
109
0
    if (next_offset == 0) {
110
0
      break;
111
0
    }
112
113
    /* Integer wrap protection for the increment. */
114
0
    if (offset + next_offset < offset) {
115
0
      break;
116
0
    }
117
118
0
    offset += next_offset;
119
120
    /* Integer wrap protection for while loop. */
121
0
    if (offset + 4 < offset) {
122
0
      break;
123
0
    }
124
125
0
  }
126
127
0
  return ea_list_head;
128
0
}