Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

DiskUtils.TryGetReparseDataBuffer reads a struct from unzeroed pooled memory and ignores the number of bytes returned

Ouverte
#242 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
3/5
Temps estimé
Une demi-journée
Accessibilité débutants
57/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
csharp
Domaine
backend

Piste de recherche

Start with TruePath/DiskUtils.cs at TryGetReparseDataBuffer and inspect how DeviceIoControl reports the number of bytes returned. Check how IsJunction consumes the result and how SymbolicLinkReparseBuffer represents tag-specific fields. Done when short responses cannot produce a successful read of stale data and fields are interpreted according to the reparse tag.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

bug good first issue help wanted

DiskUtils.TryGetReparseDataBuffer reads a SymbolicLinkReparseBuffer out of a buffer rented from ArrayPool<byte>.Shared:

byte[] buffer = ArrayPool<byte>.Shared.Rent(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
// ... DeviceIoControl(..., out _, ...)   // bytes returned are discarded
Span<byte> bufferSpan = new(buffer);
success = MemoryMarshal.TryRead(bufferSpan, out SymbolicLinkReparseBuffer reparseDataBuffer);

Two things are wrong here:

  1. Pooled arrays are not zeroed, and the number of bytes written by DeviceIoControl is ignored. The span covers the whole (larger-than-needed) array, so TryRead always succeeds, even when the driver returned fewer bytes than sizeof(SymbolicLinkReparseBuffer) (20 bytes). Reparse points with little or no payload leave the remaining fields filled with leftovers of whatever previously used the pooled array.
  2. SymbolicLinkReparseBuffer is a symlink-specific layout. Its Flags field only exists for symlinks. For junctions (mount points), and for other tags, the same four bytes are PathBuffer contents or arbitrary data.

No wrong result is observable today, because the only consumer, DiskUtils.IsJunction, reads just ReparseTag, which is always in the first four bytes of a successful response. But the method is a trap for the next person who reads another field. It reads uninitialized (stale) data and returns a struct whose fields can be garbage while the method reports success.

Recommendations

  • Capture lpBytesReturned and use new Span<byte>(buffer, 0, (int)bytesReturned), so that TryRead fails for a response that's too short.
  • Better: make the method return only what it can actually vouch for. Either return just the ReparseTag (that's all IsJunction needs), or expose a header-only struct (ReparseTag, ReparseDataLength, Reserved) and parse the tag-specific part per tag.
  • Rename or document the struct accordingly, so it's clear that Flags is valid only for IO_REPARSE_TAG_SYMLINK.
Langage dominant
C#
Étoiles
107
Forks
22
Merge moyen
3 j 2 h
PR mergées (30 j)
13

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de ForNeVeR/TruePath

Toutes les issues de ForNeVeR/TruePath

Issues similaires

Plus d'issues C#

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.